From: Jason-jh Lin <[email protected]>
Memory Definitions:
secure memory - Memory allocated in the TEE (Trusted Execution
Environment) which is inaccessible in the REE (Rich Execution
Environment, i.e. linux kernel/userspace).
secure handle - Integer value which acts as reference to 'secure
memory'. Used in communication between TEE and REE to reference
'secure memory'.
secure buffer - 'secure memory' that is used to store decrypted,
compressed video or for other general purposes in the TEE.
secure surface - 'secure memory' that is used to store graphic buffers.
Memory Usage in SVP:
The overall flow of SVP starts with encrypted video coming in from an
outside source into the REE. The REE will then allocate a 'secure
buffer' and send the corresponding 'secure handle' along with the
encrypted, compressed video data to the TEE. The TEE will then decrypt
the video and store the result in the 'secure buffer'. The REE will
then allocate a 'secure surface'. The REE will pass the 'secure
handles' for both the 'secure buffer' and 'secure surface' into the
TEE for video decoding. The video decoder HW will then decode the
contents of the 'secure buffer' and place the result in the 'secure
surface'. The REE will then attach the 'secure surface' to the overlay
plane for rendering of the video.
Everything relating to ensuring security of the actual contents of the
'secure buffer' and 'secure surface' is out of scope for the REE and
is the responsibility of the TEE.
DRM driver handles allocation of gem objects that are backed by a 'secure
surface' and for displaying a 'secure surface' on the overlay plane.
This introduces a new flag for object creation called
DRM_MTK_GEM_CREATE_ENCRYPTED which indicates it should be a 'secure
surface'. All changes here are in MediaTek specific code.
---
TODO:
1) Remove get sec larb port interface in ddp_comp, ovl and ovl_adaptor.
2) Verify instruction for enabling/disabling dapc and larb port in TEE
drop the sec_engine flags in normal world and.
3) Move DISP_REG_OVL_SECURE setting to secure world for mtk_disp_ovl.c.
4) Change the parameter register address in mtk_ddp_sec_write()
from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
5) Implement setting mmsys routing table in the secure world series.
---
Based on 5 series and 1 patch:
[1] v3 dma-buf: heaps: Add MediaTek secure heap
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=809023
[2] v3 add driver to support secure video decoder
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=807308
[3] v4 soc: mediatek: Add register definitions for GCE
- https://patchwork.kernel.org/project/linux-mediatek/patch/[email protected]/
[4] v2 Add CMDQ driver support for mt8188
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=810302
[5] Add mediatek,gce-events definition to mediatek,gce-mailbox bindings
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=810938
[6] v3 Add CMDQ secure driver for SVP
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=812379
---
Change in v3:
1. fix kerneldoc problems
2. fix typo in title and commit message
3. adjust naming for secure variable
4. add the missing part for is_suecure plane implementation
5. use BIT_ULL macro to replace bit shifting
6. move modification of ovl_adaptor part to the correct patch
7. add TODO list in commit message
8. add commit message for using share memory to store execute count
Change in v2:
1. remove the DRIVER_RDNDER flag for mtk_drm_ioctl
2. move cmdq_insert_backup_cookie into client driver
3. move secure gce node define from mt8195-cherry.dtsi to mt8195.dtsi
---
CK Hu (1):
drm/mediatek: Add interface to allocate MediaTek GEM buffer.
Jason-JH.Lin (10):
drm/mediatek/uapi: Add DRM_MTK_GEM_CREATE_ENCRYPTED flag
drm/mediatek: Add secure buffer control flow to mtk_drm_gem
drm/mediatek: Add secure identify flag and funcution to mtk_drm_plane
drm/mediatek: Add mtk_ddp_sec_write to config secure buffer info
drm/mediatek: Add get_sec_port interface to mtk_ddp_comp
drm/mediatek: Add secure layer config support for ovl
drm/mediatek: Add secure layer config support for ovl_adaptor
drm/mediatek: Add secure flow support to mediatek-drm
drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt finalize
arm64: dts: mt8195: Add secure mbox settings for vdosys
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 +-
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +
drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 31 +-
.../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15 +
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 274 +++++++++++++++++-
drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 +
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ++
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 14 +
drivers/gpu/drm/mediatek/mtk_drm_drv.c | 13 +
drivers/gpu/drm/mediatek/mtk_drm_gem.c | 122 ++++++++
drivers/gpu/drm/mediatek/mtk_drm_gem.h | 16 +
drivers/gpu/drm/mediatek/mtk_drm_plane.c | 26 ++
drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +
drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 +-
drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 +
include/uapi/drm/mediatek_drm.h | 59 ++++
16 files changed, 607 insertions(+), 18 deletions(-)
create mode 100644 include/uapi/drm/mediatek_drm.h
--
2.18.0
Add a secure mailbox channel to support secure video path on
vdosys0 and vdosys1.
Signed-off-by: Jason-JH.Lin <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index e0ac2e9f5b72..416d575be123 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -2621,7 +2621,8 @@
vdosys0: syscon@1c01a000 {
compatible = "mediatek,mt8195-vdosys0", "mediatek,mt8195-mmsys", "syscon";
reg = <0 0x1c01a000 0 0x1000>;
- mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
+ mboxes = <&gce0 0 CMDQ_THR_PRIO_4>,
+ <&gce0 8 CMDQ_THR_PRIO_4>; /* secure mbox */
#clock-cells = <1>;
};
@@ -2806,7 +2807,8 @@
vdosys1: syscon@1c100000 {
compatible = "mediatek,mt8195-vdosys1", "syscon";
reg = <0 0x1c100000 0 0x1000>;
- mboxes = <&gce0 1 CMDQ_THR_PRIO_4>;
+ mboxes = <&gce0 1 CMDQ_THR_PRIO_4>,
+ <&gce0 9 CMDQ_THR_PRIO_4>; /* secure mbox */;
mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x0000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
--
2.18.0
To add secure flow support for mediatek-drm, each crtc have to
create a secure cmdq mailbox channel. Then cmdq packets with
display HW configuration will be sent to secure cmdq mailbox channel
and configured in the secure world.
Each crtc have to use secure cmdq interface to configure some secure
settings for display HW before sending cmdq packets to secure cmdq
mailbox channel.
If any of fb get from current drm_atomic_state is secure, then crtc
will switch to the secure flow to configure display HW.
If all fbs are not secure in current drm_atomic_state, then crtc will
switch to the normal flow.
TODO:
1. Remove get sec larb port interface in ddp_comp, ovl and ovl_adaptor.
2. Verify instruction for enabling/disabling dapc and larb port in TEE
drop the sec_engine flags in normal world.
Signed-off-by: Jason-JH.Lin <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 272 ++++++++++++++++++++++-
drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 +
drivers/gpu/drm/mediatek/mtk_drm_plane.c | 7 +
3 files changed, 269 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index db43f9dff912..79617c0f016d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -56,6 +56,11 @@ struct mtk_drm_crtc {
u32 cmdq_event;
u32 cmdq_vblank_cnt;
wait_queue_head_t cb_blocking_queue;
+
+ struct cmdq_client sec_cmdq_client;
+ struct cmdq_pkt sec_cmdq_handle;
+ bool sec_cmdq_working;
+ wait_queue_head_t sec_cb_blocking_queue;
#endif
struct device *mmsys_dev;
@@ -69,6 +74,7 @@ struct mtk_drm_crtc {
/* lock for display hardware access */
struct mutex hw_lock;
bool config_updating;
+ bool sec_on;
};
struct mtk_crtc_state {
@@ -111,6 +117,154 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
}
}
+void mtk_crtc_disable_secure_state(struct drm_crtc *crtc)
+{
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ enum cmdq_sec_scenario sec_scn = CMDQ_SEC_SCNR_MAX;
+ int i;
+ struct mtk_ddp_comp *ddp_first_comp;
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ u64 sec_engine = 0; /* for hw engine write output secure fb */
+ u64 sec_port = 0; /* for larb port read input secure fb */
+
+ mutex_lock(&mtk_crtc->hw_lock);
+
+ if (!mtk_crtc->sec_cmdq_client.chan) {
+ pr_err("crtc-%d secure mbox channel is NULL\n", drm_crtc_index(crtc));
+ goto err;
+ }
+
+ if (!mtk_crtc->sec_on) {
+ pr_debug("crtc-%d is already disabled!\n", drm_crtc_index(crtc));
+ goto err;
+ }
+
+ mbox_flush(mtk_crtc->sec_cmdq_client.chan, 0);
+ mtk_crtc->sec_cmdq_handle.cmd_buf_size = 0;
+
+ if (mtk_crtc->sec_cmdq_handle.sec_data) {
+ struct cmdq_sec_data *sec_data;
+
+ sec_data = mtk_crtc->sec_cmdq_handle.sec_data;
+ sec_data->addr_metadata_cnt = 0;
+ sec_data->addr_metadatas = (uintptr_t)NULL;
+ }
+
+ /*
+ * Secure path only support DL mode, so we just wait
+ * the first path frame done here
+ */
+ cmdq_pkt_wfe(&mtk_crtc->sec_cmdq_handle, mtk_crtc->cmdq_event, false);
+
+ ddp_first_comp = mtk_crtc->ddp_comp[0];
+ for (i = 0; i < mtk_crtc->layer_nr; i++) {
+ struct drm_plane *plane = &mtk_crtc->planes[i];
+
+ sec_port |= mtk_ddp_comp_layer_get_sec_port(ddp_first_comp, i);
+
+ /* make sure secure layer off before switching secure state */
+ if (!mtk_plane_fb_is_secure(plane->state->fb)) {
+ struct mtk_plane_state *plane_state = to_mtk_plane_state(plane->state);
+
+ plane_state->pending.enable = false;
+ mtk_ddp_comp_layer_config(ddp_first_comp, i, plane_state,
+ &mtk_crtc->sec_cmdq_handle);
+ }
+ }
+
+ /* Disable secure path */
+ if (drm_crtc_index(crtc) == 0)
+ sec_scn = CMDQ_SEC_SCNR_PRIMARY_DISP_DISABLE;
+ else if (drm_crtc_index(crtc) == 1)
+ sec_scn = CMDQ_SEC_SCNR_SUB_DISP_DISABLE;
+
+ cmdq_sec_pkt_set_data(&mtk_crtc->sec_cmdq_handle, sec_engine, sec_engine, sec_scn);
+
+ cmdq_pkt_finalize(&mtk_crtc->sec_cmdq_handle);
+ dma_sync_single_for_device(mtk_crtc->sec_cmdq_client.chan->mbox->dev,
+ mtk_crtc->sec_cmdq_handle.pa_base,
+ mtk_crtc->sec_cmdq_handle.cmd_buf_size,
+ DMA_TO_DEVICE);
+
+ mtk_crtc->sec_cmdq_working = true;
+ mbox_send_message(mtk_crtc->sec_cmdq_client.chan, &mtk_crtc->sec_cmdq_handle);
+ mbox_client_txdone(mtk_crtc->sec_cmdq_client.chan, 0);
+
+ // Wait for sec state to be disabled by cmdq
+ wait_event_timeout(mtk_crtc->sec_cb_blocking_queue,
+ !mtk_crtc->sec_cmdq_working,
+ msecs_to_jiffies(500));
+
+ mtk_crtc->sec_on = false;
+ pr_debug("crtc-%d disable secure plane!\n", drm_crtc_index(crtc));
+
+err:
+ mutex_unlock(&mtk_crtc->hw_lock);
+#endif
+}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+static void mtk_crtc_enable_secure_state(struct drm_crtc *crtc)
+{
+ enum cmdq_sec_scenario sec_scn = CMDQ_SEC_SCNR_MAX;
+ int i;
+ struct mtk_ddp_comp *ddp_first_comp;
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ u64 sec_engine = 0; /* for hw engine write output secure fb */
+ u64 sec_port = 0; /* for larb port read input secure fb */
+
+ cmdq_pkt_wfe(&mtk_crtc->sec_cmdq_handle, mtk_crtc->cmdq_event, false);
+
+ ddp_first_comp = mtk_crtc->ddp_comp[0];
+ for (i = 0; i < mtk_crtc->layer_nr; i++)
+ if (mtk_crtc->planes[i].type == DRM_PLANE_TYPE_CURSOR)
+ sec_port |= mtk_ddp_comp_layer_get_sec_port(ddp_first_comp, i);
+
+ if (drm_crtc_index(crtc) == 0)
+ sec_scn = CMDQ_SEC_SCNR_PRIMARY_DISP;
+ else if (drm_crtc_index(crtc) == 1)
+ sec_scn = CMDQ_SEC_SCNR_SUB_DISP;
+
+ cmdq_sec_pkt_set_data(&mtk_crtc->sec_cmdq_handle, sec_engine, sec_port, sec_scn);
+
+ pr_debug("crtc-%d enable secure plane!\n", drm_crtc_index(crtc));
+}
+#endif
+
+static void mtk_drm_crtc_plane_switch_sec_state(struct drm_crtc *crtc,
+ struct drm_atomic_state *state)
+{
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+ bool sec_on[MAX_CRTC] = {0};
+ int i;
+ struct drm_crtc_state *crtc_state;
+ struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct drm_plane *plane;
+ struct drm_plane_state *old_plane_state;
+
+ for_each_old_plane_in_state(state, plane, old_plane_state, i) {
+ if (!plane->state->crtc)
+ continue;
+
+ if (plane->state->fb &&
+ mtk_plane_fb_is_secure(plane->state->fb) &&
+ mtk_crtc->sec_cmdq_client.chan)
+ sec_on[drm_crtc_index(plane->state->crtc)] = true;
+ }
+
+ for_each_old_crtc_in_state(state, crtc, crtc_state, i) {
+ mtk_crtc = to_mtk_crtc(crtc);
+
+ if (!sec_on[i])
+ mtk_crtc_disable_secure_state(crtc);
+
+ mutex_lock(&mtk_crtc->hw_lock);
+ mtk_crtc->sec_on = true;
+ mutex_unlock(&mtk_crtc->hw_lock);
+ }
+#endif
+}
+
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
size_t size)
@@ -146,22 +300,33 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
DMA_TO_DEVICE);
kfree(pkt->va_base);
+ kfree(pkt->sec_data);
}
#endif
static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
{
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+ struct mtk_drm_private *priv = crtc->dev->dev_private;
int i;
+ priv = priv->all_drm_private[drm_crtc_index(crtc)];
+
mtk_mutex_put(mtk_crtc->mutex);
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
+ mtk_drm_cmdq_pkt_destroy(&mtk_crtc->sec_cmdq_handle);
if (mtk_crtc->cmdq_client.chan) {
mbox_free_channel(mtk_crtc->cmdq_client.chan);
mtk_crtc->cmdq_client.chan = NULL;
}
+
+ if (mtk_crtc->sec_cmdq_client.chan) {
+ device_link_remove(priv->dev, mtk_crtc->sec_cmdq_client.chan->mbox->dev);
+ mbox_free_channel(mtk_crtc->sec_cmdq_client.chan);
+ mtk_crtc->sec_cmdq_client.chan = NULL;
+ }
#endif
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
@@ -288,13 +453,18 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
{
struct cmdq_cb_data *data = mssg;
struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
- struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
+ struct mtk_drm_crtc *mtk_crtc;
struct mtk_crtc_state *state;
unsigned int i;
if (data->sta < 0)
return;
+ if (!data->pkt || !data->pkt->sec_data)
+ mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
+ else
+ mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, sec_cmdq_client);
+
state = to_mtk_crtc_state(mtk_crtc->base.state);
state->pending_config = false;
@@ -323,6 +493,11 @@ static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
mtk_crtc->pending_async_planes = false;
}
+ if (mtk_crtc->sec_cmdq_working) {
+ mtk_crtc->sec_cmdq_working = false;
+ wake_up(&mtk_crtc->sec_cb_blocking_queue);
+ }
+
mtk_crtc->cmdq_vblank_cnt = 0;
wake_up(&mtk_crtc->cb_blocking_queue);
}
@@ -549,7 +724,8 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
bool needs_vblank)
{
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
+ struct cmdq_client cmdq_client;
+ struct cmdq_pkt *cmdq_handle;
#endif
struct drm_crtc *crtc = &mtk_crtc->base;
struct mtk_drm_private *priv = crtc->dev->dev_private;
@@ -587,14 +763,36 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
mtk_mutex_release(mtk_crtc->mutex);
}
#if IS_REACHABLE(CONFIG_MTK_CMDQ)
- if (mtk_crtc->cmdq_client.chan) {
+ if (mtk_crtc->sec_on) {
+ mbox_flush(mtk_crtc->sec_cmdq_client.chan, 0);
+ mtk_crtc->sec_cmdq_handle.cmd_buf_size = 0;
+
+ if (mtk_crtc->sec_cmdq_handle.sec_data) {
+ struct cmdq_sec_data *sec_data;
+
+ sec_data = mtk_crtc->sec_cmdq_handle.sec_data;
+ sec_data->addr_metadata_cnt = 0;
+ sec_data->addr_metadatas = (uintptr_t)NULL;
+ }
+
+ mtk_crtc_enable_secure_state(crtc);
+
+ cmdq_client = mtk_crtc->sec_cmdq_client;
+ cmdq_handle = &mtk_crtc->sec_cmdq_handle;
+ } else if (mtk_crtc->cmdq_client.chan) {
mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
- cmdq_handle->cmd_buf_size = 0;
+ mtk_crtc->cmdq_handle.cmd_buf_size = 0;
+
+ cmdq_client = mtk_crtc->cmdq_client;
+ cmdq_handle = &mtk_crtc->cmdq_handle;
+ }
+
+ if (cmdq_client.chan) {
cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
mtk_crtc_ddp_config(crtc, cmdq_handle);
cmdq_pkt_finalize(cmdq_handle);
- dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
+ dma_sync_single_for_device(cmdq_client.chan->mbox->dev,
cmdq_handle->pa_base,
cmdq_handle->cmd_buf_size,
DMA_TO_DEVICE);
@@ -607,8 +805,8 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
*/
mtk_crtc->cmdq_vblank_cnt = 3;
- mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
- mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
+ mbox_send_message(cmdq_client.chan, cmdq_handle);
+ mbox_client_txdone(cmdq_client.chan, 0);
}
#endif
mtk_crtc->config_updating = false;
@@ -750,6 +948,8 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
if (!mtk_crtc->enabled)
return;
+ mtk_crtc_disable_secure_state(crtc);
+
/* Set all pending plane state to disabled */
for (i = 0; i < mtk_crtc->layer_nr; i++) {
struct drm_plane *plane = &mtk_crtc->planes[i];
@@ -790,6 +990,8 @@ static void mtk_drm_crtc_atomic_begin(struct drm_crtc *crtc,
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
unsigned long flags;
+ mtk_drm_crtc_plane_switch_sec_state(crtc, state);
+
if (mtk_crtc->event && mtk_crtc_state->base.event)
DRM_ERROR("new event while there is still a pending event\n");
@@ -1082,8 +1284,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (ret) {
dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
drm_crtc_index(&mtk_crtc->base));
- mbox_free_channel(mtk_crtc->cmdq_client.chan);
- mtk_crtc->cmdq_client.chan = NULL;
+ goto cmdq_err;
} else {
ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
&mtk_crtc->cmdq_handle,
@@ -1091,14 +1292,63 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
if (ret) {
dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
drm_crtc_index(&mtk_crtc->base));
- mbox_free_channel(mtk_crtc->cmdq_client.chan);
- mtk_crtc->cmdq_client.chan = NULL;
+ goto cmdq_err;
}
}
/* for sending blocking cmd in crtc disable */
init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
}
+
+ mtk_crtc->sec_cmdq_client.client.dev = mtk_crtc->mmsys_dev;
+ mtk_crtc->sec_cmdq_client.client.tx_block = false;
+ mtk_crtc->sec_cmdq_client.client.knows_txdone = true;
+ mtk_crtc->sec_cmdq_client.client.rx_callback = ddp_cmdq_cb;
+ mtk_crtc->sec_cmdq_client.chan =
+ mbox_request_channel(&mtk_crtc->sec_cmdq_client.client, i + 1);
+ if (IS_ERR(mtk_crtc->sec_cmdq_client.chan)) {
+ dev_err(dev, "mtk_crtc %d failed to create sec mailbox client\n",
+ drm_crtc_index(&mtk_crtc->base));
+ mtk_crtc->sec_cmdq_client.chan = NULL;
+ }
+
+ if (mtk_crtc->sec_cmdq_client.chan) {
+ struct device_link *link;
+
+ /* add devlink to cmdq dev to make sure suspend/resume order is correct */
+ link = device_link_add(priv->dev, mtk_crtc->sec_cmdq_client.chan->mbox->dev,
+ DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+ if (!link) {
+ dev_err(priv->dev, "Unable to link dev=%s\n",
+ dev_name(mtk_crtc->sec_cmdq_client.chan->mbox->dev));
+ ret = -ENODEV;
+ goto cmdq_err;
+ }
+
+ ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->sec_cmdq_client,
+ &mtk_crtc->sec_cmdq_handle,
+ PAGE_SIZE);
+ if (ret) {
+ dev_dbg(dev, "mtk_crtc %d failed to create cmdq secure packet\n",
+ drm_crtc_index(&mtk_crtc->base));
+ goto cmdq_err;
+ }
+
+ /* for sending blocking cmd in crtc disable */
+ init_waitqueue_head(&mtk_crtc->sec_cb_blocking_queue);
+ }
+
+cmdq_err:
+ if (ret) {
+ if (mtk_crtc->cmdq_client.chan) {
+ mbox_free_channel(mtk_crtc->cmdq_client.chan);
+ mtk_crtc->cmdq_client.chan = NULL;
+ }
+ if (mtk_crtc->sec_cmdq_client.chan) {
+ mbox_free_channel(mtk_crtc->sec_cmdq_client.chan);
+ mtk_crtc->sec_cmdq_client.chan = NULL;
+ }
+ }
#endif
if (conn_routes) {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index 1f988ff1bf9f..cf8433846108 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -21,6 +21,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
int priv_data_index,
const struct mtk_drm_route *conn_routes,
unsigned int num_conn_routes);
+void mtk_crtc_disable_secure_state(struct drm_crtc *crtc);
int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
struct mtk_plane_state *state);
void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index d4d515627ca4..96293c632d67 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -287,6 +287,13 @@ static void mtk_plane_atomic_disable(struct drm_plane *plane,
mtk_plane_state->pending.enable = false;
wmb(); /* Make sure the above parameter is set before update */
mtk_plane_state->pending.dirty = true;
+
+ if (mtk_plane_state->pending.is_secure) {
+ struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
+
+ if (old_state->crtc)
+ mtk_crtc_disable_secure_state(old_state->crtc);
+ }
}
static void mtk_plane_atomic_update(struct drm_plane *plane,
--
2.18.0
Add get_sec_port interface to ddp_comp to get the secure port settings
from ovl and ovl_adaptor.
Then mediatek-drm will use secure cmdq driver to configure DRAM access
permission in secure world by their secure port settings.
Signed-off-by: Jason-JH.Lin <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index b5a05ca3a385..1e6a120a103d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -84,6 +84,7 @@ struct mtk_ddp_comp_funcs {
void (*add)(struct device *dev, struct mtk_mutex *mutex);
void (*remove)(struct device *dev, struct mtk_mutex *mutex);
unsigned int (*encoder_index)(struct device *dev);
+ u64 (*get_sec_port)(struct mtk_ddp_comp *comp, unsigned int idx);
};
struct mtk_ddp_comp {
@@ -199,6 +200,14 @@ static inline unsigned int mtk_ddp_gamma_get_lut_size(struct mtk_ddp_comp *comp)
return 0;
}
+static inline u64 mtk_ddp_comp_layer_get_sec_port(struct mtk_ddp_comp *comp,
+ unsigned int idx)
+{
+ if (comp->funcs && comp->funcs->get_sec_port)
+ return comp->funcs->get_sec_port(comp, idx);
+ return 0;
+}
+
static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp,
struct drm_crtc_state *state)
{
--
2.18.0
Add secure layer config support for ovl_adaptor and sub driver mdp_rdma.
Signed-off-by: Jason-JH.Lin <[email protected]>
---
drivers/gpu/drm/mediatek/mtk_disp_drv.h | 1 +
drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15 +++++++++++++++
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 +
drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 ++++++++---
drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 ++
5 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 77054adcd9cf..ec9746767468 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -117,6 +117,7 @@ void mtk_ovl_adaptor_clk_disable(struct device *dev);
void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
unsigned int h, unsigned int vrefresh,
unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp, unsigned int idx);
void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index 6bf6367853fb..f419c2e70ba3 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -83,6 +83,18 @@ static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
[OVL_ADAPTOR_ETHDR0] = { OVL_ADAPTOR_TYPE_ETHDR, 0 },
};
+static const u64 ovl_adaptor_sec_port[] = {
+ BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L0),
+ BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L1),
+ BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L2),
+ BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L3),
+};
+
+u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp, unsigned int idx)
+{
+ return ovl_adaptor_sec_port[idx];
+}
+
void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
struct mtk_plane_state *state,
struct cmdq_pkt *cmdq_pkt)
@@ -141,6 +153,9 @@ void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
rdma_config.pitch = pending->pitch;
rdma_config.fmt = pending->format;
rdma_config.color_encoding = pending->color_encoding;
+ rdma_config.source_size = (pending->height - 1) * pending->pitch +
+ pending->width * fmt_info->cpp[0];
+ rdma_config.is_secure = state->pending.is_secure;
mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
if (use_dual_pipe) {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 6aed7647dfc0..9b7fe34df9a6 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -445,6 +445,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
.remove = mtk_ovl_adaptor_remove_comp,
.get_formats = mtk_ovl_adaptor_get_formats,
.get_num_formats = mtk_ovl_adaptor_get_num_formats,
+ .get_sec_port = mtk_ovl_adaptor_get_sec_port,
};
static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
index c3adaeefd551..a164ba82d022 100644
--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -94,6 +94,7 @@ struct mtk_mdp_rdma {
void __iomem *regs;
struct clk *clk;
struct cmdq_client_reg cmdq_reg;
+ resource_size_t regs_pa;
};
static unsigned int rdma_fmt_convert(unsigned int fmt)
@@ -198,9 +199,12 @@ void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
else
mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
-
- mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs,
- MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
+ if (cfg->is_secure)
+ mtk_ddp_sec_write(cmdq_pkt, priv->regs_pa + MDP_RDMA_SRC_BASE_0,
+ cfg->addr0, CMDQ_IWC_H_2_MVA, 0, cfg->source_size, 0);
+ else
+ mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs,
+ MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg, priv->regs,
MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, FLD_MF_BKGD_WB);
@@ -285,6 +289,7 @@ static int mtk_mdp_rdma_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->regs_pa = res->start;
priv->regs = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->regs)) {
dev_err(dev, "failed to ioremap rdma\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
index 9943ee3aac31..cd4840411411 100644
--- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
@@ -15,6 +15,8 @@ struct mtk_mdp_rdma_cfg {
unsigned int y_top;
int fmt;
int color_encoding;
+ unsigned int source_size;
+ unsigned int is_secure;
};
#endif // __MTK_MDP_RDMA_H__
--
2.18.0
Hi, Jason:
On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> Add secure layer config support for ovl_adaptor and sub driver
> mdp_rdma.
>
> Signed-off-by: Jason-JH.Lin <[email protected]>
> ---
> drivers/gpu/drm/mediatek/mtk_disp_drv.h | 1 +
> drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15 +++++++++++++++
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 +
> drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 ++++++++---
> drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 ++
> 5 files changed, 27 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 77054adcd9cf..ec9746767468 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -117,6 +117,7 @@ void mtk_ovl_adaptor_clk_disable(struct device
> *dev);
> void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
> unsigned int h, unsigned int vrefresh,
> unsigned int bpc, struct cmdq_pkt
> *cmdq_pkt);
> +u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp, unsigned
> int idx);
> void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> idx,
> struct mtk_plane_state *state,
> struct cmdq_pkt *cmdq_pkt);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index 6bf6367853fb..f419c2e70ba3 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -83,6 +83,18 @@ static const struct ovl_adaptor_comp_match
> comp_matches[OVL_ADAPTOR_ID_MAX] = {
> [OVL_ADAPTOR_ETHDR0] = { OVL_ADAPTOR_TYPE_ETHDR, 0 },
> };
>
> +static const u64 ovl_adaptor_sec_port[] = {
> + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L0),
> + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L1),
> + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L2),
> + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L3),
> +};
> +
> +u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp, unsigned
> int idx)
> +{
> + return ovl_adaptor_sec_port[idx];
> +}
> +
> void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> idx,
> struct mtk_plane_state *state,
> struct cmdq_pkt *cmdq_pkt)
> @@ -141,6 +153,9 @@ void mtk_ovl_adaptor_layer_config(struct device
> *dev, unsigned int idx,
> rdma_config.pitch = pending->pitch;
> rdma_config.fmt = pending->format;
> rdma_config.color_encoding = pending->color_encoding;
> + rdma_config.source_size = (pending->height - 1) * pending-
> >pitch +
> + pending->width * fmt_info->cpp[0];
> + rdma_config.is_secure = state->pending.is_secure;
> mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
>
> if (use_dual_pipe) {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 6aed7647dfc0..9b7fe34df9a6 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -445,6 +445,7 @@ static const struct mtk_ddp_comp_funcs
> ddp_ovl_adaptor = {
> .remove = mtk_ovl_adaptor_remove_comp,
> .get_formats = mtk_ovl_adaptor_get_formats,
> .get_num_formats = mtk_ovl_adaptor_get_num_formats,
> + .get_sec_port = mtk_ovl_adaptor_get_sec_port,
> };
>
> static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] =
> {
> diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> index c3adaeefd551..a164ba82d022 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> @@ -94,6 +94,7 @@ struct mtk_mdp_rdma {
> void __iomem *regs;
> struct clk *clk;
> struct cmdq_client_reg cmdq_reg;
> + resource_size_t regs_pa;
> };
>
> static unsigned int rdma_fmt_convert(unsigned int fmt)
> @@ -198,9 +199,12 @@ void mtk_mdp_rdma_config(struct device *dev,
> struct mtk_mdp_rdma_cfg *cfg,
> else
> mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv-
> >regs,
> MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
> -
> - mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv-
> >regs,
> - MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
> + if (cfg->is_secure)
> + mtk_ddp_sec_write(cmdq_pkt, priv->regs_pa +
> MDP_RDMA_SRC_BASE_0,
> + cfg->addr0, CMDQ_IWC_H_2_MVA, 0, cfg-
> >source_size, 0);
In OVL, there is one bit that control OVL hardware could access secure
buffer or not. Why mdp rdma has no this bit?
Regards,
CK
> + else
> + mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv-
> >cmdq_reg, priv->regs,
> + MDP_RDMA_SRC_BASE_0,
> FLD_SRC_BASE_0);
>
> mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg,
> priv->regs,
> MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
> FLD_MF_BKGD_WB);
> @@ -285,6 +289,7 @@ static int mtk_mdp_rdma_probe(struct
> platform_device *pdev)
> return -ENOMEM;
>
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + priv->regs_pa = res->start;
> priv->regs = devm_ioremap_resource(dev, res);
> if (IS_ERR(priv->regs)) {
> dev_err(dev, "failed to ioremap rdma\n");
> diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> index 9943ee3aac31..cd4840411411 100644
> --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
> @@ -15,6 +15,8 @@ struct mtk_mdp_rdma_cfg {
> unsigned int y_top;
> int fmt;
> int color_encoding;
> + unsigned int source_size;
> + unsigned int is_secure;
> };
>
> #endif // __MTK_MDP_RDMA_H__
On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> Add get_sec_port interface to ddp_comp to get the secure port
> settings
> from ovl and ovl_adaptor.
> Then mediatek-drm will use secure cmdq driver to configure DRAM
> access
> permission in secure world by their secure port settings.
>
> Signed-off-by: Jason-JH.Lin <[email protected]>
> ---
TODO: drop this patch.
Regards,
CK
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index b5a05ca3a385..1e6a120a103d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -84,6 +84,7 @@ struct mtk_ddp_comp_funcs {
> void (*add)(struct device *dev, struct mtk_mutex *mutex);
> void (*remove)(struct device *dev, struct mtk_mutex *mutex);
> unsigned int (*encoder_index)(struct device *dev);
> + u64 (*get_sec_port)(struct mtk_ddp_comp *comp, unsigned int
> idx);
> };
>
> struct mtk_ddp_comp {
> @@ -199,6 +200,14 @@ static inline unsigned int
> mtk_ddp_gamma_get_lut_size(struct mtk_ddp_comp *comp)
> return 0;
> }
>
> +static inline u64 mtk_ddp_comp_layer_get_sec_port(struct
> mtk_ddp_comp *comp,
> + unsigned int idx)
> +{
> + if (comp->funcs && comp->funcs->get_sec_port)
> + return comp->funcs->get_sec_port(comp, idx);
> + return 0;
> +}
> +
> static inline void mtk_ddp_gamma_set(struct mtk_ddp_comp *comp,
> struct drm_crtc_state *state)
> {
Hi, Jason:
On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> To add secure flow support for mediatek-drm, each crtc have to
> create a secure cmdq mailbox channel. Then cmdq packets with
> display HW configuration will be sent to secure cmdq mailbox channel
> and configured in the secure world.
>
> Each crtc have to use secure cmdq interface to configure some secure
> settings for display HW before sending cmdq packets to secure cmdq
> mailbox channel.
>
> If any of fb get from current drm_atomic_state is secure, then crtc
> will switch to the secure flow to configure display HW.
> If all fbs are not secure in current drm_atomic_state, then crtc will
> switch to the normal flow.
>
> TODO:
> 1. Remove get sec larb port interface in ddp_comp, ovl and
> ovl_adaptor.
> 2. Verify instruction for enabling/disabling dapc and larb port in
> TEE
> drop the sec_engine flags in normal world.
>
> Signed-off-by: Jason-JH.Lin <[email protected]>
>
[snip]
> @@ -1091,14 +1292,63 @@ int mtk_drm_crtc_create(struct drm_device
> *drm_dev,
> if (ret) {
> dev_dbg(dev, "mtk_crtc %d failed to
> create cmdq packet\n",
> drm_crtc_index(&mtk_crtc-
> >base));
> - mbox_free_channel(mtk_crtc-
> >cmdq_client.chan);
> - mtk_crtc->cmdq_client.chan = NULL;
> + goto cmdq_err;
> }
> }
>
> /* for sending blocking cmd in crtc disable */
> init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
> }
> +
> + mtk_crtc->sec_cmdq_client.client.dev = mtk_crtc->mmsys_dev;
> + mtk_crtc->sec_cmdq_client.client.tx_block = false;
> + mtk_crtc->sec_cmdq_client.client.knows_txdone = true;
> + mtk_crtc->sec_cmdq_client.client.rx_callback = ddp_cmdq_cb;
> + mtk_crtc->sec_cmdq_client.chan =
> + mbox_request_channel(&mtk_crtc-
> >sec_cmdq_client.client, i + 1);
> + if (IS_ERR(mtk_crtc->sec_cmdq_client.chan)) {
> + dev_err(dev, "mtk_crtc %d failed to create sec mailbox
> client\n",
> + drm_crtc_index(&mtk_crtc->base));
> + mtk_crtc->sec_cmdq_client.chan = NULL;
> + }
> +
> + if (mtk_crtc->sec_cmdq_client.chan) {
I would like use secure channel to replace normal channel. It means
that no extra channel is required and change the original normal
channel to secure channel. The secure channel could process both normal
buffer and secure buffer, so you need not to switch the channel.
Regards,
CK
> + struct device_link *link;
> +
> + /* add devlink to cmdq dev to make sure suspend/resume
> order is correct */
> + link = device_link_add(priv->dev, mtk_crtc-
> >sec_cmdq_client.chan->mbox->dev,
> + DL_FLAG_PM_RUNTIME |
> DL_FLAG_STATELESS);
> + if (!link) {
> + dev_err(priv->dev, "Unable to link dev=%s\n",
> + dev_name(mtk_crtc-
> >sec_cmdq_client.chan->mbox->dev));
> + ret = -ENODEV;
> + goto cmdq_err;
> + }
> +
> + ret = mtk_drm_cmdq_pkt_create(&mtk_crtc-
> >sec_cmdq_client,
> + &mtk_crtc-
> >sec_cmdq_handle,
> + PAGE_SIZE);
> + if (ret) {
> + dev_dbg(dev, "mtk_crtc %d failed to create cmdq
> secure packet\n",
> + drm_crtc_index(&mtk_crtc->base));
> + goto cmdq_err;
> + }
> +
> + /* for sending blocking cmd in crtc disable */
> + init_waitqueue_head(&mtk_crtc->sec_cb_blocking_queue);
> + }
> +
> +cmdq_err:
> + if (ret) {
> + if (mtk_crtc->cmdq_client.chan) {
> + mbox_free_channel(mtk_crtc->cmdq_client.chan);
> + mtk_crtc->cmdq_client.chan = NULL;
> + }
> + if (mtk_crtc->sec_cmdq_client.chan) {
> + mbox_free_channel(mtk_crtc-
> >sec_cmdq_client.chan);
> + mtk_crtc->sec_cmdq_client.chan = NULL;
> + }
> + }
> #endif
>
> if (conn_routes) {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> index 1f988ff1bf9f..cf8433846108 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
> @@ -21,6 +21,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
> int priv_data_index,
> const struct mtk_drm_route *conn_routes,
> unsigned int num_conn_routes);
> +void mtk_crtc_disable_secure_state(struct drm_crtc *crtc);
> int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane
> *plane,
> struct mtk_plane_state *state);
> void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct
> drm_plane *plane,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index d4d515627ca4..96293c632d67 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -287,6 +287,13 @@ static void mtk_plane_atomic_disable(struct
> drm_plane *plane,
> mtk_plane_state->pending.enable = false;
> wmb(); /* Make sure the above parameter is set before update */
> mtk_plane_state->pending.dirty = true;
> +
> + if (mtk_plane_state->pending.is_secure) {
> + struct drm_plane_state *old_state =
> drm_atomic_get_old_plane_state(state, plane);
> +
> + if (old_state->crtc)
> + mtk_crtc_disable_secure_state(old_state->crtc);
> + }
> }
>
> static void mtk_plane_atomic_update(struct drm_plane *plane,
Hi CK,
Thanks for the reviews.
On Tue, 2023-12-26 at 05:24 +0000, CK Hu (胡俊光) wrote:
> On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> > Add get_sec_port interface to ddp_comp to get the secure port
> > settings
> > from ovl and ovl_adaptor.
> > Then mediatek-drm will use secure cmdq driver to configure DRAM
> > access
> > permission in secure world by their secure port settings.
> >
> > Signed-off-by: Jason-JH.Lin <[email protected]>
> > ---
>
> TODO: drop this patch.
>
>
> Regards,
> CK
>
OK, I'll drop this.
Regards,
Jason-JH.Lin
Hi CK,
Thanks for the reivews.
On Tue, 2023-12-26 at 03:20 +0000, CK Hu (胡俊光) wrote:
> Hi, Jason:
>
> On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> > Add secure layer config support for ovl_adaptor and sub driver
> > mdp_rdma.
> >
> > Signed-off-by: Jason-JH.Lin <[email protected]>
> > ---
> > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 1 +
> > drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15
> > +++++++++++++++
> > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 1 +
> > drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 ++++++++---
> > drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 ++
> > 5 files changed, 27 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index 77054adcd9cf..ec9746767468 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -117,6 +117,7 @@ void mtk_ovl_adaptor_clk_disable(struct device
> > *dev);
> > void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
> > unsigned int h, unsigned int vrefresh,
> > unsigned int bpc, struct cmdq_pkt
> > *cmdq_pkt);
> > +u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp,
> > unsigned
> > int idx);
> > void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> > idx,
> > struct mtk_plane_state *state,
> > struct cmdq_pkt *cmdq_pkt);
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > index 6bf6367853fb..f419c2e70ba3 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> > @@ -83,6 +83,18 @@ static const struct ovl_adaptor_comp_match
> > comp_matches[OVL_ADAPTOR_ID_MAX] = {
> > [OVL_ADAPTOR_ETHDR0] = { OVL_ADAPTOR_TYPE_ETHDR, 0 },
> > };
> >
> > +static const u64 ovl_adaptor_sec_port[] = {
> > + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L0),
> > + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L1),
> > + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L2),
> > + BIT_ULL(CMDQ_SEC_VDO1_DISP_RDMA_L3),
> > +};
> > +
> > +u64 mtk_ovl_adaptor_get_sec_port(struct mtk_ddp_comp *comp,
> > unsigned
> > int idx)
> > +{
> > + return ovl_adaptor_sec_port[idx];
> > +}
> > +
> > void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> > idx,
> > struct mtk_plane_state *state,
> > struct cmdq_pkt *cmdq_pkt)
> > @@ -141,6 +153,9 @@ void mtk_ovl_adaptor_layer_config(struct device
> > *dev, unsigned int idx,
> > rdma_config.pitch = pending->pitch;
> > rdma_config.fmt = pending->format;
> > rdma_config.color_encoding = pending->color_encoding;
> > + rdma_config.source_size = (pending->height - 1) * pending-
> > > pitch +
> >
> > + pending->width * fmt_info->cpp[0];
> > + rdma_config.is_secure = state->pending.is_secure;
> > mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
> >
> > if (use_dual_pipe) {
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > index 6aed7647dfc0..9b7fe34df9a6 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> > @@ -445,6 +445,7 @@ static const struct mtk_ddp_comp_funcs
> > ddp_ovl_adaptor = {
> > .remove = mtk_ovl_adaptor_remove_comp,
> > .get_formats = mtk_ovl_adaptor_get_formats,
> > .get_num_formats = mtk_ovl_adaptor_get_num_formats,
> > + .get_sec_port = mtk_ovl_adaptor_get_sec_port,
> > };
> >
> > static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX]
> > =
> > {
> > diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> > b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> > index c3adaeefd551..a164ba82d022 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
> > @@ -94,6 +94,7 @@ struct mtk_mdp_rdma {
> > void __iomem *regs;
> > struct clk *clk;
> > struct cmdq_client_reg cmdq_reg;
> > + resource_size_t regs_pa;
> > };
> >
> > static unsigned int rdma_fmt_convert(unsigned int fmt)
> > @@ -198,9 +199,12 @@ void mtk_mdp_rdma_config(struct device *dev,
> > struct mtk_mdp_rdma_cfg *cfg,
> > else
> > mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv-
> > > regs,
> >
> > MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
> > -
> > - mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv-
> > > regs,
> >
> > - MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
> > + if (cfg->is_secure)
> > + mtk_ddp_sec_write(cmdq_pkt, priv->regs_pa +
> > MDP_RDMA_SRC_BASE_0,
> > + cfg->addr0, CMDQ_IWC_H_2_MVA, 0, cfg-
> > > source_size, 0);
>
> In OVL, there is one bit that control OVL hardware could access
> secure
> buffer or not. Why mdp rdma has no this bit?
>
> Regards,
> CK
>
Yes, that's different HW design for OVL.
Because OVL has 4 layers, we can't witch the whole larb port to secure
like MDP_RDMA. So that OVL can support normal buffer input and secure
buffer input at the same time.
Regards,
Jason-JH.Lin
Hi CK,
Thanks for the reviews.
On Tue, 2023-12-26 at 05:43 +0000, CK Hu (胡俊光) wrote:
> Hi, Jason:
>
> On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> > To add secure flow support for mediatek-drm, each crtc have to
> > create a secure cmdq mailbox channel. Then cmdq packets with
> > display HW configuration will be sent to secure cmdq mailbox
> > channel
> > and configured in the secure world.
> >
> > Each crtc have to use secure cmdq interface to configure some
> > secure
> > settings for display HW before sending cmdq packets to secure cmdq
> > mailbox channel.
> >
> > If any of fb get from current drm_atomic_state is secure, then crtc
> > will switch to the secure flow to configure display HW.
> > If all fbs are not secure in current drm_atomic_state, then crtc
> > will
> > switch to the normal flow.
> >
> > TODO:
> > 1. Remove get sec larb port interface in ddp_comp, ovl and
> > ovl_adaptor.
> > 2. Verify instruction for enabling/disabling dapc and larb port in
> > TEE
> > drop the sec_engine flags in normal world.
> >
> > Signed-off-by: Jason-JH.Lin <[email protected]>
> >
>
> [snip]
>
> > @@ -1091,14 +1292,63 @@ int mtk_drm_crtc_create(struct drm_device
> > *drm_dev,
> > if (ret) {
> > dev_dbg(dev, "mtk_crtc %d failed to
> > create cmdq packet\n",
> > drm_crtc_index(&mtk_crtc-
> > > base));
> >
> > - mbox_free_channel(mtk_crtc-
> > > cmdq_client.chan);
> >
> > - mtk_crtc->cmdq_client.chan = NULL;
> > + goto cmdq_err;
> > }
> > }
> >
> > /* for sending blocking cmd in crtc disable */
> > init_waitqueue_head(&mtk_crtc->cb_blocking_queue);
> > }
> > +
> > + mtk_crtc->sec_cmdq_client.client.dev = mtk_crtc->mmsys_dev;
> > + mtk_crtc->sec_cmdq_client.client.tx_block = false;
> > + mtk_crtc->sec_cmdq_client.client.knows_txdone = true;
> > + mtk_crtc->sec_cmdq_client.client.rx_callback = ddp_cmdq_cb;
> > + mtk_crtc->sec_cmdq_client.chan =
> > + mbox_request_channel(&mtk_crtc-
> > > sec_cmdq_client.client, i + 1);
> >
> > + if (IS_ERR(mtk_crtc->sec_cmdq_client.chan)) {
> > + dev_err(dev, "mtk_crtc %d failed to create sec mailbox
> > client\n",
> > + drm_crtc_index(&mtk_crtc->base));
> > + mtk_crtc->sec_cmdq_client.chan = NULL;
> > + }
> > +
> > + if (mtk_crtc->sec_cmdq_client.chan) {
>
> I would like use secure channel to replace normal channel. It means
> that no extra channel is required and change the original normal
> channel to secure channel. The secure channel could process both
> normal
> buffer and secure buffer, so you need not to switch the channel.
>
> Regards,
> CK
It sounds quite reasonable!
If the platform or project support OPTEE, we can default use secure
channel to handle both normal and secure buffers.
I will try to to refine this and make sure it won't cause latency issue
on OPTEE transaction frequently.
Regards,
Jason-JH.Lin
Hi, Jason:
On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> From: Jason-jh Lin <[email protected]>
>
> Memory Definitions:
> secure memory - Memory allocated in the TEE (Trusted Execution
> Environment) which is inaccessible in the REE (Rich Execution
> Environment, i.e. linux kernel/userspace).
> secure handle - Integer value which acts as reference to 'secure
> memory'. Used in communication between TEE and REE to reference
> 'secure memory'.
> secure buffer - 'secure memory' that is used to store decrypted,
> compressed video or for other general purposes in the TEE.
> secure surface - 'secure memory' that is used to store graphic
> buffers.
>
> Memory Usage in SVP:
> The overall flow of SVP starts with encrypted video coming in from an
> outside source into the REE. The REE will then allocate a 'secure
> buffer' and send the corresponding 'secure handle' along with the
> encrypted, compressed video data to the TEE. The TEE will then
> decrypt
> the video and store the result in the 'secure buffer'. The REE will
> then allocate a 'secure surface'. The REE will pass the 'secure
> handles' for both the 'secure buffer' and 'secure surface' into the
> TEE for video decoding. The video decoder HW will then decode the
> contents of the 'secure buffer' and place the result in the 'secure
> surface'. The REE will then attach the 'secure surface' to the
> overlay
> plane for rendering of the video.
>
> Everything relating to ensuring security of the actual contents of
> the
> 'secure buffer' and 'secure surface' is out of scope for the REE and
> is the responsibility of the TEE.
>
> DRM driver handles allocation of gem objects that are backed by a
> 'secure
> surface' and for displaying a 'secure surface' on the overlay plane.
> This introduces a new flag for object creation called
> DRM_MTK_GEM_CREATE_ENCRYPTED which indicates it should be a 'secure
> surface'. All changes here are in MediaTek specific code.
I would like to decouple secure display and secure decode. One reason
is that I would like secure display could be tested itself without
secure decode. Another reason is that if someone has draw an image and
want to display securely, this is not related to decode.
To achieve this, mediatek drm driver should provide render function on
secure surface. The most simple function is to bitblt a normal surface
onto secure surface. User could allocate both normal surface and secure
surface, draw on normal surface and bitblt normal surface onto secure
surface. We could have limitation that normal surface and secure
surface have the same width, height, pitch, pixel format, and the
bitblt is the full image bitblt. So mediatek drm driver just need a TEE
function that do memory copy from normal surface to secure surface.
This is not a must-be function, but it has some benefit for secure
display.
Regards,
CK
> ---
> TODO:
> 1) Remove get sec larb port interface in ddp_comp, ovl and
> ovl_adaptor.
> 2) Verify instruction for enabling/disabling dapc and larb port in
> TEE
> drop the sec_engine flags in normal world and.
> 3) Move DISP_REG_OVL_SECURE setting to secure world for
> mtk_disp_ovl.c.
> 4) Change the parameter register address in mtk_ddp_sec_write()
> from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
> 5) Implement setting mmsys routing table in the secure world series.
> ---
> Based on 5 series and 1 patch:
> [1] v3 dma-buf: heaps: Add MediaTek secure heap
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=809023__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqATHgDnU$
>
> [2] v3 add driver to support secure video decoder
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=807308__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSq9TXMSIQ$
>
> [3] v4 soc: mediatek: Add register definitions for GCE
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/[email protected]/__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqkO4_0ac$
>
> [4] v2 Add CMDQ driver support for mt8188
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=810302__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqcXdKnXU$
>
> [5] Add mediatek,gce-events definition to mediatek,gce-mailbox
> bindings
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=810938__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqqGM08aE$
>
> [6] v3 Add CMDQ secure driver for SVP
> -
> https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=812379__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSq_YXTH9A$
>
> ---
> Change in v3:
> 1. fix kerneldoc problems
> 2. fix typo in title and commit message
> 3. adjust naming for secure variable
> 4. add the missing part for is_suecure plane implementation
> 5. use BIT_ULL macro to replace bit shifting
> 6. move modification of ovl_adaptor part to the correct patch
> 7. add TODO list in commit message
> 8. add commit message for using share memory to store execute count
>
> Change in v2:
>
> 1. remove the DRIVER_RDNDER flag for mtk_drm_ioctl
> 2. move cmdq_insert_backup_cookie into client driver
> 3. move secure gce node define from mt8195-cherry.dtsi to mt8195.dtsi
> ---
> CK Hu (1):
> drm/mediatek: Add interface to allocate MediaTek GEM buffer.
>
> Jason-JH.Lin (10):
> drm/mediatek/uapi: Add DRM_MTK_GEM_CREATE_ENCRYPTED flag
> drm/mediatek: Add secure buffer control flow to mtk_drm_gem
> drm/mediatek: Add secure identify flag and funcution to
> mtk_drm_plane
> drm/mediatek: Add mtk_ddp_sec_write to config secure buffer info
> drm/mediatek: Add get_sec_port interface to mtk_ddp_comp
> drm/mediatek: Add secure layer config support for ovl
> drm/mediatek: Add secure layer config support for ovl_adaptor
> drm/mediatek: Add secure flow support to mediatek-drm
> drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt
> finalize
> arm64: dts: mt8195: Add secure mbox settings for vdosys
>
> arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 +-
> drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +
> drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 31 +-
> .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15 +
> drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 274
> +++++++++++++++++-
> drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 +
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ++
> drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 14 +
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 13 +
> drivers/gpu/drm/mediatek/mtk_drm_gem.c | 122 ++++++++
> drivers/gpu/drm/mediatek/mtk_drm_gem.h | 16 +
> drivers/gpu/drm/mediatek/mtk_drm_plane.c | 26 ++
> drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +
> drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 +-
> drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 +
> include/uapi/drm/mediatek_drm.h | 59 ++++
> 16 files changed, 607 insertions(+), 18 deletions(-)
> create mode 100644 include/uapi/drm/mediatek_drm.h
>
Hi CK,
Thanks for the reviews.
On Thu, 2023-12-28 at 06:27 +0000, CK Hu (胡俊光) wrote:
> Hi, Jason:
>
> On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> > From: Jason-jh Lin <[email protected]>
> >
> > Memory Definitions:
> > secure memory - Memory allocated in the TEE (Trusted Execution
> > Environment) which is inaccessible in the REE (Rich Execution
> > Environment, i.e. linux kernel/userspace).
> > secure handle - Integer value which acts as reference to 'secure
> > memory'. Used in communication between TEE and REE to reference
> > 'secure memory'.
> > secure buffer - 'secure memory' that is used to store decrypted,
> > compressed video or for other general purposes in the TEE.
> > secure surface - 'secure memory' that is used to store graphic
> > buffers.
> >
> > Memory Usage in SVP:
> > The overall flow of SVP starts with encrypted video coming in from
> > an
> > outside source into the REE. The REE will then allocate a 'secure
> > buffer' and send the corresponding 'secure handle' along with the
> > encrypted, compressed video data to the TEE. The TEE will then
> > decrypt
> > the video and store the result in the 'secure buffer'. The REE will
> > then allocate a 'secure surface'. The REE will pass the 'secure
> > handles' for both the 'secure buffer' and 'secure surface' into the
> > TEE for video decoding. The video decoder HW will then decode the
> > contents of the 'secure buffer' and place the result in the 'secure
> > surface'. The REE will then attach the 'secure surface' to the
> > overlay
> > plane for rendering of the video.
> >
> > Everything relating to ensuring security of the actual contents of
> > the
> > 'secure buffer' and 'secure surface' is out of scope for the REE
> > and
> > is the responsibility of the TEE.
> >
> > DRM driver handles allocation of gem objects that are backed by a
> > 'secure
> > surface' and for displaying a 'secure surface' on the overlay
> > plane.
> > This introduces a new flag for object creation called
> > DRM_MTK_GEM_CREATE_ENCRYPTED which indicates it should be a 'secure
> > surface'. All changes here are in MediaTek specific code.
>
> I would like to decouple secure display and secure decode. One reason
> is that I would like secure display could be tested itself without
> secure decode. Another reason is that if someone has draw an image
> and
> want to display securely, this is not related to decode.
>
> To achieve this, mediatek drm driver should provide render function
> on
> secure surface. The most simple function is to bitblt a normal
> surface
> onto secure surface. User could allocate both normal surface and
> secure
> surface, draw on normal surface and bitblt normal surface onto secure
> surface. We could have limitation that normal surface and secure
> surface have the same width, height, pitch, pixel format, and the
> bitblt is the full image bitblt. So mediatek drm driver just need a
> TEE
> function that do memory copy from normal surface to secure surface.
>
> This is not a must-be function, but it has some benefit for secure
> display.
>
> Regards,
> CK
>
OK, I'll also add this to TODO.
Regards,
Jason-JH.Lin
> > ---
> > TODO:
> > 1) Remove get sec larb port interface in ddp_comp, ovl and
> > ovl_adaptor.
> > 2) Verify instruction for enabling/disabling dapc and larb port in
> > TEE
> > drop the sec_engine flags in normal world and.
> > 3) Move DISP_REG_OVL_SECURE setting to secure world for
> > mtk_disp_ovl.c.
> > 4) Change the parameter register address in mtk_ddp_sec_write()
> > from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
> > 5) Implement setting mmsys routing table in the secure world
> > series.
> > ---
> > Based on 5 series and 1 patch:
> > [1] v3 dma-buf: heaps: Add MediaTek secure heap
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=809023__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqATHgDnU$
> >
> > [2] v3 add driver to support secure video decoder
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=807308__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSq9TXMSIQ$
> >
> > [3] v4 soc: mediatek: Add register definitions for GCE
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/[email protected]/__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqkO4_0ac$
> >
> > [4] v2 Add CMDQ driver support for mt8188
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=810302__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqcXdKnXU$
> >
> > [5] Add mediatek,gce-events definition to mediatek,gce-mailbox
> > bindings
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=810938__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSqqGM08aE$
> >
> > [6] v3 Add CMDQ secure driver for SVP
> > -
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=812379__;!!CTRNKA9wMg0ARbw!lYGWfjjIBlxJvwBXWyxHTyc2vew5YagqT_qJZrYONTH20h95qxC3PH9V91vjplYU3S0ayseyHpxRQFSq_YXTH9A$
> >
> > ---
> > Change in v3:
> > 1. fix kerneldoc problems
> > 2. fix typo in title and commit message
> > 3. adjust naming for secure variable
> > 4. add the missing part for is_suecure plane implementation
> > 5. use BIT_ULL macro to replace bit shifting
> > 6. move modification of ovl_adaptor part to the correct patch
> > 7. add TODO list in commit message
> > 8. add commit message for using share memory to store execute count
> >
> > Change in v2:
> >
> > 1. remove the DRIVER_RDNDER flag for mtk_drm_ioctl
> > 2. move cmdq_insert_backup_cookie into client driver
> > 3. move secure gce node define from mt8195-cherry.dtsi to
> > mt8195.dtsi
> > ---
> > CK Hu (1):
> > drm/mediatek: Add interface to allocate MediaTek GEM buffer.
> >
> > Jason-JH.Lin (10):
> > drm/mediatek/uapi: Add DRM_MTK_GEM_CREATE_ENCRYPTED flag
> > drm/mediatek: Add secure buffer control flow to mtk_drm_gem
> > drm/mediatek: Add secure identify flag and funcution to
> > mtk_drm_plane
> > drm/mediatek: Add mtk_ddp_sec_write to config secure buffer info
> > drm/mediatek: Add get_sec_port interface to mtk_ddp_comp
> > drm/mediatek: Add secure layer config support for ovl
> > drm/mediatek: Add secure layer config support for ovl_adaptor
> > drm/mediatek: Add secure flow support to mediatek-drm
> > drm/mediatek: Add cmdq_insert_backup_cookie before secure pkt
> > finalize
> > arm64: dts: mt8195: Add secure mbox settings for vdosys
> >
> > arch/arm64/boot/dts/mediatek/mt8195.dtsi | 6 +-
> > drivers/gpu/drm/mediatek/mtk_disp_drv.h | 3 +
> > drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 31 +-
> > .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c | 15 +
> > drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 274
> > +++++++++++++++++-
> > drivers/gpu/drm/mediatek/mtk_drm_crtc.h | 1 +
> > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ++
> > drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 14 +
> > drivers/gpu/drm/mediatek/mtk_drm_drv.c | 13 +
> > drivers/gpu/drm/mediatek/mtk_drm_gem.c | 122 ++++++++
> > drivers/gpu/drm/mediatek/mtk_drm_gem.h | 16 +
> > drivers/gpu/drm/mediatek/mtk_drm_plane.c | 26 ++
> > drivers/gpu/drm/mediatek/mtk_drm_plane.h | 2 +
> > drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 11 +-
> > drivers/gpu/drm/mediatek/mtk_mdp_rdma.h | 2 +
> > include/uapi/drm/mediatek_drm.h | 59 ++++
> > 16 files changed, 607 insertions(+), 18 deletions(-)
> > create mode 100644 include/uapi/drm/mediatek_drm.h
> >