drm/mediatek: Add support for AR30 and BA30 overlays
authorJustin Green <greenjustin@chromium.org>
Thu, 9 Mar 2023 21:06:23 +0000 (16:06 -0500)
committerChun-Kuang Hu <chunkuang.hu@kernel.org>
Sun, 12 Mar 2023 15:07:16 +0000 (15:07 +0000)
Add the ability for the Mediatek DRM driver to control
the bit depth register. If the DTS indicates the device supports
10-bit overlays and the current format has a fourcc of AR30, BA30,
or RA30, we set the bit depth register to 10 bit.

The next patch in the series actually enables 10-bit overlays for
MT8195 devices, but this current patch should be a no-op. This
patch was tested by simply running Chrome on an MT8195 and looking
for regressions.

Signed-off-by: Justin Green <greenjustin@chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20230309210623.1167567-1-greenjustin@chromium.org/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
drivers/gpu/drm/mediatek/mtk_disp_ovl.c

index 2a2cdcf558d1191fc8e747d0800b0e3eb91cf1f6..6228cd2c51d7004b3ee57bb730c1079afc422a0d 100644 (file)
@@ -42,6 +42,7 @@
 #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
+#define DISP_REG_OVL_CLRFMT_EXT                        0x02D0
 #define DISP_REG_OVL_ADDR_MT8173               0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)              ((ovl)->data->addr + 0x20 * (n))
 #define DISP_REG_OVL_HDR_ADDR(ovl, n)          ((ovl)->data->addr + 0x20 * (n) + 0x04)
                                        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_BIT_DEPTH_MASK(ovl)     (0xFF << 4 * (ovl))
+#define OVL_CON_CLRFMT_BIT_DEPTH(depth, ovl)   (depth << 4 * (ovl))
+#define OVL_CON_CLRFMT_8_BIT                   0x00
+#define OVL_CON_CLRFMT_10_BIT                  0x01
 #define        OVL_CON_AEN             BIT(8)
 #define        OVL_CON_ALPHA           0xff
 #define        OVL_CON_VIRT_FLIP       BIT(9)
@@ -90,6 +95,7 @@ struct mtk_disp_ovl_data {
        bool supports_afbc;
        const u32 *formats;
        size_t num_formats;
+       bool supports_clrfmt_ext;
 };
 
 /*
@@ -219,6 +225,30 @@ static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt *cmdq_pkt
                           DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
+static void mtk_ovl_set_bit_depth(struct device *dev, int idx, u32 format,
+                                 struct cmdq_pkt *cmdq_pkt)
+{
+       struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+       unsigned int reg;
+       unsigned int bit_depth = OVL_CON_CLRFMT_8_BIT;
+
+       if (!ovl->data->supports_clrfmt_ext)
+               return;
+
+       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)
+               bit_depth = OVL_CON_CLRFMT_10_BIT;
+
+       reg |= OVL_CON_CLRFMT_BIT_DEPTH(bit_depth, idx);
+
+       mtk_ddp_write(cmdq_pkt, reg, &ovl->cmdq_reg,
+                     ovl->regs, DISP_REG_OVL_CLRFMT_EXT);
+}
+
 void mtk_ovl_config(struct device *dev, unsigned int w,
                    unsigned int h, unsigned int vrefresh,
                    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -333,9 +363,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
                return OVL_CON_CLRFMT_ARGB8888;
        case DRM_FORMAT_BGRX8888:
        case DRM_FORMAT_BGRA8888:
+       case DRM_FORMAT_BGRA1010102:
                return OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP;
        case DRM_FORMAT_XRGB8888:
        case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ARGB2101010:
                return OVL_CON_CLRFMT_RGBA8888;
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ABGR8888:
@@ -419,6 +451,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
                                      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
        }
 
+       mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
        mtk_ovl_layer_on(dev, idx, cmdq_pkt);
 }