Il 15/02/24 11:11, Hsiao Chien Sung ha scritto:
Support "Pre-multiplied" and "None" blend mode on MediaTek's chips.
Before this patch, only the "Coverage" mode is supported.

Please refer to the description of the commit
"drm/mediatek: Support alpha blending in display driver"
for more information.

Signed-off-by: Hsiao Chien Sung <shawn.s...@mediatek.com>
---
  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 83 +++++++++++++++++++++----
  1 file changed, 72 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index c42fce38a35eb..98c989fddcc08 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -39,6 +39,7 @@
  #define DISP_REG_OVL_PITCH_MSB(n)             (0x0040 + 0x20 * (n))
  #define OVL_PITCH_MSB_2ND_SUBBUF                      BIT(16)
  #define DISP_REG_OVL_PITCH(n)                 (0x0044 + 0x20 * (n))
+#define OVL_CONST_BLEND                                        BIT(28)
  #define DISP_REG_OVL_RDMA_CTRL(n)             (0x00c0 + 0x20 * (n))
  #define DISP_REG_OVL_RDMA_GMC(n)              (0x00c8 + 0x20 * (n))
  #define DISP_REG_OVL_ADDR_MT2701              0x0040
@@ -52,13 +53,16 @@
  #define GMC_THRESHOLD_HIGH    ((1 << GMC_THRESHOLD_BITS) / 4)
  #define GMC_THRESHOLD_LOW     ((1 << GMC_THRESHOLD_BITS) / 8)
+#define OVL_CON_CLRFMT_MAN BIT(23)
  #define OVL_CON_BYTE_SWAP     BIT(24)
-#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
+#define OVL_CON_RGB_SWAP       BIT(25)
  #define OVL_CON_CLRFMT_RGB    (1 << 12)
  #define OVL_CON_CLRFMT_RGBA8888       (2 << 12)
  #define OVL_CON_CLRFMT_ARGB8888       (3 << 12)
  #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       (OVL_CON_CLRFMT_ARGB8888 | 
OVL_CON_CLRFMT_MAN)
  #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 ? \
@@ -72,6 +76,22 @@
  #define       OVL_CON_VIRT_FLIP       BIT(9)
  #define       OVL_CON_HORZ_FLIP       BIT(10)
+static inline bool is_10bit_rgb(u32 fmt)
+{
+       switch (fmt) {
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_ARGB2101010:
+       case DRM_FORMAT_RGBX1010102:
+       case DRM_FORMAT_RGBA1010102:
+       case DRM_FORMAT_XBGR2101010:
+       case DRM_FORMAT_ABGR2101010:
+       case DRM_FORMAT_BGRX1010102:
+       case DRM_FORMAT_BGRA1010102:
+               return true;
+       }
+       return false;
+}
+
  static const u32 mt8173_formats[] = {
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_ARGB8888,
@@ -89,12 +109,20 @@ static const u32 mt8173_formats[] = {
  static const u32 mt8195_formats[] = {
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_ARGB8888,
+       DRM_FORMAT_XRGB2101010,
        DRM_FORMAT_ARGB2101010,
        DRM_FORMAT_BGRX8888,
        DRM_FORMAT_BGRA8888,
+       DRM_FORMAT_BGRX1010102,
        DRM_FORMAT_BGRA1010102,
        DRM_FORMAT_ABGR8888,
        DRM_FORMAT_XBGR8888,
+       DRM_FORMAT_XBGR2101010,
+       DRM_FORMAT_ABGR2101010,
+       DRM_FORMAT_RGBX8888,
+       DRM_FORMAT_RGBA8888,
+       DRM_FORMAT_RGBX1010102,
+       DRM_FORMAT_RGBA1010102,
        DRM_FORMAT_RGB888,
        DRM_FORMAT_BGR888,
        DRM_FORMAT_RGB565,
@@ -254,9 +282,7 @@ static void mtk_ovl_set_bit_depth(struct device *dev, int 
idx, u32 format,
        reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
        reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
- if (format == DRM_FORMAT_RGBA1010102 ||
-           format == DRM_FORMAT_BGRA1010102 ||
-           format == DRM_FORMAT_ARGB2101010)
+       if (is_10bit_rgb(format))
                bit_depth = OVL_CON_CLRFMT_10_BIT;
reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
@@ -274,7 +300,13 @@ void mtk_ovl_config(struct device *dev, unsigned int w,
        if (w != 0 && h != 0)
                mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, 
ovl->regs,
                                      DISP_REG_OVL_ROI_SIZE);
-       mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, 
DISP_REG_OVL_ROI_BGCLR);
+
+       /*
+        * The background color should be opaque black (ARGB),
+        * otherwise there will be no effect with alpha blend
+        */
+       mtk_ddp_write_relaxed(cmdq_pkt, 0xff000000, &ovl->cmdq_reg,
+                             ovl->regs, DISP_REG_OVL_ROI_BGCLR);

Multiple (all of?) OVL color registers, like{L0-3,EL0-2}_YUV1BIT_COLOR(x),
ROI_BGCLR, L{0-3}_CLR and others do follow this exact layout:

#define OVL_COLOR_ALPHA                         GENMASK(31, 24)
#define OVL_COLOR_GREEN                         GENMASK(23, 16)
#define OVL_COLOR_RED                           GENMASK(15, 8)
#define OVL_COLOR_BLUE                          GENMASK(7, 0)

...so we can define those as they're valid for multiple registers, and then
we can use the definition instead of an apparently random value.

/*
 * The background color should be opaque black (ARGB),
 * otherwise there will be no effect with alpha blend
 */
mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,
                      ovl->regs, DISP_REG_OVL_ROI_BGCLR);

Everything else looks ok.

Regards,
Angelo

Reply via email to