[PATCH 09/20] drm/amdgpu: psp DTM init
Harry Wentland
hwentlan at amd.com
Thu Sep 5 19:31:13 UTC 2019
On 2019-08-29 12:22 p.m., Bhawanpreet Lakha wrote:
> DTM is the display topology manager. This is needed to communicate with
> psp about the display configurations.
>
> This patch adds
> -Loading the firmware
> -The functions and definitions for communication with the firmware
>
> Signed-off-by: Bhawanpreet Lakha <Bhawanpreet.Lakha at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 153 ++++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 15 +++
> drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 3 +
> drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 4 +
> 4 files changed, 175 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> index ccce1b506a12..7192e7fba6dc 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
> @@ -942,6 +942,149 @@ static int psp_hdcp_terminate(struct psp_context *psp)
> }
> // HDCP end
>
> +// DTM start
> +static void psp_prep_dtm_ta_load_cmd_buf(struct psp_gfx_cmd_resp *cmd,
> + uint64_t dtm_ta_mc, uint64_t dtm_mc_shared,
> + uint32_t dtm_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(dtm_ta_mc);
> + cmd->cmd.cmd_load_ta.app_phy_addr_hi = upper_32_bits(dtm_ta_mc);
> + cmd->cmd.cmd_load_ta.app_len = dtm_ta_size;
> +
> + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_lo = lower_32_bits(dtm_mc_shared);
> + cmd->cmd.cmd_load_ta.cmd_buf_phy_addr_hi = upper_32_bits(dtm_mc_shared);
> + cmd->cmd.cmd_load_ta.cmd_buf_len = shared_size;
> +}
> +
> +static int psp_dtm_init_shared_buf(struct psp_context *psp)
> +{
> + int ret;
> +
> + /*
> + * Allocate 16k memory aligned to 4k from Frame Buffer (local
> + * physical) for dtm ta <-> Driver
> + */
> + ret = amdgpu_bo_create_kernel(psp->adev, PSP_DTM_SHARED_MEM_SIZE,
> + PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,
> + &psp->dtm_context.dtm_shared_bo,
> + &psp->dtm_context.dtm_shared_mc_addr,
> + &psp->dtm_context.dtm_shared_buf);
Formatting is off here and elsewhere. Same on psp HDCP init patch.
> +
> + return ret;
> +}
> +
> +static int psp_dtm_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_dtm_start_addr, psp->ta_dtm_ucode_size);
> +
> + psp_prep_dtm_ta_load_cmd_buf(cmd, psp->fw_pri_mc_addr,
> + psp->dtm_context.dtm_shared_mc_addr,
> + psp->ta_dtm_ucode_size, PSP_DTM_SHARED_MEM_SIZE);
> +
> + ret = psp_cmd_submit_buf(psp, NULL, cmd,
> + psp->fence_buf_mc_addr);
> +
> + if (!ret) {
> + printk("LOADEDDE dtm !!!!!1");
debug printk? please drop it
> + psp->dtm_context.dtm_initialized = 1;
> + psp->dtm_context.session_id = cmd->resp.session_id;
> + }
> +
> + kfree(cmd);
> +
> + return ret;
> +}
> +
> +static int psp_dtm_initialize(struct psp_context *psp)
> +{
> + int ret;
> +
> + if (!psp->dtm_context.dtm_initialized) {
> + ret = psp_dtm_init_shared_buf(psp);
> + if (ret)
> + return ret;
> + }
> +
> + ret = psp_dtm_load(psp);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
> +static void psp_prep_dtm_ta_invoke_cmd_buf(struct psp_gfx_cmd_resp *cmd,
> + uint32_t ta_cmd_id,
> + uint32_t dtm_session_id)
> +{
> + cmd->cmd_id = GFX_CMD_ID_INVOKE_CMD;
> + cmd->cmd.cmd_invoke_cmd.session_id = dtm_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_dtm_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_dtm_ta_invoke_cmd_buf(cmd, ta_cmd_id,
> + psp->dtm_context.session_id);
> +
> + ret = psp_cmd_submit_buf(psp, NULL, cmd,
> + psp->fence_buf_mc_addr);
> +
> + kfree(cmd);
> +
> + return ret;
> +}
> +
> +static int psp_dtm_terminate(struct psp_context *psp)
> +{
> + int ret;
> +
> + if (!psp->dtm_context.dtm_initialized)
> + return 0;
> +
> + ret = psp_hdcp_unload(psp);
> + if (ret)
> + return ret;
> +
> + psp->dtm_context.dtm_initialized = 0;
> +
> + /* free hdcp shared memory */
> + amdgpu_bo_free_kernel(&psp->dtm_context.dtm_shared_bo,
> + &psp->dtm_context.dtm_shared_mc_addr,
> + &psp->dtm_context.dtm_shared_buf);
> +
> + return 0;
> +}
> +// DTM end
> +
> static int psp_hw_start(struct psp_context *psp)
> {
> struct amdgpu_device *adev = psp->adev;
> @@ -1021,6 +1164,10 @@ static int psp_hw_start(struct psp_context *psp)
> dev_err(psp->adev->dev,
> "HDCP: Failed to initialize HDCP\n");
>
> + ret = psp_dtm_initialize(psp);
> + if (ret)
> + dev_err(psp->adev->dev,
> + "DTM: Failed to initialize DTM\n");
Does the init/terminate order matter for HDCP and DTM FW? You seem to be
initializing and terminating them in the same order, rather than in
reverse order. It's fine if they don't have any dependency on each other.
Harry
> }
>
> return 0;
> @@ -1393,6 +1540,7 @@ static int psp_hw_fini(void *handle)
> if (psp->adev->psp.ta_fw) {
> psp_ras_terminate(psp);
> psp_hdcp_terminate(psp);
> + psp_dtm_terminate(psp);
> }
>
> psp_ring_destroy(psp, PSP_RING_TYPE__KM);
> @@ -1439,6 +1587,11 @@ static int psp_suspend(void *handle)
> DRM_ERROR("Failed to terminate hdcp ta\n");
> return ret;
> }
> + ret = psp_dtm_terminate(psp);
> + if (ret) {
> + DRM_ERROR("Failed to terminate dtm ta\n");
> + return ret;
> + }
> }
>
> ret = psp_ring_stop(psp, PSP_RING_TYPE__KM);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> index 6788e1601945..7dd9ae7dbbe4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
> @@ -38,6 +38,7 @@
> #define PSP_1_MEG 0x100000
> #define PSP_TMR_SIZE 0x400000
> #define PSP_HDCP_SHARED_MEM_SIZE 0x4000
> +#define PSP_DTM_SHARED_MEM_SIZE 0x4000
> #define PSP_SHARED_MEM_SIZE 0x4000
>
> struct psp_context;
> @@ -152,6 +153,14 @@ struct psp_hdcp_context {
> void *hdcp_shared_buf;
> };
>
> +struct psp_dtm_context {
> + bool dtm_initialized;
> + uint32_t session_id;
> + struct amdgpu_bo *dtm_shared_bo;
> + uint64_t dtm_shared_mc_addr;
> + void *dtm_shared_buf;
> +};
> +
> struct psp_context
> {
> struct amdgpu_device *adev;
> @@ -221,9 +230,14 @@ struct psp_context
> uint32_t ta_hdcp_ucode_size;
> uint8_t *ta_hdcp_start_addr;
>
> + uint32_t ta_dtm_ucode_version;
> + uint32_t ta_dtm_ucode_size;
> + uint8_t *ta_dtm_start_addr;
> +
> struct psp_xgmi_context xgmi_context;
> struct psp_ras_context ras;
> struct psp_hdcp_context hdcp_context;
> + struct psp_dtm_context dtm_context;
> struct mutex mutex;
> };
>
> @@ -296,6 +310,7 @@ 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);
> int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
> +int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
>
> int psp_rlc_autoload_start(struct psp_context *psp);
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
> index c2b593ab7495..410587b950f3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h
> @@ -111,6 +111,9 @@ struct ta_firmware_header_v1_0 {
> uint32_t ta_hdcp_ucode_version;
> uint32_t ta_hdcp_offset_bytes;
> uint32_t ta_hdcp_size_bytes;
> + uint32_t ta_dtm_ucode_version;
> + uint32_t ta_dtm_offset_bytes;
> + uint32_t ta_dtm_size_bytes;
> };
>
> /* version_major=1, version_minor=0 */
> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> index 348ec4e275f3..e93770133ad7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c
> @@ -97,6 +97,10 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)
>
> adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);
>
> + adev->psp.ta_dtm_ucode_version = le32_to_cpu(ta_hdr->ta_dtm_ucode_version);
> + adev->psp.ta_dtm_ucode_size = le32_to_cpu(ta_hdr->ta_dtm_size_bytes);
> + adev->psp.ta_dtm_start_addr = (uint8_t *)adev->psp.ta_hdcp_start_addr +
> + le32_to_cpu(ta_hdr->ta_dtm_offset_bytes);
> }
>
> return 0;
>
More information about the amd-gfx
mailing list