aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch314
1 files changed, 314 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch
new file mode 100644
index 00000000..3fd8b4a0
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1510-drm-amdgpu-add-psp-ras-subsystem-infrastructure.patch
@@ -0,0 +1,314 @@
+From 53a8ad4fc8d5cfba8a3d825610c9cadec3c7f3cd Mon Sep 17 00:00:00 2001
+From: xinhui pan <xinhui.pan@amd.com>
+Date: Wed, 21 Nov 2018 11:17:49 +0800
+Subject: [PATCH 1510/2940] drm/amdgpu: add psp ras subsystem infrastructure
+
+Add ras fw loading, init, terminate.
+Add ras cmd submit helper.
+Add ras feature enable/disable common function.
+
+Signed-off-by: xinhui pan <xinhui.pan@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 215 ++++++++++++++++++++++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 16 ++
+ 2 files changed, 231 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+index a4de6da19219..5abc07265107 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+@@ -470,6 +470,207 @@ static int psp_xgmi_initialize(struct psp_context *psp)
+ return ret;
+ }
+
++// ras begin
++static void psp_prep_ras_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
++ uint64_t ras_ta_mc, uint64_t ras_mc_shared,
++ uint32_t ras_ta_size, uint32_t shared_size)
++{
++ cmd->cmd_id = GFX_CMD_ID_LOAD_TA;
++ cmd->cmd.cmd_load_ta.app_phy_addr_lo = lower_32_bits(ras_ta_mc);
++ cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(ras_ta_mc);
++ cmd->cmd.cmd_load_ta.app_len = ras_ta_size;
++
++ cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(ras_mc_shared);
++ cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(ras_mc_shared);
++ cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
++}
++
++static int psp_ras_init_shared_buf(struct psp_context *psp)
++{
++ int ret;
++
++ /*
++ * Allocate 16k memory aligned to 4k from Frame Buffer (local
++ * physical) for ras ta <-> Driver
++ */
++ ret = amdgpu_bo_create_kernel(psp->adev, PSP_RAS_SHARED_MEM_SIZE,
++ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
++ &psp->ras.ras_shared_bo,
++ &psp->ras.ras_shared_mc_addr,
++ &psp->ras.ras_shared_buf);
++
++ return ret;
++}
++
++static int psp_ras_load(struct psp_context *psp)
++{
++ int ret;
++ struct psp_gfx_cmd_resp *cmd;
++
++ /*
++ * TODO: bypass the loading in sriov for now
++ */
++ if (amdgpu_sriov_vf(psp->adev))
++ return 0;
++
++ cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
++ if (!cmd)
++ return -ENOMEM;
++
++ memset(psp->fw_pri_buf, 0, PSP_1_MEG);
++ memcpy(psp->fw_pri_buf, psp->ta_ras_start_addr, psp->ta_ras_ucode_size);
++
++ psp_prep_ras_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
++ psp->ras.ras_shared_mc_addr,
++ psp->ta_ras_ucode_size, PSP_RAS_SHARED_MEM_SIZE);
++
++ ret = psp_cmd_submit_buf(psp, NULL, cmd,
++ psp->fence_buf_mc_addr);
++
++ if (!ret) {
++ psp->ras.ras_initialized = 1;
++ psp->ras.session_id = cmd->resp.session_id;
++ }
++
++ kfree(cmd);
++
++ return ret;
++}
++
++static void psp_prep_ras_ta_unload_cmd_buf(struct psp_gfx_cmd_resp *cmd,
++ uint32_t ras_session_id)
++{
++ cmd->cmd_id = GFX_CMD_ID_UNLOAD_TA;
++ cmd->cmd.cmd_unload_ta.session_id = ras_session_id;
++}
++
++static int psp_ras_unload(struct psp_context *psp)
++{
++ int ret;
++ struct psp_gfx_cmd_resp *cmd;
++
++ /*
++ * TODO: bypass the unloading in sriov for now
++ */
++ if (amdgpu_sriov_vf(psp->adev))
++ return 0;
++
++ cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
++ if (!cmd)
++ return -ENOMEM;
++
++ psp_prep_ras_ta_unload_cmd_buf(cmd, psp->ras.session_id);
++
++ ret = psp_cmd_submit_buf(psp, NULL, cmd,
++ psp->fence_buf_mc_addr);
++
++ kfree(cmd);
++
++ return ret;
++}
++
++static void psp_prep_ras_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
++ uint32_t ta_cmd_id,
++ uint32_t ras_session_id)
++{
++ cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
++ cmd->cmd.cmd_invoke_cmd.session_id = ras_session_id;
++ cmd->cmd.cmd_invoke_cmd.ta_cmd_id = ta_cmd_id;
++ /* Note: cmd_invoke_cmd.buf is not used for now */
++}
++
++int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
++{
++ int ret;
++ struct psp_gfx_cmd_resp *cmd;
++
++ /*
++ * TODO: bypass the loading in sriov for now
++ */
++ if (amdgpu_sriov_vf(psp->adev))
++ return 0;
++
++ cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);
++ if (!cmd)
++ return -ENOMEM;
++
++ psp_prep_ras_ta_invoke_cmd_buf(cmd, ta_cmd_id,
++ psp->ras.session_id);
++
++ ret = psp_cmd_submit_buf(psp, NULL, cmd,
++ psp->fence_buf_mc_addr);
++
++ kfree(cmd);
++
++ return ret;
++}
++
++int psp_ras_enable_features(struct psp_context *psp,
++ union ta_ras_cmd_input *info, bool enable)
++{
++ struct ta_ras_shared_memory *ras_cmd;
++ int ret;
++
++ if (!psp->ras.ras_initialized)
++ return -EINVAL;
++
++ ras_cmd = (struct ta_ras_shared_memory *)psp->ras.ras_shared_buf;
++ memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory));
++
++ if (enable)
++ ras_cmd->cmd_id = TA_RAS_COMMAND__ENABLE_FEATURES;
++ else
++ ras_cmd->cmd_id = TA_RAS_COMMAND__DISABLE_FEATURES;
++
++ ras_cmd->ras_in_message = *info;
++
++ ret = psp_ras_invoke(psp, ras_cmd->cmd_id);
++ if (ret)
++ return -EINVAL;
++
++ return ras_cmd->ras_status;
++}
++
++static int psp_ras_terminate(struct psp_context *psp)
++{
++ int ret;
++
++ if (!psp->ras.ras_initialized)
++ return 0;
++
++ ret = psp_ras_unload(psp);
++ if (ret)
++ return ret;
++
++ psp->ras.ras_initialized = 0;
++
++ /* free ras shared memory */
++ amdgpu_bo_free_kernel(&psp->ras.ras_shared_bo,
++ &psp->ras.ras_shared_mc_addr,
++ &psp->ras.ras_shared_buf);
++
++ return 0;
++}
++
++static int psp_ras_initialize(struct psp_context *psp)
++{
++ struct ta_ras_shared_memory *ras_cmd;
++ int ret;
++
++ if (!psp->ras.ras_initialized) {
++ ret = psp_ras_init_shared_buf(psp);
++ if (ret)
++ return ret;
++ }
++
++ ret = psp_ras_load(psp);
++ if (ret)
++ return ret;
++
++ return 0;
++}
++// ras end
++
+ static int psp_hw_start(struct psp_context *psp)
+ {
+ struct amdgpu_device *adev = psp->adev;
+@@ -506,6 +707,12 @@ static int psp_hw_start(struct psp_context *psp)
+ dev_err(psp->adev->dev,
+ "XGMI: Failed to initialize XGMI session\n");
+ }
++
++ ret = psp_ras_initialize(psp);
++ if (ret)
++ dev_err(psp->adev->dev,
++ "RAS: Failed to initialize RAS\n");
++
+ return 0;
+ }
+
+@@ -757,6 +964,8 @@ static int psp_hw_fini(void *handle)
+ psp->xgmi_context.initialized == 1)
+ psp_xgmi_terminate(psp);
+
++ psp_ras_terminate(psp);
++
+ psp_ring_destroy(psp, PSP_RING_TYPE__KM);
+
+ amdgpu_bo_free_kernel(&psp->tmr_bo, &psp->tmr_mc_addr, &psp->tmr_buf);
+@@ -790,6 +999,12 @@ static int psp_suspend(void *handle)
+ }
+ }
+
++ ret = psp_ras_terminate(psp);
++ if (ret) {
++ DRM_ERROR("Failed to terminate ras ta\n");
++ return ret;
++ }
++
+ ret = psp_ring_stop(psp, PSP_RING_TYPE__KM);
+ if (ret) {
+ DRM_ERROR("PSP ring stop failed\n");
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+index 3e6fcc9cdef0..9c067e760a5f 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+@@ -34,6 +34,7 @@
+ #define PSP_CMD_BUFFER_SIZE 0x1000
+ #define PSP_ASD_SHARED_MEM_SIZE 0x4000
+ #define PSP_XGMI_SHARED_MEM_SIZE 0x4000
++#define PSP_RAS_SHARED_MEM_SIZE 0x4000
+ #define PSP_1_MEG 0x100000
+ #define PSP_TMR_SIZE 0x400000
+
+@@ -102,6 +103,15 @@ struct psp_xgmi_context {
+ void *xgmi_shared_buf;
+ };
+
++struct psp_ras_context {
++ /*ras fw*/
++ bool ras_initialized;
++ uint32_t session_id;
++ struct amdgpu_bo *ras_shared_bo;
++ uint64_t ras_shared_mc_addr;
++ void *ras_shared_buf;
++};
++
+ struct psp_context
+ {
+ struct amdgpu_device *adev;
+@@ -162,6 +172,7 @@ struct psp_context
+ uint32_t ta_ras_ucode_size;
+ uint8_t *ta_ras_start_addr;
+ struct psp_xgmi_context xgmi_context;
++ struct psp_ras_context ras;
+ };
+
+ struct amdgpu_psp_funcs {
+@@ -232,6 +243,11 @@ extern const struct amdgpu_ip_block_version psp_v10_0_ip_block;
+
+ int psp_gpu_reset(struct amdgpu_device *adev);
+ int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
++
++int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
++int psp_ras_enable_features(struct psp_context *psp,
++ union ta_ras_cmd_input *info, bool enable);
++
+ extern const struct amdgpu_ip_block_version psp_v11_0_ip_block;
+
+ #endif
+--
+2.17.1
+