diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2021-03-26 15:52:01 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2021-03-26 15:53:21 +0100 |
commit | 2cbcb78c9ee5520c8d836c7ff57d1b60ebe8e9b7 (patch) | |
tree | 99d79eecc71a17ccb53205b28bfbe395dba91e43 /drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | |
parent | 06debd6e1b28029e6e77c41e59a162868f377897 (diff) | |
parent | 8c44390d8872ebf3a28558b59a0074df39b3da8f (diff) |
Merge tag 'amd-drm-next-5.13-2021-03-23' of https://gitlab.freedesktop.org/agd5f/linux into drm-next
amd-drm-next-5.13-2021-03-23:
amdgpu:
- Debugfs cleanup
- Various cleanups and spelling fixes
- Flexible array cleanups
- Initial AMD Freesync HDMI
- Display fixes
- 10bpc dithering improvements
- Display ASSR support
- Clean up and unify powerplay and swsmu interfaces
- Vangogh fixes
- Add SMU gfx busy queues for RV/PCO
- PCIE DPM fixes
- S0ix fixes
- GPU metrics data fixes
- DCN secure display support
- Backlight type override
- Add initial support for Aldebaran
- RAS fixes
- Prime fixes for A+A systems
- Reset fixes
- Initial resource cursor support
- Drop legacy IO BAR requirements
- Various power fixes
amdkfd:
- MMU notifier fixes
- APU fixes
radeon:
- Debugfs cleanups
- Flexible array cleanups
UAPI:
- amdgpu: Add a new INFO ioctl interface to query video capabilities
rather than hardcoding them in userspace. This allows us to provide
fine grained asic capabilities (e.g., if a particular part is
bandwidth limited, we can limit the capabilities). Proposed userspace:
https://gitlab.freedesktop.org/leoliu/drm/-/commits/info_video_caps
https://gitlab.freedesktop.org/leoliu/mesa/-/commits/info_video_caps
- amdkfd: bump the driver version. There was a problem with reporting
some RAS features on older versions of the driver. Proposed userspace:
https://github.com/RadeonOpenCompute/ROCT-Thunk-Interface/commit/7cdd63475c36bb9f49bb960f90f9a8cdb7e80a21
Danvet: A bunch of conflicts all over, but it seems to compile ... I
did put the call to dc_allow_idle_optimizations() on a single line
since it looked a bit too jarring to be left alone.
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210324040147.1990338-1-alexander.deucher@amd.com
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 95 |
1 files changed, 77 insertions, 18 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 839917eb7bc3..bae304b0d67a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -34,6 +34,7 @@ #include "psp_v10_0.h" #include "psp_v11_0.h" #include "psp_v12_0.h" +#include "psp_v13_0.h" #include "amdgpu_ras.h" #include "amdgpu_securedisplay.h" @@ -56,7 +57,7 @@ static int psp_load_smu_fw(struct psp_context *psp); * - Load XGMI/RAS/HDCP/DTM TA if any * * This new sequence is required for - * - Arcturus + * - Arcturus and onwards * - Navi12 and onwards */ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp) @@ -71,7 +72,7 @@ static void psp_check_pmfw_centralized_cstate_management(struct psp_context *psp if (adev->flags & AMD_IS_APU) return; - if ((adev->asic_type == CHIP_ARCTURUS) || + if ((adev->asic_type >= CHIP_ARCTURUS) || (adev->asic_type >= CHIP_NAVI12)) psp->pmfw_centralized_cstate_management = true; } @@ -109,6 +110,9 @@ static int psp_early_init(void *handle) case CHIP_RENOIR: psp_v12_0_set_psp_funcs(psp); break; + case CHIP_ALDEBARAN: + psp_v13_0_set_psp_funcs(psp); + break; default: return -EINVAL; } @@ -383,7 +387,7 @@ static int psp_tmr_init(struct psp_context *psp) * Note: this memory need be reserved till the driver * uninitializes. */ - tmr_size = PSP_TMR_SIZE; + 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 */ @@ -399,10 +403,20 @@ static int psp_tmr_init(struct psp_context *psp) } pptr = amdgpu_sriov_vf(psp->adev) ? &tmr_buf : NULL; - ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE, + ret = amdgpu_bo_create_kernel(psp->adev, tmr_size, PSP_TMR_SIZE(psp->adev), AMDGPU_GEM_DOMAIN_VRAM, &psp->tmr_bo, &psp->tmr_mc_addr, pptr); + /* workaround the tmr_mc_addr: + * PSP requires an address in FB aperture. Right now driver produce + * tmr_mc_addr in the GART aperture. Convert it back to FB aperture + * for PSP. Will revert it after we get a fix from PSP FW. + */ + if (psp->adev->asic_type == CHIP_ALDEBARAN) { + psp->tmr_mc_addr -= psp->adev->gmc.fb_start; + psp->tmr_mc_addr += psp->adev->gmc.fb_start_original; + } + return ret; } @@ -542,6 +556,28 @@ int psp_get_fw_attestation_records_addr(struct psp_context *psp, return ret; } +static int psp_rl_load(struct amdgpu_device *adev) +{ + struct psp_context *psp = &adev->psp; + struct psp_gfx_cmd_resp *cmd = psp->cmd; + + if (psp->rl_bin_size == 0) + return 0; + + memset(psp->fw_pri_buf, 0, PSP_1_MEG); + memcpy(psp->fw_pri_buf, psp->rl_start_addr, psp->rl_bin_size); + + memset(cmd, 0, sizeof(struct psp_gfx_cmd_resp)); + + cmd->cmd_id = GFX_CMD_ID_LOAD_IP_FW; + cmd->cmd.cmd_load_ip_fw.fw_phy_addr_lo = lower_32_bits(psp->fw_pri_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_phy_addr_hi = upper_32_bits(psp->fw_pri_mc_addr); + cmd->cmd.cmd_load_ip_fw.fw_size = psp->rl_bin_size; + cmd->cmd.cmd_load_ip_fw.fw_type = GFX_FW_TYPE_REG_LIST; + + return psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr); +} + static void psp_prep_asd_load_cmd_buf(struct psp_gfx_cmd_resp *cmd, uint64_t asd_mc, uint32_t size) { @@ -755,8 +791,9 @@ static int psp_xgmi_unload(struct psp_context *psp) struct psp_gfx_cmd_resp *cmd; struct amdgpu_device *adev = psp->adev; - /* XGMI TA unload currently is not supported on Arcturus */ - if (adev->asic_type == CHIP_ARCTURUS) + /* XGMI TA unload currently is not supported on Arcturus/Aldebaran A+A */ + if (adev->asic_type == CHIP_ARCTURUS || + (adev->asic_type == CHIP_ALDEBARAN && adev->gmc.xgmi.connected_to_cpu)) return 0; /* @@ -1561,6 +1598,7 @@ static int psp_rap_unload(struct psp_context *psp) static int psp_rap_initialize(struct psp_context *psp) { int ret; + enum ta_rap_status status = TA_RAP_STATUS__SUCCESS; /* * TODO: bypass the initialize in sriov for now @@ -1584,8 +1622,8 @@ static int psp_rap_initialize(struct psp_context *psp) if (ret) return ret; - ret = psp_rap_invoke(psp, TA_CMD_RAP__INITIALIZE); - if (ret != TA_RAP_STATUS__SUCCESS) { + ret = psp_rap_invoke(psp, TA_CMD_RAP__INITIALIZE, &status); + if (ret || status != TA_RAP_STATUS__SUCCESS) { psp_rap_unload(psp); amdgpu_bo_free_kernel(&psp->rap_context.rap_shared_bo, @@ -1594,8 +1632,10 @@ static int psp_rap_initialize(struct psp_context *psp) psp->rap_context.rap_initialized = false; - dev_warn(psp->adev->dev, "RAP TA initialize fail.\n"); - return -EINVAL; + dev_warn(psp->adev->dev, "RAP TA initialize fail (%d) status %d.\n", + ret, status); + + return ret; } return 0; @@ -1620,13 +1660,13 @@ static int psp_rap_terminate(struct psp_context *psp) return ret; } -int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id) +int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_status *status) { struct ta_rap_shared_memory *rap_cmd; - int ret; + int ret = 0; if (!psp->rap_context.rap_initialized) - return -EINVAL; + return 0; if (ta_cmd_id != TA_CMD_RAP__INITIALIZE && ta_cmd_id != TA_CMD_RAP__VALIDATE_L0) @@ -1642,14 +1682,16 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id) rap_cmd->validation_method_id = METHOD_A; ret = psp_ta_invoke(psp, rap_cmd->cmd_id, psp->rap_context.session_id); - if (ret) { - mutex_unlock(&psp->rap_context.mutex); - return ret; - } + if (ret) + goto out_unlock; + if (status) + *status = rap_cmd->rap_status; + +out_unlock: mutex_unlock(&psp->rap_context.mutex); - return rap_cmd->rap_status; + return ret; } // RAP end @@ -2276,6 +2318,12 @@ skip_memalloc: return ret; } + ret = psp_rl_load(adev); + if (ret) { + DRM_ERROR("PSP load RL failed!\n"); + return ret; + } + if (psp->adev->psp.ta_fw) { ret = psp_ras_initialize(psp); if (ret) @@ -2751,6 +2799,9 @@ int psp_init_sos_microcode(struct psp_context *psp, adev->psp.spl_bin_size = le32_to_cpu(sos_hdr_v1_3->spl_size_bytes); adev->psp.spl_start_addr = (uint8_t *)adev->psp.sys_start_addr + le32_to_cpu(sos_hdr_v1_3->spl_offset_bytes); + adev->psp.rl_bin_size = le32_to_cpu(sos_hdr_v1_3->rl_size_bytes); + adev->psp.rl_start_addr = (uint8_t *)adev->psp.sys_start_addr + + le32_to_cpu(sos_hdr_v1_3->rl_offset_bytes); } break; default: @@ -3052,3 +3103,11 @@ const struct amdgpu_ip_block_version psp_v12_0_ip_block = .rev = 0, .funcs = &psp_ip_funcs, }; + +const struct amdgpu_ip_block_version psp_v13_0_ip_block = { + .type = AMD_IP_BLOCK_TYPE_PSP, + .major = 13, + .minor = 0, + .rev = 0, + .funcs = &psp_ip_funcs, +}; |