[PATCH 09/20] drm/amdgpu: psp DTM init
Lakha, Bhawanpreet
Bhawanpreet.Lakha at amd.com
Thu Sep 5 19:36:01 UTC 2019
On 2019-09-05 3:31 p.m., Wentland, Harry wrote:
>
> 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.
I copied this from "ras_init_shared_buff" but will fix it in v2
>> +
>> + 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