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

2022-10-14 Thread Daniel Stone
Hi,

On Fri, 14 Oct 2022 at 08:46, AngeloGioacchino Del Regno <
angelogioacchino.delre...@collabora.com> wrote:

> Il 13/10/22 21:31, Justin Green ha scritto:
> > Signed-off-by: Justin Green 
>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delre...@collabora.com>
>

And also:
Acked-by: Daniel Stone 

I was worried about INVALID being passed through, but for the most part it
seems like it magically turns into LINEAR through either zero extension or
explicit initialisation to zero.

Cheers,
Daniel


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

2022-10-14 Thread AngeloGioacchino Del Regno

Il 13/10/22 21:31, Justin Green ha scritto:

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 


Reviewed-by: AngeloGioacchino Del Regno 





[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->supports_afbc)
+   mtk_ovl_set_afbc(dev, cmdq_pkt, idx, is_afbc);
+