diff options
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.patch | 314 |
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 + |