diff mbox series

[v5,14/14] drm/mediatek: Support MT8188 Padding in display driver

Message ID 20230627063946.14935-15-shawn.sung@mediatek.com (mailing list archive)
State New, archived
Headers show
Series Add display driver for MT8188 VDOSYS1 | expand

Commit Message

Shawn Sung (宋孝謙) June 27, 2023, 6:39 a.m. UTC
Padding is a new display module on MT8188, it provides ability
to add pixels to width and height of a layer with specified colors.

Due to hardware design, Mixer in VDOSYS1 requires width of a layer
to be 2-pixel-align, or 4-pixel-align when ETHDR is enabled,
we need Padding to deal with odd width.

Please notice that even if the Padding is in bypass mode,
settings in register must be cleared to 0,
or undefined behaviors could happen.

Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile             |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   3 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  33 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   2 +-
 drivers/gpu/drm/mediatek/mtk_padding.c        | 136 ++++++++++++++++++
 6 files changed, 176 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_padding.c

Comments

CK Hu (胡俊光) July 31, 2023, 10:08 a.m. UTC | #1
Hi, Hsiao-chien:

On Tue, 2023-06-27 at 14:39 +0800, Hsiao Chien Sung wrote:
> Padding is a new display module on MT8188, it provides ability
> to add pixels to width and height of a layer with specified colors.
> 
> Due to hardware design, Mixer in VDOSYS1 requires width of a layer
> to be 2-pixel-align, or 4-pixel-align when ETHDR is enabled,
> we need Padding to deal with odd width.
> 
> Please notice that even if the Padding is in bypass mode,
> settings in register must be cleared to 0,
> or undefined behaviors could happen.

Separate this patch to two patches. One for padding driver and another
one for ovl adapator.

> 
> Signed-off-by: Hsiao Chien Sung <shawn.sung@mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/Makefile             |   3 +-
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   3 +
>  .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   |  33 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c        |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   2 +-
>  drivers/gpu/drm/mediatek/mtk_padding.c        | 136
> ++++++++++++++++++
>  6 files changed, 176 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_padding.c
> 
> diff --git a/drivers/gpu/drm/mediatek/Makefile
> b/drivers/gpu/drm/mediatek/Makefile
> index d4d193f60271..5e4436403b8d 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -16,7 +16,8 @@ mediatek-drm-y := mtk_disp_aal.o \
>  		  mtk_dsi.o \
>  		  mtk_dpi.o \
>  		  mtk_ethdr.o \
> -		  mtk_mdp_rdma.o
> +		  mtk_mdp_rdma.o \
> +		  mtk_padding.o
>  
>  obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 2254038519e1..f9fdb1268aa5 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -157,4 +157,7 @@ void mtk_mdp_rdma_config(struct device *dev,
> struct mtk_mdp_rdma_cfg *cfg,
>  const u32 *mtk_mdp_rdma_get_formats(struct device *dev);
>  size_t mtk_mdp_rdma_get_num_formats(struct device *dev);
>  
> +int mtk_padding_clk_enable(struct device *dev);
> +void mtk_padding_clk_disable(struct device *dev);
> +void mtk_padding_config(struct device *dev, struct cmdq_pkt
> *cmdq_pkt);
>  #endif
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> index f73a558dcf93..ca8f3febbf11 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
> @@ -29,6 +29,7 @@ enum mtk_ovl_adaptor_comp_type {
>  	OVL_ADAPTOR_TYPE_ETHDR,
>  	OVL_ADAPTOR_TYPE_MDP_RDMA,
>  	OVL_ADAPTOR_TYPE_MERGE,
> +	OVL_ADAPTOR_TYPE_PADDING,
>  	OVL_ADAPTOR_TYPE_NUM,
>  };
>  
> @@ -46,6 +47,14 @@ enum mtk_ovl_adaptor_comp_id {
>  	OVL_ADAPTOR_MERGE1,
>  	OVL_ADAPTOR_MERGE2,
>  	OVL_ADAPTOR_MERGE3,
> +	OVL_ADAPTOR_PADDING0,
> +	OVL_ADAPTOR_PADDING1,
> +	OVL_ADAPTOR_PADDING2,
> +	OVL_ADAPTOR_PADDING3,
> +	OVL_ADAPTOR_PADDING4,
> +	OVL_ADAPTOR_PADDING5,
> +	OVL_ADAPTOR_PADDING6,
> +	OVL_ADAPTOR_PADDING7,
>  	OVL_ADAPTOR_ID_MAX
>  };
>  
> @@ -66,6 +75,7 @@ static const char * const
> private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
>  	[OVL_ADAPTOR_TYPE_ETHDR]	= "ethdr",
>  	[OVL_ADAPTOR_TYPE_MDP_RDMA]	= "vdo1-rdma",
>  	[OVL_ADAPTOR_TYPE_MERGE]	= "merge",
> +	[OVL_ADAPTOR_TYPE_PADDING]	= "padding",
>  };
>  
>  static const struct mtk_ddp_comp_funcs _ethdr = {
> @@ -78,6 +88,11 @@ static const struct mtk_ddp_comp_funcs _merge = {
>  	.clk_disable = mtk_merge_clk_disable,
>  };
>  
> +static const struct mtk_ddp_comp_funcs _padding = {
> +	.clk_enable = mtk_padding_clk_enable,
> +	.clk_disable = mtk_padding_clk_disable,
> +};
> +
>  static const struct mtk_ddp_comp_funcs _rdma = {
>  	.clk_enable = mtk_mdp_rdma_clk_enable,
>  	.clk_disable = mtk_mdp_rdma_clk_disable,
> @@ -97,6 +112,14 @@ static const struct ovl_adaptor_comp_match
> comp_matches[OVL_ADAPTOR_ID_MAX] = {
>  	[OVL_ADAPTOR_MERGE1] = { OVL_ADAPTOR_TYPE_MERGE,
> DDP_COMPONENT_MERGE2, 2, &_merge },
>  	[OVL_ADAPTOR_MERGE2] = { OVL_ADAPTOR_TYPE_MERGE,
> DDP_COMPONENT_MERGE3, 3, &_merge },
>  	[OVL_ADAPTOR_MERGE3] = { OVL_ADAPTOR_TYPE_MERGE,
> DDP_COMPONENT_MERGE4, 4, &_merge },
> +	[OVL_ADAPTOR_PADDING0] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING0, 0, &_padding },
> +	[OVL_ADAPTOR_PADDING1] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING1, 1, &_padding },
> +	[OVL_ADAPTOR_PADDING2] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING2, 2, &_padding },
> +	[OVL_ADAPTOR_PADDING3] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING3, 3, &_padding },
> +	[OVL_ADAPTOR_PADDING4] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING4, 4, &_padding },
> +	[OVL_ADAPTOR_PADDING5] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING5, 5, &_padding },
> +	[OVL_ADAPTOR_PADDING6] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING6, 6, &_padding },
> +	[OVL_ADAPTOR_PADDING7] = { OVL_ADAPTOR_TYPE_PADDING,
> DDP_COMPONENT_PADDING7, 7, &_padding },
>  };
>  
>  void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int
> idx,
> @@ -108,6 +131,8 @@ void mtk_ovl_adaptor_layer_config(struct device
> *dev, unsigned int idx,
>  	struct mtk_mdp_rdma_cfg rdma_config = {0};
>  	struct device *ethdr;
>  	struct device *merge;
> +	struct device *padding_l;
> +	struct device *padding_r;
>  	struct device *rdma_l;
>  	struct device *rdma_r;
>  	const struct drm_format_info *fmt_info =
> drm_format_info(pending->format);
> @@ -124,6 +149,8 @@ void mtk_ovl_adaptor_layer_config(struct device
> *dev, unsigned int idx,
>  
>  	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
>  	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 +
> idx];
> +	padding_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_PADDING0
> + 2 * idx];
> +	padding_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_PADDING0
> + 2 * idx + 1];
>  	rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 +
> 2 * idx];
>  	rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 +
> 2 * idx + 1];
>  
> @@ -159,10 +186,15 @@ void mtk_ovl_adaptor_layer_config(struct device
> *dev, unsigned int idx,
>  	rdma_config.color_encoding = pending->color_encoding;
>  	mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
>  
> +	if (padding_l)
> +		mtk_padding_config(padding_l, cmdq_pkt);
> +
>  	if (use_dual_pipe) {
>  		rdma_config.x_left = l_w;
>  		rdma_config.width = r_w;
>  		mtk_mdp_rdma_config(rdma_r, &rdma_config, cmdq_pkt);
> +		if (padding_r)
> +			mtk_padding_config(padding_r, cmdq_pkt);
>  	}
>  
>  	mtk_merge_start_cmdq(merge, cmdq_pkt);
> @@ -353,6 +385,7 @@ static int ovl_adaptor_comp_get_id(struct device
> *dev, struct device_node *node,
>  }
>  
>  static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
> +	{ .compatible = "mediatek,mt8188-padding", .data = (void
> *)OVL_ADAPTOR_TYPE_PADDING },
>  	{ .compatible = "mediatek,mt8195-disp-ethdr", .data = (void
> *)OVL_ADAPTOR_TYPE_ETHDR },
>  	{ .compatible = "mediatek,mt8195-disp-merge", .data = (void
> *)OVL_ADAPTOR_TYPE_MERGE },
>  	{ .compatible = "mediatek,mt8195-vdo1-rdma", .data = (void
> *)OVL_ADAPTOR_TYPE_MDP_RDMA },
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 613093068bb4..ed5b5b8d6c2e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -977,6 +977,7 @@ static struct platform_driver * const
> mtk_drm_drivers[] = {
>  	&mtk_dsi_driver,
>  	&mtk_ethdr_driver,
>  	&mtk_mdp_rdma_driver,
> +	&mtk_padding_driver,
>  };
>  
>  static int __init mtk_drm_init(void)
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index eb2fd45941f0..562f2db47add 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -64,5 +64,5 @@ extern struct platform_driver mtk_dpi_driver;
>  extern struct platform_driver mtk_dsi_driver;
>  extern struct platform_driver mtk_ethdr_driver;
>  extern struct platform_driver mtk_mdp_rdma_driver;
> -

Why remove this blanking line?

> +extern struct platform_driver mtk_padding_driver;
>  #endif /* MTK_DRM_DRV_H */
> diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c
> b/drivers/gpu/drm/mediatek/mtk_padding.c
> new file mode 100644
> index 000000000000..bbb9c5e286ce
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_padding.c
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2023 MediaTek Inc.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
> +#include "mtk_disp_drv.h"
> +#include "mtk_drm_crtc.h"
> +#include "mtk_drm_ddp_comp.h"
> +
> +/**
> + * struct mtk_padding - basic information of Padding
> + * @clk: Clock of the module
> + * @regs: Virtual address of the Padding for CPU to access

hardware control register.

> + * @cmdq_reg: CMDQ setting of the Padding

CMDQ client register setting.

> + *
> + * Every Padding should have different clock source, register base,
> and
> + * CMDQ settings, we stored these differences all together.

This comment is redundant.

Regards,
CK

> + */
> +struct mtk_padding {
> +	struct clk		*clk;
> +	void __iomem		*regs;
> +	struct cmdq_client_reg	cmdq_reg;
> +};
> +
> +int mtk_padding_clk_enable(struct device *dev)
> +{
> +	struct mtk_padding *padding = dev_get_drvdata(dev);
> +
> +	return clk_prepare_enable(padding->clk);
> +}
> +
> +void mtk_padding_clk_disable(struct device *dev)
> +{
> +	struct mtk_padding *padding = dev_get_drvdata(dev);
> +
> +	clk_disable_unprepare(padding->clk);
> +}
> +
> +void mtk_padding_config(struct device *dev, struct cmdq_pkt
> *cmdq_pkt)
> +{
> +	struct mtk_padding *padding = dev_get_drvdata(dev);
> +
> +	/* bypass padding */
> +	mtk_ddp_write_mask(cmdq_pkt, GENMASK(1, 0), &padding->cmdq_reg, 
> padding->regs, 0,
> +			   GENMASK(1, 0));
> +}
> +
> +static int mtk_padding_bind(struct device *dev, struct device
> *master, void *data)
> +{
> +	return 0;
> +}
> +
> +static void mtk_padding_unbind(struct device *dev, struct device
> *master, void *data)
> +{
> +}
> +
> +static const struct component_ops mtk_padding_component_ops = {
> +	.bind	= mtk_padding_bind,
> +	.unbind = mtk_padding_unbind,
> +};
> +
> +static int mtk_padding_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_padding *priv;
> +	struct resource *res;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->clk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(priv->clk)) {
> +		dev_err(dev, "failed to get clk\n");
> +		return PTR_ERR(priv->clk);
> +	}
> +
> +	priv->regs = devm_platform_get_and_ioremap_resource(pdev, 0,
> &res);
> +	if (IS_ERR(priv->regs)) {
> +		dev_err(dev, "failed to do ioremap\n");
> +		return PTR_ERR(priv->regs);
> +	}
> +
> +#if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
> +	if (ret) {
> +		dev_err(dev, "failed to get gce client reg\n");
> +		return ret;
> +	}
> +#endif
> +
> +	platform_set_drvdata(pdev, priv);
> +
> +	ret = devm_pm_runtime_enable(dev);
> +	if (ret)
> +		return ret;
> +
> +	ret = component_add(dev, &mtk_padding_component_ops);
> +	if (ret) {
> +		pm_runtime_disable(dev);
> +		return dev_err_probe(dev, ret, "failed to add
> component\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_padding_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &mtk_padding_component_ops);
> +	return 0;
> +}
> +
> +static const struct of_device_id mtk_padding_driver_dt_match[] = {
> +	{ .compatible = "mediatek,mt8188-padding" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_padding_driver_dt_match);
> +
> +struct platform_driver mtk_padding_driver = {
> +	.probe		= mtk_padding_probe,
> +	.remove		= mtk_padding_remove,
> +	.driver		= {
> +		.name	= "mediatek-padding",
> +		.owner	= THIS_MODULE,
> +		.of_match_table = mtk_padding_driver_dt_match,
> +	},
> +};
diff mbox series

Patch

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index d4d193f60271..5e4436403b8d 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -16,7 +16,8 @@  mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
 		  mtk_ethdr.o \
-		  mtk_mdp_rdma.o
+		  mtk_mdp_rdma.o \
+		  mtk_padding.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 2254038519e1..f9fdb1268aa5 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -157,4 +157,7 @@  void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
 const u32 *mtk_mdp_rdma_get_formats(struct device *dev);
 size_t mtk_mdp_rdma_get_num_formats(struct device *dev);
 
+int mtk_padding_clk_enable(struct device *dev);
+void mtk_padding_clk_disable(struct device *dev);
+void mtk_padding_config(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
index f73a558dcf93..ca8f3febbf11 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -29,6 +29,7 @@  enum mtk_ovl_adaptor_comp_type {
 	OVL_ADAPTOR_TYPE_ETHDR,
 	OVL_ADAPTOR_TYPE_MDP_RDMA,
 	OVL_ADAPTOR_TYPE_MERGE,
+	OVL_ADAPTOR_TYPE_PADDING,
 	OVL_ADAPTOR_TYPE_NUM,
 };
 
@@ -46,6 +47,14 @@  enum mtk_ovl_adaptor_comp_id {
 	OVL_ADAPTOR_MERGE1,
 	OVL_ADAPTOR_MERGE2,
 	OVL_ADAPTOR_MERGE3,
+	OVL_ADAPTOR_PADDING0,
+	OVL_ADAPTOR_PADDING1,
+	OVL_ADAPTOR_PADDING2,
+	OVL_ADAPTOR_PADDING3,
+	OVL_ADAPTOR_PADDING4,
+	OVL_ADAPTOR_PADDING5,
+	OVL_ADAPTOR_PADDING6,
+	OVL_ADAPTOR_PADDING7,
 	OVL_ADAPTOR_ID_MAX
 };
 
@@ -66,6 +75,7 @@  static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
 	[OVL_ADAPTOR_TYPE_ETHDR]	= "ethdr",
 	[OVL_ADAPTOR_TYPE_MDP_RDMA]	= "vdo1-rdma",
 	[OVL_ADAPTOR_TYPE_MERGE]	= "merge",
+	[OVL_ADAPTOR_TYPE_PADDING]	= "padding",
 };
 
 static const struct mtk_ddp_comp_funcs _ethdr = {
@@ -78,6 +88,11 @@  static const struct mtk_ddp_comp_funcs _merge = {
 	.clk_disable = mtk_merge_clk_disable,
 };
 
+static const struct mtk_ddp_comp_funcs _padding = {
+	.clk_enable = mtk_padding_clk_enable,
+	.clk_disable = mtk_padding_clk_disable,
+};
+
 static const struct mtk_ddp_comp_funcs _rdma = {
 	.clk_enable = mtk_mdp_rdma_clk_enable,
 	.clk_disable = mtk_mdp_rdma_clk_disable,
@@ -97,6 +112,14 @@  static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
 	[OVL_ADAPTOR_MERGE1] = { OVL_ADAPTOR_TYPE_MERGE, DDP_COMPONENT_MERGE2, 2, &_merge },
 	[OVL_ADAPTOR_MERGE2] = { OVL_ADAPTOR_TYPE_MERGE, DDP_COMPONENT_MERGE3, 3, &_merge },
 	[OVL_ADAPTOR_MERGE3] = { OVL_ADAPTOR_TYPE_MERGE, DDP_COMPONENT_MERGE4, 4, &_merge },
+	[OVL_ADAPTOR_PADDING0] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING0, 0, &_padding },
+	[OVL_ADAPTOR_PADDING1] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING1, 1, &_padding },
+	[OVL_ADAPTOR_PADDING2] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING2, 2, &_padding },
+	[OVL_ADAPTOR_PADDING3] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING3, 3, &_padding },
+	[OVL_ADAPTOR_PADDING4] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING4, 4, &_padding },
+	[OVL_ADAPTOR_PADDING5] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING5, 5, &_padding },
+	[OVL_ADAPTOR_PADDING6] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING6, 6, &_padding },
+	[OVL_ADAPTOR_PADDING7] = { OVL_ADAPTOR_TYPE_PADDING, DDP_COMPONENT_PADDING7, 7, &_padding },
 };
 
 void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
@@ -108,6 +131,8 @@  void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 	struct mtk_mdp_rdma_cfg rdma_config = {0};
 	struct device *ethdr;
 	struct device *merge;
+	struct device *padding_l;
+	struct device *padding_r;
 	struct device *rdma_l;
 	struct device *rdma_r;
 	const struct drm_format_info *fmt_info = drm_format_info(pending->format);
@@ -124,6 +149,8 @@  void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 
 	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
 	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
+	padding_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_PADDING0 + 2 * idx];
+	padding_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_PADDING0 + 2 * idx + 1];
 	rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
 	rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
 
@@ -159,10 +186,15 @@  void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
 	rdma_config.color_encoding = pending->color_encoding;
 	mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
 
+	if (padding_l)
+		mtk_padding_config(padding_l, cmdq_pkt);
+
 	if (use_dual_pipe) {
 		rdma_config.x_left = l_w;
 		rdma_config.width = r_w;
 		mtk_mdp_rdma_config(rdma_r, &rdma_config, cmdq_pkt);
+		if (padding_r)
+			mtk_padding_config(padding_r, cmdq_pkt);
 	}
 
 	mtk_merge_start_cmdq(merge, cmdq_pkt);
@@ -353,6 +385,7 @@  static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
 }
 
 static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
+	{ .compatible = "mediatek,mt8188-padding", .data = (void *)OVL_ADAPTOR_TYPE_PADDING },
 	{ .compatible = "mediatek,mt8195-disp-ethdr", .data = (void *)OVL_ADAPTOR_TYPE_ETHDR },
 	{ .compatible = "mediatek,mt8195-disp-merge", .data = (void *)OVL_ADAPTOR_TYPE_MERGE },
 	{ .compatible = "mediatek,mt8195-vdo1-rdma", .data = (void *)OVL_ADAPTOR_TYPE_MDP_RDMA },
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 613093068bb4..ed5b5b8d6c2e 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -977,6 +977,7 @@  static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_dsi_driver,
 	&mtk_ethdr_driver,
 	&mtk_mdp_rdma_driver,
+	&mtk_padding_driver,
 };
 
 static int __init mtk_drm_init(void)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index eb2fd45941f0..562f2db47add 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -64,5 +64,5 @@  extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
 extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
-
+extern struct platform_driver mtk_padding_driver;
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_padding.c b/drivers/gpu/drm/mediatek/mtk_padding.c
new file mode 100644
index 000000000000..bbb9c5e286ce
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_padding.c
@@ -0,0 +1,136 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+
+/**
+ * struct mtk_padding - basic information of Padding
+ * @clk: Clock of the module
+ * @regs: Virtual address of the Padding for CPU to access
+ * @cmdq_reg: CMDQ setting of the Padding
+ *
+ * Every Padding should have different clock source, register base, and
+ * CMDQ settings, we stored these differences all together.
+ */
+struct mtk_padding {
+	struct clk		*clk;
+	void __iomem		*regs;
+	struct cmdq_client_reg	cmdq_reg;
+};
+
+int mtk_padding_clk_enable(struct device *dev)
+{
+	struct mtk_padding *padding = dev_get_drvdata(dev);
+
+	return clk_prepare_enable(padding->clk);
+}
+
+void mtk_padding_clk_disable(struct device *dev)
+{
+	struct mtk_padding *padding = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(padding->clk);
+}
+
+void mtk_padding_config(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_padding *padding = dev_get_drvdata(dev);
+
+	/* bypass padding */
+	mtk_ddp_write_mask(cmdq_pkt, GENMASK(1, 0), &padding->cmdq_reg, padding->regs, 0,
+			   GENMASK(1, 0));
+}
+
+static int mtk_padding_bind(struct device *dev, struct device *master, void *data)
+{
+	return 0;
+}
+
+static void mtk_padding_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops mtk_padding_component_ops = {
+	.bind	= mtk_padding_bind,
+	.unbind = mtk_padding_unbind,
+};
+
+static int mtk_padding_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_padding *priv;
+	struct resource *res;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to do ioremap\n");
+		return PTR_ERR(priv->regs);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret) {
+		dev_err(dev, "failed to get gce client reg\n");
+		return ret;
+	}
+#endif
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	ret = component_add(dev, &mtk_padding_component_ops);
+	if (ret) {
+		pm_runtime_disable(dev);
+		return dev_err_probe(dev, ret, "failed to add component\n");
+	}
+
+	return 0;
+}
+
+static int mtk_padding_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_padding_component_ops);
+	return 0;
+}
+
+static const struct of_device_id mtk_padding_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8188-padding" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_padding_driver_dt_match);
+
+struct platform_driver mtk_padding_driver = {
+	.probe		= mtk_padding_probe,
+	.remove		= mtk_padding_remove,
+	.driver		= {
+		.name	= "mediatek-padding",
+		.owner	= THIS_MODULE,
+		.of_match_table = mtk_padding_driver_dt_match,
+	},
+};