This configures the TPR unit, using the DRM format modifier. For now only
the single buffer modifiers are supported, as split buffer needs more
configuration for the required cropping.

Signed-off-by: Lucas Stach <l.st...@pengutronix.de>
---
 drivers/gpu/ipu-v3/ipu-pre.c | 24 ++++++++++++++++++++++--
 drivers/gpu/ipu-v3/ipu-prg.c |  2 +-
 drivers/gpu/ipu-v3/ipu-prv.h |  4 ++--
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c
index c55563379e2e..d895f92d8d33 100644
--- a/drivers/gpu/ipu-v3/ipu-pre.c
+++ b/drivers/gpu/ipu-v3/ipu-pre.c
@@ -49,6 +49,10 @@
 #define IPU_PRE_TPR_CTRL                               0x070
 #define  IPU_PRE_TPR_CTRL_TILE_FORMAT(v)               ((v & 0xff) << 0)
 #define  IPU_PRE_TPR_CTRL_TILE_FORMAT_MASK             0xff
+#define  IPU_PRE_TPR_CTRL_TILE_FORMAT_16_BIT           (1 << 0)
+#define  IPU_PRE_TPR_CTRL_TILE_FORMAT_SPLIT_BUF                (1 << 4)
+#define  IPU_PRE_TPR_CTRL_TILE_FORMAT_SINGLE_BUF       (1 << 5)
+#define  IPU_PRE_TPR_CTRL_TILE_FORMAT_SUPER_TILED      (1 << 6)
 
 #define IPU_PRE_PREFETCH_ENG_CTRL                      0x080
 #define  IPU_PRE_PREF_ENG_CTRL_PREFETCH_EN             (1 << 0)
@@ -140,7 +144,7 @@ int ipu_pre_get(struct ipu_pre *pre)
        val = IPU_PRE_CTRL_HANDSHAKE_ABORT_SKIP_EN |
              IPU_PRE_CTRL_HANDSHAKE_EN |
              IPU_PRE_CTRL_TPR_REST_SEL |
-             IPU_PRE_CTRL_BLOCK_16 | IPU_PRE_CTRL_SDW_UPDATE;
+             IPU_PRE_CTRL_SDW_UPDATE;
        writel(val, pre->regs + IPU_PRE_CTRL);
 
        pre->in_use = true;
@@ -161,7 +165,7 @@ void ipu_pre_put(struct ipu_pre *pre)
 
 void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
                       unsigned int height, unsigned int stride, u32 format,
-                      unsigned int bufaddr)
+                      uint64_t modifier, unsigned int bufaddr)
 {
        const struct drm_format_info *info = drm_format_info(format);
        u32 active_bpp = info->cpp[0] >> 1;
@@ -198,9 +202,25 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int 
width,
 
        writel(pre->buffer_paddr, pre->regs + IPU_PRE_STORE_ENG_ADDR);
 
+       val = readl(pre->regs + IPU_PRE_TPR_CTRL);
+       val &= ~IPU_PRE_TPR_CTRL_TILE_FORMAT_MASK;
+       if (modifier != DRM_FORMAT_MOD_LINEAR) {
+               /* only support single buffer formats for now */
+               val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_SINGLE_BUF;
+               if (modifier == DRM_FORMAT_MOD_VIVANTE_SUPER_TILED)
+                       val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_SUPER_TILED;
+               if (info->cpp[0] == 2)
+                       val |= IPU_PRE_TPR_CTRL_TILE_FORMAT_16_BIT;
+       }
+       writel(val, pre->regs + IPU_PRE_TPR_CTRL);
+
        val = readl(pre->regs + IPU_PRE_CTRL);
        val |= IPU_PRE_CTRL_EN_REPEAT | IPU_PRE_CTRL_ENABLE |
               IPU_PRE_CTRL_SDW_UPDATE;
+       if (modifier == DRM_FORMAT_MOD_LINEAR)
+               val &= ~IPU_PRE_CTRL_BLOCK_EN;
+       else
+               val |= IPU_PRE_CTRL_BLOCK_EN;
        writel(val, pre->regs + IPU_PRE_CTRL);
 }
 
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c
index ecc9ea44dc50..454b1f1eb5df 100644
--- a/drivers/gpu/ipu-v3/ipu-prg.c
+++ b/drivers/gpu/ipu-v3/ipu-prg.c
@@ -295,7 +295,7 @@ int ipu_prg_channel_configure(struct ipuv3_channel 
*ipu_chan,
                return ret;
 
        ipu_pre_configure(prg->pres[chan->used_pre],
-                         width, height, stride, format, *eba);
+                         width, height, stride, format, 0, *eba);
 
 
        ret = clk_prepare_enable(prg->clk_ipg);
diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h
index ca2a223a0d1e..11be49de2eba 100644
--- a/drivers/gpu/ipu-v3/ipu-prv.h
+++ b/drivers/gpu/ipu-v3/ipu-prv.h
@@ -274,8 +274,8 @@ int ipu_pre_get(struct ipu_pre *pre);
 void ipu_pre_put(struct ipu_pre *pre);
 u32 ipu_pre_get_baddr(struct ipu_pre *pre);
 void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
-                      unsigned int height,
-                      unsigned int stride, u32 format, unsigned int bufaddr);
+                      unsigned int height, unsigned int stride, u32 format,
+                      uint64_t modifier, unsigned int bufaddr);
 void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr);
 
 struct ipu_prg *ipu_prg_lookup_by_phandle(struct device *dev, const char *name,
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to