[PATCH RESEND] drm/mediatek: Add 0 size check to mtk_drm_gem_obj

2024-03-07 Thread Justin Green
Add a check to mtk_drm_gem_init if we attempt to allocate a GEM object
of 0 bytes. Currently, no such check exists and the kernel will panic if
a userspace application attempts to allocate a 0x0 GBM buffer.

Tested by attempting to allocate a 0x0 GBM buffer on an MT8188 and
verifying that we now return EINVAL.

Fixes: 119f5173628a ("drm/mediatek: Add DRM Driver for Mediatek SoC MT8173.")
Signed-off-by: Justin green 
Reviewed-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_drm_gem.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c 
b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 4f2e3feabc0f..ee49367b6138 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -38,6 +38,9 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct 
drm_device *dev,
 
size = round_up(size, PAGE_SIZE);
 
+if (size == 0)
+   return ERR_PTR(-EINVAL);
+
mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL);
if (!mtk_gem_obj)
return ERR_PTR(-ENOMEM);
-- 
2.44.0.278.ge034bb2e1d-goog



[PATCH] drm/mediatek: Add 0 size check to mtk_drm_gem_obj

2024-03-06 Thread Justin Green
Add a check to mtk_drm_gem_init if we attempt to allocate a GEM object
of 0 bytes. Currently, no such check exists and the kernel will panic if
a userspace application attempts to allocate a 0x0 GBM buffer.

Tested by attempting to allocate a 0x0 GBM buffer on an MT8188 and
verifying that we now return EINVAL.

Signed-off-by: Justin green 
---
 drivers/gpu/drm/mediatek/mtk_drm_gem.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_gem.c 
b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
index 4f2e3feabc0f..ee49367b6138 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -38,6 +38,9 @@ static struct mtk_drm_gem_obj *mtk_drm_gem_init(struct 
drm_device *dev,
 
size = round_up(size, PAGE_SIZE);
 
+if (size == 0)
+   return ERR_PTR(-EINVAL);
+
mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL);
if (!mtk_gem_obj)
return ERR_PTR(-ENOMEM);
-- 
2.44.0.278.ge034bb2e1d-goog



[PATCH] drm/mediatek: Add MT8188 Overlay Driver Data

2024-02-21 Thread Justin Green
Add MT8188 overlay driver configuration data. This change consequently
enables 10-bit overlay support on MT8188 devices.

Tested by running ChromeOS UI on MT8188 and using modetest -P. AR30 and
BA30 overlays are confirmed to work from modetest.

Signed-off-by: Justin Green 
Tested-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 2bffe4245466..696aabe124c2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -635,6 +635,17 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.supports_clrfmt_ext = true,
 };
 
+static const struct mtk_disp_ovl_data mt8188_ovl_driver_data = {
+   .addr = DISP_REG_OVL_ADDR_MT8173,
+   .gmc_bits = 10,
+   .layer_nr = 4,
+   .fmt_rgb565_is_0 = true,
+   .smi_id_en = true,
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
+   .supports_clrfmt_ext = true,
+};
+
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
{ .compatible = "mediatek,mt2701-disp-ovl",
  .data = _ovl_driver_data},
@@ -650,6 +661,8 @@ static const struct of_device_id 
mtk_disp_ovl_driver_dt_match[] = {
  .data = _ovl_2l_driver_data},
{ .compatible = "mediatek,mt8195-disp-ovl",
  .data = _ovl_driver_data},
+   { .compatible = "mediatek,mt8188-disp-ovl",
+ .data = _ovl_driver_data},
{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_ovl_driver_dt_match);
-- 
2.44.0.rc0.258.g7320e95886-goog



Re: [PATCH RESEND] drm/mediatek: Add valid modifier check

2023-08-03 Thread Justin Green
> See c91acda3a380 ("drm/gem: Check for valid formats") and the related gem
fb helper functions to see how this is supposed to be done.

Oh that's interesting, so does this imply that the infrastructure
automatically calls format_mod_supported() during framebuffer
creation? In that case, this entire patch might be unnecessary in the
tip of tree kernel.

On Thu, Aug 3, 2023 at 4:24 AM Daniel Vetter  wrote:
>
> On Mon, Jul 24, 2023 at 01:58:39PM -0400, Justin Green wrote:
> > Add a check to mtk_drm_mode_fb_create() that rejects any modifier that
> > is not the AFBC mode supported by MT8195's display overlays.
> >
> > Tested by booting ChromeOS and verifying the UI works, and by running
> > the ChromeOS kms_addfb_basic binary, which has a test called
> > "addfb25-bad-modifier" that attempts to create a framebuffer with the
> > modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns
> > EINVAL.
> >
> > Signed-off-by: Justin Green 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
> > b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > index cd5b18ef7951..2096e8a794ad 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> > @@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev,
> >   if (info->num_planes != 1)
> >   return ERR_PTR(-EINVAL);
> >
> > + if (cmd->modifier[0] &&
> > + cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC(
> > + AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
> > + AFBC_FORMAT_MOD_SPLIT |
> > + AFBC_FORMAT_MOD_SPARSE))
> > + return ERR_PTR(-EINVAL);
>
> If you set the modifiers/format properties correctly and use all the
> helpers then the drm core should already validate that only formats you
> can use are allowed.
>
> See c91acda3a380 ("drm/gem: Check for valid formats") and the related gem
> fb helper functions to see how this is supposed to be done. These kind of
> checks in driver code for gem drivers (which really is everyone at this
> point) should not be needed at all.
>
> Cheers, Sima
>
> > +
> >   return drm_gem_fb_create(dev, file, cmd);
> >  }
> >
> > --
> > 2.41.0.162.gfafddb0af9-goog
> >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch


Re: [PATCH RESEND] drm/mediatek: Add valid modifier check

2023-07-27 Thread Justin Green
> ...so that a per-plane logic in mtk_drm_plane can be easily added, because...
I think my concern is more that if we need to validate the format and
the modifier differently because of the plane data, then this method
would provide limited value. For example, on my MT8195, plane ID 38
supports AR30 and BA30, but plane ID 50 does not support any 10-bit
pixel formats.

On Thu, Jul 27, 2023 at 5:37 AM AngeloGioacchino Del Regno
 wrote:
>
> Il 26/07/23 21:44, Justin Green ha scritto:
> >> Would it make more sense to commmonize function 
> >> mtk_plane_format_mod_supported()
> >> and call that one here instead?
> > I had considered that, but mtk_plane_format_mod_supported() is
> > required to take a drm_plane as a parameter in order to conform to the
> > type signature defined in drm_plane_funcs, but
> > mtk_drm_mode_fb_create() does not have a drm_plane to provide, since
> > the framebuffer is created later in the function. Technically we don't
> > actually use the drm_plane in the implementation of
> > mtk_plane_format_mod_supported() today, so we could just use a null
> > pointer, but I figured we may one day need to add per-plane logic.
> >
>
> My suggestion was not to use that function as-is, but rather to add a helper 
> like
>
> bool mtk_format_modifier_supported(u32 format, u32 modifier) { ... }
>
> ...so that a per-plane logic in mtk_drm_plane can be easily added, because...
>
> static bool mtk_plane_format_mod_supported(struct drm_plane *plane,
>u32 format, u32 modifier)
> {
> return mtk_format_modifier_supported(format, modifier);
> }
>
> so apart from that, is there any other reason to not do that? :-)
>
> Regards,
> Angelo
>
> >> This is not DRM_FORMAT_MOD_INVALID. Please either explicitly compare 
> >> against INVALID if that's what you meant, or against LINEAR if that's what 
> >> you meant, or both.
> > Ack, I meant to use LINEAR. Will update for the next version of the patch.
>
>


[PATCH v2] drm/mediatek: Add valid modifier check

2023-07-26 Thread Justin Green
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that
is not the AFBC mode supported by MT8195's display overlays.

Tested by booting ChromeOS and verifying the UI works, and by running
the ChromeOS kms_addfb_basic binary, which has a test called
"addfb25-bad-modifier" that attempts to create a framebuffer with the
modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns
EINVAL.

Signed-off-by: Justin Green 
Tested-by: Fei Shao 
---
v2:
 * Replace zero check with comparison to DRM_FORMAT_MOD_LINEAR.

 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cd5b18ef7951..2719a1e3163a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev,
if (info->num_planes != 1)
return ERR_PTR(-EINVAL);
 
+   if (cmd->modifier[0] != DRM_FORMAT_MOD_LINEAR &&
+   cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC(
+   AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return ERR_PTR(-EINVAL);
+
return drm_gem_fb_create(dev, file, cmd);
 }
 
-- 
2.41.0.487.g6d72f3e995-goog



Re: [PATCH RESEND] drm/mediatek: Add valid modifier check

2023-07-26 Thread Justin Green
> Would it make more sense to commmonize function 
> mtk_plane_format_mod_supported()
> and call that one here instead?
I had considered that, but mtk_plane_format_mod_supported() is
required to take a drm_plane as a parameter in order to conform to the
type signature defined in drm_plane_funcs, but
mtk_drm_mode_fb_create() does not have a drm_plane to provide, since
the framebuffer is created later in the function. Technically we don't
actually use the drm_plane in the implementation of
mtk_plane_format_mod_supported() today, so we could just use a null
pointer, but I figured we may one day need to add per-plane logic.

> This is not DRM_FORMAT_MOD_INVALID. Please either explicitly compare against 
> INVALID if that's what you meant, or against LINEAR if that's what you meant, 
> or both.
Ack, I meant to use LINEAR. Will update for the next version of the patch.


[PATCH RESEND] drm/mediatek: Add valid modifier check

2023-07-24 Thread Justin Green
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that
is not the AFBC mode supported by MT8195's display overlays.

Tested by booting ChromeOS and verifying the UI works, and by running
the ChromeOS kms_addfb_basic binary, which has a test called
"addfb25-bad-modifier" that attempts to create a framebuffer with the
modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns
EINVAL.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cd5b18ef7951..2096e8a794ad 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev,
if (info->num_planes != 1)
return ERR_PTR(-EINVAL);
 
+   if (cmd->modifier[0] &&
+   cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC(
+   AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return ERR_PTR(-EINVAL);
+
return drm_gem_fb_create(dev, file, cmd);
 }
 
-- 
2.41.0.162.gfafddb0af9-goog



[PATCH] drm/mediatek: Add valid modifier check

2023-06-13 Thread Justin Green
Add a check to mtk_drm_mode_fb_create() that rejects any modifier that
is not the AFBC mode supported by MT8195's display overlays.

Tested by booting ChromeOS and verifying the UI works, and by running
the ChromeOS kms_addfb_basic binary, which has a test called
"addfb25-bad-modifier" that attempts to create a framebuffer with the
modifier DRM_FORMAT_MOD_INVALID and verifies the ADDFB2 ioctl returns
EINVAL.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c 
b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index cd5b18ef7951..2096e8a794ad 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -51,6 +51,13 @@ mtk_drm_mode_fb_create(struct drm_device *dev,
if (info->num_planes != 1)
return ERR_PTR(-EINVAL);
 
+   if (cmd->modifier[0] &&
+   cmd->modifier[0] != DRM_FORMAT_MOD_ARM_AFBC(
+   AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return ERR_PTR(-EINVAL);
+
return drm_gem_fb_create(dev, file, cmd);
 }
 
-- 
2.41.0.162.gfafddb0af9-goog



[PATCH v8 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
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 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,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, >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)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v8 1/3] drm/mediatek: Refactor pixel format logic

2023-03-09 Thread Justin Green
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 mt8173_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   const u32 *formats;
+   size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data 
mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data 
mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data 
mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mt

[PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
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 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,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, >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)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-09 Thread Justin Green
Hi Chun-Kuang,
Thanks for the review! This patch was tested like the previous one, by
running Chrome on an MT8195 and looking for regressions. I'll post a
new series with the updated patch descriptions.

Regards,
Justin

On Wed, Mar 8, 2023 at 6:34 PM Chun-Kuang Hu  wrote:
>
> Hi, Justin:
>
> Justin Green  於 2023年3月8日 週三 下午11:34寫道:
> >
> > Tested using "modetest -P" on an MT8195 device.
>
> I think you could not test this when only apply the first two patches
> of this series, so move the test information to the third patch. In
> this patch, you could describe more about what and why this patch
> does. The other modification looks good to me.
>
> Regards,
> Chun-Kuang.
>
> >
> > Signed-off-by: Justin Green 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
> >  1 file changed, 33 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 8743c8047dc9..a6255e847104 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -41,6 +41,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_EXT0x02D0
> >  #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)
> > @@ -61,6 +62,10 @@
> > 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
> >  #defineOVL_CON_AEN BIT(8)
> >  #defineOVL_CON_ALPHA   0xff
> >  #defineOVL_CON_VIRT_FLIP   BIT(9)
> > @@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
> > bool supports_afbc;
> > const u32 *formats;
> > size_t num_formats;
> > +   bool supports_clrfmt_ext;
> >  };
> >
> >  /*
> > @@ -218,6 +224,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, >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)
> > @@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct 
> > mtk_disp_ovl *ovl, unsigned int fmt)
> > return OVL_CON_CLRFMT_ARGB;
> > case DRM_FORMAT_BGRX:
> > case DRM_FORMAT_BGRA:
> > +   case DRM_FORMAT_BGRA1010102:
> > return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
> > case DRM_FORMAT_XRGB:
> > case DRM_FORMAT_ARGB:
> > +   case DRM_FORMAT_ARGB2101010:
> > return OVL_CON_CLRFMT_RGBA;
> > case DRM_FORMAT_XBGR:
> > case DRM_FORMAT_ABGR:
> > @@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
> > int idx,
> >   >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);
> >  }
> >
> > --
> > 2.39.1.456.gfc5497dd1b-goog
> >


[PATCH v8 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195

2023-03-09 Thread Justin Green
Modify the overlay driver data for MT8195 to enable bit depth control and
enable support for AR30 and BA30 framebuffer formats. This patch in
combination with the previous two patches in the series will allow MT8195
devices to scanout AR30 and BA30 framebuffers.

Tested using "modetest -P" on an MT8195 device. The test pattern displays
correctly for both AR30 and BA30 formats.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a6255e847104..7d26f7055751 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = {
DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
-   .formats = mt8173_formats,
-   .num_formats = ARRAY_SIZE(mt8173_formats),
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
+   .supports_clrfmt_ext = true,
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v8 0/3] drm/mediatek: Add support for 10-bit overlays

2023-03-09 Thread Justin Green
This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
lay the groundwork for supporting more 10-bit formats on more devices.

1. Refactor plane initialization logic to allow individual DDP components to
provide their supported pixel formats.

2. Add AR30 and BA30 support to overlay driver.

3. Enable AR30 and BA30 overlays on MT8195.


Version history:
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.
v7:
 * Gate setting OVL_CLRFMT_EXT register on compatibility.
 * Split patches for adding 10-bit support and enabling 10-bit support on
   MT8195.
v8:
 * Updated descriptions for patches 2 and 3 in the series.


Justin Green (3):
  drm/mediatek: Refactor pixel format logic
  drm/mediatek: Add support for AR30 and BA30 overlays
  drm/mediatek: Enable AR30 and BA30 overlays on MT8195

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 173 insertions(+), 18 deletions(-)

-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v7 RESEND 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195

2023-03-08 Thread Justin Green
Tested using "modetest -P" on an MT8195 device.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a6255e847104..7d26f7055751 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = {
DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
-   .formats = mt8173_formats,
-   .num_formats = ARRAY_SIZE(mt8173_formats),
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
+   .supports_clrfmt_ext = true,
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v7 RESEND 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-03-08 Thread Justin Green
Tested using "modetest -P" on an MT8195 device.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,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, >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)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH v7 RESEND 1/3] drm/mediatek: Refactor pixel format logic

2023-03-08 Thread Justin Green
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 mt8173_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   const u32 *formats;
+   size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data 
mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data 
mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data 
mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mt

[PATCH v7 RESEND 0/3] drm/mediatek: Add support for 10-bit overlays

2023-03-08 Thread Justin Green
This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
lay the groundwork for supporting more 10-bit formats on more devices.

1. Refactor plane initialization logic to allow individual DDP components to
provide their supported pixel formats.

2. Add AR30 and BA30 support to overlay driver.

3. Enable AR30 and BA30 overlays on MT8195.


Version history:
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.
v7:
 * Gate setting OVL_CLRFMT_EXT register on compatibility.
 * Split patches for adding 10-bit support and enabling 10-bit support on
   MT8195.


Justin Green (3):
  drm/mediatek: Refactor pixel format logic
  drm/mediatek: Add support for AR30 and BA30 overlays
  drm/mediatek: Enable AR30 and BA30 overlays on MT8195

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 173 insertions(+), 18 deletions(-)

-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH 1/3] drm/mediatek: Refactor pixel format logic

2023-02-02 Thread Justin Green
> Yes, I had a comment on the naming in that patch. Never the less, I think if 
> we
> don't need to "overwrite" the value, we should use just one struct for the
> values instead of copying them to the different .c files and give them SoC
> specific names.
I don't have a very strong opinion about this, and in fact that is how
v1 of the patch worked, but Chun-Kuang specifically suggested moving
that struct into the .c files a few versions back. I think it makes
sense if we expect additional skew between the different components
and what pixel formats they support.


Re: [PATCH 1/3] drm/mediatek: Refactor pixel format logic

2023-02-02 Thread Justin Green
Hi Matthias,

> mt8173_formats are the same as the old struct formats. Maybe we should use 
> that
> and only overwrite where we actually use a different array.
I think this was sort of how the original patch worked, but we wanted
to add some flexibility to allow different components to support
different formats. In patch 3 of the series, we actually overwrite
this field with mt8195_formats.

> Why can't we use ARRAY_SIZE(formats) here like we did before?
I think ARRAY_SIZE is just a macro for getting the length of
statically allocated arrays. Because we won't know until runtime which
list of pixel formats we will be using, I'm not sure we can use that
in this circumstance?

Regards,
Justin


[PATCH 3/3] drm/mediatek: Enable AR30 and BA30 overlays on MT8195

2023-02-01 Thread Justin Green
Tested using "modetest -P" on an MT8195 device.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index a6255e847104..7d26f7055751 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -85,6 +85,22 @@ static const u32 mt8173_formats[] = {
DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -616,8 +632,9 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
-   .formats = mt8173_formats,
-   .num_formats = ARRAY_SIZE(mt8173_formats),
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
+   .supports_clrfmt_ext = true,
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH 2/3] drm/mediatek: Add support for AR30 and BA30 overlays

2023-02-01 Thread Justin Green
Tested using "modetest -P" on an MT8195 device.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 33 +
 1 file changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..a6255e847104 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -89,6 +94,7 @@ struct mtk_disp_ovl_data {
bool supports_afbc;
const u32 *formats;
size_t num_formats;
+   bool supports_clrfmt_ext;
 };
 
 /*
@@ -218,6 +224,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, >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)
@@ -332,9 +362,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +450,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH 1/3] drm/mediatek: Refactor pixel format logic

2023-02-01 Thread Justin Green
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 mt8173_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   const u32 *formats;
+   size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data 
mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data 
mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data 
mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mt

[PATCH 0/3 v7] drm/mediatek: Add support for 10-bit overlays

2023-02-01 Thread Justin Green
This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
lay the groundwork for supporting more 10-bit formats on more devices.

1. Refactor plane initialization logic to allow individual DDP components to
provide their supported pixel formats.

2. Add AR30 and BA30 support to overlay driver.

3. Enable AR30 and BA30 overlays on MT8195.


Version history:
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.
v7:
 * Gate setting OVL_CLRFMT_EXT register on compatibility.
 * Split patches for adding 10-bit support and enabling 10-bit support on
   MT8195.


Justin Green (3):
  drm/mediatek: Refactor pixel format logic
  drm/mediatek: Add support for AR30 and BA30 overlays
  drm/mediatek: Enable AR30 and BA30 overlays on MT8195

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 94 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 173 insertions(+), 18 deletions(-)

-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH 2/2] drm/mediatek: Add support for AR30 and BA30 overlays

2023-02-01 Thread Justin Green
Hi Chun-Kuang,

> Does all SoC have this register? If no, you should write this register
> for the SoC have this register.

I can't confirm this from the documentation that I have, I can only
confirm this register exists on MT8195 and MT8186. I will send out
another patch.

Thanks,
Justin


Re: [PATCH v5] drm/mediatek: Add support for AR30 and BA30

2023-02-01 Thread Justin Green
Hi Chun-Kuang,
These two series are independent, so my preference would be to apply
whichever series becomes ready first. There won't technically be a
merge conflict, but I think the ovl-adaptor component will fail to
initialize correctly once the first patch of this series lands,
because the ovl-adaptor patch series does not yet implement the
get_formats() interface. I can send a follow-up patch after the
ovl-adaptor series lands, or let Nancy know about the potential
runtime issue.

Regards,
Justin

On Wed, Feb 1, 2023 at 10:30 AM Chun-Kuang Hu  wrote:
>
> Hi, Justin:
>
> Justin Green  於 2023年1月31日 週二 下午11:04寫道:
> >
> > Hi Chun-Kuang,
> > Thanks for the review! Will try to have a new patch out later today.
> >
> > Re MT8195 RDMA: Yes, the MT8195 RDMA has a 10 bit mode, but I left
> > this unimplemented because I have no means of testing it
> > unfortunately; ChromeOS does not use this hardware.
> >
> > I also wanted to mention, I think this patch might conflict with the
> > in-flight ovl-adaptor patch. Is there a protocol for a situation like
> > this?
>
> If I prefer the order of the two series, I would told you. But I have
> no preference of these two series, so you may decide these two serious
> are independent or dependent. If independent, I would apply the one
> which is ready first, so the other one should rebase. If dependent,
> you should discuss with Nancy the order of these two serious, the
> second series should rebase on first series.
>
> Regards,
> Chun-Kuang.
>
> >
> > Regards,
> > Justin
> >
> > On Mon, Jan 30, 2023 at 7:28 PM Chun-Kuang Hu  
> > wrote:
> > >
> > > Hi, Justin:
> > >
> > > Justin Green  於 2023年1月31日 週二 上午4:36寫道:
> > > >
> > > > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.
> > > >
> > > > Tested using "modetest -P" on an MT8195.
> > > >
> > > > Signed-off-by: Justin Green 
> > > > ---
> > > > v2:
> > > >  * Rebase and resolve merge conflicts with the AFBC patch.
> > > > v3:
> > > >  * Moved 10-bit support detection to mtk_disk_ovl.c
> > > > v4:
> > > >  * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
> > > > v5:
> > > >  * Minor style adjustments per checkpatch.pl
> > > >
> > > >  drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
> > > >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
> > > >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
> > > >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
> > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
> > > >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
> > > >  drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
> > > >  drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
> > > >  8 files changed, 146 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
> > > > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > > index 33e61a136bbc..6ad22ce75b81 100644
> > > > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > > > @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
> > > >  void mtk_ovl_unregister_vblank_cb(struct device *dev);
> > > >  void mtk_ovl_enable_vblank(struct device *dev);
> > > >  void mtk_ovl_disable_vblank(struct device *dev);
> > > > +const u32 *mtk_ovl_get_formats(struct device *dev);
> > > > +size_t mtk_ovl_get_num_formats(struct device *dev);
> > > >
> > > >  void mtk_rdma_bypass_shadow(struct device *dev);
> > > >  int mtk_rdma_clk_enable(struct device *dev);
> > > > @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct 
> > > > cmdq_pkt *cmdq_pkt);
> > > >  void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
> > > >  void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg 
> > > > *cfg,
> > > >  struct cmdq_pkt *cmdq_pkt);
> > > > +const u32 *mtk_rdma_get_formats(struct device *dev);
> > > > +size_t mtk_rdma_get_num_formats(struct device *dev);
> > > >  #endif
> > > > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > > > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > > > index 84daeaffab6a..1db70a775

Re: [PATCH 0/2 v6] drm/mediatek: Add support for 10-bit overlays

2023-01-31 Thread Justin Green
My apologies, I accidentally mangled the version history. It should
actually read:

v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.

On Tue, Jan 31, 2023 at 3:08 PM Justin Green  wrote:
>
> This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
> Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
> lay the groundwork for supporting more 10-bit formats on more devices.
>
> 1. Refactor plane initialization logic to allow individual DDP components to
> provide their supported pixel formats.
>
> 2. Add AR30 and BA30 support to the MT8195 overlay driver.
>
>
> Version history:
> v6:
>  * Refactor patch into patch series.
>  * Add formats directly to private data.
>
> v5:
> * Removed some dead defines.
> * Refactored mtk_ovl_set_afbc().
>
> v4:
> * Move modifier validation to format_mod_supported function.
> * Add modifiers to drm_universal_plane_init() call.
> * Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on
>   DRM_FORMAT_LINEAR being equal to 0.
> * Gate AFBC control bit writes on device compatibility.
>
> v3:
> * Replaced pitch bitshift math with union based approach.
> * Refactored overlay register writes to shared code between non-AFBC and
>   AFBC.
> * Minor code cleanups.
>
> v2:
> * Marked mtk_ovl_set_afbc as static.
> * Reflowed some lines to fit column limit.
>
>
> Justin Green (2):
>   drm/mediatek: Refactor pixel format logic
>   drm/mediatek: Add support for AR30 and BA30 overlays
>
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
>  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 89 +
>  drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
>  drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
>  drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
>  8 files changed, 168 insertions(+), 18 deletions(-)
>
> --
> 2.39.1.456.gfc5497dd1b-goog
>


[PATCH 1/2] drm/mediatek: Refactor pixel format logic

2023-01-31 Thread Justin Green
Add an DDP component interface for querying pixel format support and move list
of supported pixel formats into DDP components instead of mtk_drm_plane.c

Tested by running Chrome on an MT8195.

Signed-off-by: Justin Green 

edit1
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 44 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 123 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..0df6a06defb8 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -115,6 +117,8 @@ void mtk_rdma_register_vblank_cb(struct device *dev,
 void mtk_rdma_unregister_vblank_cb(struct device *dev);
 void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..8743c8047dc9 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -66,6 +66,20 @@
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 mt8173_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +87,8 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   const u32 *formats;
+   size_t num_formats;
 };
 
 /*
@@ -138,6 +154,20 @@ void mtk_ovl_disable_vblank(struct device *dev)
writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
+const u32 *mtk_ovl_get_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->formats;
+}
+
+size_t mtk_ovl_get_num_formats(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->num_formats;
+}
+
 int mtk_ovl_clk_enable(struct device *dev)
 {
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
@@ -495,6 +525,8 @@ static const struct mtk_disp_ovl_data 
mt2701_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = false,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8173_ovl_driver_data = {
@@ -502,6 +534,8 @@ static const struct mtk_disp_ovl_data 
mt8173_ovl_driver_data = {
.gmc_bits = 8,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_driver_data = {
@@ -509,6 +543,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_driver_data = {
.gmc_bits = 10,
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8183_ovl_2l_driver_data = {
@@ -516,6 +552,8 @@ static const struct mtk_disp_ovl_data 
mt8183_ovl_2l_driver_data = {
.gmc_bits = 10,
.layer_nr = 2,
.fmt_rgb565_is_0 = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = {
@@ -524,6 +562,8 @@ static const struct mtk_disp_ovl_data 
mt8192_ovl_driver_data = {
.layer_nr = 4,
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
+   .formats = mt8173_formats,
+   .num_formats = ARRAY_SIZE(mt8173_formats),
 };
 
 static const struct mt

[PATCH 2/2] drm/mediatek: Add support for AR30 and BA30 overlays

2023-01-31 Thread Justin Green
Add support for overlays with pixel formats AR30 and BA30 on MT8195.

Tested using "modetest -P" on an MT8195 device.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 49 -
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 8743c8047dc9..cd2f9a156456 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -80,6 +85,22 @@ static const u32 mt8173_formats[] = {
DRM_FORMAT_YUYV,
 };
 
+static const u32 mt8195_formats[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -218,6 +239,27 @@ 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;
+
+   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, >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)
@@ -332,9 +374,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -418,6 +462,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
@@ -583,8 +628,8 @@ static const struct mtk_disp_ovl_data 
mt8195_ovl_driver_data = {
.fmt_rgb565_is_0 = true,
.smi_id_en = true,
.supports_afbc = true,
-   .formats = mt8173_formats,
-   .num_formats = ARRAY_SIZE(mt8173_formats),
+   .formats = mt8195_formats,
+   .num_formats = ARRAY_SIZE(mt8195_formats),
 };
 
 static const struct of_device_id mtk_disp_ovl_driver_dt_match[] = {
-- 
2.39.1.456.gfc5497dd1b-goog



[PATCH 0/2 v6] drm/mediatek: Add support for 10-bit overlays

2023-01-31 Thread Justin Green
This patch series adds support for 10-bit overlays to the Mediatek DRM driver.
Specifically, we add support for AR30 and BA30 overlays on MT8195 devices and
lay the groundwork for supporting more 10-bit formats on more devices.

1. Refactor plane initialization logic to allow individual DDP components to
provide their supported pixel formats.

2. Add AR30 and BA30 support to the MT8195 overlay driver.


Version history:
v6:
 * Refactor patch into patch series.
 * Add formats directly to private data.

v5:
* Removed some dead defines.
* Refactored mtk_ovl_set_afbc().

v4:
* Move modifier validation to format_mod_supported function.
* Add modifiers to drm_universal_plane_init() call.
* Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on
  DRM_FORMAT_LINEAR being equal to 0.
* Gate AFBC control bit writes on device compatibility.

v3:
* Replaced pitch bitshift math with union based approach.
* Refactored overlay register writes to shared code between non-AFBC and
  AFBC.
* Minor code cleanups.

v2:
* Marked mtk_ovl_set_afbc as static.
* Reflowed some lines to fit column limit.


Justin Green (2):
  drm/mediatek: Refactor pixel format logic
  drm/mediatek: Add support for AR30 and BA30 overlays

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 89 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 38 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 24 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 168 insertions(+), 18 deletions(-)

-- 
2.39.1.456.gfc5497dd1b-goog



Re: [PATCH v5] drm/mediatek: Add support for AR30 and BA30

2023-01-31 Thread Justin Green
Hi Chun-Kuang,
Thanks for the review! Will try to have a new patch out later today.

Re MT8195 RDMA: Yes, the MT8195 RDMA has a 10 bit mode, but I left
this unimplemented because I have no means of testing it
unfortunately; ChromeOS does not use this hardware.

I also wanted to mention, I think this patch might conflict with the
in-flight ovl-adaptor patch. Is there a protocol for a situation like
this?

Regards,
Justin

On Mon, Jan 30, 2023 at 7:28 PM Chun-Kuang Hu  wrote:
>
> Hi, Justin:
>
> Justin Green  於 2023年1月31日 週二 上午4:36寫道:
> >
> > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.
> >
> > Tested using "modetest -P" on an MT8195.
> >
> > Signed-off-by: Justin Green 
> > ---
> > v2:
> >  * Rebase and resolve merge conflicts with the AFBC patch.
> > v3:
> >  * Moved 10-bit support detection to mtk_disk_ovl.c
> > v4:
> >  * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
> > v5:
> >  * Minor style adjustments per checkpatch.pl
> >
> >  drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
> >  drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
> >  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
> >  drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
> >  drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
> >  8 files changed, 146 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
> > b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > index 33e61a136bbc..6ad22ce75b81 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> > @@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
> >  void mtk_ovl_unregister_vblank_cb(struct device *dev);
> >  void mtk_ovl_enable_vblank(struct device *dev);
> >  void mtk_ovl_disable_vblank(struct device *dev);
> > +const u32 *mtk_ovl_get_formats(struct device *dev);
> > +size_t mtk_ovl_get_num_formats(struct device *dev);
> >
> >  void mtk_rdma_bypass_shadow(struct device *dev);
> >  int mtk_rdma_clk_enable(struct device *dev);
> > @@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct 
> > cmdq_pkt *cmdq_pkt);
> >  void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
> >  void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
> >  struct cmdq_pkt *cmdq_pkt);
> > +const u32 *mtk_rdma_get_formats(struct device *dev);
> > +size_t mtk_rdma_get_num_formats(struct device *dev);
> >  #endif
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 84daeaffab6a..1db70a77560f 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -41,6 +41,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_EXT0x02D0
> >  #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)
> > @@ -61,11 +62,45 @@
> > 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
> >  #defineOVL_CON_AEN BIT(8)
> >  #defineOVL_CON_ALPHA   0xff
> >  #defineOVL_CON_VIRT_FLIP   BIT(9)
> >  #defineOVL_CON_HORZ_FLIP   BIT(10)
> >
> > +static const u32 formats_mt8173[] = {
> > +   DRM_FORMAT_XRGB,
> > +   DRM_FORMAT_ARGB,
> > +   DRM_FORMAT_BGRX,
> > +   DRM_FORMAT_BGRA,
> > +   DRM_FORMAT_ABGR,
> > +   DRM_FORMAT_XBGR,
> > +   D

[PATCH v5] drm/mediatek: Add support for AR30 and BA30

2023-01-30 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c
v5:
 * Minor style adjustments per checkpatch.pl

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 146 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..6ad22ce75b81 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32 *mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt 
*cmdq_pkt);
 void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
 struct cmdq_pkt *cmdq_pkt);
+const u32 *mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..1db70a77560f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,11 +62,45 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 formats_mt8173[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
+static const u32 formats_mt8195[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +108,7 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   bool supports_10bit;
 };
 
 /*
@@ -188,6 +224,26 @@ 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;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);

[PATCH v4] drm/mediatek: Add support for AR30 and BA30

2023-01-30 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c
v4:
 * Moved formats to mtk_disp_ovl.c and mtk_disp_rdma.c

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  4 ++
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 75 +
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c| 27 
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  4 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 20 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 28 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  3 +-
 8 files changed, 146 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..c292022b8270 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,8 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+const u32* mtk_ovl_get_formats(struct device *dev);
+size_t mtk_ovl_get_num_formats(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
@@ -122,4 +124,6 @@ void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt 
*cmdq_pkt);
 void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
 struct cmdq_pkt *cmdq_pkt);
+const u32* mtk_rdma_get_formats(struct device *dev);
+size_t mtk_rdma_get_num_formats(struct device *dev);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..781cd18f94ba 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,11 +62,45 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
 #defineOVL_CON_HORZ_FLIP   BIT(10)
 
+static const u32 formats_mt8173[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
+static const u32 formats_mt8195[] = {
+   DRM_FORMAT_XRGB,
+   DRM_FORMAT_ARGB,
+   DRM_FORMAT_ARGB2101010,
+   DRM_FORMAT_BGRX,
+   DRM_FORMAT_BGRA,
+   DRM_FORMAT_BGRA1010102,
+   DRM_FORMAT_ABGR,
+   DRM_FORMAT_XBGR,
+   DRM_FORMAT_RGB888,
+   DRM_FORMAT_BGR888,
+   DRM_FORMAT_RGB565,
+   DRM_FORMAT_UYVY,
+   DRM_FORMAT_YUYV,
+};
+
 struct mtk_disp_ovl_data {
unsigned int addr;
unsigned int gmc_bits;
@@ -73,6 +108,7 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   bool supports_10bit;
 };
 
 /*
@@ -188,6 +224,26 @@ 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;
+
+   reg = readl(ovl->regs + DISP_REG_OVL_CLRFMT_EXT);
+   reg &= ~OVL_CON_CLRFMT_BIT_DEPTH_MASK(idx);
+
+   if (format == DRM_FORMAT_RGBA1010102 

[PATCH v3] drm/mediatek: Add support for AR30 and BA30

2023-01-27 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.
v3:
 * Moved 10-bit support detection to mtk_disk_ovl.c

 drivers/gpu/drm/mediatek/mtk_disp_drv.h |  1 +
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c | 37 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 10 ++
 drivers/gpu/drm/mediatek/mtk_drm_plane.c| 37 ++---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h|  2 +-
 7 files changed, 84 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h 
b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 33e61a136bbc..b75139da3032 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -96,6 +96,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev,
 void mtk_ovl_unregister_vblank_cb(struct device *dev);
 void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
+int mtk_ovl_supports_10bit(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..412a749a509e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -73,6 +78,7 @@ struct mtk_disp_ovl_data {
bool fmt_rgb565_is_0;
bool smi_id_en;
bool supports_afbc;
+   bool supports_10bit;
 };
 
 /*
@@ -188,6 +194,26 @@ 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;
+
+   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, >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)
@@ -216,6 +242,13 @@ unsigned int mtk_ovl_supported_rotations(struct device 
*dev)
   DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
 }
 
+int mtk_ovl_supports_10bit(struct device *dev)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   return ovl->data->supports_10bit;
+}
+
 int mtk_ovl_layer_check(struct device *dev, unsigned int idx,
struct mtk_plane_state *mtk_state)
 {
@@ -302,9 +335,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -388,6 +423,7 @@ void

Re: [PATCH v2] drm/mediatek: Add support for AR30 and BA30

2023-01-27 Thread Justin Green
Thanks for the suggestion! That's a lot cleaner than manually
traversing the device tree. Will send out another patch.

On Thu, Jan 26, 2023 at 7:36 PM Chun-Kuang Hu  wrote:
>
> Hi, Justin:
>
> Justin Green  於 2023年1月11日 週三 上午4:47寫道:
> >
> > Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.
> >
> > Tested using "modetest -P" on an MT8195.
> >
> > Signed-off-by: Justin Green 
> > ---
> > v2:
> >  * Rebase and resolve merge conflicts with the AFBC patch.
> >
> >  drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 28 +
> >  drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 19 +++-
> >  drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 +---
> >  drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +-
> >  4 files changed, 81 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 84daeaffab6a..667ae57c8754 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > @@ -41,6 +41,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_EXT0x02D0
> >  #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)
> > @@ -61,6 +62,10 @@
> > 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
> >  #defineOVL_CON_AEN BIT(8)
> >  #defineOVL_CON_ALPHA   0xff
> >  #defineOVL_CON_VIRT_FLIP   BIT(9)
> > @@ -188,6 +193,26 @@ 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;
> > +
> > +   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, >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)
> > @@ -302,9 +327,11 @@ static unsigned int ovl_fmt_convert(struct 
> > mtk_disp_ovl *ovl, unsigned int fmt)
> > return OVL_CON_CLRFMT_ARGB;
> > case DRM_FORMAT_BGRX:
> > case DRM_FORMAT_BGRA:
> > +   case DRM_FORMAT_BGRA1010102:
> > return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
> > case DRM_FORMAT_XRGB:
> > case DRM_FORMAT_ARGB:
> > +   case DRM_FORMAT_ARGB2101010:
> > return OVL_CON_CLRFMT_RGBA;
> > case DRM_FORMAT_XBGR:
> > case DRM_FORMAT_ABGR:
> > @@ -388,6 +415,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
> > int idx,
> >   >cmdq_reg, ovl->regs, 
> > DISP_REG_OVL_PITCH_MSB(idx));
> > }
> >
> > +   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
> > m

[PATCH v2] drm/mediatek: Add support for AR30 and BA30

2023-01-10 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
v2:
 * Rebase and resolve merge conflicts with the AFBC patch.

 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 28 +
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 19 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 +---
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +-
 4 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 84daeaffab6a..667ae57c8754 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -41,6 +41,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_EXT0x02D0
 #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)
@@ -61,6 +62,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -188,6 +193,26 @@ 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;
+
+   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, >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)
@@ -302,9 +327,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -388,6 +415,7 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
  >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);
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 112615817dcb..d50379c97c4b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -842,6 +842,21 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int 
plane_idx,
 
 }
 
+static const char *ovls_with_10bit_cap[] = {
+   "mediatek,mt8195-disp-ovl",
+};
+
+static bool is_10bit_cap_device(void)
+{
+   for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) {
+   if (of_find_compatible_node(NULL, NULL,
+   ovls_with_10bit_cap[i]))
+   return true;
+   }
+
+   return false;
+}
+
 static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 struct mtk_drm_crtc *mtk_crtc,
 int comp_idx, int pipe)
@@ -849,6 +864,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device 
*drm_dev,
int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
struct mtk_ddp_comp *comp = mtk_c

[RESEND PATCH] drm/mediatek: Add support for AR30 and BA30

2023-01-09 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 29 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 19 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 38 
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +-
 4 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..be1dfc82aab2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -38,6 +38,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_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))

@@ -56,6 +57,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -175,6 +180,26 @@ void mtk_ovl_stop(struct device *dev)

 }

+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;
+
+   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, >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)
@@ -289,9 +314,11 @@ static unsigned int ovl_fmt_convert(struct
mtk_disp_ovl *ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -346,6 +373,8 @@ void mtk_ovl_layer_config(struct device *dev,
unsigned int idx,
mtk_ddp_write_relaxed(cmdq_pkt, addr, >cmdq_reg, ovl->regs,
  DISP_REG_OVL_ADDR(ovl, idx));

+   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
+
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
 }

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 42cc7052b050..b2b944344c7a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -843,6 +843,21 @@ enum drm_plane_type
mtk_drm_crtc_plane_type(unsigned int plane_idx,

 }

+static const char *ovls_with_10bit_cap[] = {
+   "mediatek,mt8195-disp-ovl",
+};
+
+static bool is_10bit_cap_device(void)
+{
+   for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) {
+   if (of_find_compatible_node(NULL, NULL,
+   ovls_with_10bit_cap[i]))
+   return true;
+   }
+
+   return false;
+}
+
 static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 struct mtk_drm_crtc *mtk_crtc,
 int comp_idx, int pipe)
@@ -850,6 +865,7 @@ static int mtk_drm_crtc_init_comp_planes(struct
drm_device *drm_dev,
int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
int i, ret;
+   bool supports_10bit = is_10bit_cap_device();

for (i = 0; i < num_planes; i++) {
ret = mtk_plane_init(drm_dev,
@@ -857,7 +873,8 @@ static int mtk_drm_crtc_init_comp_pla

[PATCH v5] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-11-16 Thread Justin Green
From: Justin Green 

Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

v5:
* Removed some dead defines.
* Refactored mtk_ovl_set_afbc().

v4:
* Move modifier validation to format_mod_supported function.
* Add modifiers to drm_universal_plane_init() call.
* Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on
  DRM_FORMAT_LINEAR being equal to 0.
* Gate AFBC control bit writes on device compatibility.

v3:
* Replaced pitch bitshift math with union based approach.
* Refactored overlay register writes to shared code between non-AFBC and
  AFBC.
* Minor code cleanups.

v2:
* Marked mtk_ovl_set_afbc as static.
* Reflowed some lines to fit column limit.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 57 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 74 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  8 +++
 3 files changed, 134 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..5a59e7b99c5d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,22 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#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 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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +72,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +178,14 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
 
+static void mtk_ovl_set_afbc(struct mtk_disp_ovl *ovl, struct cmdq_pkt 
*cmdq_pkt,
+int idx, bool enabled)
+{
+   mtk_ddp_write_mask(cmdq_pkt, enabled ? OVL_LAYER_AFBC_EN(idx) : 0,
+   >cmdq_reg, ovl->regs,
+   DISP_REG_OVL_DATAPATH_CON, OVL_LAYER_AFBC_EN(idx));
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -310,11 +323,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
int idx,
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
struct mtk_plane_pending_state *pending = >pending;
unsigned int addr = pending->addr;
-   unsigned int pitch = pending->pitch & 0x;
+   unsigned int hdr_addr = pending->hdr_addr;
+   unsigned int pitch = pending->pitch;
+   unsigned int hdr_pitch = pending->hdr_pitch;
unsigned int fmt = pending->format;
unsigned int offset = (pending->y << 16) | pending->x;
unsigned int src_size = (pending->height << 16) | pending->width;
unsigned int con;
+   bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
+   union overlay_pitch {
+   struct split_pitch {
+   u16 lsb;
+   u16 msb;
+   } split_pitch;
+   u32 pitch;
+   } overlay_pitch;
+
+   overlay_pitch.pitch = pitch;
 
if (!pending->enable) {
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -335,9 +360,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
addr += pending->pitch - 1;
}
 
+   if (ovl->data->supports_afbc)
+   mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
+
mtk_ddp_write_relaxed(cmdq_pkt, con, >cmdq_reg, ovl->regs,
  DISP_REG_OVL_CON(idx));
-   mtk_ddp_write_relaxed(cmdq_pkt, pitch, &

Re: [PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-11-16 Thread Justin Green
Hi Chun-Kuang,

> > +   mtk_ovl_set_afbc(dev, cmdq_pkt, idx, is_afbc);
> > mtk_ddp_write_relaxed(cmdq_pkt, con, >cmdq_reg, ovl->regs,
> >   DISP_REG_OVL_CON(idx));
> > -   mtk_ddp_write_relaxed(cmdq_pkt, pitch, >cmdq_reg, ovl->regs,
> > +   mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, 
> > >cmdq_reg, ovl->regs,
> >   DISP_REG_OVL_PITCH(idx));
>
> Is this general for all MediaTek SoC? If so, separate this to an
> independent patch. Otherwise, use a device variable to separate this
> setting.

Yes and no. Technically all MediaTek SoCs have two separate registers
for the pitch, each are 16 bits, so this code is technically always
needed. However, because the lsb register is 16 bit, this issue has
never come up, because nobody has tried to display a plane that was
16384 ARGB pixels across. In fact, I think most MediaTek SoCs have a
resolution limit of 4K. The reason this issue comes up now is because
"pitch" is calculated differently for AFBC frames, and actually refers
to the size in bytes of one row of AFBC blocks. Should I still
separate this into an independent patch?

> >  }
> > @@ -492,6 +567,15 @@ static const struct mtk_disp_ovl_data 
> > mt8192_ovl_2l_driver_data = {
> > .smi_id_en = true,
> >  };
> >
> > +static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = {
>
> In this binding document, mt8195 ovl is compatible to mt8133 ovl.
> Please confirm that mt8195 is not identical with mt8133.

Do you mean MT8183? If so, we do not have any documentation indicating
that the MT8183 supports AFBC. Do you have some reason to believe
otherwise?

> Usually the pitch needs alignment. So I guess the formula is
>
> hdr_pitch = ALIGN(width_in_blocks * AFBC_HEADER_BLOCK_SIZE,
> AFBC_HEADER_ALIGNMENT);
> hdr_size = hdr_pitch * height_in_blocks;

The documentation does not indicate that the pitch needs alignment
beyond the AFBC header block size.

> Could you explain the meaning of hdr_pitch?

hdr_pitch refers to the size in bytes of one row of AFBC header
blocks. AFBC is a proprietary compressed frame buffer format, but from
what public information we have, it appears to be block compressed
data stored in 2 contiguous planes. The first is called the "header"
plane, and the second is called the "body" plane. The header plane
contains metadata for each block of pixel data, and the body plane
contains sparse compressed block data.


I'll send another patch with the other changes you mentioned.

Thanks!
Justin


[PATCH] drm/mediatek: Add support for AR30 and BA30

2022-11-10 Thread Justin Green
Add support for AR30 and BA30 pixel formats to the Mediatek DRM driver.

Tested using "modetest -P" on an MT8195.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 29 ++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 19 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 38 
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  2 +-
 4 files changed, 81 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..be1dfc82aab2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -38,6 +38,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_EXT0x02D0
 #define DISP_REG_OVL_ADDR_MT8173   0x0f40
 #define DISP_REG_OVL_ADDR(ovl, n)  ((ovl)->data->addr + 0x20 * (n))
 
@@ -56,6 +57,10 @@
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
 #defineOVL_CON_AEN BIT(8)
 #defineOVL_CON_ALPHA   0xff
 #defineOVL_CON_VIRT_FLIP   BIT(9)
@@ -175,6 +180,26 @@ void mtk_ovl_stop(struct device *dev)
 
 }
 
+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;
+
+   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, >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)
@@ -289,9 +314,11 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl 
*ovl, unsigned int fmt)
return OVL_CON_CLRFMT_ARGB;
case DRM_FORMAT_BGRX:
case DRM_FORMAT_BGRA:
+   case DRM_FORMAT_BGRA1010102:
return OVL_CON_CLRFMT_ARGB | OVL_CON_BYTE_SWAP;
case DRM_FORMAT_XRGB:
case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_ARGB2101010:
return OVL_CON_CLRFMT_RGBA;
case DRM_FORMAT_XBGR:
case DRM_FORMAT_ABGR:
@@ -346,6 +373,8 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
mtk_ddp_write_relaxed(cmdq_pkt, addr, >cmdq_reg, ovl->regs,
  DISP_REG_OVL_ADDR(ovl, idx));
 
+   mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
+
mtk_ovl_layer_on(dev, idx, cmdq_pkt);
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c 
b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 42cc7052b050..b2b944344c7a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -843,6 +843,21 @@ enum drm_plane_type mtk_drm_crtc_plane_type(unsigned int 
plane_idx,
 
 }
 
+static const char *ovls_with_10bit_cap[] = {
+   "mediatek,mt8195-disp-ovl",
+};
+
+static bool is_10bit_cap_device(void)
+{
+   for (int i = 0; i < ARRAY_SIZE(ovls_with_10bit_cap); i++) {
+   if (of_find_compatible_node(NULL, NULL,
+   ovls_with_10bit_cap[i]))
+   return true;
+   }
+
+   return false;
+}
+
 static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 struct mtk_drm_crtc *mtk_crtc,
 int comp_idx, int pipe)
@@ -850,6 +865,7 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device 
*drm_dev,
int num_planes = mtk_drm_crtc_num_comp_planes(mtk_crtc, comp_idx);
struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[comp_idx];
int i, ret;
+   bool supports_10bit = is_10bit_cap_device();
 
for (i = 0; i < num_planes; i++) {
ret = mtk_plane_init(drm_dev,
@@ -857,7 +873,8 @@ static int mtk_drm_crtc_init_comp

[PATCH v4] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-13 Thread Justin Green
Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

v4:
* Move modifier validation to format_mod_supported function.
* Add modifiers to drm_universal_plane_init() call.
* Make comparisons to DRM_FORMAT_MOD_LINEAR explicit rather than relying on
  DRM_FORMAT_LINEAR being equal to 0.
* Gate AFBC control bit writes on device compatibility.

v3:
* Replaced pitch bitshift math with union based approach.
* Refactored overlay register writes to shared code between non-AFBC and
  AFBC.
* Minor code cleanups.

v2:
* Marked mtk_ovl_set_afbc as static.
* Reflowed some lines to fit column limit.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 67 -
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 74 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  8 +++
 3 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..6d4c0e44a2f1 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,24 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#define DISP_REG_OVL_PITCH_MSB(n)  (0x0040 + 0x20 * (n))
+#define OVL_PITCH_MSB_2ND_SUBBUF   BIT(16)
+#define OVL_PITCH_MSB_YUV_TRANSBIT(20)
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
+#define DISP_REG_OVL_CLIP(n)   (0x004c + 0x20 * (n))
 #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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +74,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
+
+static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt,
+int idx, bool enabled)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
 
+   reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+   if (enabled)
+   reg = reg | OVL_LAYER_AFBC_EN(idx);
+   else
+   reg = reg & ~OVL_LAYER_AFBC_EN(idx);
+
+   mtk_ddp_write_relaxed(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_DATAPATH_CON);
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -310,11 +333,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
int idx,
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
struct mtk_plane_pending_state *pending = >pending;
unsigned int addr = pending->addr;
-   unsigned int pitch = pending->pitch & 0x;
+   unsigned int hdr_addr = pending->hdr_addr;
+   unsigned int pitch = pending->pitch;
+   unsigned int hdr_pitch = pending->hdr_pitch;
unsigned int fmt = pending->format;
unsigned int offset = (pending->y << 16) | pending->x;
unsigned int src_size = (pending->height << 16) | pending->width;
unsigned int con;
+   bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
+   union overlay_pitch {
+   struct split_pitch {
+   u16 lsb;
+   u16 msb;
+   } split_pitch;
+   u32 pitch;
+   } overlay_pitch;
+
+   overlay_pitch.pitch = pitch;
 
if (!pending->enable) {
mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -335,9 +370,12 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int 
idx,
addr += pending->pitch - 1;
}
 
+   if (ovl->data->s

Re: [PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-13 Thread Justin Green
Thanks for the comments everyone! I'll upload a new CL sometime today.

I did want to ask though, I realize I should be using u32/u64 for
kernel code in general, but the rest of this file seems to be written
using unsigned int/unsigned long long. In this circumstance, does
keeping with the style of the original source take precedence over
general style guidelines, or vice versa?


[PATCH v3] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-12 Thread Justin Green
Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

v3:
* Replaced pitch bitshift math with union based approach.
* Refactored overlay register writes to shared code between non-AFBC and
  AFBC.
* Minor code cleanups.

v2:
* Marked mtk_ovl_set_afbc as static.
* Reflowed some lines to fit column limit.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 90 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 37 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |  8 +++
 3 files changed, 131 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..3f89b5f5064f 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,24 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#define DISP_REG_OVL_PITCH_MSB(n)  (0x0040 + 0x20 * (n))
+#define OVL_PITCH_MSB_2ND_SUBBUF   BIT(16)
+#define OVL_PITCH_MSB_YUV_TRANSBIT(20)
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
+#define DISP_REG_OVL_CLIP(n)   (0x004c + 0x20 * (n))
 #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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +74,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
+
+static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt,
+int idx, bool enabled)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
 
+   reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+   if (enabled)
+   reg = reg | OVL_LAYER_AFBC_EN(idx);
+   else
+   reg = reg & ~OVL_LAYER_AFBC_EN(idx);
+
+   mtk_ddp_write_relaxed(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_DATAPATH_CON);
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -226,6 +249,32 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
if (state->fb->format->is_yuv && rotation != 0)
return -EINVAL;
 
+   if (state->fb->modifier) {
+   unsigned long long modifier;
+   unsigned int fourcc;
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   if (!ovl->data->supports_afbc)
+   return -EINVAL;
+
+   modifier = state->fb->modifier;
+
+   if (modifier != 
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return -EINVAL;
+
+   fourcc = state->fb->format->format;
+   if (fourcc != DRM_FORMAT_BGRA &&
+   fourcc != DRM_FORMAT_ABGR &&
+   fourcc != DRM_FORMAT_ARGB &&
+   fourcc != DRM_FORMAT_XRGB &&
+   fourcc != DRM_FORMAT_XBGR &&
+   fourcc != DRM_FORMAT_RGB888 &&
+   fourcc != DRM_FORMAT_BGR888)
+   return -EINVAL;
+   }
+
state->rotation = rotation;
 
return 0;
@@ -310,11 +359,23 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
int idx,
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
struct mtk_plane_pending_state

Re: [RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-12 Thread Justin Green
> These would be different from the macros that are available in bitfield.h, but
> not *fundamentally* different, so these would look a little redundant...
>
> I think that you refer to that `pitch` variable that's coming from the 
> DRM(/fb)
> API... and bitfield macros are for register access... so I guess that one 
> clean
> way of avoiding the magic shifting (that is purely used to split the 32-bits
> number in two 16-bits 'chunks') would be to perhaps use a union, so that you
> will have something like u.pitch_lsb, u.pitch_msb (with lsb/msb being two 
> u16).

Do you mean something like this?

union pitch_val {
 struct split_pitch_val {
  uint16_t lsb;
  uint16_t msb;
 } split;
 uint32_t val;
};

I think my concern with that approach would be it assumes the compiler
packs structs tightly and it also assumes the endianness of the
machine, whereas a bitshift is maybe more portable. Is this an issue
worth considering since we know this driver will only run on specific
MTK SoCs?


Re: [RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-11 Thread Justin Green
Hi Angelo,
Thanks for the suggestions! I'll upload another patch with those changes.

Re the pitch register math, would it be acceptable to define separate
macros for the LSB and MSB to abstract away the magic numbers? For
example:
#define OVL_PITCH_MSB(n)((n >> 16) & GENMASK(15, 0))
#define OVL_PITCH_LSB(n)(n & GENMASK(15, 0))

Regards,
Justin

On Tue, Oct 11, 2022 at 5:09 AM AngeloGioacchino Del Regno
 wrote:
>
> Il 10/10/22 17:01, Justin Green ha scritto:
> > From: Justin Green 
> >
> > Add AFBC support to Mediatek DRM driver and enable on MT8195.
> >
> > Tested on MT8195 and confirmed both correct video output and improved DRAM
> > bandwidth performance.
> >
> > v2:
> > Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column
> > limit.
> >
> > Signed-off-by: Justin Green 
>
> Hello Justin,
> thanks for the patch!
>
> However, there's something to improve...
>
> > ---
> >   drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 108 ---
> >   drivers/gpu/drm/mediatek/mtk_drm_plane.c |  37 +++-
> >   drivers/gpu/drm/mediatek/mtk_drm_plane.h |   8 ++
> >   3 files changed, 140 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
> > b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > index 002b0f6cae1a..1724ea85a840 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
>
> ..snip..
>
> > @@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned 
> > int idx,
> >   {
> >   struct drm_plane_state *state = _state->base;
> >   unsigned int rotation = 0;
> > + unsigned long long modifier;
> > + unsigned int fourcc;
> >
> >   rotation = drm_rotation_simplify(state->rotation,
> >DRM_MODE_ROTATE_0 |
> > @@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned 
> > int idx,
> >   if (state->fb->format->is_yuv && rotation != 0)
> >   return -EINVAL;
> >
> > + if (state->fb->modifier) {
> > + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
>
> Since you're introducing modifier and fourcc for this branch only, you
> may as well just declare them here instead, but either way is fine.
>
> > +
> > + if (!ovl->data->supports_afbc)
> > + return -EINVAL;
> > +
> > + modifier = state->fb->modifier;
> > +
> > + if (modifier != 
> > DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
> > + AFBC_FORMAT_MOD_SPLIT 
> > |
> > + 
> > AFBC_FORMAT_MOD_SPARSE))
> > + return -EINVAL;
> > +
> > + fourcc = state->fb->format->format;
> > + if (fourcc != DRM_FORMAT_BGRA &&
> > + fourcc != DRM_FORMAT_ABGR &&
> > + fourcc != DRM_FORMAT_ARGB &&
> > + fourcc != DRM_FORMAT_XRGB &&
> > + fourcc != DRM_FORMAT_XBGR &&
> > + fourcc != DRM_FORMAT_RGB888 &&
> > + fourcc != DRM_FORMAT_BGR888)
> > + return -EINVAL;
> > + }
> > +
> >   state->rotation = rotation;
> >
> >   return 0;
> > @@ -310,11 +359,14 @@ void mtk_ovl_layer_config(struct device *dev, 
> > unsigned int idx,
> >   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
> >   struct mtk_plane_pending_state *pending = >pending;
> >   unsigned int addr = pending->addr;
> > - unsigned int pitch = pending->pitch & 0x;
> > + unsigned int hdr_addr = pending->hdr_addr;
> > + unsigned int pitch = pending->pitch;
> > + unsigned int hdr_pitch = pending->hdr_pitch;
> >   unsigned int fmt = pending->format;
> >   unsigned int offset = (pending->y << 16) | pending->x;
> >   unsigned int src_size = (pending->height << 16) | pending->width;
> >   unsigned int con;
> > + bool is_afbc = pending->modifier;
> >
> >   if (!pending->enable) {
> >   mtk_ovl_layer_off(dev, idx, cmdq_pkt);
> > @@ -335,16 +387,39 @@ void mtk_ovl_layer_config(struct device *dev, 
> > unsigned int idx,
> &g

[RESEND PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-10-10 Thread Justin Green
From: Justin Green 

Add AFBC support to Mediatek DRM driver and enable on MT8195.

Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

v2:
Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column
limit.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 108 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c |  37 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |   8 ++
 3 files changed, 140 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..1724ea85a840 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,24 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#define DISP_REG_OVL_PITCH_MSB(n)  (0x0040 + 0x20 * (n))
+#define OVL_PITCH_MSB_2ND_SUBBUF   BIT(16)
+#define OVL_PITCH_MSB_YUV_TRANSBIT(20)
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
+#define DISP_REG_OVL_CLIP(n)   (0x004c + 0x20 * (n))
 #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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +74,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
+
+static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt,
+int idx, bool enabled)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
 
+   reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+   if (enabled)
+   reg = reg | OVL_LAYER_AFBC_EN(idx);
+   else
+   reg = reg & ~OVL_LAYER_AFBC_EN(idx);
+
+   mtk_ddp_write_relaxed(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_DATAPATH_CON);
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
 {
struct drm_plane_state *state = _state->base;
unsigned int rotation = 0;
+   unsigned long long modifier;
+   unsigned int fourcc;
 
rotation = drm_rotation_simplify(state->rotation,
 DRM_MODE_ROTATE_0 |
@@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
if (state->fb->format->is_yuv && rotation != 0)
return -EINVAL;
 
+   if (state->fb->modifier) {
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   if (!ovl->data->supports_afbc)
+   return -EINVAL;
+
+   modifier = state->fb->modifier;
+
+   if (modifier != 
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return -EINVAL;
+
+   fourcc = state->fb->format->format;
+   if (fourcc != DRM_FORMAT_BGRA &&
+   fourcc != DRM_FORMAT_ABGR &&
+   fourcc != DRM_FORMAT_ARGB &&
+   fourcc != DRM_FORMAT_XRGB &&
+   fourcc != DRM_FORMAT_XBGR &&
+   fourcc != DRM_FORMAT_RGB888 &&
+   fourcc != DRM_FORMAT_BGR888)
+   return -EINVAL;
+   }
+
state->rotation = rota

[PATCH v2] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-09-27 Thread Justin Green
Add AFBC support to Mediatek DRM driver and enable on MT8195.

Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

v2:
Marked mtk_ovl_set_afbc as static, reflowed some lines to fit column
limit.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 108 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c |  37 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |   8 ++
 3 files changed, 140 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..1724ea85a840 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,24 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#define DISP_REG_OVL_PITCH_MSB(n)  (0x0040 + 0x20 * (n))
+#define OVL_PITCH_MSB_2ND_SUBBUF   BIT(16)
+#define OVL_PITCH_MSB_YUV_TRANSBIT(20)
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
+#define DISP_REG_OVL_CLIP(n)   (0x004c + 0x20 * (n))
 #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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +74,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +180,22 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
+
+static void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt,
+int idx, bool enabled)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
 
+   reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+   if (enabled)
+   reg = reg | OVL_LAYER_AFBC_EN(idx);
+   else
+   reg = reg & ~OVL_LAYER_AFBC_EN(idx);
+
+   mtk_ddp_write_relaxed(cmdq_pkt, reg, >cmdq_reg,
+ ovl->regs, DISP_REG_OVL_DATAPATH_CON);
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -208,6 +231,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
 {
struct drm_plane_state *state = _state->base;
unsigned int rotation = 0;
+   unsigned long long modifier;
+   unsigned int fourcc;
 
rotation = drm_rotation_simplify(state->rotation,
 DRM_MODE_ROTATE_0 |
@@ -226,6 +251,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
if (state->fb->format->is_yuv && rotation != 0)
return -EINVAL;
 
+   if (state->fb->modifier) {
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   if (!ovl->data->supports_afbc)
+   return -EINVAL;
+
+   modifier = state->fb->modifier;
+
+   if (modifier != 
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return -EINVAL;
+
+   fourcc = state->fb->format->format;
+   if (fourcc != DRM_FORMAT_BGRA &&
+   fourcc != DRM_FORMAT_ABGR &&
+   fourcc != DRM_FORMAT_ARGB &&
+   fourcc != DRM_FORMAT_XRGB &&
+   fourcc != DRM_FORMAT_XBGR &&
+   fourcc != DRM_FORMAT_RGB888 &&
+   fourcc != DRM_FORMAT_BGR888)
+   return -EINVAL;
+   }
+
state->rotation = rotation;
 
return

[PATCH] drm/mediatek: Add AFBC support to Mediatek DRM driver

2022-09-23 Thread Justin Green
Add AFBC support to Mediatek DRM driver and enable on MT8195.

Tested on MT8195 and confirmed both correct video output and improved DRAM
bandwidth performance.

Signed-off-by: Justin Green 
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  | 106 ---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c |  37 +++-
 drivers/gpu/drm/mediatek/mtk_drm_plane.h |   8 ++
 3 files changed, 138 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c 
b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 002b0f6cae1a..7425c88964d0 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -29,17 +29,24 @@
 #define DISP_REG_OVL_DATAPATH_CON  0x0024
 #define OVL_LAYER_SMI_ID_ENBIT(0)
 #define OVL_BGCLR_SEL_IN   BIT(2)
+#define OVL_LAYER_AFBC_EN(n)   BIT(4+n)
 #define DISP_REG_OVL_ROI_BGCLR 0x0028
 #define DISP_REG_OVL_SRC_CON   0x002c
 #define DISP_REG_OVL_CON(n)(0x0030 + 0x20 * (n))
 #define DISP_REG_OVL_SRC_SIZE(n)   (0x0038 + 0x20 * (n))
 #define DISP_REG_OVL_OFFSET(n) (0x003c + 0x20 * (n))
+#define DISP_REG_OVL_PITCH_MSB(n)  (0x0040 + 0x20 * (n))
+#define OVL_PITCH_MSB_2ND_SUBBUF   BIT(16)
+#define OVL_PITCH_MSB_YUV_TRANSBIT(20)
 #define DISP_REG_OVL_PITCH(n)  (0x0044 + 0x20 * (n))
+#define DISP_REG_OVL_CLIP(n)   (0x004c + 0x20 * (n))
 #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_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)
+#define DISP_REG_OVL_HDR_PITCH(ovl, n) ((ovl)->data->addr + 0x20 * (n) 
+ 0x08)
 
 #define GMC_THRESHOLD_BITS 16
 #define GMC_THRESHOLD_HIGH ((1 << GMC_THRESHOLD_BITS) / 4)
@@ -67,6 +74,7 @@ struct mtk_disp_ovl_data {
unsigned int layer_nr;
bool fmt_rgb565_is_0;
bool smi_id_en;
+   bool supports_afbc;
 };
 
 /*
@@ -172,7 +180,20 @@ void mtk_ovl_stop(struct device *dev)
reg = reg & ~OVL_LAYER_SMI_ID_EN;
writel_relaxed(reg, ovl->regs + DISP_REG_OVL_DATAPATH_CON);
}
+}
+
+void mtk_ovl_set_afbc(struct device *dev, struct cmdq_pkt *cmdq_pkt, int idx, 
bool enabled)
+{
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+   unsigned int reg;
 
+   reg = readl(ovl->regs + DISP_REG_OVL_DATAPATH_CON);
+   if (enabled)
+   reg = reg | OVL_LAYER_AFBC_EN(idx);
+   else
+   reg = reg & ~OVL_LAYER_AFBC_EN(idx);
+
+   mtk_ddp_write_relaxed(cmdq_pkt, reg, >cmdq_reg, ovl->regs, 
DISP_REG_OVL_DATAPATH_CON);
 }
 
 void mtk_ovl_config(struct device *dev, unsigned int w,
@@ -208,6 +229,8 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
 {
struct drm_plane_state *state = _state->base;
unsigned int rotation = 0;
+   unsigned long long modifier;
+   unsigned int fourcc;
 
rotation = drm_rotation_simplify(state->rotation,
 DRM_MODE_ROTATE_0 |
@@ -226,6 +249,30 @@ int mtk_ovl_layer_check(struct device *dev, unsigned int 
idx,
if (state->fb->format->is_yuv && rotation != 0)
return -EINVAL;
 
+   if (state->fb->modifier) {
+   struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+   if (!ovl->data->supports_afbc)
+   return -EINVAL;
+
+   modifier = state->fb->modifier;
+
+   if (modifier != 
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
+   AFBC_FORMAT_MOD_SPLIT |
+   AFBC_FORMAT_MOD_SPARSE))
+   return -EINVAL;
+
+   fourcc = state->fb->format->format;
+   if (fourcc != DRM_FORMAT_BGRA &&
+   fourcc != DRM_FORMAT_ABGR &&
+   fourcc != DRM_FORMAT_ARGB &&
+   fourcc != DRM_FORMAT_XRGB &&
+   fourcc != DRM_FORMAT_XBGR &&
+   fourcc != DRM_FORMAT_RGB888 &&
+   fourcc != DRM_FORMAT_BGR888)
+   return -EINVAL;
+   }
+
state->rotation = rotation;
 
return 0;
@@ -310,11 +357,14 @@ void mtk_ovl_layer_config(struct device *dev, unsigned 
int idx,
struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
st