Re: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL

2024-03-01 Thread 胡俊光


Re: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL

2024-02-15 Thread 宋孝謙


Re: [PATCH v5 08/13] drm/mediatek: Support alpha blending in OVL

2024-02-15 Thread AngeloGioacchino Del Regno

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 
---
  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_BLENDBIT(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_RGBA   (2 << 12)
  #define OVL_CON_CLRFMT_ARGB   (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_PARGB   (OVL_CON_CLRFMT_ARGB | 
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_XRGB,
DRM_FORMAT_ARGB,
@@ -89,12 +109,20 @@ static const u32 mt8173_formats[] = {
  static const u32 mt8195_formats[] = {
DRM_FORMAT_XRGB,
DRM_FORMAT_ARGB,
+   DRM_FORMAT_XRGB2101010,
DRM_FORMAT_ARGB2101010,
DRM_FORMAT_BGRX,
DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRX1010102,
DRM_FORMAT_BGRA1010102,
DRM_FORMAT_ABGR,
DRM_FORMAT_XBGR,
+   DRM_FORMAT_XBGR2101010,
+   DRM_FORMAT_ABGR2101010,
+   DRM_FORMAT_RGBX,
+   DRM_FORMAT_RGBA,
+   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, 0xff00, &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