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

2022-11-23 Thread Chun-Kuang Hu
Hi, Justin:

Justin Green  於 2022年11月17日 週四 凌晨3:33寫道:
>
> From: Justin Green 
>
> Tested on MT8195 and confirmed both correct video output and improved DRAM
> bandwidth performance.

I've break this patch into two patches and apply to mediatek-drm-next
[1], thanks.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/chunkuang.hu/linux.git/log/?h=mediatek-drm-next

Regards,
Chun-Kuang.

>
> 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 

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

2022-11-17 Thread AngeloGioacchino Del Regno

Il 16/11/22 20:33, Justin Green ha scritto:

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 


Can you please move the version log to *after* the "---"?
That's not something that should actually end up being in the commit 
description.

After that, or if the maintainer wants to take care about removing that
while applying...:

Reviewed-by: AngeloGioacchino Del Regno 




[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, >cmdq_reg, ovl->regs,
+   mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, 
>cmdq_reg,