diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 184 | 
1 files changed, 89 insertions, 95 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 78d1ee71f3f4..8fdca54bb8a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -45,9 +45,6 @@  #define AMD_VBIOS_FILE_MAX_SIZE_B      (1024*1024*3) -static int psp_sysfs_init(struct amdgpu_device *adev); -static void psp_sysfs_fini(struct amdgpu_device *adev); -  static int psp_load_smu_fw(struct psp_context *psp);  static int psp_rap_terminate(struct psp_context *psp);  static int psp_securedisplay_terminate(struct psp_context *psp); @@ -148,6 +145,7 @@ static int psp_init_sriov_microcode(struct psp_context *psp)  		break;  	case IP_VERSION(13, 0, 6):  		ret = psp_init_cap_microcode(psp, ucode_prefix); +		ret &= psp_init_ta_microcode(psp, ucode_prefix);  		break;  	case IP_VERSION(13, 0, 10):  		adev->virt.autoload_ucode_id = AMDGPU_UCODE_ID_CP_MES1_DATA; @@ -180,9 +178,11 @@ static int psp_early_init(void *handle)  		psp->autoload_supported = false;  		break;  	case IP_VERSION(11, 0, 0): +	case IP_VERSION(11, 0, 7): +		adev->psp.sup_pd_fw_up = !amdgpu_sriov_vf(adev); +		fallthrough;  	case IP_VERSION(11, 0, 5):  	case IP_VERSION(11, 0, 9): -	case IP_VERSION(11, 0, 7):  	case IP_VERSION(11, 0, 11):  	case IP_VERSION(11, 5, 0):  	case IP_VERSION(11, 0, 12): @@ -202,8 +202,8 @@ static int psp_early_init(void *handle)  	case IP_VERSION(13, 0, 3):  	case IP_VERSION(13, 0, 5):  	case IP_VERSION(13, 0, 8): -	case IP_VERSION(13, 0, 10):  	case IP_VERSION(13, 0, 11): +	case IP_VERSION(14, 0, 0):  		psp_v13_0_set_psp_funcs(psp);  		psp->autoload_supported = true;  		break; @@ -215,8 +215,10 @@ static int psp_early_init(void *handle)  		break;  	case IP_VERSION(13, 0, 0):  	case IP_VERSION(13, 0, 7): +	case IP_VERSION(13, 0, 10):  		psp_v13_0_set_psp_funcs(psp);  		psp->autoload_supported = true; +		adev->psp.sup_ifwi_up = !amdgpu_sriov_vf(adev);  		break;  	case IP_VERSION(13, 0, 4):  		psp_v13_0_4_set_psp_funcs(psp); @@ -437,14 +439,15 @@ static int psp_sw_init(void *handle)  			/* If psp runtime database exists, then  			 * only enable two stage memory training  			 * when TWO_STAGE_DRAM_TRAINING bit is set -			 * in runtime database */ +			 * in runtime database +			 */  			mem_training_ctx->enable_mem_training = true;  		}  	} else { -		/* If psp runtime database doesn't exist or -		 * is invalid, force enable two stage memory -		 * training */ +		/* If psp runtime database doesn't exist or is +		 * invalid, force enable two stage memory training +		 */  		mem_training_ctx->enable_mem_training = true;  	} @@ -462,13 +465,6 @@ static int psp_sw_init(void *handle)  		}  	} -	if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) || -	    adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7)) { -		ret = psp_sysfs_init(adev); -		if (ret) -			return ret; -	} -  	ret = amdgpu_bo_create_kernel(adev, PSP_1_MEG, PSP_1_MEG,  				      amdgpu_sriov_vf(adev) ?  				      AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT, @@ -520,10 +516,6 @@ static int psp_sw_fini(void *handle)  	amdgpu_ucode_release(&psp->cap_fw);  	amdgpu_ucode_release(&psp->toc_fw); -	if (adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 0) || -	    adev->ip_versions[MP0_HWIP][0] == IP_VERSION(11, 0, 7)) -		psp_sysfs_fini(adev); -  	kfree(cmd);  	cmd = NULL; @@ -807,7 +799,8 @@ static int psp_tmr_init(struct psp_context *psp)  	tmr_size = PSP_TMR_SIZE(psp->adev);  	/* For ASICs support RLC autoload, psp will parse the toc -	 * and calculate the total size of TMR needed */ +	 * and calculate the total size of TMR needed +	 */  	if (!amdgpu_sriov_vf(psp->adev) &&  	    psp->toc.start_addr &&  	    psp->toc.size_bytes && @@ -1147,9 +1140,9 @@ int psp_ta_init_shared_buf(struct psp_context *psp,  				  struct ta_mem_context *mem_ctx)  {  	/* -	* Allocate 16k memory aligned to 4k from Frame Buffer (local -	* physical) for ta to host memory -	*/ +	 * Allocate 16k memory aligned to 4k from Frame Buffer (local +	 * physical) for ta to host memory +	 */  	return amdgpu_bo_create_kernel(psp->adev, mem_ctx->shared_mem_size,  				      PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM |  				      AMDGPU_GEM_DOMAIN_GTT, @@ -1738,7 +1731,8 @@ int psp_ras_trigger_error(struct psp_context *psp,  		return -EINVAL;  	/* If err_event_athub occurs error inject was successful, however -	   return status from TA is no long reliable */ +	 *  return status from TA is no long reliable +	 */  	if (amdgpu_ras_intr_triggered())  		return 0; @@ -2459,8 +2453,8 @@ static int psp_prep_load_ip_fw_cmd_buf(struct amdgpu_firmware_info *ucode,  	return ret;  } -static int psp_execute_non_psp_fw_load(struct psp_context *psp, -				  struct amdgpu_firmware_info *ucode) +int psp_execute_ip_fw_load(struct psp_context *psp, +			   struct amdgpu_firmware_info *ucode)  {  	int ret = 0;  	struct psp_gfx_cmd_resp *cmd = acquire_psp_cmd_buf(psp); @@ -2503,7 +2497,7 @@ static int psp_load_smu_fw(struct psp_context *psp)  			DRM_WARN("Failed to set MP1 state prepare for reload\n");  	} -	ret = psp_execute_non_psp_fw_load(psp, ucode); +	ret = psp_execute_ip_fw_load(psp, ucode);  	if (ret)  		DRM_ERROR("PSP load smu failed!\n"); @@ -2545,7 +2539,7 @@ int psp_load_fw_list(struct psp_context *psp,  	for (i = 0; i < ucode_count; ++i) {  		ucode = ucode_list[i];  		psp_print_fw_hdr(psp, ucode); -		ret = psp_execute_non_psp_fw_load(psp, ucode); +		ret = psp_execute_ip_fw_load(psp, ucode);  		if (ret)  			return ret;  	} @@ -2587,12 +2581,13 @@ static int psp_load_non_psp_fw(struct psp_context *psp)  		     ucode->ucode_id == AMDGPU_UCODE_ID_SDMA2 ||  		     ucode->ucode_id == AMDGPU_UCODE_ID_SDMA3))  			/* PSP only receive one SDMA fw for sienna_cichlid, -			 * as all four sdma fw are same */ +			 * as all four sdma fw are same +			 */  			continue;  		psp_print_fw_hdr(psp, ucode); -		ret = psp_execute_non_psp_fw_load(psp, ucode); +		ret = psp_execute_ip_fw_load(psp, ucode);  		if (ret)  			return ret; @@ -2652,8 +2647,8 @@ static int psp_load_fw(struct amdgpu_device *adev)  		if (adev->gmc.xgmi.num_physical_nodes > 1) {  			ret = psp_xgmi_initialize(psp, false, true);  			/* Warning the XGMI seesion initialize failure -			* Instead of stop driver initialization -			*/ +			 * Instead of stop driver initialization +			 */  			if (ret)  				dev_err(psp->adev->dev,  					"XGMI: Failed to initialize XGMI session\n"); @@ -2931,19 +2926,6 @@ int psp_rlc_autoload_start(struct psp_context *psp)  	return ret;  } -int psp_update_vcn_sram(struct amdgpu_device *adev, int inst_idx, -			uint64_t cmd_gpu_addr, int cmd_size) -{ -	struct amdgpu_firmware_info ucode = {0}; - -	ucode.ucode_id = inst_idx ? AMDGPU_UCODE_ID_VCN1_RAM : -		AMDGPU_UCODE_ID_VCN0_RAM; -	ucode.mc_addr = cmd_gpu_addr; -	ucode.ucode_size = cmd_size; - -	return psp_execute_non_psp_fw_load(&adev->psp, &ucode); -} -  int psp_ring_cmd_submit(struct psp_context *psp,  			uint64_t cmd_buf_mc_addr,  			uint64_t fence_mc_addr, @@ -3584,6 +3566,11 @@ void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size  	drm_dev_exit(idx);  } +/** + * DOC: usbc_pd_fw + * Reading from this file will retrieve the USB-C PD firmware version. Writing to + * this file will trigger the update process. + */  static DEVICE_ATTR(usbc_pd_fw, 0644,  		   psp_usbc_pd_fw_sysfs_read,  		   psp_usbc_pd_fw_sysfs_write); @@ -3624,7 +3611,7 @@ static ssize_t amdgpu_psp_vbflash_write(struct file *filp, struct kobject *kobj,  	adev->psp.vbflash_image_size += count;  	mutex_unlock(&adev->psp.mutex); -	dev_info(adev->dev, "VBIOS flash write PSP done"); +	dev_dbg(adev->dev, "IFWI staged for update");  	return count;  } @@ -3644,7 +3631,7 @@ static ssize_t amdgpu_psp_vbflash_read(struct file *filp, struct kobject *kobj,  	if (adev->psp.vbflash_image_size == 0)  		return -EINVAL; -	dev_info(adev->dev, "VBIOS flash to PSP started"); +	dev_dbg(adev->dev, "PSP IFWI flash process initiated");  	ret = amdgpu_bo_create_kernel(adev, adev->psp.vbflash_image_size,  					AMDGPU_GPU_PAGE_SIZE, @@ -3669,14 +3656,32 @@ rel_buf:  	adev->psp.vbflash_image_size = 0;  	if (ret) { -		dev_err(adev->dev, "Failed to load VBIOS FW, err = %d", ret); +		dev_err(adev->dev, "Failed to load IFWI, err = %d", ret);  		return ret;  	} -	dev_info(adev->dev, "VBIOS flash to PSP done"); +	dev_dbg(adev->dev, "PSP IFWI flash process done");  	return 0;  } +/** + * DOC: psp_vbflash + * Writing to this file will stage an IFWI for update. Reading from this file + * will trigger the update process. + */ +static struct bin_attribute psp_vbflash_bin_attr = { +	.attr = {.name = "psp_vbflash", .mode = 0660}, +	.size = 0, +	.write = amdgpu_psp_vbflash_write, +	.read = amdgpu_psp_vbflash_read, +}; + +/** + * DOC: psp_vbflash_status + * The status of the flash process. + * 0: IFWI flash not complete. + * 1: IFWI flash complete. + */  static ssize_t amdgpu_psp_vbflash_status(struct device *dev,  					 struct device_attribute *attr,  					 char *buf) @@ -3693,39 +3698,49 @@ static ssize_t amdgpu_psp_vbflash_status(struct device *dev,  	return sysfs_emit(buf, "0x%x\n", vbflash_status);  } +static DEVICE_ATTR(psp_vbflash_status, 0440, amdgpu_psp_vbflash_status, NULL); -static const struct bin_attribute psp_vbflash_bin_attr = { -	.attr = {.name = "psp_vbflash", .mode = 0660}, -	.size = 0, -	.write = amdgpu_psp_vbflash_write, -	.read = amdgpu_psp_vbflash_read, +static struct bin_attribute *bin_flash_attrs[] = { +	&psp_vbflash_bin_attr, +	NULL  }; -static DEVICE_ATTR(psp_vbflash_status, 0440, amdgpu_psp_vbflash_status, NULL); +static struct attribute *flash_attrs[] = { +	&dev_attr_psp_vbflash_status.attr, +	&dev_attr_usbc_pd_fw.attr, +	NULL +}; -int amdgpu_psp_sysfs_init(struct amdgpu_device *adev) +static umode_t amdgpu_flash_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx)  { -	int ret = 0; +	struct device *dev = kobj_to_dev(kobj); +	struct drm_device *ddev = dev_get_drvdata(dev); +	struct amdgpu_device *adev = drm_to_adev(ddev); -	if (amdgpu_sriov_vf(adev)) -		return -EINVAL; +	if (attr == &dev_attr_usbc_pd_fw.attr) +		return adev->psp.sup_pd_fw_up ? 0660 : 0; -	switch (adev->ip_versions[MP0_HWIP][0]) { -	case IP_VERSION(13, 0, 0): -	case IP_VERSION(13, 0, 7): -	case IP_VERSION(13, 0, 10): -		ret = sysfs_create_bin_file(&adev->dev->kobj, &psp_vbflash_bin_attr); -		if (ret) -			dev_err(adev->dev, "Failed to create device file psp_vbflash"); -		ret = device_create_file(adev->dev, &dev_attr_psp_vbflash_status); -		if (ret) -			dev_err(adev->dev, "Failed to create device file psp_vbflash_status"); -		return ret; -	default: -		return 0; -	} +	return adev->psp.sup_ifwi_up ? 0440 : 0; +} + +static umode_t amdgpu_bin_flash_attr_is_visible(struct kobject *kobj, +						struct bin_attribute *attr, +						int idx) +{ +	struct device *dev = kobj_to_dev(kobj); +	struct drm_device *ddev = dev_get_drvdata(dev); +	struct amdgpu_device *adev = drm_to_adev(ddev); + +	return adev->psp.sup_ifwi_up ? 0660 : 0;  } +const struct attribute_group amdgpu_flash_attr_group = { +	.attrs = flash_attrs, +	.bin_attrs = bin_flash_attrs, +	.is_bin_visible = amdgpu_bin_flash_attr_is_visible, +	.is_visible = amdgpu_flash_attr_is_visible, +}; +  const struct amd_ip_funcs psp_ip_funcs = {  	.name = "psp",  	.early_init = psp_early_init, @@ -3744,27 +3759,6 @@ const struct amd_ip_funcs psp_ip_funcs = {  	.set_powergating_state = psp_set_powergating_state,  }; -static int psp_sysfs_init(struct amdgpu_device *adev) -{ -	int ret = device_create_file(adev->dev, &dev_attr_usbc_pd_fw); - -	if (ret) -		DRM_ERROR("Failed to create USBC PD FW control file!"); - -	return ret; -} - -void amdgpu_psp_sysfs_fini(struct amdgpu_device *adev) -{ -	sysfs_remove_bin_file(&adev->dev->kobj, &psp_vbflash_bin_attr); -	device_remove_file(adev->dev, &dev_attr_psp_vbflash_status); -} - -static void psp_sysfs_fini(struct amdgpu_device *adev) -{ -	device_remove_file(adev->dev, &dev_attr_usbc_pd_fw); -} -  const struct amdgpu_ip_block_version psp_v3_1_ip_block = {  	.type = AMD_IP_BLOCK_TYPE_PSP,  	.major = 3, | 
