<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-2022-jp">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<p style="font-family:Arial;font-size:11pt;color:#0078D7;margin:5pt;" align="Left">
[AMD Official Use Only - Internal Distribution Only]<br>
</p>
<br>
<div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> amd-gfx <amd-gfx-bounces@lists.freedesktop.org> on behalf of Jinzhou Su <Jinzhou.Su@amd.com><br>
<b>Sent:</b> Wednesday, January 13, 2021 11:43 AM<br>
<b>To:</b> amd-gfx@lists.freedesktop.org <amd-gfx@lists.freedesktop.org><br>
<b>Cc:</b> Su, Jinzhou (Joe) <Jinzhou.Su@amd.com>; Huang, Ray <Ray.Huang@amd.com><br>
<b>Subject:</b> [PATCH 2/2] drm/amdgpu: Add secure display TA interface</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">Add interface to load, unload, invoke command for<br>
secure display TA.<br>
<br>
v2: Add debugfs interface for secure display TA<br>
<br>
Signed-off-by: Jinzhou.Su <Jinzhou.Su@amd.com><br>
Reviewed-by: Huang Rui <ray.huang@amd.com><br>
---<br>
drivers/gpu/drm/amd/amdgpu/Makefile | 2 +-<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 3 +<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 195 ++++++++++++++++++<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h | 17 ++<br>
.../gpu/drm/amd/amdgpu/amdgpu_securedisplay.c | 174 ++++++++++++++++<br>
.../gpu/drm/amd/amdgpu/amdgpu_securedisplay.h | 36 ++++<br>
drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 4 +<br>
drivers/gpu/drm/amd/amdgpu/psp_v10_0.c | 12 +-<br>
8 files changed, 440 insertions(+), 3 deletions(-)<br>
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c<br>
create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.h<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/Makefile b/drivers/gpu/drm/amd/amdgpu/Makefile<br>
index c6262689e14e..e4bebbfa88af 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/Makefile<br>
+++ b/drivers/gpu/drm/amd/amdgpu/Makefile<br>
@@ -56,7 +56,7 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \<br>
amdgpu_gmc.o amdgpu_mmhub.o amdgpu_xgmi.o amdgpu_csa.o amdgpu_ras.o amdgpu_vm_cpu.o \<br>
amdgpu_vm_sdma.o amdgpu_discovery.o amdgpu_ras_eeprom.o amdgpu_nbio.o \<br>
amdgpu_umc.o smu_v11_0_i2c.o amdgpu_fru_eeprom.o amdgpu_rap.o \<br>
- amdgpu_fw_attestation.o<br>
+ amdgpu_fw_attestation.o amdgpu_securedisplay.o<br>
<br>
amdgpu-$(CONFIG_PERF_EVENTS) += amdgpu_pmu.o<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
index 477bead4fab1..4c38c5771cbc 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c<br>
@@ -35,6 +35,7 @@<br>
#include "amdgpu_dm_debugfs.h"<br>
#include "amdgpu_ras.h"<br>
#include "amdgpu_rap.h"<br>
+#include "amdgpu_securedisplay.h"<br>
#include "amdgpu_fw_attestation.h"<br>
<br>
/**<br>
@@ -1666,6 +1667,8 @@ int amdgpu_debugfs_init(struct amdgpu_device *adev)<br>
<br>
amdgpu_rap_debugfs_init(adev);<br>
<br>
+ amdgpu_securedisplay_debugfs_init(adev);<br>
+<br>
amdgpu_fw_attestation_debugfs_init(adev);<br>
<br>
return amdgpu_debugfs_add_files(adev, amdgpu_debugfs_list,<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c<br>
index 523d22db094b..eb19ae734396 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c<br>
@@ -36,6 +36,7 @@<br>
#include "psp_v12_0.h"<br>
<br>
#include "amdgpu_ras.h"<br>
+#include "amdgpu_securedisplay.h"<br>
<br>
static int psp_sysfs_init(struct amdgpu_device *adev);<br>
static void psp_sysfs_fini(struct amdgpu_device *adev);<br>
@@ -1642,6 +1643,179 @@ int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id)<br>
}<br>
// RAP end<br>
<br>
+/* securedisplay start */<br>
+static int psp_securedisplay_init_shared_buf(struct psp_context *psp)<br>
+{<br>
+ int ret;<br>
+<br>
+ /*<br>
+ * Allocate 16k memory aligned to 4k from Frame Buffer (local<br>
+ * physical) for sa ta <-> Driver<br>
+ */<br>
+ ret = amdgpu_bo_create_kernel(psp->adev, PSP_SECUREDISPLAY_SHARED_MEM_SIZE,<br>
+ PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM,<br>
+ &psp->securedisplay_context.securedisplay_shared_bo,<br>
+ &psp->securedisplay_context.securedisplay_shared_mc_addr,<br>
+ &psp->securedisplay_context.securedisplay_shared_buf);<br>
+<br>
+ return ret;<br>
+}<br>
+<br>
+static int psp_securedisplay_load(struct psp_context *psp)<br>
+{<br>
+ int ret;<br>
+ struct psp_gfx_cmd_resp *cmd;<br>
+<br>
+ /*<br>
+ * TODO: bypass the loading in sriov for now<br>
+ */<br>
+<br>
+ cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);<br>
+ if (!cmd)<br>
+ return -ENOMEM;<br>
+<br>
+ memset(psp->fw_pri_buf, 0, PSP_1_MEG);<br>
+ memcpy(psp->fw_pri_buf, psp->ta_securedisplay_start_addr, psp->ta_securedisplay_ucode_size);<br>
+<br>
+ psp_prep_ta_load_cmd_buf(cmd,<br>
+ psp->fw_pri_mc_addr,<br>
+ psp->ta_securedisplay_ucode_size,<br>
+ psp->securedisplay_context.securedisplay_shared_mc_addr,<br>
+ PSP_SECUREDISPLAY_SHARED_MEM_SIZE);<br>
+<br>
+ ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);<br>
+<br>
+ if (ret)<br>
+ goto failed;<br>
+<br>
+ psp->securedisplay_context.securedisplay_initialized = true;<br>
+ psp->securedisplay_context.session_id = cmd->resp.session_id;<br>
+ mutex_init(&psp->securedisplay_context.mutex);<br>
+<br>
+failed:<br>
+ kfree(cmd);<br>
+ return ret;<br>
+}<br>
+<br>
+static int psp_securedisplay_unload(struct psp_context *psp)<br>
+{<br>
+ int ret;<br>
+ struct psp_gfx_cmd_resp *cmd;<br>
+<br>
+ cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL);<br>
+ if (!cmd)<br>
+ return -ENOMEM;<br>
+<br>
+ psp_prep_ta_unload_cmd_buf(cmd, psp->securedisplay_context.session_id);<br>
+<br>
+ ret = psp_cmd_submit_buf(psp, NULL, cmd, psp->fence_buf_mc_addr);<br>
+<br>
+ kfree(cmd);<br>
+<br>
+ return ret;<br>
+}<br>
+<br>
+static int psp_securedisplay_initialize(struct psp_context *psp)<br>
+{<br>
+ int ret;<br>
+ struct securedisplay_cmd *securedisplay_cmd;<br>
+<br>
+ /*<br>
+ * TODO: bypass the initialize in sriov for now<br>
+ */<br>
+ if (amdgpu_sriov_vf(psp->adev))<br>
+ return 0;<br>
+<br>
+ if (!psp->adev->psp.ta_securedisplay_ucode_size ||<br>
+ !psp->adev->psp.ta_securedisplay_start_addr) {<br>
+ dev_info(psp->adev->dev, "SECUREDISPLAY: securedisplay ta ucode is not available\n");<br>
+ return 0;<br>
+ }<br>
+<br>
+ if (!psp->securedisplay_context.securedisplay_initialized) {<br>
+ ret = psp_securedisplay_init_shared_buf(psp);<br>
+ if (ret)<br>
+ return ret;<br>
+ }<br>
+<br>
+ ret = psp_securedisplay_load(psp);<br>
+ if (ret)<br>
+ return ret;<br>
+<br>
+ psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,<br>
+ TA_SECUREDISPLAY_COMMAND__QUERY_TA);<br>
+<br>
+ ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA);<br>
+ if (ret) {<br>
+ psp_securedisplay_unload(psp);<br>
+<br>
+ amdgpu_bo_free_kernel(&psp->securedisplay_context.securedisplay_shared_bo,<br>
+ &psp->securedisplay_context.securedisplay_shared_mc_addr,<br>
+ &psp->securedisplay_context.securedisplay_shared_buf);<br>
+<br>
+ psp->securedisplay_context.securedisplay_initialized = false;<br>
+<br>
+ dev_err(psp->adev->dev, "SECUREDISPLAY TA initialize fail.\n");<br>
+ return -EINVAL;<br>
+ }<br>
+<br>
+ if (securedisplay_cmd->status != TA_SECUREDISPLAY_STATUS__SUCCESS) {<br>
+ psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);<br>
+ dev_err(psp->adev->dev, "SECUREDISPLAY: query securedisplay TA failed. ret 0x%x\n",<br>
+ securedisplay_cmd->securedisplay_out_message.query_ta.query_cmd_ret);<br>
+ }<br>
+<br>
+ return 0;<br>
+}<br>
+<br>
+static int psp_securedisplay_terminate(struct psp_context *psp)<br>
+{<br>
+ int ret;<br>
+<br>
+ /*<br>
+ * TODO:bypass the terminate in sriov for now<br>
+ */<br>
+ if (amdgpu_sriov_vf(psp->adev))<br>
+ return 0;<br>
+<br>
+ if (!psp->securedisplay_context.securedisplay_initialized)<br>
+ return 0;<br>
+<br>
+ ret = psp_securedisplay_unload(psp);<br>
+ if (ret)<br>
+ return ret;<br>
+<br>
+ psp->securedisplay_context.securedisplay_initialized = false;<br>
+<br>
+ /* free securedisplay shared memory */<br>
+ amdgpu_bo_free_kernel(&psp->securedisplay_context.securedisplay_shared_bo,<br>
+ &psp->securedisplay_context.securedisplay_shared_mc_addr,<br>
+ &psp->securedisplay_context.securedisplay_shared_buf);<br>
+<br>
+ return ret;<br>
+}<br>
+<br>
+int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id)<br>
+{<br>
+ int ret;<br>
+<br>
+ if (!psp->securedisplay_context.securedisplay_initialized)<br>
+ return -EINVAL;<br>
+<br>
+ if (ta_cmd_id != TA_SECUREDISPLAY_COMMAND__QUERY_TA &&<br>
+ ta_cmd_id != TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC)<br>
+ return -EINVAL;<br>
+<br>
+ mutex_lock(&psp->securedisplay_context.mutex);<br>
+<br>
+ ret = psp_ta_invoke(psp, ta_cmd_id, psp->securedisplay_context.session_id);<br>
+<br>
+ mutex_unlock(&psp->securedisplay_context.mutex);<br>
+<br>
+ return ret;<br>
+}<br>
+/* SECUREDISPLAY end */<br>
+<br>
static int psp_hw_start(struct psp_context *psp)<br>
{<br>
struct amdgpu_device *adev = psp->adev;<br>
@@ -2116,6 +2290,11 @@ static int psp_load_fw(struct amdgpu_device *adev)<br>
if (ret)<br>
dev_err(psp->adev->dev,<br>
"RAP: Failed to initialize RAP\n");<br>
+<br>
+ ret = psp_securedisplay_initialize(psp);<br>
+ if (ret)<br>
+ dev_err(psp->adev->dev,<br>
+ "SECUREDISPLAY: Failed to initialize SECUREDISPLAY\n");<br>
}<br>
<br>
return 0;<br>
@@ -2166,6 +2345,7 @@ static int psp_hw_fini(void *handle)<br>
<br>
if (psp->adev->psp.ta_fw) {<br>
psp_ras_terminate(psp);<br>
+ psp_securedisplay_terminate(psp);<br>
psp_rap_terminate(psp);<br>
psp_dtm_terminate(psp);<br>
psp_hdcp_terminate(psp);<br>
@@ -2230,6 +2410,11 @@ static int psp_suspend(void *handle)<br>
DRM_ERROR("Failed to terminate rap ta\n");<br>
return ret;<br>
}<br>
+ ret = psp_securedisplay_terminate(psp);<br>
+ if (ret) {<br>
+ DRM_ERROR("Failed to terminate securedisplay ta\n");<br>
+ return ret;<br>
+ }<br>
}<br>
<br>
ret = psp_asd_unload(psp);<br>
@@ -2313,6 +2498,11 @@ static int psp_resume(void *handle)<br>
if (ret)<br>
dev_err(psp->adev->dev,<br>
"RAP: Failed to initialize RAP\n");<br>
+<br>
+ ret = psp_securedisplay_initialize(psp);<br>
+ if (ret)<br>
+ dev_err(psp->adev->dev,<br>
+ "SECUREDISPLAY: Failed to initialize SECUREDISPLAY\n");<br>
}<br>
<br>
mutex_unlock(&adev->firmware.mutex);<br>
@@ -2620,6 +2810,11 @@ static int parse_ta_bin_descriptor(struct psp_context *psp,<br>
psp->ta_rap_ucode_size = le32_to_cpu(desc->size_bytes);<br>
psp->ta_rap_start_addr = ucode_start_addr;<br>
break;<br>
+ case TA_FW_TYPE_PSP_SECUREDISPLAY:<br>
+ psp->ta_securedisplay_ucode_version = le32_to_cpu(desc->fw_version);<br>
+ psp->ta_securedisplay_ucode_size = le32_to_cpu(desc->size_bytes);<br>
+ psp->ta_securedisplay_start_addr = ucode_start_addr;<br>
+ break;<br>
default:<br>
dev_warn(psp->adev->dev, "Unsupported TA type: %d\n", desc->fw_type);<br>
break;<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h<br>
index da250bc1ac57..cb50ba445f8c 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h<br>
@@ -30,6 +30,7 @@<br>
#include "ta_xgmi_if.h"<br>
#include "ta_ras_if.h"<br>
#include "ta_rap_if.h"<br>
+#include "ta_secureDisplay_if.h"<br>
<br>
#define PSP_FENCE_BUFFER_SIZE 0x1000<br>
#define PSP_CMD_BUFFER_SIZE 0x1000<br>
@@ -40,6 +41,7 @@<br>
#define PSP_HDCP_SHARED_MEM_SIZE 0x4000<br>
#define PSP_DTM_SHARED_MEM_SIZE 0x4000<br>
#define PSP_RAP_SHARED_MEM_SIZE 0x4000<br>
+#define PSP_SECUREDISPLAY_SHARED_MEM_SIZE 0x4000<br>
#define PSP_SHARED_MEM_SIZE 0x4000<br>
#define PSP_FW_NAME_LEN 0x24<br>
<br>
@@ -171,6 +173,15 @@ struct psp_rap_context {<br>
struct mutex mutex;<br>
};<br>
<br>
+struct psp_securedisplay_context {<br>
+ bool securedisplay_initialized;<br>
+ uint32_t session_id;<br>
+ struct amdgpu_bo *securedisplay_shared_bo;<br>
+ uint64_t securedisplay_shared_mc_addr;<br>
+ void *securedisplay_shared_buf;<br>
+ struct mutex mutex;<br>
+};<br>
+<br>
#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942<br>
#define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000<br>
#define GDDR6_MEM_TRAINING_OFFSET 0x8000<br>
@@ -298,12 +309,17 @@ struct psp_context<br>
uint32_t ta_rap_ucode_size;<br>
uint8_t *ta_rap_start_addr;<br>
<br>
+ uint32_t ta_securedisplay_ucode_version;<br>
+ uint32_t ta_securedisplay_ucode_size;<br>
+ uint8_t *ta_securedisplay_start_addr;<br>
+<br>
struct psp_asd_context asd_context;<br>
struct psp_xgmi_context xgmi_context;<br>
struct psp_ras_context ras;<br>
struct psp_hdcp_context hdcp_context;<br>
struct psp_dtm_context dtm_context;<br>
struct psp_rap_context rap_context;<br>
+ struct psp_securedisplay_context securedisplay_context;<br>
struct mutex mutex;<br>
struct psp_memory_training_context mem_train_ctx;<br>
};<br>
@@ -380,6 +396,7 @@ int psp_ras_trigger_error(struct psp_context *psp,<br>
int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id);<br>
int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id);<br>
int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id);<br>
+int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id);<br>
<br>
int psp_rlc_autoload_start(struct psp_context *psp);<br>
<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c<br>
new file mode 100644<br>
index 000000000000..455978781380<br>
--- /dev/null<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c<br>
@@ -0,0 +1,174 @@<br>
+/*<br>
+ * Copyright 2020 Advanced Micro Devices, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be included in<br>
+ * all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL<br>
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
+ * OTHER DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ *<br>
+ */<br>
+#include <linux/debugfs.h><br>
+#include <linux/pm_runtime.h><br>
+<br>
+#include "amdgpu.h"<br>
+#include "amdgpu_securedisplay.h"<br>
+<br>
+/**<br>
+ * DOC: AMDGPU SECUREDISPLAY debugfs test interface<br>
+ *<br>
+ * how to use?<br>
+ * echo opcode <value> > <debugfs_dir>/dri/xxx/securedisplay_test<br>
+ * eg. echo 1 > <debugfs_dir>/dri/xxx/securedisplay_test<br>
+ * eg. echo 2 phy_id > <debugfs_dir>/dri/xxx/securedisplay_test<br>
+ *<br>
+ * opcode:<br>
+ * 1:Query whether TA is responding used only for validation pupose<br>
+ * 2: Send region of Interest and CRC value to I2C. (uint32)phy_id is<br>
+ * send to determine which DIO scratch register should be used to get<br>
+ * ROI and receive i2c_buf as the output.<br>
+ *<br>
+ * You can refer more detail from header file ta_securedisplay_if.h<br>
+ *<br>
+ */<br>
+<br>
+void psp_securedisplay_parse_resp_status(struct psp_context *psp,<br>
+ enum ta_securedisplay_status status)<br>
+{<br>
+ switch (status) {<br>
+ case TA_SECUREDISPLAY_STATUS__SUCCESS:<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE:<br>
+ dev_err(psp->adev->dev, "Secure display: Generic Failure.");<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__INVALID_PARAMETER:<br>
+ dev_err(psp->adev->dev, "Secure display: Invalid Parameter.");<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__NULL_POINTER:<br>
+ dev_err(psp->adev->dev, "Secure display: Null Pointer.");<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__I2C_WRITE_ERROR:<br>
+ dev_err(psp->adev->dev, "Secure display: Failed to write to I2C.");<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__READ_DIO_SCRATCH_ERROR:<br>
+ dev_err(psp->adev->dev, "Secure display: Failed to Read DIO Scratch Register.");<br>
+ break;<br>
+ case TA_SECUREDISPLAY_STATUS__READ_CRC_ERROR:<br>
+ dev_err(psp->adev->dev, "Secure display: Failed to Read CRC");<br>
+ break;<br>
+ default:<br>
+ dev_err(psp->adev->dev, "Secure display: Failed to parse status: %d\n", status);<br>
+ }<br>
+}<br>
+<br>
+void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd,<br>
+ enum ta_securedisplay_command command_id)<br>
+{<br>
+ *cmd = (struct securedisplay_cmd *)psp->securedisplay_context.securedisplay_shared_buf;<br>
+ memset(*cmd, 0, sizeof(struct securedisplay_cmd));<br>
+ (*cmd)->status = TA_SECUREDISPLAY_STATUS__GENERIC_FAILURE;<br>
+ (*cmd)->cmd_id = command_id;<br>
+}<br>
+<br>
+static ssize_t amdgpu_securedisplay_debugfs_write(struct file *f, const char __user *buf,<br>
+ size_t size, loff_t *pos)<br>
+{<br>
+ struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;<br>
+ struct psp_context *psp = &adev->psp;<br>
+ struct securedisplay_cmd *securedisplay_cmd;<br>
+ struct drm_device *dev = adev_to_drm(adev);<br>
+ uint32_t phy_id;<br>
+ uint32_t op;<br>
+ int i;<br>
+ char str[64];<br>
+ char i2c_output[256];<br>
+ int ret;</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">[Kevin]:</div>
<div class="PlainText">the driver should avoid allocate big block size memory in kernel stack. (x86_64:: kernel stack size is fix16K).<br>
In other words, you don't know how many kernel stacks will be used in upstream.</div>
<div class="PlainText">Generally speaking, there is no problem, but it is really unreasonable.</div>
<div class="PlainText"><br>
</div>
<div class="PlainText">Best Regards,<br>
Kevin<br>
+<br>
+ if (*pos || size > sizeof(str) - 1)<br>
+ return -EINVAL;<br>
+<br>
+ memset(str, 0, sizeof(str));<br>
+ copy_from_user(str, buf, size);<br>
+<br>
+ ret = pm_runtime_get_sync(dev->dev);<br>
+ if (ret < 0) {<br>
+ pm_runtime_put_autosuspend(dev->dev);<br>
+ return ret;<br>
+ }<br>
+<br>
+ if (size < 3)<br>
+ sscanf(str, "%u ", &op);<br>
+ else<br>
+ sscanf(str, "%u %u", &op, &phy_id);<br>
+<br>
+ switch (op) {<br>
+ case 1:<br>
+ psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,<br>
+ TA_SECUREDISPLAY_COMMAND__QUERY_TA);<br>
+ ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__QUERY_TA);<br>
+ if (!ret) {<br>
+ if (securedisplay_cmd->status == TA_SECUREDISPLAY_STATUS__SUCCESS)<br>
+ dev_info(adev->dev, "SECUREDISPLAY: query securedisplay TA ret is 0x%X\n",<br>
+ securedisplay_cmd->securedisplay_out_message.query_ta.query_cmd_ret);<br>
+ else<br>
+ psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);<br>
+ }<br>
+ break;<br>
+ case 2:<br>
+ psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,<br>
+ TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);<br>
+ securedisplay_cmd->securedisplay_in_message.send_roi_crc.phy_id = phy_id;<br>
+ ret = psp_securedisplay_invoke(psp, TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);<br>
+ if (!ret) {<br>
+ if (securedisplay_cmd->status == TA_SECUREDISPLAY_STATUS__SUCCESS) {<br>
+ memset(i2c_output, 0, sizeof(i2c_output));<br>
+ for (i = 0; i < TA_SECUREDISPLAY_I2C_BUFFER_SIZE; i++)<br>
+ sprintf(i2c_output, "%s 0x%X", i2c_output,<br>
+ securedisplay_cmd->securedisplay_out_message.send_roi_crc.i2c_buf[i]);<br>
+ dev_info(adev->dev, "SECUREDISPLAY: I2C buffer out put is :%s\n", i2c_output);<br>
+ } else {<br>
+ psp_securedisplay_parse_resp_status(psp, securedisplay_cmd->status);<br>
+ }<br>
+ }<br>
+ break;<br>
+ default:<br>
+ dev_err(adev->dev, "Invalid input: %s\n", str);<br>
+ }<br>
+<br>
+ pm_runtime_mark_last_busy(dev->dev);<br>
+ pm_runtime_put_autosuspend(dev->dev);<br>
+<br>
+ return size;<br>
+}<br>
+<br>
+static const struct file_operations amdgpu_securedisplay_debugfs_ops = {<br>
+ .owner = THIS_MODULE,<br>
+ .read = NULL,<br>
+ .write = amdgpu_securedisplay_debugfs_write,<br>
+ .llseek = default_llseek<br>
+};<br>
+<br>
+void amdgpu_securedisplay_debugfs_init(struct amdgpu_device *adev)<br>
+{<br>
+#if defined(CONFIG_DEBUG_FS)<br>
+<br>
+ if (!adev->psp.securedisplay_context.securedisplay_initialized)<br>
+ return;<br>
+<br>
+ debugfs_create_file("securedisplay_test", S_IWUSR, adev_to_drm(adev)->primary->debugfs_root,<br>
+ adev, &amdgpu_securedisplay_debugfs_ops);<br>
+#endif<br>
+}<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.h<br>
new file mode 100644<br>
index 000000000000..983446c72520<br>
--- /dev/null<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.h<br>
@@ -0,0 +1,36 @@<br>
+/*<br>
+ * Copyright 2020 Advanced Micro Devices, Inc.<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice shall be included in<br>
+ * all copies or substantial portions of the Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL<br>
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
+ * OTHER DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ *<br>
+ */<br>
+#ifndef _AMDGPU_SECUREDISPLAY_H<br>
+#define _AMDGPU_SECUREDISPLAY_H<br>
+<br>
+#include "amdgpu.h"<br>
+#include "ta_secureDisplay_if.h"<br>
+<br>
+void amdgpu_securedisplay_debugfs_init(struct amdgpu_device *adev);<br>
+void psp_securedisplay_parse_resp_status(struct psp_context *psp,<br>
+ enum ta_securedisplay_status status);<br>
+void psp_prep_securedisplay_cmd_buf(struct psp_context *psp, struct securedisplay_cmd **cmd,<br>
+ enum ta_securedisplay_command command_id);<br>
+<br>
+#endif<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h<br>
index 0e43b46d3ab5..46449e70348b 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h<br>
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h<br>
@@ -122,6 +122,9 @@ struct ta_firmware_header_v1_0 {<br>
uint32_t ta_dtm_ucode_version;<br>
uint32_t ta_dtm_offset_bytes;<br>
uint32_t ta_dtm_size_bytes;<br>
+ uint32_t ta_securedisplay_ucode_version;<br>
+ uint32_t ta_securedisplay_offset_bytes;<br>
+ uint32_t ta_securedisplay_size_bytes;<br>
};<br>
<br>
enum ta_fw_type {<br>
@@ -132,6 +135,7 @@ enum ta_fw_type {<br>
TA_FW_TYPE_PSP_HDCP,<br>
TA_FW_TYPE_PSP_DTM,<br>
TA_FW_TYPE_PSP_RAP,<br>
+ TA_FW_TYPE_PSP_SECUREDISPLAY,<br>
};<br>
<br>
struct ta_fw_bin_desc {<br>
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c<br>
index d7f92634eba2..4b1cc5e9ee92 100644<br>
--- a/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c<br>
+++ b/drivers/gpu/drm/amd/amdgpu/psp_v10_0.c<br>
@@ -92,8 +92,6 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)<br>
(uint8_t *)ta_hdr +<br>
le32_to_cpu(ta_hdr->header.ucode_array_offset_bytes);<br>
<br>
- adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);<br>
-<br>
adev->psp.ta_dtm_ucode_version =<br>
le32_to_cpu(ta_hdr->ta_dtm_ucode_version);<br>
adev->psp.ta_dtm_ucode_size =<br>
@@ -101,6 +99,16 @@ static int psp_v10_0_init_microcode(struct psp_context *psp)<br>
adev->psp.ta_dtm_start_addr =<br>
(uint8_t *)adev->psp.ta_hdcp_start_addr +<br>
le32_to_cpu(ta_hdr->ta_dtm_offset_bytes);<br>
+<br>
+ adev->psp.ta_securedisplay_ucode_version =<br>
+ le32_to_cpu(ta_hdr->ta_securedisplay_ucode_version);<br>
+ adev->psp.ta_securedisplay_ucode_size =<br>
+ le32_to_cpu(ta_hdr->ta_securedisplay_size_bytes);<br>
+ adev->psp.ta_securedisplay_start_addr =<br>
+ (uint8_t *)adev->psp.ta_hdcp_start_addr +<br>
+ le32_to_cpu(ta_hdr->ta_securedisplay_offset_bytes);<br>
+<br>
+ adev->psp.ta_fw_version = le32_to_cpu(ta_hdr->header.ucode_version);<br>
}<br>
<br>
return 0;<br>
-- <br>
2.17.1<br>
<br>
_______________________________________________<br>
amd-gfx mailing list<br>
amd-gfx@lists.freedesktop.org<br>
<a href="https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CKevin1.Wang%40amd.com%7C105d330e2a9f417d324408d8b775887e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637461062772245289%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=j3wrRxVVnVEu9UWN%2F1UiLZUHyO6jNy8tBEOlkq0DOGk%3D&reserved=0">https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flists.freedesktop.org%2Fmailman%2Flistinfo%2Famd-gfx&data=04%7C01%7CKevin1.Wang%40amd.com%7C105d330e2a9f417d324408d8b775887e%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637461062772245289%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=j3wrRxVVnVEu9UWN%2F1UiLZUHyO6jNy8tBEOlkq0DOGk%3D&reserved=0</a><br>
</div>
</span></font></div>
</div>
</body>
</html>