diff mbox series

[v3,07/11] drm/mediatek: Add secure layer config support for ovl

Message ID 20231223182932.27683-8-jason-jh.lin@mediatek.com (mailing list archive)
State New, archived
Headers show
Series Add mediate-drm secure flow for SVP | expand

Commit Message

Jason-JH.Lin Dec. 23, 2023, 6:29 p.m. UTC
Add secure layer config support for ovl.

TODO:
1. Move DISP_REG_OVL_SECURE setting to secure world.
2. Change the parameter register address in mtk_ddp_sec_write()
   from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".

Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  2 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 31 +++++++++++++++++++--
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29 +++++++++++++++++++
 3 files changed, 60 insertions(+), 2 deletions(-)

Comments

CK Hu (胡俊光) Dec. 26, 2023, 5:14 a.m. UTC | #1
Hi, Jason:

On Sun, 2023-12-24 at 02:29 +0800, Jason-JH.Lin wrote:
> Add secure layer config support for ovl.
> 
> TODO:
> 1. Move DISP_REG_OVL_SECURE setting to secure world.
> 2. Change the parameter register address in mtk_ddp_sec_write()
>    from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
> 
> Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  2 ++
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 31
> +++++++++++++++++++--
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29 +++++++++++++++++++
>  3 files changed, 60 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 1311562d25cc..77054adcd9cf 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -9,6 +9,7 @@
>  #include <linux/soc/mediatek/mtk-cmdq.h>
>  #include <linux/soc/mediatek/mtk-mmsys.h>
>  #include <linux/soc/mediatek/mtk-mutex.h>
> +#include "mtk_drm_ddp_comp.h"
>  #include "mtk_drm_plane.h"
>  #include "mtk_mdp_rdma.h"
>  
> @@ -82,6 +83,7 @@ void mtk_ovl_clk_disable(struct device *dev);
>  void mtk_ovl_config(struct device *dev, unsigned int w,
>  		    unsigned int h, unsigned int vrefresh,
>  		    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> idx);
>  int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
>  			struct mtk_plane_state *mtk_state);
>  void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 2bffe4245466..c18f76412a2e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -46,6 +46,7 @@
>  #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr +
> 0x20 * (n))
>  #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data-
> >addr + 0x20 * (n) + 0x04)
>  #define DISP_REG_OVL_HDR_PITCH(ovl, n)		((ovl)->data-
> >addr + 0x20 * (n) + 0x08)
> +#define DISP_REG_OVL_SECURE			0x0fc0
>  
>  #define GMC_THRESHOLD_BITS	16
>  #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
> @@ -126,8 +127,19 @@ struct mtk_disp_ovl {
>  	const struct mtk_disp_ovl_data	*data;
>  	void				(*vblank_cb)(void *data);
>  	void				*vblank_cb_data;
> +	resource_size_t			regs_pa;
>  };
>  
> +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> idx)
> +{
> +	if (comp->id == DDP_COMPONENT_OVL0)
> +		return BIT_ULL(CMDQ_SEC_DISP_OVL0);
> +	else if (comp->id == DDP_COMPONENT_OVL1)
> +		return BIT_ULL(CMDQ_SEC_DISP_OVL1);
> +
> +	return 0;
> +}
> +
>  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
>  {
>  	struct mtk_disp_ovl *priv = dev_id;
> @@ -449,8 +461,22 @@ void mtk_ovl_layer_config(struct device *dev,
> unsigned int idx,
>  			      DISP_REG_OVL_SRC_SIZE(idx));
>  	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl-
> >regs,
>  			      DISP_REG_OVL_OFFSET(idx));
> -	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl-
> >regs,
> -			      DISP_REG_OVL_ADDR(ovl, idx));
> +
> +	if (state->pending.is_secure) {
> +		const struct drm_format_info *fmt_info =
> drm_format_info(fmt);
> +		unsigned int buf_size = (pending->height - 1) *
> pending->pitch +
> +					pending->width * fmt_info-
> >cpp[0];
> +
> +		mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg,
> ovl->regs,
> +				   DISP_REG_OVL_SECURE, BIT(idx));
> +		mtk_ddp_sec_write(cmdq_pkt, ovl->regs_pa +
> DISP_REG_OVL_ADDR(ovl, idx),
> +				  pending->addr, CMDQ_IWC_H_2_MVA, 0,
> buf_size, 0);

Mapping iova should be done when buffer allocation or some other
mapping function, instead of every OVL frame configuration. So the size
should not be set here.

Regards,
CK

> +	} else {
> +		mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl-
> >regs,
> +				   DISP_REG_OVL_SECURE, BIT(idx));
> +		mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg,
> ovl->regs,
> +				      DISP_REG_OVL_ADDR(ovl, idx));
> +	}
>  
>  	if (is_afbc) {
>  		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl-
> >cmdq_reg, ovl->regs,
> @@ -529,6 +555,7 @@ static int mtk_disp_ovl_probe(struct
> platform_device *pdev)
>  	}
>  
>  	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 ovl\n");
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 3046c0409353..6aed7647dfc0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -111,6 +111,34 @@ void mtk_ddp_write_mask(struct cmdq_pkt
> *cmdq_pkt, unsigned int value,
>  #endif
>  }
>  
> +void mtk_ddp_sec_write(struct cmdq_pkt *cmdq_pkt, u32 addr, u64
> base,
> +		       const enum cmdq_iwc_addr_metadata_type type,
> +		       const u32 offset, const u32 size, const u32
> port)
> +{
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	if (!cmdq_pkt)
> +		return;
> +
> +	/* secure buffer will be 4K alignment */
> +	cmdq_sec_pkt_write(cmdq_pkt, addr, base, type,
> +			   offset, ALIGN(size, PAGE_SIZE), port);
> +#endif
> +}
> +
> +void mtk_ddp_sec_write(struct cmdq_pkt *cmdq_pkt, u32 addr, u64
> base,
> +		       const enum cmdq_iwc_addr_metadata_type type,
> +		       const u32 offset, const u32 size, const u32
> port)
> +{
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	if (!cmdq_pkt)
> +		return;
> +
> +	/* secure buffer will be 4K alignment */
> +	cmdq_sec_pkt_write(cmdq_pkt, addr, base, type,
> +			   offset, ALIGN(size, PAGE_SIZE), port);
> +#endif
> +}
> +
>  static int mtk_ddp_clk_enable(struct device *dev)
>  {
>  	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
> @@ -365,6 +393,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl =
> {
>  	.bgclr_in_off = mtk_ovl_bgclr_in_off,
>  	.get_formats = mtk_ovl_get_formats,
>  	.get_num_formats = mtk_ovl_get_num_formats,
> +	.get_sec_port = mtk_ovl_get_sec_port,
>  };
>  
>  static const struct mtk_ddp_comp_funcs ddp_postmask = {
Jason-JH.Lin Dec. 27, 2023, 7:16 a.m. UTC | #2
Hi CK,

Thanks for the review.

On Tue, 2023-12-26 at 05:14 +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.
> > 
> > TODO:
> > 1. Move DISP_REG_OVL_SECURE setting to secure world.
> > 2. Change the parameter register address in mtk_ddp_sec_write()
> >    from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
> > 
> > Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  2 ++
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 31
> > +++++++++++++++++++--
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29
> > +++++++++++++++++++
> >  3 files changed, 60 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index 1311562d25cc..77054adcd9cf 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -9,6 +9,7 @@
> >  #include <linux/soc/mediatek/mtk-cmdq.h>
> >  #include <linux/soc/mediatek/mtk-mmsys.h>
> >  #include <linux/soc/mediatek/mtk-mutex.h>
> > +#include "mtk_drm_ddp_comp.h"
> >  #include "mtk_drm_plane.h"
> >  #include "mtk_mdp_rdma.h"
> >  
> > @@ -82,6 +83,7 @@ void mtk_ovl_clk_disable(struct device *dev);
> >  void mtk_ovl_config(struct device *dev, unsigned int w,
> >  		    unsigned int h, unsigned int vrefresh,
> >  		    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> > +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> > idx);
> >  int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
> >  			struct mtk_plane_state *mtk_state);
> >  void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 2bffe4245466..c18f76412a2e 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -46,6 +46,7 @@
> >  #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr +
> > 0x20 * (n))
> >  #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data-
> > > addr + 0x20 * (n) + 0x04)
> > 
> >  #define DISP_REG_OVL_HDR_PITCH(ovl, n)		((ovl)->data-
> > > addr + 0x20 * (n) + 0x08)
> > 
> > +#define DISP_REG_OVL_SECURE			0x0fc0
> >  
> >  #define GMC_THRESHOLD_BITS	16
> >  #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
> > @@ -126,8 +127,19 @@ struct mtk_disp_ovl {
> >  	const struct mtk_disp_ovl_data	*data;
> >  	void				(*vblank_cb)(void *data);
> >  	void				*vblank_cb_data;
> > +	resource_size_t			regs_pa;
> >  };
> >  
> > +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> > idx)
> > +{
> > +	if (comp->id == DDP_COMPONENT_OVL0)
> > +		return BIT_ULL(CMDQ_SEC_DISP_OVL0);
> > +	else if (comp->id == DDP_COMPONENT_OVL1)
> > +		return BIT_ULL(CMDQ_SEC_DISP_OVL1);
> > +
> > +	return 0;
> > +}
> > +
> >  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
> >  {
> >  	struct mtk_disp_ovl *priv = dev_id;
> > @@ -449,8 +461,22 @@ void mtk_ovl_layer_config(struct device *dev,
> > unsigned int idx,
> >  			      DISP_REG_OVL_SRC_SIZE(idx));
> >  	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl-
> > > regs,
> > 
> >  			      DISP_REG_OVL_OFFSET(idx));
> > -	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl-
> > > regs,
> > 
> > -			      DISP_REG_OVL_ADDR(ovl, idx));
> > +
> > +	if (state->pending.is_secure) {
> > +		const struct drm_format_info *fmt_info =
> > drm_format_info(fmt);
> > +		unsigned int buf_size = (pending->height - 1) *
> > pending->pitch +
> > +					pending->width * fmt_info-
> > > cpp[0];
> > 
> > +
> > +		mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg,
> > ovl->regs,
> > +				   DISP_REG_OVL_SECURE, BIT(idx));
> > +		mtk_ddp_sec_write(cmdq_pkt, ovl->regs_pa +
> > DISP_REG_OVL_ADDR(ovl, idx),
> > +				  pending->addr, CMDQ_IWC_H_2_MVA, 0,
> > buf_size, 0);
> 
> Mapping iova should be done when buffer allocation or some other
> mapping function, instead of every OVL frame configuration. So the
> size
> should not be set here.
> 
> Regards,
> CK
> 

Since we can only get the secure handle when the plane updates, the
buffer have to be mapped here every time.
So I'll ask IOMMU owner to move this mapping process into allocation
step, then we can remove the size here.

Regards,
Jason-JH.Lin
Jason-JH.Lin Jan. 12, 2024, 3:41 a.m. UTC | #3
On Wed, 2023-12-27 at 15:16 +0800, Jason-JH.Lin wrote:
> Hi CK,
> 
> Thanks for the review.
> 
> On Tue, 2023-12-26 at 05:14 +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.
> > > 
> > > TODO:
> > > 1. Move DISP_REG_OVL_SECURE setting to secure world.
> > > 2. Change the parameter register address in mtk_ddp_sec_write()
> > >    from "u32 addr" to "struct cmdq_client_reg *cmdq_reg".
> > > 
> > > Signed-off-by: Jason-JH.Lin <jason-jh.lin@mediatek.com>
> > > ---
> > >  drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  2 ++
> > >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 31
> > > +++++++++++++++++++--
> > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 29
> > > +++++++++++++++++++
> > >  3 files changed, 60 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > index 1311562d25cc..77054adcd9cf 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > @@ -9,6 +9,7 @@
> > >  #include <linux/soc/mediatek/mtk-cmdq.h>
> > >  #include <linux/soc/mediatek/mtk-mmsys.h>
> > >  #include <linux/soc/mediatek/mtk-mutex.h>
> > > +#include "mtk_drm_ddp_comp.h"
> > >  #include "mtk_drm_plane.h"
> > >  #include "mtk_mdp_rdma.h"
> > >  
> > > @@ -82,6 +83,7 @@ void mtk_ovl_clk_disable(struct device *dev);
> > >  void mtk_ovl_config(struct device *dev, unsigned int w,
> > >  		    unsigned int h, unsigned int vrefresh,
> > >  		    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> > > +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> > > idx);
> > >  int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
> > >  			struct mtk_plane_state *mtk_state);
> > >  void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
> > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > > index 2bffe4245466..c18f76412a2e 100644
> > > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > > @@ -46,6 +46,7 @@
> > >  #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data-
> > > >addr +
> > > 0x20 * (n))
> > >  #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data-
> > > > addr + 0x20 * (n) + 0x04)
> > > 
> > >  #define DISP_REG_OVL_HDR_PITCH(ovl, n)		((ovl)->data-
> > > > addr + 0x20 * (n) + 0x08)
> > > 
> > > +#define DISP_REG_OVL_SECURE			0x0fc0
> > >  
> > >  #define GMC_THRESHOLD_BITS	16
> > >  #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
> > > @@ -126,8 +127,19 @@ struct mtk_disp_ovl {
> > >  	const struct mtk_disp_ovl_data	*data;
> > >  	void				(*vblank_cb)(void *data);
> > >  	void				*vblank_cb_data;
> > > +	resource_size_t			regs_pa;
> > >  };
> > >  
> > > +u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int
> > > idx)
> > > +{
> > > +	if (comp->id == DDP_COMPONENT_OVL0)
> > > +		return BIT_ULL(CMDQ_SEC_DISP_OVL0);
> > > +	else if (comp->id == DDP_COMPONENT_OVL1)
> > > +		return BIT_ULL(CMDQ_SEC_DISP_OVL1);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void
> > > *dev_id)
> > >  {
> > >  	struct mtk_disp_ovl *priv = dev_id;
> > > @@ -449,8 +461,22 @@ void mtk_ovl_layer_config(struct device
> > > *dev,
> > > unsigned int idx,
> > >  			      DISP_REG_OVL_SRC_SIZE(idx));
> > >  	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl-
> > > > regs,
> > > 
> > >  			      DISP_REG_OVL_OFFSET(idx));
> > > -	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl-
> > > > regs,
> > > 
> > > -			      DISP_REG_OVL_ADDR(ovl, idx));
> > > +
> > > +	if (state->pending.is_secure) {
> > > +		const struct drm_format_info *fmt_info =
> > > drm_format_info(fmt);
> > > +		unsigned int buf_size = (pending->height - 1) *
> > > pending->pitch +
> > > +					pending->width * fmt_info-
> > > > cpp[0];
> > > 
> > > +
> > > +		mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg,
> > > ovl->regs,
> > > +				   DISP_REG_OVL_SECURE, BIT(idx));
> > > +		mtk_ddp_sec_write(cmdq_pkt, ovl->regs_pa +
> > > DISP_REG_OVL_ADDR(ovl, idx),
> > > +				  pending->addr, CMDQ_IWC_H_2_MVA, 0,
> > > buf_size, 0);
> > 
> > Mapping iova should be done when buffer allocation or some other
> > mapping function, instead of every OVL frame configuration. So the
> > size
> > should not be set here.
> > 
> > Regards,
> > CK
> > 
> 
> Since we can only get the secure handle when the plane updates, the
> buffer have to be mapped here every time.
> So I'll ask IOMMU owner to move this mapping process into allocation
> step, then we can remove the size here.
> 

After discuss with IOMMU owner, we can remove the size parameter.
I'll remove it in the next version.

Regards,
Jason-JH.Lin

> Regards,
> Jason-JH.Lin
diff mbox series

Patch

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 1311562d25cc..77054adcd9cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -9,6 +9,7 @@ 
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
+#include "mtk_drm_ddp_comp.h"
 #include "mtk_drm_plane.h"
 #include "mtk_mdp_rdma.h"
 
@@ -82,6 +83,7 @@  void mtk_ovl_clk_disable(struct device *dev);
 void mtk_ovl_config(struct device *dev, unsigned int w,
 		    unsigned int h, unsigned int vrefresh,
 		    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int idx);
 int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
 			struct mtk_plane_state *mtk_state);
 void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 2bffe4245466..c18f76412a2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -46,6 +46,7 @@ 
 #define DISP_REG_OVL_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x04)
 #define DISP_REG_OVL_HDR_PITCH(ovl, n)		((ovl)->data->addr + 0x20 * (n) + 0x08)
+#define DISP_REG_OVL_SECURE			0x0fc0
 
 #define GMC_THRESHOLD_BITS	16
 #define GMC_THRESHOLD_HIGH	((1 << GMC_THRESHOLD_BITS) / 4)
@@ -126,8 +127,19 @@  struct mtk_disp_ovl {
 	const struct mtk_disp_ovl_data	*data;
 	void				(*vblank_cb)(void *data);
 	void				*vblank_cb_data;
+	resource_size_t			regs_pa;
 };
 
+u64 mtk_ovl_get_sec_port(struct mtk_ddp_comp *comp, unsigned int idx)
+{
+	if (comp->id == DDP_COMPONENT_OVL0)
+		return BIT_ULL(CMDQ_SEC_DISP_OVL0);
+	else if (comp->id == DDP_COMPONENT_OVL1)
+		return BIT_ULL(CMDQ_SEC_DISP_OVL1);
+
+	return 0;
+}
+
 static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
 {
 	struct mtk_disp_ovl *priv = dev_id;
@@ -449,8 +461,22 @@  void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 			      DISP_REG_OVL_SRC_SIZE(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_OFFSET(idx));
-	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
-			      DISP_REG_OVL_ADDR(ovl, idx));
+
+	if (state->pending.is_secure) {
+		const struct drm_format_info *fmt_info = drm_format_info(fmt);
+		unsigned int buf_size = (pending->height - 1) * pending->pitch +
+					pending->width * fmt_info->cpp[0];
+
+		mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &ovl->cmdq_reg, ovl->regs,
+				   DISP_REG_OVL_SECURE, BIT(idx));
+		mtk_ddp_sec_write(cmdq_pkt, ovl->regs_pa + DISP_REG_OVL_ADDR(ovl, idx),
+				  pending->addr, CMDQ_IWC_H_2_MVA, 0, buf_size, 0);
+	} else {
+		mtk_ddp_write_mask(cmdq_pkt, 0, &ovl->cmdq_reg, ovl->regs,
+				   DISP_REG_OVL_SECURE, BIT(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
+				      DISP_REG_OVL_ADDR(ovl, idx));
+	}
 
 	if (is_afbc) {
 		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
@@ -529,6 +555,7 @@  static int mtk_disp_ovl_probe(struct platform_device *pdev)
 	}
 
 	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 ovl\n");
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 3046c0409353..6aed7647dfc0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -111,6 +111,34 @@  void mtk_ddp_write_mask(struct cmdq_pkt *cmdq_pkt, unsigned int value,
 #endif
 }
 
+void mtk_ddp_sec_write(struct cmdq_pkt *cmdq_pkt, u32 addr, u64 base,
+		       const enum cmdq_iwc_addr_metadata_type type,
+		       const u32 offset, const u32 size, const u32 port)
+{
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (!cmdq_pkt)
+		return;
+
+	/* secure buffer will be 4K alignment */
+	cmdq_sec_pkt_write(cmdq_pkt, addr, base, type,
+			   offset, ALIGN(size, PAGE_SIZE), port);
+#endif
+}
+
+void mtk_ddp_sec_write(struct cmdq_pkt *cmdq_pkt, u32 addr, u64 base,
+		       const enum cmdq_iwc_addr_metadata_type type,
+		       const u32 offset, const u32 size, const u32 port)
+{
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (!cmdq_pkt)
+		return;
+
+	/* secure buffer will be 4K alignment */
+	cmdq_sec_pkt_write(cmdq_pkt, addr, base, type,
+			   offset, ALIGN(size, PAGE_SIZE), port);
+#endif
+}
+
 static int mtk_ddp_clk_enable(struct device *dev)
 {
 	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
@@ -365,6 +393,7 @@  static const struct mtk_ddp_comp_funcs ddp_ovl = {
 	.bgclr_in_off = mtk_ovl_bgclr_in_off,
 	.get_formats = mtk_ovl_get_formats,
 	.get_num_formats = mtk_ovl_get_num_formats,
+	.get_sec_port = mtk_ovl_get_sec_port,
 };
 
 static const struct mtk_ddp_comp_funcs ddp_postmask = {