From: Nancy Lin <nancy....@mediatek.com>

Refine OVL format convert API and export to public.

Signed-off-by: Nancy Lin <nancy....@mediatek.com>
Signed-off-by: Paul-pl Chen <paul-pl.c...@mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 158 ++++++++++++++++--------
 drivers/gpu/drm/mediatek/mtk_disp_ovl.h |  16 +++
 2 files changed, 122 insertions(+), 52 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl.h

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index d0581c4e3c99..e2b125a717c6 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -18,6 +18,7 @@
 #include "mtk_crtc.h"
 #include "mtk_ddp_comp.h"
 #include "mtk_disp_drv.h"
+#include "mtk_disp_ovl.h"
 #include "mtk_drm_drv.h"
 
 #define DISP_REG_OVL_INTEN                     0x0004
@@ -62,22 +63,15 @@
 /* OVL_CON_RGB_SWAP works only if OVL_CON_CLRFMT_MAN is enabled */
 #define OVL_CON_RGB_SWAP       BIT(25)
 
-#define OVL_CON_CLRFMT_RGB     (1 << 12)
-#define OVL_CON_CLRFMT_ARGB8888        (2 << 12)
-#define OVL_CON_CLRFMT_RGBA8888        (3 << 12)
-#define OVL_CON_CLRFMT_ABGR8888        (OVL_CON_CLRFMT_ARGB8888 | 
OVL_CON_BYTE_SWAP)
-#define OVL_CON_CLRFMT_BGRA8888        (OVL_CON_CLRFMT_RGBA8888 | 
OVL_CON_BYTE_SWAP)
-#define OVL_CON_CLRFMT_UYVY    (4 << 12)
-#define OVL_CON_CLRFMT_YUYV    (5 << 12)
-#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
-#define OVL_CON_CLRFMT_PARGB8888 ((3 << 12) | OVL_CON_CLRFMT_MAN)
-#define OVL_CON_CLRFMT_PABGR8888 (OVL_CON_CLRFMT_PARGB8888 | OVL_CON_RGB_SWAP)
-#define OVL_CON_CLRFMT_PBGRA8888 (OVL_CON_CLRFMT_PARGB8888 | OVL_CON_BYTE_SWAP)
-#define OVL_CON_CLRFMT_PRGBA8888 (OVL_CON_CLRFMT_PABGR8888 | OVL_CON_BYTE_SWAP)
-#define OVL_CON_CLRFMT_RGB565(ovl)     ((ovl)->data->fmt_rgb565_is_0 ? \
-                                       0 : OVL_CON_CLRFMT_RGB)
-#define OVL_CON_CLRFMT_RGB888(ovl)     ((ovl)->data->fmt_rgb565_is_0 ? \
-                                       OVL_CON_CLRFMT_RGB : 0)
+#define OVL_CON_CLRFMT_RGB565(shift)   (0 << (shift))
+#define OVL_CON_CLRFMT_RGB888(shift)   (1 << (shift))
+#define OVL_CON_CLRFMT_ARGB8888(shift) (2 << (shift))
+#define OVL_CON_CLRFMT_RGBA8888(shift) (3 << (shift))
+#define OVL_CON_CLRFMT_UYVY(shift)     (4 << (shift))
+#define OVL_CON_CLRFMT_YUYV(shift)     (5 << (shift))
+#define OVL_CON_MTX_YUV_TO_RGB         (6 << 16)
+#define OVL_CON_CLRFMT_PARGB8888(shift, man) ((3 << (shift)) | (man))
+
 #define        OVL_CON_AEN             BIT(8)
 #define        OVL_CON_ALPHA           0xff
 #define        OVL_CON_VIRT_FLIP       BIT(9)
@@ -85,7 +79,7 @@
 
 #define OVL_COLOR_ALPHA                GENMASK(31, 24)
 
-static inline bool is_10bit_rgb(u32 fmt)
+bool mtk_ovl_is_10bit_rgb(unsigned int fmt)
 {
        switch (fmt) {
        case DRM_FORMAT_XRGB2101010:
@@ -295,7 +289,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int 
idx, u32 format,
        if (!ovl->data->supports_clrfmt_ext)
                return;
 
-       if (is_10bit_rgb(format))
+       if (mtk_ovl_is_10bit_rgb(format))
                bit_depth = OVL_CON_CLRFMT_10_BIT;
 
        mtk_ddp_write_mask(cmdq_pkt, OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx),
@@ -394,10 +388,26 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int 
idx,
                      DISP_REG_OVL_RDMA_CTRL(idx));
 }
 
-static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl,
-                                       struct mtk_plane_state *state)
+bool mtk_ovl_is_ignore_pixel_alpha(struct mtk_plane_state *state, unsigned int 
blend_mode)
+{
+       if (!state->base.fb)
+               return false;
+
+       /*
+        * Although the alpha channel can be ignored, CONST_BLD must be enabled
+        * for XRGB format, otherwise OVL will still read the value from memory.
+        * For RGB888 related formats, whether CONST_BLD is enabled or not won't
+        * affect the result. Therefore we use !has_alpha as the condition.
+        */
+
+       if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || 
!state->base.fb->format->has_alpha)
+               return true;
+
+       return false;
+}
+
+unsigned int mtk_ovl_get_blend_mode(struct mtk_plane_state *state, unsigned 
int blend_modes)
 {
-       unsigned int fmt = state->pending.format;
        unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE;
 
        /*
@@ -412,52 +422,102 @@ static unsigned int mtk_ovl_fmt_convert(struct 
mtk_disp_ovl *ovl,
         * will get an error return from drm_plane_create_blend_mode_property() 
and
         * state->base.pixel_blend_mode should not be used.
         */
-       if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI))
+       if (blend_modes & BIT(DRM_MODE_BLEND_PREMULTI))
                blend_mode = state->base.pixel_blend_mode;
 
+       return blend_mode;
+}
+
+unsigned int mtk_ovl_fmt_convert(unsigned int fmt, unsigned int blend_mode,
+                                bool fmt_rgb565_is_0, bool color_convert,
+                                u8 clrfmt_shift, u32 clrfmt_man, u32 
byte_swap, u32 rgb_swap)
+{
+       unsigned int con = 0;
+       bool need_byte_swap = false, need_rgb_swap = false;
+
        switch (fmt) {
        default:
        case DRM_FORMAT_RGB565:
-               return OVL_CON_CLRFMT_RGB565(ovl);
+               con = fmt_rgb565_is_0 ?
+                       OVL_CON_CLRFMT_RGB565(clrfmt_shift) : 
OVL_CON_CLRFMT_RGB888(clrfmt_shift);
+       break;
        case DRM_FORMAT_BGR565:
-               return OVL_CON_CLRFMT_RGB565(ovl) | OVL_CON_BYTE_SWAP;
+               con = fmt_rgb565_is_0 ?
+                       OVL_CON_CLRFMT_RGB565(clrfmt_shift) : 
OVL_CON_CLRFMT_RGB888(clrfmt_shift);
+               need_byte_swap = true;  /* RGB565 -> BGR565 */
+       break;
        case DRM_FORMAT_RGB888:
-               return OVL_CON_CLRFMT_RGB888(ovl);
+               con = fmt_rgb565_is_0 ?
+                       OVL_CON_CLRFMT_RGB888(clrfmt_shift) : 
OVL_CON_CLRFMT_RGB565(clrfmt_shift);
+       break;
        case DRM_FORMAT_BGR888:
-               return OVL_CON_CLRFMT_RGB888(ovl) | OVL_CON_BYTE_SWAP;
+               con = fmt_rgb565_is_0 ?
+                       OVL_CON_CLRFMT_RGB888(clrfmt_shift) : 
OVL_CON_CLRFMT_RGB565(clrfmt_shift);
+               need_byte_swap = true;  /* RGB888 -> BGR888 */
+       break;
        case DRM_FORMAT_RGBX8888:
        case DRM_FORMAT_RGBA8888:
        case DRM_FORMAT_RGBX1010102:
        case DRM_FORMAT_RGBA1010102:
-               return blend_mode == DRM_MODE_BLEND_COVERAGE ?
-                      OVL_CON_CLRFMT_RGBA8888 :
-                      OVL_CON_CLRFMT_PRGBA8888;
+               if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
+                       con = OVL_CON_CLRFMT_RGBA8888(clrfmt_shift);
+               } else {
+                       con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, 
clrfmt_man);
+                       need_byte_swap = true;  /* PARGB8888 -> PBGRA8888 */
+                       need_rgb_swap = true;   /* PBGRA8888 -> PRGBA8888 */
+               }
+       break;
        case DRM_FORMAT_BGRX8888:
        case DRM_FORMAT_BGRA8888:
        case DRM_FORMAT_BGRX1010102:
        case DRM_FORMAT_BGRA1010102:
-               return blend_mode == DRM_MODE_BLEND_COVERAGE ?
-                      OVL_CON_CLRFMT_BGRA8888 :
-                      OVL_CON_CLRFMT_PBGRA8888;
+               if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
+                       con = OVL_CON_CLRFMT_RGBA8888(clrfmt_shift);
+                       need_byte_swap = true;  /* RGB8888 -> BGR8888 */
+               } else {
+                       con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, 
clrfmt_man);
+                       need_byte_swap = true;  /* PARGB8888 -> PBGRA8888 */
+               }
+       break;
        case DRM_FORMAT_XRGB8888:
        case DRM_FORMAT_ARGB8888:
        case DRM_FORMAT_XRGB2101010:
        case DRM_FORMAT_ARGB2101010:
-               return blend_mode == DRM_MODE_BLEND_COVERAGE ?
-                      OVL_CON_CLRFMT_ARGB8888 :
-                      OVL_CON_CLRFMT_PARGB8888;
+               if (blend_mode == DRM_MODE_BLEND_COVERAGE)
+                       con = OVL_CON_CLRFMT_ARGB8888(clrfmt_shift);
+               else
+                       con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, 
clrfmt_man);
+       break;
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ABGR8888:
        case DRM_FORMAT_XBGR2101010:
        case DRM_FORMAT_ABGR2101010:
-               return blend_mode == DRM_MODE_BLEND_COVERAGE ?
-                      OVL_CON_CLRFMT_ABGR8888 :
-                      OVL_CON_CLRFMT_PABGR8888;
+               if (blend_mode == DRM_MODE_BLEND_COVERAGE) {
+                       con = OVL_CON_CLRFMT_ARGB8888(clrfmt_shift);
+                       need_rgb_swap = true;   /* ARGB8888 -> ABGR8888 */
+               } else {
+                       con = OVL_CON_CLRFMT_PARGB8888(clrfmt_shift, 
clrfmt_man);
+                       need_rgb_swap = true;   /* PARGB8888 -> PABGR8888 */
+               }
+       break;
        case DRM_FORMAT_UYVY:
-               return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
+               con = OVL_CON_CLRFMT_UYVY(clrfmt_shift);
+       break;
        case DRM_FORMAT_YUYV:
-               return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;
+               con = OVL_CON_CLRFMT_YUYV(clrfmt_shift);
+       break;
        }
+
+       if (color_convert)
+               con |= OVL_CON_MTX_YUV_TO_RGB;
+
+       if (need_byte_swap)
+               con |= byte_swap;
+
+       if (need_rgb_swap)
+               con |= rgb_swap;
+
+       return con;
 }
 
 static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
@@ -495,7 +555,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
        unsigned int rotation = pending->rotation;
        unsigned int offset = (pending->y << 16) | pending->x;
        unsigned int src_size = (pending->height << 16) | pending->width;
-       unsigned int blend_mode = state->base.pixel_blend_mode;
+       unsigned int blend_mode = mtk_ovl_get_blend_mode(state, 
ovl->data->blend_modes);
        unsigned int ignore_pixel_alpha = 0;
        unsigned int con;
 
@@ -504,7 +564,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
                return;
        }
 
-       con = mtk_ovl_fmt_convert(ovl, state);
+       con = mtk_ovl_fmt_convert(fmt, blend_mode, ovl->data->fmt_rgb565_is_0, 
true,
+                                 12, OVL_CON_CLRFMT_MAN, OVL_CON_BYTE_SWAP, 
OVL_CON_RGB_SWAP);
        if (state->base.fb) {
                con |= state->base.alpha & OVL_CON_ALPHA;
 
@@ -512,17 +573,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
                 * For blend_modes supported SoCs, always enable alpha blending.
                 * For blend_modes unsupported SoCs, enable alpha blending when 
has_alpha is set.
                 */
-               if (blend_mode || state->base.fb->format->has_alpha)
+               if (state->base.pixel_blend_mode || 
state->base.fb->format->has_alpha)
                        con |= OVL_CON_AEN;
-
-               /*
-                * Although the alpha channel can be ignored, CONST_BLD must be 
enabled
-                * for XRGB format, otherwise OVL will still read the value 
from memory.
-                * For RGB888 related formats, whether CONST_BLD is enabled or 
not won't
-                * affect the result. Therefore we use !has_alpha as the 
condition.
-                */
-               if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || 
!state->base.fb->format->has_alpha)
-                       ignore_pixel_alpha = OVL_CONST_BLEND;
        }
 
        /*
@@ -548,6 +600,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
 
        mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
                              DISP_REG_OVL_CON(idx));
+
+       ignore_pixel_alpha = mtk_ovl_is_ignore_pixel_alpha(state, blend_mode) ? 
OVL_CONST_BLEND : 0;
        mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
                              &ovl->cmdq_reg, ovl->regs, 
DISP_REG_OVL_PITCH(idx));
        mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.h 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.h
new file mode 100644
index 000000000000..9bd5dc62d626
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025 MediaTek Inc.
+ */
+
+#ifndef __MTK_DISP_OVL_H__
+#define __MTK_DISP_OVL_H__
+
+bool mtk_ovl_is_10bit_rgb(unsigned int fmt);
+bool mtk_ovl_is_ignore_pixel_alpha(struct mtk_plane_state *state, unsigned int 
blend_mode);
+unsigned int mtk_ovl_get_blend_mode(struct mtk_plane_state *state, unsigned 
int blend_modes);
+unsigned int mtk_ovl_fmt_convert(unsigned int fmt, unsigned int blend_mode,
+                                bool fmt_rgb565_is_0, bool color_convert,
+                                u8 clrfmt_shift, u32 clrfmt_man, u32 
byte_swap, u32 rgb_swap);
+
+#endif
-- 
2.45.2

Reply via email to