[PATCH v2 13/15] drm/mediatek: add ovlsys_adaptor support for MT8196
CK Hu (胡俊光)
ck.hu at mediatek.com
Fri Apr 11 03:07:01 UTC 2025
On Fri, 2025-03-21 at 17:33 +0800, paul-pl.chen wrote:
> From: Nancy Lin <nancy.lin at mediatek.com>
>
> Ovlsys_adaptor is an encapsulated module designed to
> simplify the DRM control flow. This module is composed
> of 20 EXDMAs, 20 BLENDERs, and 12 OUTPROCs.
> Two EXDMAs merge into one layer, allowing the module
> to support 20 layers for 3 display paths.
> Ovlsys_adaptor driver is integrated within the
> mtk_ddp_comp framework.
>
> Signed-off-by: Nancy Lin <nancy.lin at mediatek.com>
> Signed-off-by: Paul-pl Chen <paul-pl.chen at mediatek.com>
> ---
> drivers/gpu/drm/mediatek/Makefile | 1 +
> drivers/gpu/drm/mediatek/mtk_ddp_comp.c | 28 +
> drivers/gpu/drm/mediatek/mtk_ddp_comp.h | 1 +
> drivers/gpu/drm/mediatek/mtk_disp_drv.h | 32 +
> .../drm/mediatek/mtk_disp_ovlsys_adaptor.c | 797 ++++++++++++++++++
> drivers/gpu/drm/mediatek/mtk_drm_drv.c | 73 ++
> drivers/gpu/drm/mediatek/mtk_drm_drv.h | 11 +-
> 7 files changed, 942 insertions(+), 1 deletion(-)
> create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c
>
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index 9546bc6b7b2e..dedf50860d3f 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -9,6 +9,7 @@ mediatek-drm-y := mtk_crtc.o \
> mtk_disp_exdma.o \
> mtk_disp_gamma.o \
> mtk_disp_merge.o \
> + mtk_disp_ovlsys_adaptor.o \
> mtk_disp_ovl.o \
> mtk_disp_outproc.o \
> mtk_disp_ovl_adaptor.o \
> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> index cc780744f060..c96e027359ac 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.c
> @@ -368,6 +368,31 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
> .get_num_formats = mtk_ovl_get_num_formats,
> };
>
> +static const struct mtk_ddp_comp_funcs ddp_ovlsys_adaptor = {
> + .power_on = mtk_ovlsys_adaptor_power_on,
> + .power_off = mtk_ovlsys_adaptor_power_off,
> + .clk_enable = mtk_ovlsys_adaptor_clk_enable,
> + .clk_disable = mtk_ovlsys_adaptor_clk_disable,
> + .config = mtk_ovlsys_adaptor_config,
> + .start = mtk_ovlsys_adaptor_start,
> + .stop = mtk_ovlsys_adaptor_stop,
> + .layer_check = mtk_ovlsys_adaptor_layer_check,
> + .layer_nr = mtk_ovlsys_adaptor_layer_nr,
> + .layer_config = mtk_ovlsys_adaptor_layer_config,
> + .register_vblank_cb = mtk_ovlsys_adaptor_register_vblank_cb,
> + .unregister_vblank_cb = mtk_ovlsys_adaptor_unregister_vblank_cb,
> + .enable_vblank = mtk_ovlsys_adaptor_enable_vblank,
> + .disable_vblank = mtk_ovlsys_adaptor_disable_vblank,
> + .dma_dev_get = mtk_ovlsys_adaptor_dma_dev_get,
> + .connect = mtk_ovlsys_adaptor_connect,
> + .disconnect = mtk_ovlsys_adaptor_disconnect,
> + .add = mtk_ovlsys_adaptor_add_comp,
> + .remove = mtk_ovlsys_adaptor_remove_comp,
> + .get_blend_modes = mtk_ovlsys_adaptor_get_blend_modes,
> + .get_formats = mtk_ovlsys_adaptor_get_formats,
> + .get_num_formats = mtk_ovlsys_adaptor_get_num_formats,
> +};
> +
> static const struct mtk_ddp_comp_funcs ddp_postmask = {
> .clk_enable = mtk_ddp_clk_enable,
> .clk_disable = mtk_ddp_clk_disable,
> @@ -437,6 +462,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
> [MTK_DISP_OVL] = "ovl",
> [MTK_DISP_OVL_2L] = "ovl-2l",
> [MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
> + [MTK_DISP_OVLSYS_ADAPTOR] = "ovlsys_adaptor",
> [MTK_DISP_POSTMASK] = "postmask",
> [MTK_DISP_PWM] = "pwm",
> [MTK_DISP_RDMA] = "rdma",
> @@ -469,6 +495,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_DRM_ID_MAX]
> [DDP_COMPONENT_DPI0] = { MTK_DPI, 0, &ddp_dpi },
> [DDP_COMPONENT_DPI1] = { MTK_DPI, 1, &ddp_dpi },
> [DDP_COMPONENT_DRM_OVL_ADAPTOR] = { MTK_DISP_OVL_ADAPTOR, 0, &ddp_ovl_adaptor },
> + [DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0] = { MTK_DISP_OVLSYS_ADAPTOR, 0, &ddp_ovlsys_adaptor},
> + [DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1] = { MTK_DISP_OVLSYS_ADAPTOR, 1, &ddp_ovlsys_adaptor},
> [DDP_COMPONENT_DSC0] = { MTK_DISP_DSC, 0, &ddp_dsc },
> [DDP_COMPONENT_DSC1] = { MTK_DISP_DSC, 1, &ddp_dsc },
> [DDP_COMPONENT_DSI0] = { MTK_DSI, 0, &ddp_dsi },
> diff --git a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> index b33d3289b8b6..ef64ce7a071f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_ddp_comp.h
> @@ -33,6 +33,7 @@ enum mtk_ddp_comp_type {
> MTK_DISP_MUTEX,
> MTK_DISP_OD,
> MTK_DISP_OVL,
> + MTK_DISP_OVLSYS_ADAPTOR,
> MTK_DISP_OVL_2L,
> MTK_DISP_OVL_ADAPTOR,
> MTK_DISP_POSTMASK,
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 3c519a662074..1ff8c4593fc1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -174,6 +174,38 @@ size_t mtk_ovl_adaptor_get_num_formats(struct device *dev);
> enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev,
> const struct drm_display_mode *mode);
>
> +int mtk_ovlsys_adaptor_power_on(struct device *dev);
> +void mtk_ovlsys_adaptor_power_off(struct device *dev);
> +void mtk_ovlsys_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex);
> +void mtk_ovlsys_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex);
> +void mtk_ovlsys_adaptor_connect(struct device *dev, struct device *mmsys_dev,
> + unsigned int next);
> +void mtk_ovlsys_adaptor_disconnect(struct device *dev, struct device *mmsys_dev,
> + unsigned int next);
> +int mtk_ovlsys_adaptor_clk_enable(struct device *dev);
> +void mtk_ovlsys_adaptor_clk_disable(struct device *dev);
> +void mtk_ovlsys_adaptor_config(struct device *dev, unsigned int w,
> + unsigned int h, unsigned int vrefresh,
> + unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> +void mtk_ovlsys_adaptor_layer_config(struct device *dev, unsigned int idx,
> + struct mtk_plane_state *state,
> + struct cmdq_pkt *cmdq_pkt);
> +int mtk_ovlsys_adaptor_layer_check(struct device *dev,
> + unsigned int idx,
> + struct mtk_plane_state *mtk_state);
> +void mtk_ovlsys_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(void *),
> + void *vblank_cb_data);
> +void mtk_ovlsys_adaptor_unregister_vblank_cb(struct device *dev);
> +void mtk_ovlsys_adaptor_enable_vblank(struct device *dev);
> +void mtk_ovlsys_adaptor_disable_vblank(struct device *dev);
> +void mtk_ovlsys_adaptor_start(struct device *dev);
> +void mtk_ovlsys_adaptor_stop(struct device *dev);
> +unsigned int mtk_ovlsys_adaptor_layer_nr(struct device *dev);
> +struct device *mtk_ovlsys_adaptor_dma_dev_get(struct device *dev);
> +u32 mtk_ovlsys_adaptor_get_blend_modes(struct device *dev);
> +const u32 *mtk_ovlsys_adaptor_get_formats(struct device *dev);
> +size_t mtk_ovlsys_adaptor_get_num_formats(struct device *dev);
> +
> void mtk_rdma_bypass_shadow(struct device *dev);
> int mtk_rdma_clk_enable(struct device *dev);
> void mtk_rdma_clk_disable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c
> new file mode 100644
> index 000000000000..04cb555bd77b
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovlsys_adaptor.c
> @@ -0,0 +1,797 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2025 MediaTek Inc.
> + */
> +
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_of.h>
> +#include <drm/drm_print.h>
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/of_platform.h>
> +#include <linux/of_device.h>
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +#include <linux/soc/mediatek/mtk-mmsys.h>
> +#include <linux/soc/mediatek/mtk-mutex.h>
> +
> +#include "mtk_disp_blender.h"
> +#include "mtk_disp_drv.h"
> +#include "mtk_crtc.h"
Alphabetic order.
> +#include "mtk_ddp_comp.h"
Ditto.
> +#include "mtk_drm_drv.h"
> +
> +#define OVLSYS_ADAPTOR_DRIVER_DATA_MAX_SIZE 8191
> +
> +enum mtk_ovlsys_adaptor_comp_type {
> + OVLSYS_ADAPTOR_TYPE_EXDMA = 0,
> + OVLSYS_ADAPTOR_TYPE_BLENDER,
> + OVLSYS_ADAPTOR_TYPE_OUTPROC,
> + OVLSYS_ADAPTOR_TYPE_NUM,
> +};
> +
> +enum mtk_ovlsys_adaptor_comp_id {
> + OVLSYS_ADAPTOR_EXDMA0,
> + OVLSYS_ADAPTOR_EXDMA1,
> + OVLSYS_ADAPTOR_EXDMA2,
> + OVLSYS_ADAPTOR_EXDMA3,
> + OVLSYS_ADAPTOR_EXDMA4,
> + OVLSYS_ADAPTOR_EXDMA5,
> + OVLSYS_ADAPTOR_EXDMA6,
> + OVLSYS_ADAPTOR_EXDMA7,
> + OVLSYS_ADAPTOR_EXDMA8,
> + OVLSYS_ADAPTOR_EXDMA9,
> + OVLSYS_ADAPTOR_EXDMA10,
> + OVLSYS_ADAPTOR_EXDMA11,
> + OVLSYS_ADAPTOR_EXDMA12,
> + OVLSYS_ADAPTOR_EXDMA13,
> + OVLSYS_ADAPTOR_EXDMA14,
> + OVLSYS_ADAPTOR_EXDMA15,
> + OVLSYS_ADAPTOR_EXDMA16,
> + OVLSYS_ADAPTOR_EXDMA17,
> + OVLSYS_ADAPTOR_EXDMA18,
> + OVLSYS_ADAPTOR_EXDMA19,
> + OVLSYS_ADAPTOR_BLENDER0,
> + OVLSYS_ADAPTOR_BLENDER1,
> + OVLSYS_ADAPTOR_BLENDER2,
> + OVLSYS_ADAPTOR_BLENDER3,
> + OVLSYS_ADAPTOR_BLENDER4,
> + OVLSYS_ADAPTOR_BLENDER5,
> + OVLSYS_ADAPTOR_BLENDER6,
> + OVLSYS_ADAPTOR_BLENDER7,
> + OVLSYS_ADAPTOR_BLENDER8,
> + OVLSYS_ADAPTOR_BLENDER9,
> + OVLSYS_ADAPTOR_BLENDER10,
> + OVLSYS_ADAPTOR_BLENDER11,
> + OVLSYS_ADAPTOR_BLENDER12,
> + OVLSYS_ADAPTOR_BLENDER13,
> + OVLSYS_ADAPTOR_BLENDER14,
> + OVLSYS_ADAPTOR_BLENDER15,
> + OVLSYS_ADAPTOR_BLENDER16,
> + OVLSYS_ADAPTOR_BLENDER17,
> + OVLSYS_ADAPTOR_BLENDER18,
> + OVLSYS_ADAPTOR_BLENDER19,
> + OVLSYS_ADAPTOR_OUTPROC0,
> + OVLSYS_ADAPTOR_OUTPROC1,
> + OVLSYS_ADAPTOR_OUTPROC2,
> + OVLSYS_ADAPTOR_OUTPROC3,
> + OVLSYS_ADAPTOR_OUTPROC4,
> + OVLSYS_ADAPTOR_OUTPROC5,
> + OVLSYS_ADAPTOR_OUTPROC6,
> + OVLSYS_ADAPTOR_OUTPROC7,
> + OVLSYS_ADAPTOR_OUTPROC8,
> + OVLSYS_ADAPTOR_OUTPROC9,
> + OVLSYS_ADAPTOR_OUTPROC10,
> + OVLSYS_ADAPTOR_OUTPROC11,
> + OVLSYS_ADAPTOR_ID_MAX
> +};
> +
> +struct ovlsys_adaptor_comp_match {
> + enum mtk_ovlsys_adaptor_comp_type type;
> + int alias_id;
> + enum mtk_ddp_comp_id comp_id;
> +};
> +
> +struct mtk_disp_ovlsys_adaptor {
> + struct device *ovl_adaptor_comp[OVLSYS_ADAPTOR_ID_MAX];
> + struct device *mmsys_dev;
> + const unsigned int *path;
> + unsigned int path_size;
> + unsigned int layer_nr;
> + bool children_bound;
> + unsigned int max_size;
It's not necessary to store max_size in private data.
Drop this and use OVLSYS_ADAPTOR_DRIVER_DATA_MAX_SIZE directly.
> +};
> +
> +static const char * const private_comp_stem[OVLSYS_ADAPTOR_TYPE_NUM] = {
> + [OVLSYS_ADAPTOR_TYPE_EXDMA] = "exdma",
> + [OVLSYS_ADAPTOR_TYPE_BLENDER] = "blender",
> + [OVLSYS_ADAPTOR_TYPE_OUTPROC] = "outproc",
> +};
> +
> +static const struct ovlsys_adaptor_comp_match comp_matches[OVLSYS_ADAPTOR_ID_MAX] = {
> + [OVLSYS_ADAPTOR_EXDMA0] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 0, DDP_COMPONENT_ID_MAX},
> + [OVLSYS_ADAPTOR_EXDMA1] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 1, DDP_COMPONENT_ID_MAX},
> + [OVLSYS_ADAPTOR_EXDMA2] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 2, DDP_COMPONENT_OVL0_EXDMA2},
> + [OVLSYS_ADAPTOR_EXDMA3] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 3, DDP_COMPONENT_OVL0_EXDMA3},
> + [OVLSYS_ADAPTOR_EXDMA4] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 4, DDP_COMPONENT_OVL0_EXDMA4},
> + [OVLSYS_ADAPTOR_EXDMA5] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 5, DDP_COMPONENT_OVL0_EXDMA5},
> + [OVLSYS_ADAPTOR_EXDMA6] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 6, DDP_COMPONENT_OVL0_EXDMA6},
> + [OVLSYS_ADAPTOR_EXDMA7] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 7, DDP_COMPONENT_OVL0_EXDMA7},
> + [OVLSYS_ADAPTOR_EXDMA8] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 8, DDP_COMPONENT_OVL0_EXDMA8},
> + [OVLSYS_ADAPTOR_EXDMA9] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 9, DDP_COMPONENT_OVL0_EXDMA9},
> + [OVLSYS_ADAPTOR_EXDMA12] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 12, DDP_COMPONENT_OVL1_EXDMA2},
> + [OVLSYS_ADAPTOR_EXDMA13] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 13, DDP_COMPONENT_OVL1_EXDMA3},
> + [OVLSYS_ADAPTOR_EXDMA14] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 14, DDP_COMPONENT_OVL1_EXDMA4},
> + [OVLSYS_ADAPTOR_EXDMA15] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 15, DDP_COMPONENT_OVL1_EXDMA5},
> + [OVLSYS_ADAPTOR_EXDMA16] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 16, DDP_COMPONENT_OVL1_EXDMA6},
> + [OVLSYS_ADAPTOR_EXDMA17] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 17, DDP_COMPONENT_OVL1_EXDMA7},
> + [OVLSYS_ADAPTOR_EXDMA18] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 18, DDP_COMPONENT_OVL1_EXDMA8},
> + [OVLSYS_ADAPTOR_EXDMA19] = { OVLSYS_ADAPTOR_TYPE_EXDMA, 19, DDP_COMPONENT_OVL1_EXDMA9},
> + [OVLSYS_ADAPTOR_BLENDER1] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 1, DDP_COMPONENT_OVL0_BLENDER1},
> + [OVLSYS_ADAPTOR_BLENDER2] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 2, DDP_COMPONENT_OVL0_BLENDER2},
> + [OVLSYS_ADAPTOR_BLENDER3] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 3, DDP_COMPONENT_OVL0_BLENDER3},
> + [OVLSYS_ADAPTOR_BLENDER4] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 4, DDP_COMPONENT_OVL0_BLENDER4},
> + [OVLSYS_ADAPTOR_BLENDER5] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 5, DDP_COMPONENT_OVL0_BLENDER5},
> + [OVLSYS_ADAPTOR_BLENDER6] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 6, DDP_COMPONENT_OVL0_BLENDER6},
> + [OVLSYS_ADAPTOR_BLENDER7] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 7, DDP_COMPONENT_OVL0_BLENDER7},
> + [OVLSYS_ADAPTOR_BLENDER8] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 8, DDP_COMPONENT_OVL0_BLENDER8},
> + [OVLSYS_ADAPTOR_BLENDER9] = { OVLSYS_ADAPTOR_TYPE_BLENDER, 9, DDP_COMPONENT_OVL0_BLENDER9},
> + [OVLSYS_ADAPTOR_BLENDER11] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 11, DDP_COMPONENT_OVL1_BLENDER1},
> + [OVLSYS_ADAPTOR_BLENDER12] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 12, DDP_COMPONENT_OVL1_BLENDER2},
> + [OVLSYS_ADAPTOR_BLENDER13] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 13, DDP_COMPONENT_OVL1_BLENDER3},
> + [OVLSYS_ADAPTOR_BLENDER14] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 14, DDP_COMPONENT_OVL1_BLENDER4},
> + [OVLSYS_ADAPTOR_BLENDER15] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 15, DDP_COMPONENT_OVL1_BLENDER5},
> + [OVLSYS_ADAPTOR_BLENDER16] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 16, DDP_COMPONENT_OVL1_BLENDER6},
> + [OVLSYS_ADAPTOR_BLENDER17] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 17, DDP_COMPONENT_OVL1_BLENDER7},
> + [OVLSYS_ADAPTOR_BLENDER18] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 18, DDP_COMPONENT_OVL1_BLENDER8},
> + [OVLSYS_ADAPTOR_BLENDER19] = {
> + OVLSYS_ADAPTOR_TYPE_BLENDER, 19, DDP_COMPONENT_OVL1_BLENDER9},
> + [OVLSYS_ADAPTOR_OUTPROC0] = { OVLSYS_ADAPTOR_TYPE_OUTPROC, 0, DDP_COMPONENT_OVL0_OUTPROC0},
> + [OVLSYS_ADAPTOR_OUTPROC1] = { OVLSYS_ADAPTOR_TYPE_OUTPROC, 1, DDP_COMPONENT_OVL0_OUTPROC1},
> + [OVLSYS_ADAPTOR_OUTPROC6] = { OVLSYS_ADAPTOR_TYPE_OUTPROC, 6, DDP_COMPONENT_OVL1_OUTPROC0},
> +};
> +
> +static const unsigned int mt8196_mtk_ovl_main[] = {
> + OVLSYS_ADAPTOR_EXDMA2,
> + OVLSYS_ADAPTOR_BLENDER1,
> + OVLSYS_ADAPTOR_EXDMA3,
> + OVLSYS_ADAPTOR_BLENDER2,
> + OVLSYS_ADAPTOR_EXDMA4,
> + OVLSYS_ADAPTOR_BLENDER3,
> + OVLSYS_ADAPTOR_EXDMA5,
> + OVLSYS_ADAPTOR_BLENDER4,
> + OVLSYS_ADAPTOR_OUTPROC0,
> +};
> +
> +static const unsigned int mt8196_mtk_ovl_ext[] = {
> + OVLSYS_ADAPTOR_EXDMA6,
> + OVLSYS_ADAPTOR_BLENDER5,
> + OVLSYS_ADAPTOR_EXDMA7,
> + OVLSYS_ADAPTOR_BLENDER6,
> + OVLSYS_ADAPTOR_EXDMA8,
> + OVLSYS_ADAPTOR_BLENDER7,
> + OVLSYS_ADAPTOR_EXDMA9,
> + OVLSYS_ADAPTOR_BLENDER8,
> + OVLSYS_ADAPTOR_OUTPROC1,
> +};
> +
> +static const unsigned int mt8196_mtk_ovl_third[] = {
> + OVLSYS_ADAPTOR_EXDMA12,
> + OVLSYS_ADAPTOR_BLENDER11,
> + OVLSYS_ADAPTOR_EXDMA13,
> + OVLSYS_ADAPTOR_BLENDER12,
> + OVLSYS_ADAPTOR_EXDMA14,
> + OVLSYS_ADAPTOR_BLENDER13,
> + OVLSYS_ADAPTOR_EXDMA15,
> + OVLSYS_ADAPTOR_BLENDER14,
> + OVLSYS_ADAPTOR_OUTPROC6,
> +};
> +
> +static enum mtk_ovlsys_adaptor_comp_type get_type(enum mtk_ovlsys_adaptor_comp_id id)
> +{
> + return comp_matches[id].type;
> +}
> +
> +static enum mtk_ddp_comp_id get_ddp_comp_id(enum mtk_ovlsys_adaptor_comp_id id)
> +{
> + return comp_matches[id].comp_id;
> +}
> +
> +static struct device *get_comp_by_type_idx(struct device *dev,
> + enum mtk_ovlsys_adaptor_comp_type type,
> + unsigned int idx)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> + int count = 0;
> +
> + for (i = 0; i < priv->path_size; i++) {
> + if (get_type(priv->path[i]) == type) {
> + if (count == idx)
> + return priv->ovl_adaptor_comp[priv->path[i]];
> + count++;
> + }
> + }
> + return NULL;
> +}
> +
> +int mtk_ovlsys_adaptor_power_on(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp;
> + int ret = 0;
> + int i;
> +
> + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
Why this for-loop is not as below example?
for (i = 0; i < priv->path_size; i++) {
> + comp = priv->ovl_adaptor_comp[i];
> +
> + if (!comp)
> + continue;
> +
> + if (get_type(i) != OVLSYS_ADAPTOR_TYPE_EXDMA)
Why only EXDMA need power on?
> + continue;
> +
> + ret = pm_runtime_get_sync(comp);
> + if (ret < 0) {
> + dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
> + goto pwr_err;
> + }
> + }
> +
> + return ret;
> +pwr_err:
> + while (--i >= 0) {
> + comp = priv->ovl_adaptor_comp[i];
> + if (!comp)
> + continue;
> + if (get_type(i) != OVLSYS_ADAPTOR_TYPE_EXDMA)
> + continue;
> + pm_runtime_put(priv->ovl_adaptor_comp[i]);
> + }
> +
> + return ret;
> +}
> +
> +void mtk_ovlsys_adaptor_power_off(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp;
> + int i;
> +
> + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> + comp = priv->ovl_adaptor_comp[i];
> +
> + if (!comp)
> + continue;
> +
> + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + pm_runtime_put(comp);
> + }
> +}
> +
> +void mtk_ovlsys_adaptor_layer_config(struct device *dev, unsigned int idx,
> + struct mtk_plane_state *state,
> + struct cmdq_pkt *cmdq_pkt)
> +{
> + struct mtk_plane_pending_state *pending = &state->pending;
> + struct device *exdma;
> + struct device *blender;
> + unsigned int align_width = 0;
> + const struct drm_format_info *fmt_info = drm_format_info(pending->format);
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + DRM_DEV_DEBUG_DRIVER(dev, "idx:%d enable:%d fmt:0x%x addr:0x%pad fb_w:%d {%d,%d,%d,%d}\n",
> + idx, pending->enable, pending->format,
> + &pending->addr, (pending->pitch / fmt_info->cpp[0]),
> + pending->x, pending->y, pending->width, pending->height);
> +
> + exdma = get_comp_by_type_idx(dev, OVLSYS_ADAPTOR_TYPE_EXDMA, idx);
exdma = priv->ovl_adaptor_comp[priv->path[idx * 2]];
> + if (!exdma) {
You just need to check idx < priv->layer_nr.
> + dev_err(dev, "%s: exdma%d comp not found\n", __func__, idx);
> + return;
> + }
> + blender = get_comp_by_type_idx(dev, OVLSYS_ADAPTOR_TYPE_BLENDER, idx);
blender = priv->ovl_adaptor_comp[priv->path[idx * 2 + 1]];
> + if (!blender) {
> + dev_err(dev, "%s: blender%d comp not found\n", __func__, idx);
> + return;
> + }
> +
> + /* OVLSYS is in 1T2P domain, width needs to be 2 pixels align */
> + align_width = ALIGN_DOWN(pending->width, 2);
> +
> + if (pending->height == 0 || align_width == 0 ||
> + pending->x > priv->max_size || pending->y > priv->max_size) {
> + pending->enable = false;
Why modify pending->enable?
> + mtk_disp_exdma_layer_config(exdma, state, cmdq_pkt);
> + mtk_disp_blender_layer_config(blender, state, cmdq_pkt);
> + return;
> + }
> +
> + mtk_disp_exdma_layer_config(exdma, state, cmdq_pkt);
> +
> + mtk_disp_blender_layer_config(blender, state, cmdq_pkt);
> +
> + mtk_disp_exdma_start(exdma, cmdq_pkt);
> + mtk_disp_blender_start(blender, cmdq_pkt);
The start function is done in ovlsys_start(), so remove these start function.
> +}
> +
> +void mtk_ovlsys_adaptor_config(struct device *dev, unsigned int w,
> + unsigned int h, unsigned int vrefresh,
> + unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> + int blender_idx = 0;
> + bool most_top;
> + bool most_bottom;
> +
> + for (i = 0; i < priv->path_size; i++) {
> + if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER) {
> + blender_idx++;
> +
> + if (priv->layer_nr == 1) {
> + most_top = true; /*SINGLE_BLENDER;*/
> + most_bottom = false; /*blender is LAST_BLENDER*/
Only one blender, so most_bottom = true;
> + } else if (blender_idx == 1) {
> + most_top = false; /* NON-SINGLE LAYER */
> + most_bottom = true; /* FIRST LAYER */
> + } else if (blender_idx == priv->layer_nr) {
> + most_top = true; /* NON-SINGLE LAYER */
> + most_bottom = false; /* LAST LAYER */
> + } else {
> + most_top = false; /* NON-SINGLE LAYER */
> + most_bottom = false; /* OTHER LAYER */
> + }
> +
> + mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
> + vrefresh, bpc, most_top, most_bottom, cmdq_pkt);
You could remove the if-else checking, and
mtk_disp_blender_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
vrefresh, bpc, blender_idx == priv->layer_nr,
blender_idx == 1, cmdq_pkt);
> + } else if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_OUTPROC) {
> + mtk_disp_outproc_config(priv->ovl_adaptor_comp[priv->path[i]], w, h,
> + vrefresh, bpc, cmdq_pkt);
> + }
> + }
> +}
> +
> +int mtk_ovlsys_adaptor_layer_check(struct device *dev,
> + unsigned int idx,
> + struct mtk_plane_state *mtk_state)
> +{
> + struct drm_plane_state *state = &mtk_state->base;
> +
> + /* Check if any unsupported rotation is set */
> + if (state->rotation & ~DRM_MODE_ROTATE_0)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +void mtk_ovlsys_adaptor_start(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size; i++) {
> + if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + mtk_disp_exdma_start(priv->ovl_adaptor_comp[priv->path[i]], NULL);
> + else if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + mtk_disp_blender_start(priv->ovl_adaptor_comp[priv->path[i]], NULL);
> + else
> + mtk_disp_outproc_start(priv->ovl_adaptor_comp[priv->path[i]]);
> + }
I think the order in path has some rule, so this for-loop could be simplified as
for (i = 0; i < (priv->path_size - 1); i += 2) {
mtk_disp_exdma_start(priv->ovl_adaptor_comp[priv->path[i]], NULL);
mtk_disp_blender_start(priv->ovl_adaptor_comp[priv->path[i + 1]], NULL);
}
mtk_disp_outproc_start(priv->ovl_adaptor_comp[priv->path[i]]);
> +}
> +
> +void mtk_ovlsys_adaptor_stop(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size; i++) {
> + if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + mtk_disp_exdma_stop(priv->ovl_adaptor_comp[priv->path[i]], NULL);
> + else if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + mtk_disp_blender_stop(priv->ovl_adaptor_comp[priv->path[i]], NULL);
> + else
> + mtk_disp_outproc_stop(priv->ovl_adaptor_comp[priv->path[i]]);
> + }
> +}
> +
> +int mtk_ovlsys_adaptor_clk_enable(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp;
> + int ret = 0;
> + int i;
> +
> + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
Why this for-loop is not as below?
for (i = 0; i < priv->path_size; i++) {
> + comp = priv->ovl_adaptor_comp[i];
> +
> + if (!comp)
> + continue;
> +
> + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + ret = mtk_disp_exdma_clk_enable(comp);
> + else if (get_type(i) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + ret = mtk_disp_blender_clk_enable(comp);
> + else
> + ret = mtk_disp_outproc_clk_enable(comp);
> +
> + if (ret) {
> + dev_err(dev, "Failed to enable clock %d, err %d\n", i, ret);
> + goto clk_err;
> + }
> + }
> +
> + return ret;
> +
> +clk_err:
> + while (--i >= 0) {
> + comp = priv->ovl_adaptor_comp[i];
> + if (!comp)
> + continue;
> + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + mtk_disp_exdma_clk_disable(comp);
> + else if (get_type(i) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + mtk_disp_blender_clk_disable(comp);
> + else
> + mtk_disp_outproc_clk_disable(comp);
> + }
> + i = OVLSYS_ADAPTOR_ID_MAX;
Why assign i here?
> +
> + return ret;
> +}
> +
> +void mtk_ovlsys_adaptor_clk_disable(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp;
> + int i;
> +
> + for (i = 0; i < OVLSYS_ADAPTOR_ID_MAX; i++) {
> + comp = priv->ovl_adaptor_comp[i];
> +
> + if (!comp)
> + continue;
> +
> + if (get_type(i) == OVLSYS_ADAPTOR_TYPE_EXDMA)
> + mtk_disp_exdma_clk_disable(comp);
> + else if (get_type(i) == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + mtk_disp_blender_clk_disable(comp);
> + else
> + mtk_disp_outproc_clk_disable(comp);
> + }
> +}
> +
> +unsigned int mtk_ovlsys_adaptor_layer_nr(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + return priv->layer_nr;
> +}
> +
> +struct device *mtk_ovlsys_adaptor_dma_dev_get(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + return priv->ovl_adaptor_comp[priv->path[0]];
> +}
> +
> +void mtk_ovlsys_adaptor_register_vblank_cb(struct device *dev, void (*vblank_cb)(void *),
> + void *vblank_cb_data)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + mtk_disp_outproc_register_vblank_cb(priv->ovl_adaptor_comp[priv->path[priv->path_size - 1]],
> + vblank_cb, vblank_cb_data);
> +}
> +
> +void mtk_ovlsys_adaptor_unregister_vblank_cb(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp = priv->ovl_adaptor_comp[priv->path[priv->path_size - 1]];
> +
> + mtk_disp_outproc_unregister_vblank_cb(comp);
> +}
> +
> +void mtk_ovlsys_adaptor_enable_vblank(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + mtk_disp_outproc_enable_vblank(priv->ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> +}
> +
> +void mtk_ovlsys_adaptor_disable_vblank(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + mtk_disp_outproc_disable_vblank(priv->ovl_adaptor_comp[priv->path[priv->path_size - 1]]);
> +}
> +
> +u32 mtk_ovlsys_adaptor_get_blend_modes(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device *comp;
> + int i;
> +
> + for (i = 0; i < priv->path_size; i++)
> + if (get_type(priv->path[i]) == OVLSYS_ADAPTOR_TYPE_BLENDER) {
> + comp = priv->ovl_adaptor_comp[priv->path[i]];
> + return mtk_disp_blender_get_blend_modes(comp);
> + }
In mtk_ovlsys_adaptor_get_formats(), you have assume that priv->ovl_adaptor_comp[priv->path[0]] is exdma,
so you could assume that priv->ovl_adaptor_comp[priv->path[1]] is blender.
Then
return mtk_disp_blender_get_blend_modes(priv->ovl_adaptor_comp[priv->path[1]]);
> +
> + return 0;
> +}
> +
> +const u32 *mtk_ovlsys_adaptor_get_formats(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + return mtk_disp_exdma_get_formats(priv->ovl_adaptor_comp[priv->path[0]]);
> +}
> +
> +size_t mtk_ovlsys_adaptor_get_num_formats(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + return mtk_disp_exdma_get_num_formats(priv->ovl_adaptor_comp[priv->path[0]]);
> +}
> +
> +void mtk_ovlsys_adaptor_add_comp(struct device *dev, struct mtk_mutex *mutex)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size; i++)
> + mtk_mutex_add_comp(mutex, get_ddp_comp_id(priv->path[i]));
> +}
> +
> +void mtk_ovlsys_adaptor_remove_comp(struct device *dev, struct mtk_mutex *mutex)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size; i++)
> + mtk_mutex_remove_comp(mutex, get_ddp_comp_id(priv->path[i]));
> +}
> +
> +void mtk_ovlsys_adaptor_connect(struct device *dev, struct device *mmsys_dev, unsigned int next)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size - 1; i++)
> + mtk_mmsys_ddp_connect(mmsys_dev, get_ddp_comp_id(priv->path[i]),
> + get_ddp_comp_id(priv->path[i + 1]));
> +
> + mtk_mmsys_ddp_connect(mmsys_dev, get_ddp_comp_id(priv->path[i]), next);
> +}
> +
> +void mtk_ovlsys_adaptor_disconnect(struct device *dev, struct device *mmsys_dev, unsigned int next)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int i;
> +
> + for (i = 0; i < priv->path_size - 1; i++)
> + mtk_mmsys_ddp_disconnect(mmsys_dev, get_ddp_comp_id(priv->path[i]),
> + get_ddp_comp_id(priv->path[i + 1]));
> +
> + mtk_mmsys_ddp_disconnect(mmsys_dev, get_ddp_comp_id(priv->path[i]), next);
> +}
> +
> +static int ovlsys_adaptor_comp_get_id(struct device *dev, struct device_node *node,
> + enum mtk_ovlsys_adaptor_comp_type type,
> + enum mtk_ddp_comp_id *comp_id)
> +{
> + int alias_id = of_alias_get_id(node, private_comp_stem[type]);
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
> + if (comp_matches[i].type == type &&
> + comp_matches[i].alias_id == alias_id) {
> + *comp_id = comp_matches[i].comp_id;
> + return i;
> + }
> + dev_warn(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
> + return -EINVAL;
> +}
> +
> +static const struct of_device_id mtk_ovlsys_adaptor_comp_dt_ids[] = {
> + {
> + .compatible = "mediatek,mt8196-exdma",
> + .data = (void *)OVLSYS_ADAPTOR_TYPE_EXDMA,
> + }, {
> + .compatible = "mediatek,mt8196-blender",
> + .data = (void *)OVLSYS_ADAPTOR_TYPE_BLENDER,
> + }, {
> + .compatible = "mediatek,mt8196-outproc",
> + .data = (void *)OVLSYS_ADAPTOR_TYPE_OUTPROC,
> + },
> + {},
> +};
> +
> +static int ovlsys_adaptor_comp_init(struct device *dev, struct component_match **match)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + struct device_node *node, *parent;
> + struct platform_device *comp_pdev;
> + int i;
> +
> + parent = dev->parent->parent->of_node->parent;
> +
> + for_each_child_of_node(parent, node) {
for_each_child_of_node_scoped()
> + const struct of_device_id *of_id;
> + enum mtk_ovlsys_adaptor_comp_type type;
> + enum mtk_ddp_comp_id comp_id;
comp_id is useless, drop it.
> + int id;
> + bool found = false;
> +
> + of_id = of_match_node(mtk_ovlsys_adaptor_comp_dt_ids, node);
> + if (!of_id)
> + continue;
> +
> + if (!of_device_is_available(node)) {
> + dev_dbg(dev, "Skipping disabled component %pOF\n",
> + node);
> + continue;
> + }
> +
> + type = (enum mtk_ovlsys_adaptor_comp_type)(uintptr_t)of_id->data;
> + id = ovlsys_adaptor_comp_get_id(dev, node, type, &comp_id);
> + if (id < 0) {
> + dev_warn(dev, "Skipping unknown component %pOF\n",
> + node);
> + continue;
> + }
> +
> + for (i = 0; i < priv->path_size; i++)
> + if (priv->path[i] == id)
> + found = true;
> +
> + if (!found)
> + continue;
> +
> + comp_pdev = of_find_device_by_node(node);
> + if (!comp_pdev)
> + return -EPROBE_DEFER;
> +
> + priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
> +
> + drm_of_component_match_add(dev, match, component_compare_of, node);
> + dev_dbg(dev, "Adding component match for %pOF\n", node);
> + }
> +
> + if (!*match) {
> + dev_err(dev, "No match device for ovlsys_adaptor\n");
> + return -ENODEV;
> + }
> +
> + return 0;
> +}
> +
> +static int mtk_disp_ovlsys_adaptor_comp_bind(struct device *dev, struct device *master,
> + void *data)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + if (!priv->children_bound)
> + return -EPROBE_DEFER;
> +
> + return 0;
> +}
> +
> +static void mtk_disp_ovlsys_adaptor_comp_unbind(struct device *dev, struct device *master,
> + void *data)
> +{
> +}
> +
> +static const struct component_ops mtk_disp_ovlsys_adaptor_comp_ops = {
> + .bind = mtk_disp_ovlsys_adaptor_comp_bind,
> + .unbind = mtk_disp_ovlsys_adaptor_comp_unbind,
> +};
> +
> +static int mtk_disp_ovlsys_adaptor_master_bind(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> + int ret, i;
> + unsigned int layer_nr = 0;
> +
> + ret = component_bind_all(dev, priv->mmsys_dev);
> + if (ret)
> + return dev_err_probe(dev, ret, "component_bind_all failed!\n");
> +
> + priv->children_bound = true;
> +
> + for (i = 0; i < priv->path_size; i++)
> + if (comp_matches[priv->path[i]].type == OVLSYS_ADAPTOR_TYPE_BLENDER)
> + layer_nr++;
It seems you could drop layer_nr.
Assign priv->layer_nr to 0 first, and then priv->layer_nr++.
> + priv->layer_nr = layer_nr;
> +
> + return 0;
> +}
> +
> +static void mtk_disp_ovlsys_adaptor_master_unbind(struct device *dev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv = dev_get_drvdata(dev);
> +
> + priv->children_bound = false;
> +}
> +
> +static const struct component_master_ops mtk_disp_ovlsys_adaptor_master_ops = {
> + .bind = mtk_disp_ovlsys_adaptor_master_bind,
> + .unbind = mtk_disp_ovlsys_adaptor_master_unbind,
> +};
> +
> +static int mtk_disp_ovlsys_adaptor_probe(struct platform_device *pdev)
> +{
> + struct mtk_disp_ovlsys_adaptor *priv;
> + struct device *dev = &pdev->dev;
> + struct component_match *match = NULL;
> + struct mtk_ovlsys_platform_data *ovlsys_priv; //mtk_drm_ovlsys_private
Remove the comment.
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, priv);
> +
> + ovlsys_priv = pdev->dev.platform_data;
> + priv->mmsys_dev = ovlsys_priv->mmsys_dev;
> + priv->max_size = OVLSYS_ADAPTOR_DRIVER_DATA_MAX_SIZE;
> +
> + if (ovlsys_priv->use_path == CRTC_MAIN) {
> + priv->path = mt8196_mtk_ovl_main;
> + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_main);
> + } else if (ovlsys_priv->use_path == CRTC_EXT) {
> + priv->path = mt8196_mtk_ovl_ext;
> + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_ext);
> + } else if (ovlsys_priv->use_path == CRTC_THIRD) {
> + priv->path = mt8196_mtk_ovl_third;
> + priv->path_size = ARRAY_SIZE(mt8196_mtk_ovl_third);
> + }
> +
> + ret = ovlsys_adaptor_comp_init(dev, &match);
> + if (ret < 0)
> + return ret;
> +
> + component_master_add_with_match(dev, &mtk_disp_ovlsys_adaptor_master_ops, match);
> +
> + pm_runtime_enable(dev);
> +
> + ret = component_add(dev, &mtk_disp_ovlsys_adaptor_comp_ops);
> + if (ret != 0) {
> + pm_runtime_disable(dev);
> + dev_err(dev, "Failed to add component: %d\n", ret);
> + }
> +
> + return ret;
> +}
> +
> +static void mtk_disp_ovlsys_adaptor_remove(struct platform_device *pdev)
> +{
> + component_master_del(&pdev->dev, &mtk_disp_ovlsys_adaptor_master_ops);
> + pm_runtime_disable(&pdev->dev);
> +}
> +
> +struct platform_driver mtk_disp_ovlsys_adaptor_driver = {
> + .probe = mtk_disp_ovlsys_adaptor_probe,
> + .remove = mtk_disp_ovlsys_adaptor_remove,
> + .driver = {
> + .name = "mediatek-disp-ovlsys-adaptor",
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +MODULE_AUTHOR("Nancy Lin <nancy.lin at mediatek.com>");
> +MODULE_DESCRIPTION("MediaTek Ovlsys Adaptor Driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index f7b9c7a982a7..0639201e2e92 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -457,6 +457,27 @@ static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id
> return false;
> }
>
> +static int mtk_drm_mmsys_comp_in_path(struct mtk_drm_private *private, int comp_id)
> +{
> + const struct mtk_mmsys_driver_data *drv_data = private->data;
> + int i;
> +
> + if (drv_data->main_path)
> + for (i = 0; i < drv_data->main_len; i++)
> + if (drv_data->main_path[i] == comp_id)
> + return CRTC_MAIN;
> + if (drv_data->ext_path)
> + for (i = 0; i < drv_data->ext_len; i++)
> + if (drv_data->ext_path[i] == comp_id)
> + return CRTC_EXT;
> + if (drv_data->third_path)
> + for (i = 0; i < drv_data->third_len; i++)
> + if (drv_data->third_path[i] == comp_id)
> + return CRTC_THIRD;
> +
This function is almost like mtk_drm_find_mmsys_comp(), try to merge them.
> + return -EINVAL;
> +}
> +
> static int mtk_drm_kms_init(struct drm_device *drm)
> {
> struct mtk_drm_private *private = drm->dev_private;
> @@ -1122,6 +1143,57 @@ static int mtk_drm_probe(struct platform_device *pdev)
> component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
> }
>
> + if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0)) {
> + struct mtk_ovlsys_platform_data ovlsys_priv;
> +
> + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> + ovlsys_priv.use_path =
> + mtk_drm_mmsys_comp_in_path(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> + ovl_adaptor =
> + platform_device_register_data(dev, "mediatek-disp-ovlsys-adaptor",
> + PLATFORM_DEVID_AUTO,
> + (void *)&ovlsys_priv,
> + sizeof(struct mtk_ovlsys_platform_data));
> + private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0].dev = &ovl_adaptor->dev;
> + mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0],
> + DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0);
> + component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
> + }
> +
> + if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1)) {
> + struct mtk_ovlsys_platform_data ovlsys_priv; //mtk_drm_ovlsys_private
> +
> + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> + ovlsys_priv.use_path =
> + mtk_drm_mmsys_comp_in_path(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> + ovl_adaptor =
> + platform_device_register_data(dev, "mediatek-disp-ovlsys-adaptor",
> + PLATFORM_DEVID_AUTO,
> + (void *)&ovlsys_priv,
> + sizeof(struct mtk_ovlsys_platform_data));
> + private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1].dev = &ovl_adaptor->dev;
> + mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1],
> + DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1);
> + component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
> + }
> +
> + if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2)) {
> + struct mtk_ovlsys_platform_data ovlsys_priv;
> +
> + ovlsys_priv.mmsys_dev = private->mmsys_dev;
> + ovlsys_priv.use_path =
> + mtk_drm_mmsys_comp_in_path(private, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2);
> + ovl_adaptor =
> + platform_device_register_data(dev, "mediatek-disp-ovlsys-adaptor",
> + PLATFORM_DEVID_AUTO,
> + (void *)&ovlsys_priv,
> + sizeof(struct mtk_ovlsys_platform_data));
> + private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2].dev = &ovl_adaptor->dev;
> + mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2],
> + DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2);
> + component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
> + }
The code about these three path are almost the same.
Try to merge them.
You could use one function with different parameter
(such as DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1, DDP_COMPONENT_DRM_OVLSYS_ADAPTOR2).
> +
> /* Iterate over sibling DISP function blocks */
> for_each_child_of_node(phandle->parent, node) {
> enum mtk_ddp_comp_type comp_type;
> @@ -1283,6 +1355,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
> &mtk_disp_outproc_driver,
> &mtk_disp_ovl_adaptor_driver,
> &mtk_disp_ovl_driver,
> + &mtk_disp_ovlsys_adaptor_driver,
> &mtk_disp_rdma_driver,
> &mtk_dpi_driver,
> &mtk_drm_platform_driver,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> index c4717c37b0f1..6e9ed9837c5b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
> @@ -11,7 +11,9 @@
>
> #define MAX_CONNECTOR 2
> #define DDP_COMPONENT_DRM_OVL_ADAPTOR (DDP_COMPONENT_ID_MAX + 1)
> -#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
> +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 (DDP_COMPONENT_DRM_OVL_ADAPTOR + 1)
> +#define DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR0 + 1)
> +#define DDP_COMPONENT_DRM_ID_MAX (DDP_COMPONENT_DRM_OVLSYS_ADAPTOR1 + 1)
>
> enum mtk_crtc_path {
> CRTC_MAIN,
> @@ -69,6 +71,12 @@ struct mtk_drm_private {
> struct mtk_drm_private **all_drm_private;
> };
>
> +struct mtk_ovlsys_platform_data {//mtk_drm_ovlsys_private
Remove this comment
> + struct device *mmsys_dev;
> + struct device *mutex_dev;
mutex_dev is useless, drop it.
Regards,
CK
> + unsigned int use_path;
> +};
> +
> extern struct platform_driver mtk_disp_aal_driver;
> extern struct platform_driver mtk_disp_blender_driver;
> extern struct platform_driver mtk_disp_ccorr_driver;
> @@ -79,6 +87,7 @@ extern struct platform_driver mtk_disp_merge_driver;
> extern struct platform_driver mtk_disp_outproc_driver;
> extern struct platform_driver mtk_disp_ovl_adaptor_driver;
> extern struct platform_driver mtk_disp_ovl_driver;
> +extern struct platform_driver mtk_disp_ovlsys_adaptor_driver;
> extern struct platform_driver mtk_disp_rdma_driver;
> extern struct platform_driver mtk_dpi_driver;
> extern struct platform_driver mtk_dsi_driver;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20250411/044de020/attachment-0001.htm>
More information about the dri-devel
mailing list