diff mbox series

[1/3] drm/mediatek: Refactor pixel format logic

Message ID 20230201170210.1253505-2-greenjustin@chromium.org (mailing list archive)
State New, archived
Headers show
Series drm/mediatek: Add support for 10-bit overlays | expand

Commit Message

Justin Green Feb. 1, 2023, 5:02 p.m. UTC
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green <greenjustin@chromium.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 44 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    | 38 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c    | 24 ++++-------
 drivers/gpu/drm/mediatek/mtk_drm_plane.h    |  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

Comments

Matthias Brugger Feb. 2, 2023, 10:11 a.m. UTC | #1
On 01/02/2023 18:02, Justin Green wrote:
> Add an DDP component interface for querying pixel format support and move list
> of supported pixel formats into DDP components instead of mtk_drm_plane.c
> 
> Tested by running Chrome on an MT8195.
> 
> Signed-off-by: Justin Green <greenjustin@chromium.org>
> ---
>   drivers/gpu/drm/mediatek/mtk_disp_drv.h     |  4 ++
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 44 +++++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_disp_rdma.c    | 38 ++++++++++++++++++
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.c     |  4 +-
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++++++++++
>   drivers/gpu/drm/mediatek/mtk_drm_plane.c    | 24 ++++-------
>   drivers/gpu/drm/mediatek/mtk_drm_plane.h    |  3 +-
>   8 files changed, 123 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 33e61a136bbc..0df6a06defb8 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
>   void mtk_ovl_unregister_vblank_cb(struct device *dev);
>   void mtk_ovl_enable_vblank(struct device *dev);
>   void mtk_ovl_disable_vblank(struct device *dev);
> +const u32 *mtk_ovl_get_formats(struct device *dev);
> +size_t mtk_ovl_get_num_formats(struct device *dev);
>   
>   void mtk_rdma_bypass_shadow(struct device *dev);
>   int mtk_rdma_clk_enable(struct device *dev);
> @@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
>   void mtk_rdma_unregister_vblank_cb(struct device *dev);
>   void mtk_rdma_enable_vblank(struct device *dev);
>   void mtk_rdma_disable_vblank(struct device *dev);
> +const u32 *mtk_rdma_get_formats(struct device *dev);
> +size_t mtk_rdma_get_num_formats(struct device *dev);
>   
>   int mtk_mdp_rdma_clk_enable(struct device *dev);
>   void mtk_mdp_rdma_clk_disable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> index 84daeaffab6a..8743c8047dc9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> @@ -66,6 +66,20 @@
>   #define	OVL_CON_VIRT_FLIP	BIT(9)
>   #define	OVL_CON_HORZ_FLIP	BIT(10)
>   
> +static const u32 mt8173_formats[] = {
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_BGRX8888,
> +	DRM_FORMAT_BGRA8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_RGB888,
> +	DRM_FORMAT_BGR888,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_YUYV,
> +};
> +
>   struct mtk_disp_ovl_data {
>   	unsigned int addr;
>   	unsigned int gmc_bits;
> @@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
>   	bool fmt_rgb565_is_0;
>   	bool smi_id_en;
>   	bool supports_afbc;
> +	const u32 *formats;
> +	size_t num_formats;
>   };
>   
>   /*
> @@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
>   	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
>   }
>   
> +const u32 *mtk_ovl_get_formats(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	return ovl->data->formats;
> +}
> +
> +size_t mtk_ovl_get_num_formats(struct device *dev)
> +{
> +	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> +
> +	return ovl->data->num_formats;
> +}
> +
>   int mtk_ovl_clk_enable(struct device *dev)
>   {
>   	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> @@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
>   	.gmc_bits = 8,
>   	.layer_nr = 4,
>   	.fmt_rgb565_is_0 = false,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
> @@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
>   	.gmc_bits = 8,
>   	.layer_nr = 4,
>   	.fmt_rgb565_is_0 = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),

mt8173_formats are the same as the old struct formats. Maybe we should use that 
and only overwrite where we actually use a different array.

Regarding num_formats, see my comment below.

>   };
>   
>   static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
> @@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
>   	.gmc_bits = 10,
>   	.layer_nr = 4,
>   	.fmt_rgb565_is_0 = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
> @@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
>   	.gmc_bits = 10,
>   	.layer_nr = 2,
>   	.fmt_rgb565_is_0 = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
> @@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
>   	.layer_nr = 4,
>   	.fmt_rgb565_is_0 = true,
>   	.smi_id_en = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
> @@ -532,6 +572,8 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
>   	.layer_nr = 2,
>   	.fmt_rgb565_is_0 = true,
>   	.smi_id_en = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
> @@ -541,6 +583,8 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
>   	.fmt_rgb565_is_0 = true,
>   	.smi_id_en = true,
>   	.supports_afbc = true,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> index 0ec2e4049e07..cf92df845160 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
> @@ -54,8 +54,24 @@
>   
>   #define RDMA_MEM_GMC				0x40402020
>   
> +static const u32 mt8173_formats[] = {
> +	DRM_FORMAT_XRGB8888,
> +	DRM_FORMAT_ARGB8888,
> +	DRM_FORMAT_BGRX8888,
> +	DRM_FORMAT_BGRA8888,
> +	DRM_FORMAT_ABGR8888,
> +	DRM_FORMAT_XBGR8888,
> +	DRM_FORMAT_RGB888,
> +	DRM_FORMAT_BGR888,
> +	DRM_FORMAT_RGB565,
> +	DRM_FORMAT_UYVY,
> +	DRM_FORMAT_YUYV,
> +};
> +
>   struct mtk_disp_rdma_data {
>   	unsigned int fifo_size;
> +	const u32 *formats;
> +	size_t num_formats;
>   };
>   
>   /*
> @@ -126,6 +142,20 @@ void mtk_rdma_disable_vblank(struct device *dev)
>   	rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
>   }
>   
> +const u32 *mtk_rdma_get_formats(struct device *dev)
> +{
> +	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
> +
> +	return rdma->data->formats;
> +}
> +
> +size_t mtk_rdma_get_num_formats(struct device *dev)
> +{
> +	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
> +
> +	return rdma->data->num_formats;
> +}
> +
>   int mtk_rdma_clk_enable(struct device *dev)
>   {
>   	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
> @@ -360,18 +390,26 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
>   
>   static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
>   	.fifo_size = SZ_4K,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
>   	.fifo_size = SZ_8K,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
>   	.fifo_size = 5 * SZ_1K,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
>   	.fifo_size = 1920,
> +	.formats = mt8173_formats,
> +	.num_formats = ARRAY_SIZE(mt8173_formats),
>   };
>   
>   static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 112615817dcb..2ba01c484228 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -856,7 +856,9 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
>   				BIT(pipe),
>   				mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
>   							num_planes),
> -				mtk_ddp_comp_supported_rotations(comp));
> +				mtk_ddp_comp_supported_rotations(comp),
> +				mtk_ddp_comp_get_formats(comp),
> +				mtk_ddp_comp_get_num_formats(comp));
>   		if (ret)
>   			return ret;
>   
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 6b6d5335c834..4a4c1928f83d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -359,6 +359,8 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
>   	.layer_config = mtk_ovl_layer_config,
>   	.bgclr_in_on = mtk_ovl_bgclr_in_on,
>   	.bgclr_in_off = mtk_ovl_bgclr_in_off,
> +	.get_formats = mtk_ovl_get_formats,
> +	.get_num_formats = mtk_ovl_get_num_formats,
>   };
>   
>   static const struct mtk_ddp_comp_funcs ddp_postmask = {
> @@ -381,6 +383,8 @@ static const struct mtk_ddp_comp_funcs ddp_rdma = {
>   	.disable_vblank = mtk_rdma_disable_vblank,
>   	.layer_nr = mtk_rdma_layer_nr,
>   	.layer_config = mtk_rdma_layer_config,
> +	.get_formats = mtk_rdma_get_formats,
> +	.get_num_formats = mtk_rdma_get_num_formats,
>   };
>   
>   static const struct mtk_ddp_comp_funcs ddp_ufoe = {
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 2d0052c23dcb..7f2e638cfdc2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -71,6 +71,8 @@ struct mtk_ddp_comp_funcs {
>   	void (*bgclr_in_off)(struct device *dev);
>   	void (*ctm_set)(struct device *dev,
>   			struct drm_crtc_state *state);
> +	const u32 *(*get_formats)(struct device *dev);
> +	size_t (*get_num_formats)(struct device *dev);
>   };
>   
>   struct mtk_ddp_comp {
> @@ -203,6 +205,24 @@ static inline void mtk_ddp_ctm_set(struct mtk_ddp_comp *comp,
>   		comp->funcs->ctm_set(comp->dev, state);
>   }
>   
> +static inline
> +const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp)
> +{
> +	if (comp->funcs && comp->funcs->get_formats)
> +		return comp->funcs->get_formats(comp->dev);
> +
> +	return NULL;
> +}
> +
> +static inline
> +size_t mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp *comp)
> +{
> +	if (comp->funcs && comp->funcs->get_num_formats)
> +		return comp->funcs->get_num_formats(comp->dev);
> +
> +	return 0;
> +}
> +
>   int mtk_ddp_comp_get_id(struct device_node *node,
>   			enum mtk_ddp_comp_type comp_type);
>   unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index d54fbf34b000..31f9420aff6f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -19,20 +19,6 @@
>   #include "mtk_drm_gem.h"
>   #include "mtk_drm_plane.h"
>   
> -static const u32 formats[] = {
> -	DRM_FORMAT_XRGB8888,
> -	DRM_FORMAT_ARGB8888,
> -	DRM_FORMAT_BGRX8888,
> -	DRM_FORMAT_BGRA8888,
> -	DRM_FORMAT_ABGR8888,
> -	DRM_FORMAT_XBGR8888,
> -	DRM_FORMAT_RGB888,
> -	DRM_FORMAT_BGR888,
> -	DRM_FORMAT_RGB565,
> -	DRM_FORMAT_UYVY,
> -	DRM_FORMAT_YUYV,
> -};
> -
>   static const u64 modifiers[] = {
>   	DRM_FORMAT_MOD_LINEAR,
>   	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
> @@ -315,13 +301,19 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
>   
>   int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
>   		   unsigned long possible_crtcs, enum drm_plane_type type,
> -		   unsigned int supported_rotations)
> +		   unsigned int supported_rotations, const u32 *formats,
> +		   size_t num_formats)

Why can't we use ARRAY_SIZE(formats) here like we did before?

Regards,
Matthias

>   {
>   	int err;
>   
> +	if (!formats || !num_formats) {
> +		DRM_ERROR("no formats for plane\n");
> +		return -EINVAL;
> +	}
> +
>   	err = drm_universal_plane_init(dev, plane, possible_crtcs,
>   				       &mtk_plane_funcs, formats,
> -				       ARRAY_SIZE(formats), modifiers, type, NULL);
> +				       num_formats, modifiers, type, NULL);
>   	if (err) {
>   		DRM_ERROR("failed to initialize plane\n");
>   		return err;
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> index 8f39011cdbfc..99aff7da0831 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
> @@ -48,6 +48,7 @@ to_mtk_plane_state(struct drm_plane_state *state)
>   
>   int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
>   		   unsigned long possible_crtcs, enum drm_plane_type type,
> -		   unsigned int supported_rotations);
> +		   unsigned int supported_rotations, const u32 *formats,
> +		   size_t num_formats);
>   
>   #endif
Justin Green Feb. 2, 2023, 6:59 p.m. UTC | #2
Hi Matthias,

> mt8173_formats are the same as the old struct formats. Maybe we should use that
> and only overwrite where we actually use a different array.
I think this was sort of how the original patch worked, but we wanted
to add some flexibility to allow different components to support
different formats. In patch 3 of the series, we actually overwrite
this field with mt8195_formats.

> Why can't we use ARRAY_SIZE(formats) here like we did before?
I think ARRAY_SIZE is just a macro for getting the length of
statically allocated arrays. Because we won't know until runtime which
list of pixel formats we will be using, I'm not sure we can use that
in this circumstance?

Regards,
Justin
Matthias Brugger Feb. 2, 2023, 8:16 p.m. UTC | #3
On 02/02/2023 19:59, Justin Green wrote:
> Hi Matthias,
> 
>> mt8173_formats are the same as the old struct formats. Maybe we should use that
>> and only overwrite where we actually use a different array.
> I think this was sort of how the original patch worked, but we wanted
> to add some flexibility to allow different components to support
> different formats. In patch 3 of the series, we actually overwrite
> this field with mt8195_formats.
> 

Yes, I had a comment on the naming in that patch. Never the less, I think if we 
don't need to "overwrite" the value, we should use just one struct for the 
values instead of copying them to the different .c files and give them SoC 
specific names.


>> Why can't we use ARRAY_SIZE(formats) here like we did before?
> I think ARRAY_SIZE is just a macro for getting the length of
> statically allocated arrays. Because we won't know until runtime which
> list of pixel formats we will be using, I'm not sure we can use that
> in this circumstance?
> 

You are probably right.

Regards,
Matthias
Justin Green Feb. 2, 2023, 8:41 p.m. UTC | #4
> Yes, I had a comment on the naming in that patch. Never the less, I think if we
> don't need to "overwrite" the value, we should use just one struct for the
> values instead of copying them to the different .c files and give them SoC
> specific names.
I don't have a very strong opinion about this, and in fact that is how
v1 of the patch worked, but Chun-Kuang specifically suggested moving
that struct into the .c files a few versions back. I think it makes
sense if we expect additional skew between the different components
and what pixel formats they support.
Matthias Brugger Feb. 3, 2023, 7:29 a.m. UTC | #5
On 02/02/2023 21:41, Justin Green wrote:
>> Yes, I had a comment on the naming in that patch. Never the less, I think if we
>> don't need to "overwrite" the value, we should use just one struct for the
>> values instead of copying them to the different .c files and give them SoC
>> specific names.
> I don't have a very strong opinion about this, and in fact that is how
> v1 of the patch worked, but Chun-Kuang specifically suggested moving
> that struct into the .c files a few versions back. I think it makes
> sense if we expect additional skew between the different components
> and what pixel formats they support.

Ok, if Chun-Kuang asked to do it this way, then I won't object. In the end he is 
the maintainer of the driver.

Regards,
Matthias
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 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@  void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@  void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@ 
 #define	OVL_CON_VIRT_FLIP	BIT(9)
 #define	OVL_CON_HORZ_FLIP	BIT(10)
 
+static const u32 mt8173_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
 	unsigned int addr;
 	unsigned int gmc_bits;
@@ -73,6 +87,8 @@  struct mtk_disp_ovl_data {
 	bool fmt_rgb565_is_0;
 	bool smi_id_en;
 	bool supports_afbc;
+	const u32 *formats;
+	size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@  void mtk_ovl_disable_vblank(struct device *dev)
 	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@  static const struct mtk_disp_ovl_data mt2701_ovl_driver_data = {
 	.gmc_bits = 8,
 	.layer_nr = 4,
 	.fmt_rgb565_is_0 = false,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@  static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
 	.gmc_bits = 8,
 	.layer_nr = 4,
 	.fmt_rgb565_is_0 = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@  static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
 	.gmc_bits = 10,
 	.layer_nr = 4,
 	.fmt_rgb565_is_0 = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@  static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
 	.gmc_bits = 10,
 	.layer_nr = 2,
 	.fmt_rgb565_is_0 = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@  static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
 	.layer_nr = 4,
 	.fmt_rgb565_is_0 = true,
 	.smi_id_en = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
@@ -532,6 +572,8 @@  static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = {
 	.layer_nr = 2,
 	.fmt_rgb565_is_0 = true,
 	.smi_id_en = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
@@ -541,6 +583,8 @@  static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
 	.fmt_rgb565_is_0 = true,
 	.smi_id_en = true,
 	.supports_afbc = true,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 0ec2e4049e07..cf92df845160 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -54,8 +54,24 @@ 
 
 #define RDMA_MEM_GMC				0x40402020
 
+static const u32 mt8173_formats[] = {
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_rdma_data {
 	unsigned int fifo_size;
+	const u32 *formats;
+	size_t num_formats;
 };
 
 /*
@@ -126,6 +142,20 @@  void mtk_rdma_disable_vblank(struct device *dev)
 	rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
 }
 
+const u32 *mtk_rdma_get_formats(struct device *dev)
+{
+	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+	return rdma->data->formats;
+}
+
+size_t mtk_rdma_get_num_formats(struct device *dev)
+{
+	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
+
+	return rdma->data->num_formats;
+}
+
 int mtk_rdma_clk_enable(struct device *dev)
 {
 	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
@@ -360,18 +390,26 @@  static int mtk_disp_rdma_remove(struct platform_device *pdev)
 
 static const struct mtk_disp_rdma_data mt2701_rdma_driver_data = {
 	.fifo_size = SZ_4K,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_rdma_data mt8173_rdma_driver_data = {
 	.fifo_size = SZ_8K,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_rdma_data mt8183_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
 	.fifo_size = 1920,
+	.formats = mt8173_formats,
+	.num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 112615817dcb..2ba01c484228 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -856,7 +856,9 @@  static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 				BIT(pipe),
 				mtk_drm_crtc_plane_type(mtk_crtc->layer_nr,
 							num_planes),
-				mtk_ddp_comp_supported_rotations(comp));
+				mtk_ddp_comp_supported_rotations(comp),
+				mtk_ddp_comp_get_formats(comp),
+				mtk_ddp_comp_get_num_formats(comp));
 		if (ret)
 			return ret;
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 6b6d5335c834..4a4c1928f83d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -359,6 +359,8 @@  static const struct mtk_ddp_comp_funcs ddp_ovl = {
 	.layer_config = mtk_ovl_layer_config,
 	.bgclr_in_on = mtk_ovl_bgclr_in_on,
 	.bgclr_in_off = mtk_ovl_bgclr_in_off,
+	.get_formats = mtk_ovl_get_formats,
+	.get_num_formats = mtk_ovl_get_num_formats,
 };
 
 static const struct mtk_ddp_comp_funcs ddp_postmask = {
@@ -381,6 +383,8 @@  static const struct mtk_ddp_comp_funcs ddp_rdma = {
 	.disable_vblank = mtk_rdma_disable_vblank,
 	.layer_nr = mtk_rdma_layer_nr,
 	.layer_config = mtk_rdma_layer_config,
+	.get_formats = mtk_rdma_get_formats,
+	.get_num_formats = mtk_rdma_get_num_formats,
 };
 
 static const struct mtk_ddp_comp_funcs ddp_ufoe = {
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 2d0052c23dcb..7f2e638cfdc2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -71,6 +71,8 @@  struct mtk_ddp_comp_funcs {
 	void (*bgclr_in_off)(struct device *dev);
 	void (*ctm_set)(struct device *dev,
 			struct drm_crtc_state *state);
+	const u32 *(*get_formats)(struct device *dev);
+	size_t (*get_num_formats)(struct device *dev);
 };
 
 struct mtk_ddp_comp {
@@ -203,6 +205,24 @@  static inline void mtk_ddp_ctm_set(struct mtk_ddp_comp *comp,
 		comp->funcs->ctm_set(comp->dev, state);
 }
 
+static inline
+const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp)
+{
+	if (comp->funcs && comp->funcs->get_formats)
+		return comp->funcs->get_formats(comp->dev);
+
+	return NULL;
+}
+
+static inline
+size_t mtk_ddp_comp_get_num_formats(struct mtk_ddp_comp *comp)
+{
+	if (comp->funcs && comp->funcs->get_num_formats)
+		return comp->funcs->get_num_formats(comp->dev);
+
+	return 0;
+}
+
 int mtk_ddp_comp_get_id(struct device_node *node,
 			enum mtk_ddp_comp_type comp_type);
 unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index d54fbf34b000..31f9420aff6f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -19,20 +19,6 @@ 
 #include "mtk_drm_gem.h"
 #include "mtk_drm_plane.h"
 
-static const u32 formats[] = {
-	DRM_FORMAT_XRGB8888,
-	DRM_FORMAT_ARGB8888,
-	DRM_FORMAT_BGRX8888,
-	DRM_FORMAT_BGRA8888,
-	DRM_FORMAT_ABGR8888,
-	DRM_FORMAT_XBGR8888,
-	DRM_FORMAT_RGB888,
-	DRM_FORMAT_BGR888,
-	DRM_FORMAT_RGB565,
-	DRM_FORMAT_UYVY,
-	DRM_FORMAT_YUYV,
-};
-
 static const u64 modifiers[] = {
 	DRM_FORMAT_MOD_LINEAR,
 	DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
@@ -315,13 +301,19 @@  static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
 
 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		   unsigned long possible_crtcs, enum drm_plane_type type,
-		   unsigned int supported_rotations)
+		   unsigned int supported_rotations, const u32 *formats,
+		   size_t num_formats)
 {
 	int err;
 
+	if (!formats || !num_formats) {
+		DRM_ERROR("no formats for plane\n");
+		return -EINVAL;
+	}
+
 	err = drm_universal_plane_init(dev, plane, possible_crtcs,
 				       &mtk_plane_funcs, formats,
-				       ARRAY_SIZE(formats), modifiers, type, NULL);
+				       num_formats, modifiers, type, NULL);
 	if (err) {
 		DRM_ERROR("failed to initialize plane\n");
 		return err;
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
index 8f39011cdbfc..99aff7da0831 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
@@ -48,6 +48,7 @@  to_mtk_plane_state(struct drm_plane_state *state)
 
 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
 		   unsigned long possible_crtcs, enum drm_plane_type type,
-		   unsigned int supported_rotations);
+		   unsigned int supported_rotations, const u32 *formats,
+		   size_t num_formats);
 
 #endif