summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c95
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,
+};