diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 65 | 
1 files changed, 47 insertions, 18 deletions
| diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 8c2204c7b384..f1035a689d35 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -57,21 +57,23 @@ static int psp_sw_init(void *handle)  		psp->prep_cmd_buf = psp_v3_1_prep_cmd_buf;  		psp->ring_init = psp_v3_1_ring_init;  		psp->ring_create = psp_v3_1_ring_create; +		psp->ring_stop = psp_v3_1_ring_stop;  		psp->ring_destroy = psp_v3_1_ring_destroy;  		psp->cmd_submit = psp_v3_1_cmd_submit;  		psp->compare_sram_data = psp_v3_1_compare_sram_data;  		psp->smu_reload_quirk = psp_v3_1_smu_reload_quirk; +		psp->mode1_reset = psp_v3_1_mode1_reset;  		break;  	case CHIP_RAVEN: -#if 0  		psp->init_microcode = psp_v10_0_init_microcode; -#endif  		psp->prep_cmd_buf = psp_v10_0_prep_cmd_buf;  		psp->ring_init = psp_v10_0_ring_init;  		psp->ring_create = psp_v10_0_ring_create; +		psp->ring_stop = psp_v10_0_ring_stop;  		psp->ring_destroy = psp_v10_0_ring_destroy;  		psp->cmd_submit = psp_v10_0_cmd_submit;  		psp->compare_sram_data = psp_v10_0_compare_sram_data; +		psp->mode1_reset = psp_v10_0_mode1_reset;  		break;  	default:  		return -EINVAL; @@ -90,6 +92,12 @@ static int psp_sw_init(void *handle)  static int psp_sw_fini(void *handle)  { +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +	release_firmware(adev->psp.sos_fw); +	adev->psp.sos_fw = NULL; +	release_firmware(adev->psp.asd_fw); +	adev->psp.asd_fw = NULL;  	return 0;  } @@ -253,15 +261,18 @@ static int psp_asd_load(struct psp_context *psp)  static int psp_hw_start(struct psp_context *psp)  { +	struct amdgpu_device *adev = psp->adev;  	int ret; -	ret = psp_bootloader_load_sysdrv(psp); -	if (ret) -		return ret; +	if (!amdgpu_sriov_vf(adev) || !adev->in_sriov_reset) { +		ret = psp_bootloader_load_sysdrv(psp); +		if (ret) +			return ret; -	ret = psp_bootloader_load_sos(psp); -	if (ret) -		return ret; +		ret = psp_bootloader_load_sos(psp); +		if (ret) +			return ret; +	}  	ret = psp_ring_create(psp, PSP_RING_TYPE__KM);  	if (ret) @@ -400,13 +411,6 @@ static int psp_hw_init(void *handle)  		return 0;  	mutex_lock(&adev->firmware.mutex); -	/* -	 * This sequence is just used on hw_init only once, no need on -	 * resume. -	 */ -	ret = amdgpu_ucode_init_bo(adev); -	if (ret) -		goto failed;  	ret = psp_load_fw(adev);  	if (ret) { @@ -431,8 +435,6 @@ static int psp_hw_fini(void *handle)  	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)  		return 0; -	amdgpu_ucode_fini_bo(adev); -  	psp_ring_destroy(psp, PSP_RING_TYPE__KM);  	amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf); @@ -453,6 +455,16 @@ static int psp_hw_fini(void *handle)  static int psp_suspend(void *handle)  { +	int ret; +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	struct psp_context *psp = &adev->psp; + +	ret = psp_ring_stop(psp, PSP_RING_TYPE__KM); +	if (ret) { +		DRM_ERROR("PSP ring stop failed\n"); +		return ret; +	} +  	return 0;  } @@ -487,6 +499,22 @@ failed:  	return ret;  } +static bool psp_check_reset(void* handle) +{ +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +	if (adev->flags & AMD_IS_APU) +		return true; + +	return false; +} + +static int psp_reset(void* handle) +{ +	struct amdgpu_device *adev = (struct amdgpu_device *)handle; +	return psp_mode1_reset(&adev->psp); +} +  static bool psp_check_fw_loading_status(struct amdgpu_device *adev,  					enum AMDGPU_UCODE_ID ucode_type)  { @@ -530,8 +558,9 @@ const struct amd_ip_funcs psp_ip_funcs = {  	.suspend = psp_suspend,  	.resume = psp_resume,  	.is_idle = NULL, +	.check_soft_reset = psp_check_reset,  	.wait_for_idle = NULL, -	.soft_reset = NULL, +	.soft_reset = psp_reset,  	.set_clockgating_state = psp_set_clockgating_state,  	.set_powergating_state = psp_set_powergating_state,  }; | 
