diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 196 | 
1 files changed, 143 insertions, 53 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 949d74eff294..dc2713ec95a5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -113,8 +113,13 @@  #include "amdgpu_isp.h"  #endif -#define FIRMWARE_IP_DISCOVERY "amdgpu/ip_discovery.bin" -MODULE_FIRMWARE(FIRMWARE_IP_DISCOVERY); +MODULE_FIRMWARE("amdgpu/ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/vega10_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/vega12_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/vega20_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/raven_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/raven2_ip_discovery.bin"); +MODULE_FIRMWARE("amdgpu/picasso_ip_discovery.bin");  #define mmIP_DISCOVERY_VERSION  0x16A00  #define mmRCC_CONFIG_MEMSIZE	0xde3 @@ -297,21 +302,13 @@ static int amdgpu_discovery_read_binary_from_mem(struct amdgpu_device *adev,  	return ret;  } -static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, uint8_t *binary) +static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, +							uint8_t *binary, +							const char *fw_name)  {  	const struct firmware *fw; -	const char *fw_name;  	int r; -	switch (amdgpu_discovery) { -	case 2: -		fw_name = FIRMWARE_IP_DISCOVERY; -		break; -	default: -		dev_warn(adev->dev, "amdgpu_discovery is not set properly\n"); -		return -EINVAL; -	} -  	r = request_firmware(&fw, fw_name, adev->dev);  	if (r) {  		dev_err(adev->dev, "can't load firmware \"%s\"\n", @@ -404,10 +401,39 @@ static int amdgpu_discovery_verify_npsinfo(struct amdgpu_device *adev,  	return 0;  } +static const char *amdgpu_discovery_get_fw_name(struct amdgpu_device *adev) +{ +	if (amdgpu_discovery == 2) +		return "amdgpu/ip_discovery.bin"; + +	switch (adev->asic_type) { +	case CHIP_VEGA10: +		return "amdgpu/vega10_ip_discovery.bin"; +	case CHIP_VEGA12: +		return "amdgpu/vega12_ip_discovery.bin"; +	case CHIP_RAVEN: +		if (adev->apu_flags & AMD_APU_IS_RAVEN2) +			return "amdgpu/raven2_ip_discovery.bin"; +		else if (adev->apu_flags & AMD_APU_IS_PICASSO) +			return "amdgpu/picasso_ip_discovery.bin"; +		else +			return "amdgpu/raven_ip_discovery.bin"; +	case CHIP_VEGA20: +		return "amdgpu/vega20_ip_discovery.bin"; +	case CHIP_ARCTURUS: +		return "amdgpu/arcturus_ip_discovery.bin"; +	case CHIP_ALDEBARAN: +		return "amdgpu/aldebaran_ip_discovery.bin"; +	default: +		return NULL; +	} +} +  static int amdgpu_discovery_init(struct amdgpu_device *adev)  {  	struct table_info *info;  	struct binary_header *bhdr; +	const char *fw_name;  	uint16_t offset;  	uint16_t size;  	uint16_t checksum; @@ -419,9 +445,10 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev)  		return -ENOMEM;  	/* Read from file if it is the preferred option */ -	if (amdgpu_discovery == 2) { +	fw_name = amdgpu_discovery_get_fw_name(adev); +	if (fw_name != NULL) {  		dev_info(adev->dev, "use ip discovery information from file"); -		r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin); +		r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin, fw_name);  		if (r) {  			dev_err(adev->dev, "failed to read ip discovery binary from file\n"); @@ -587,16 +614,19 @@ void amdgpu_discovery_fini(struct amdgpu_device *adev)  	adev->mman.discovery_bin = NULL;  } -static int amdgpu_discovery_validate_ip(const struct ip_v4 *ip) +static int amdgpu_discovery_validate_ip(struct amdgpu_device *adev, +					uint8_t instance, uint16_t hw_id)  { -	if (ip->instance_number >= HWIP_MAX_INSTANCE) { -		DRM_ERROR("Unexpected instance_number (%d) from ip discovery blob\n", -			  ip->instance_number); +	if (instance >= HWIP_MAX_INSTANCE) { +		dev_err(adev->dev, +			"Unexpected instance_number (%d) from ip discovery blob\n", +			instance);  		return -EINVAL;  	} -	if (le16_to_cpu(ip->hw_id) >= HW_ID_MAX) { -		DRM_ERROR("Unexpected hw_id (%d) from ip discovery blob\n", -			  le16_to_cpu(ip->hw_id)); +	if (hw_id >= HW_ID_MAX) { +		dev_err(adev->dev, +			"Unexpected hw_id (%d) from ip discovery blob\n", +			hw_id);  		return -EINVAL;  	} @@ -609,8 +639,10 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,  	struct binary_header *bhdr;  	struct ip_discovery_header *ihdr;  	struct die_header *dhdr; -	struct ip_v4 *ip; +	struct ip *ip;  	uint16_t die_offset, ip_offset, num_dies, num_ips; +	uint16_t hw_id; +	uint8_t inst;  	int i, j;  	bhdr = (struct binary_header *)adev->mman.discovery_bin; @@ -626,16 +658,18 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,  		ip_offset = die_offset + sizeof(*dhdr);  		for (j = 0; j < num_ips; j++) { -			ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); - -			if (amdgpu_discovery_validate_ip(ip)) +			ip = (struct ip *)(adev->mman.discovery_bin + +					   ip_offset); +			inst = ip->number_instance; +			hw_id = le16_to_cpu(ip->hw_id); +			if (amdgpu_discovery_validate_ip(adev, inst, hw_id))  				goto next_ip; -			if (le16_to_cpu(ip->variant) == 1) { -				switch (le16_to_cpu(ip->hw_id)) { +			if (ip->harvest == 1) { +				switch (hw_id) {  				case VCN_HWID:  					(*vcn_harvest_count)++; -					if (ip->instance_number == 0) { +					if (inst == 0) {  						adev->vcn.harvest_config |= AMDGPU_VCN_HARVEST_VCN0;  						adev->vcn.inst_mask &=  							~AMDGPU_VCN_HARVEST_VCN0; @@ -657,10 +691,8 @@ static void amdgpu_discovery_read_harvest_bit_per_ip(struct amdgpu_device *adev,  				}  			}  next_ip: -			if (ihdr->base_addr_64_bit) -				ip_offset += struct_size(ip, base_address_64, ip->num_base_address); -			else -				ip_offset += struct_size(ip, base_address, ip->num_base_address); +			ip_offset += struct_size(ip, base_address, +						 ip->num_base_address);  		}  	}  } @@ -1019,6 +1051,8 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,  				      bool reg_base_64)  {  	int ii, jj, kk, res; +	uint16_t hw_id; +	uint8_t inst;  	DRM_DEBUG("num_ips:%d", num_ips); @@ -1034,8 +1068,10 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev,  			struct ip_hw_instance *ip_hw_instance;  			ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); -			if (amdgpu_discovery_validate_ip(ip) || -			    le16_to_cpu(ip->hw_id) != ii) +			inst = ip->instance_number; +			hw_id = le16_to_cpu(ip->hw_id); +			if (amdgpu_discovery_validate_ip(adev, inst, hw_id) || +			    hw_id != ii)  				goto next_ip;  			DRM_DEBUG("match:%d @ ip_offset:%zu", ii, ip_offset); @@ -1281,7 +1317,10 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)  	uint16_t die_offset;  	uint16_t ip_offset;  	uint16_t num_dies; +	uint32_t wafl_ver;  	uint16_t num_ips; +	uint16_t hw_id; +	uint8_t inst;  	int hw_ip;  	int i, j, k;  	int r; @@ -1292,6 +1331,7 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)  		return r;  	} +	wafl_ver = 0;  	adev->gfx.xcc_mask = 0;  	adev->sdma.sdma_mask = 0;  	adev->vcn.inst_mask = 0; @@ -1321,7 +1361,9 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)  		for (j = 0; j < num_ips; j++) {  			ip = (struct ip_v4 *)(adev->mman.discovery_bin + ip_offset); -			if (amdgpu_discovery_validate_ip(ip)) +			inst = ip->instance_number; +			hw_id = le16_to_cpu(ip->hw_id); +			if (amdgpu_discovery_validate_ip(adev, inst, hw_id))  				goto next_ip;  			num_base_address = ip->num_base_address; @@ -1390,6 +1432,10 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev)  				adev->gfx.xcc_mask |=  					(1U << ip->instance_number); +			if (!wafl_ver && le16_to_cpu(ip->hw_id) == WAFLC_HWID) +				wafl_ver = IP_VERSION_FULL(ip->major, ip->minor, +							   ip->revision, 0, 0); +  			for (k = 0; k < num_base_address; k++) {  				/*  				 * convert the endianness of base addresses in place, @@ -1455,22 +1501,32 @@ next_ip:  		}  	} +	if (wafl_ver && !adev->ip_versions[XGMI_HWIP][0]) +		adev->ip_versions[XGMI_HWIP][0] = wafl_ver; +  	return 0;  }  static void amdgpu_discovery_harvest_ip(struct amdgpu_device *adev)  { +	struct ip_discovery_header *ihdr; +	struct binary_header *bhdr;  	int vcn_harvest_count = 0;  	int umc_harvest_count = 0; +	uint16_t offset, ihdr_ver; +	bhdr = (struct binary_header *)adev->mman.discovery_bin; +	offset = le16_to_cpu(bhdr->table_list[IP_DISCOVERY].offset); +	ihdr = (struct ip_discovery_header *)(adev->mman.discovery_bin + +					      offset); +	ihdr_ver = le16_to_cpu(ihdr->version);  	/*  	 * Harvest table does not fit Navi1x and legacy GPUs,  	 * so read harvest bit per IP data structure to set  	 * harvest configuration.  	 */  	if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 2, 0) && -	    amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 3) && -	    amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4)) { +	    ihdr_ver <= 2) {  		if ((adev->pdev->device == 0x731E &&  			(adev->pdev->revision == 0xC6 ||  			 adev->pdev->revision == 0xC7)) || @@ -1864,6 +1920,7 @@ static int amdgpu_discovery_set_common_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		amdgpu_device_ip_block_add(adev, &soc21_common_ip_block);  		break;  	case IP_VERSION(12, 0, 0): @@ -1919,6 +1976,7 @@ static int amdgpu_discovery_set_gmc_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		amdgpu_device_ip_block_add(adev, &gmc_v11_0_ip_block);  		break;  	case IP_VERSION(12, 0, 0): @@ -1998,6 +2056,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 0, 12):  	case IP_VERSION(11, 0, 13):  	case IP_VERSION(11, 5, 0): +	case IP_VERSION(11, 5, 2):  		amdgpu_device_ip_block_add(adev, &psp_v11_0_ip_block);  		break;  	case IP_VERSION(11, 0, 8): @@ -2029,6 +2088,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev)  		break;  	case IP_VERSION(14, 0, 2):  	case IP_VERSION(14, 0, 3): +	case IP_VERSION(14, 0, 5):  		amdgpu_device_ip_block_add(adev, &psp_v14_0_ip_block);  		break;  	default: @@ -2061,6 +2121,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 0, 12):  	case IP_VERSION(11, 0, 13):  	case IP_VERSION(11, 5, 0): +	case IP_VERSION(11, 5, 2):  		amdgpu_device_ip_block_add(adev, &smu_v11_0_ip_block);  		break;  	case IP_VERSION(12, 0, 0): @@ -2079,6 +2140,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(13, 0, 10):  	case IP_VERSION(13, 0, 11):  	case IP_VERSION(13, 0, 14): +	case IP_VERSION(13, 0, 12):  		amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);  		break;  	case IP_VERSION(14, 0, 0): @@ -2086,6 +2148,7 @@ static int amdgpu_discovery_set_smu_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(14, 0, 2):  	case IP_VERSION(14, 0, 3):  	case IP_VERSION(14, 0, 4): +	case IP_VERSION(14, 0, 5):  		amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block);  		break;  	default: @@ -2137,6 +2200,7 @@ static int amdgpu_discovery_set_display_ip_blocks(struct amdgpu_device *adev)  		case IP_VERSION(3, 2, 1):  		case IP_VERSION(3, 5, 0):  		case IP_VERSION(3, 5, 1): +		case IP_VERSION(3, 6, 0):  		case IP_VERSION(4, 1, 0):  			/* TODO: Fix IP version. DC code expects version 4.0.1 */  			if (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(4, 1, 0)) @@ -2215,6 +2279,7 @@ static int amdgpu_discovery_set_gc_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		amdgpu_device_ip_block_add(adev, &gfx_v11_0_ip_block);  		break;  	case IP_VERSION(12, 0, 0): @@ -2270,6 +2335,7 @@ static int amdgpu_discovery_set_sdma_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(6, 1, 0):  	case IP_VERSION(6, 1, 1):  	case IP_VERSION(6, 1, 2): +	case IP_VERSION(6, 1, 3):  		amdgpu_device_ip_block_add(adev, &sdma_v6_0_ip_block);  		break;  	case IP_VERSION(7, 0, 0): @@ -2393,6 +2459,7 @@ static int amdgpu_discovery_set_mes_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		amdgpu_device_ip_block_add(adev, &mes_v11_0_ip_block);  		adev->enable_mes = true;  		adev->enable_mes_kiq = true; @@ -2480,6 +2547,38 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  	switch (adev->asic_type) {  	case CHIP_VEGA10: +	case CHIP_VEGA12: +	case CHIP_RAVEN: +	case CHIP_VEGA20: +	case CHIP_ARCTURUS: +	case CHIP_ALDEBARAN: +		/* this is not fatal.  We have a fallback below +		 * if the new firmwares are not present. some of +		 * this will be overridden below to keep things +		 * consistent with the current behavior. +		 */ +		r = amdgpu_discovery_reg_base_init(adev); +		if (!r) { +			amdgpu_discovery_harvest_ip(adev); +			amdgpu_discovery_get_gfx_info(adev); +			amdgpu_discovery_get_mall_info(adev); +			amdgpu_discovery_get_vcn_info(adev); +		} +		break; +	default: +		r = amdgpu_discovery_reg_base_init(adev); +		if (r) +			return -EINVAL; + +		amdgpu_discovery_harvest_ip(adev); +		amdgpu_discovery_get_gfx_info(adev); +		amdgpu_discovery_get_mall_info(adev); +		amdgpu_discovery_get_vcn_info(adev); +		break; +	} + +	switch (adev->asic_type) { +	case CHIP_VEGA10:  		vega10_reg_base_init(adev);  		adev->sdma.num_instances = 2;  		adev->gmc.num_umc = 4; @@ -2642,14 +2741,6 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  		adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 1, 0);  		break;  	default: -		r = amdgpu_discovery_reg_base_init(adev); -		if (r) -			return -EINVAL; - -		amdgpu_discovery_harvest_ip(adev); -		amdgpu_discovery_get_gfx_info(adev); -		amdgpu_discovery_get_mall_info(adev); -		amdgpu_discovery_get_vcn_info(adev);  		break;  	} @@ -2708,6 +2799,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		adev->family = AMDGPU_FAMILY_GC_11_5_0;  		break;  	case IP_VERSION(12, 0, 0): @@ -2733,19 +2825,13 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 5, 1):  	case IP_VERSION(11, 5, 2): +	case IP_VERSION(11, 5, 3):  		adev->flags |= AMD_IS_APU;  		break;  	default:  		break;  	} -	if (amdgpu_ip_version(adev, XGMI_HWIP, 0) == IP_VERSION(4, 8, 0)) -		adev->gmc.xgmi.supported = true; - -	if (amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3) || -	    amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 4)) -		adev->ip_versions[XGMI_HWIP][0] = IP_VERSION(6, 4, 0); -  	/* set NBIO version */  	switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {  	case IP_VERSION(6, 1, 0): @@ -2766,11 +2852,13 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  		adev->nbio.hdp_flush_reg = &nbio_v7_4_hdp_flush_reg;  		break;  	case IP_VERSION(7, 9, 0): +	case IP_VERSION(7, 9, 1):  		adev->nbio.funcs = &nbio_v7_9_funcs;  		adev->nbio.hdp_flush_reg = &nbio_v7_9_hdp_flush_reg;  		break;  	case IP_VERSION(7, 11, 0):  	case IP_VERSION(7, 11, 1): +	case IP_VERSION(7, 11, 2):  	case IP_VERSION(7, 11, 3):  		adev->nbio.funcs = &nbio_v7_11_funcs;  		adev->nbio.hdp_flush_reg = &nbio_v7_11_hdp_flush_reg; @@ -2898,6 +2986,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  	case IP_VERSION(11, 0, 10):  	case IP_VERSION(11, 0, 11):  	case IP_VERSION(11, 5, 0): +	case IP_VERSION(11, 5, 2):  	case IP_VERSION(13, 0, 1):  	case IP_VERSION(13, 0, 9):  	case IP_VERSION(13, 0, 10): @@ -2907,6 +2996,7 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev)  		adev->smuio.funcs = &smuio_v13_0_funcs;  		break;  	case IP_VERSION(13, 0, 3): +	case IP_VERSION(13, 0, 11):  		adev->smuio.funcs = &smuio_v13_0_3_funcs;  		if (adev->smuio.funcs->get_pkg_type(adev) == AMDGPU_PKG_TYPE_APU) {  			adev->flags |= AMD_IS_APU; | 
