MGS-3560 [#imx-913] Enable DRM compression for mscale board
authorYong Gan <yong.gan@nxp.com>
Tue, 3 Jul 2018 22:23:51 +0000 (06:23 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Wed, 17 Apr 2019 23:51:34 +0000 (02:51 +0300)
Refine the code for compressed format support.

Date: June 29, 2018
Signed-off-by: Yong Gan <yong.gan@nxp.com>
drivers/gpu/drm/imx/dcss/dcss-plane.c
drivers/gpu/imx/dcss/dcss-dec400d.c
include/video/imx-dcss.h
include/video/viv-metadata.h [new file with mode: 0644]

index d9c9721..a91945a 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/dma-buf.h>
 
 #include "video/imx-dcss.h"
+#include "video/viv-metadata.h"
 #include "dcss-plane.h"
 #include "dcss-crtc.h"
 
@@ -269,13 +270,12 @@ static void dcss_plane_atomic_set_base(struct dcss_plane *dcss_plane)
        struct drm_plane_state *state = plane->state;
        struct drm_framebuffer *fb = state->fb;
        struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
-       struct dma_buf *dma_buf;
-       struct dma_metadata *mdata;
-       struct drm_gem_object *gem_obj;
        unsigned long p1_ba, p2_ba;
        dma_addr_t caddr;
        bool modifiers_present = !!(fb->flags & DRM_MODE_FB_MODIFIERS);
        u32 pix_format = state->fb->format->format;
+       bool compressed = true;
+       uint32_t compressed_format = 0;
 
        BUG_ON(!cma_obj);
 
@@ -312,40 +312,38 @@ static void dcss_plane_atomic_set_base(struct dcss_plane *dcss_plane)
                        dcss_dec400d_bypass(dcss_plane->dcss);
                        return;
                case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED_FC:
-                       dma_buf = cma_obj->base.dma_buf;
-                       if (!dma_buf) {
-                               caddr = cma_obj->paddr +
-                                       ALIGN(fb->height, 64) * fb->pitches[0];
-                               goto config;
-                       }
-
-                       mdata = dma_buf->priv;
-                       if (!mdata ||
-                           mdata->magic != VIV_VIDMEM_METADATA_MAGIC) {
-                               WARN_ON(1);
-                               return;
-                       }
-
-                       if (!mdata->compressed) {
-                               /* Bypass dec400d */
-                               dcss_dec400d_bypass(dcss_plane->dcss);
-                               return;
-                       }
-
-                       gem_obj = dcss_plane_gem_import(plane->dev,
-                                                       mdata->ts_dma_buf);
-                       if (IS_ERR(gem_obj)) {
-                               WARN_ON(1);
-                               return;
-                       }
-
-                       caddr = to_drm_gem_cma_obj(gem_obj)->paddr;
-
-                       /* release gem_obj */
-                       drm_gem_object_unreference_unlocked(gem_obj);
-
-config:
-                       dcss_dec400d_read_config(dcss_plane->dcss, 0, true);
+                       do {
+                               struct dma_buf *dma_buf = cma_obj->base.dma_buf;
+                               struct drm_gem_object *gem_obj;
+                                       _VIV_VIDMEM_METADATA *mdata;
+
+                               if (!dma_buf) {
+                                       caddr = cma_obj->paddr + ALIGN(fb->height, 64) * fb->pitches[0];
+                                       break;
+                               }
+
+                               mdata = dma_buf->priv;
+                               if (!mdata || mdata->magic != VIV_VIDMEM_METADATA_MAGIC) {
+                                       break;
+                               }
+                               compressed = mdata->compressed ? true : false;
+                               compressed_format = mdata->compress_format;
+
+                               gem_obj = dcss_plane_gem_import(plane->dev, mdata->ts_dma_buf);
+                               if (IS_ERR(gem_obj)) {
+                                       break;
+                               }
+
+                               caddr = to_drm_gem_cma_obj(gem_obj)->paddr;
+
+                               /* release gem_obj */
+                               drm_gem_object_unreference_unlocked(gem_obj);
+
+                               dcss_dec400d_fast_clear_config(dcss_plane->dcss,
+                                               mdata->fc_value,
+                                               mdata->fc_enabled);
+                       } while (0);
+                       dcss_dec400d_read_config(dcss_plane->dcss, 0, compressed, compressed_format);
                        dcss_dec400d_addr_set(dcss_plane->dcss, p1_ba, caddr);
                        break;
                default:
index 639ed94..b37e757 100644 (file)
@@ -18,6 +18,7 @@
 #include <drm/drm_fourcc.h>
 
 #include <video/imx-dcss.h>
+#include <video/viv-metadata.h>
 #include "dcss-prv.h"
 
 #define USE_CTXLD                      1
 /* DEC400D registers offsets */
 #define DEC400D_READCONFIG_BASE                0x800
 #define DEC400D_READCONFIG(i)          (DEC400D_READCONFIG_BASE + ((i) << 2))
+#define DEC400D_READCONFIG_BASE     0x800
+#define DEC400D_READBUFFERBASE0     0x900
+#define DEC400D_READCACHEBASE0      0x980
+#define DEC400D_CONTROL             0xB00
+#define DEC400D_CLEAR               0xB80
 #define   COMPRESSION_ENABLE_BIT       0
 #define   COMPRESSION_FORMAT_BIT       3
 #define   COMPRESSION_ALIGN_MODE_BIT   16
 #define DEC400D_CONTROL                        0xB00
 #define   DISABLE_COMPRESSION_BIT      1
 #define   SHADOW_TRIGGER_BIT           29
+#define DEC400_CFMT_ARGB8           0x0
+#define DEC400_CFMT_XRGB8           0x1
+#define DEC400_CFMT_AYUV            0x2
+#define DEC400_CFMT_UYVY            0x3
+#define DEC400_CFMT_YUY2            0x4
+#define DEC400_CFMT_YUV_ONLY        0x5
+#define DEC400_CFMT_UV_MIX          0x6
+#define DEC400_CFMT_ARGB4           0x7
+#define DEC400_CFMT_XRGB4           0x8
+#define DEC400_CFMT_A1R5G5B5        0x9
+#define DEC400_CFMT_X1R5G5B5        0xA
+#define DEC400_CFMT_R5G6B5          0xB
+#define DEC400_CFMT_Z24S8           0xC
+#define DEC400_CFMT_Z24             0xD
+#define DEC400_CFMT_Z16             0xE
+#define DEC400_CFMT_A2R10G10B10     0xF
+#define DEC400_CFMT_BAYER           0x10
+#define DEC400_CFMT_SIGNED_BAYER    0x11
 
 struct dcss_dec400d_priv {
        struct dcss_soc *dcss;
@@ -118,7 +142,7 @@ void dcss_dec400d_bypass(struct dcss_soc *dcss)
        uint32_t control;
        struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
 
-       dcss_dec400d_read_config(dcss, 0, false);
+       dcss_dec400d_read_config(dcss, 0, false, 0);
 
        control = dcss_readl(dec400d->dec400d_reg + DEC400D_CONTROL);
        pr_debug("%s: dec400d control = %#x\n", __func__, control);
@@ -169,8 +193,10 @@ EXPORT_SYMBOL(dcss_dec400d_addr_set);
 
 void dcss_dec400d_read_config(struct dcss_soc *dcss,
                              uint32_t read_id,
-                             bool compress_en)
+                             bool compress_en,
+                             uint32_t compress_format)
 {
+       uint32_t cformat = 0;
        uint32_t read_config = 0x0;
        struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
 
@@ -183,17 +209,70 @@ void dcss_dec400d_read_config(struct dcss_soc *dcss,
        if (compress_en == false)
                goto config;
 
-       switch (dec400d->pixel_format) {
-       case DRM_FORMAT_ARGB8888:
-       case DRM_FORMAT_XRGB8888:
-               read_config |= 0x0 << COMPRESSION_FORMAT_BIT;
-               break;
+       switch (compress_format) {
+           case _VIV_CFMT_ARGB8:
+               cformat = DEC400_CFMT_ARGB8;
+               break;
+           case _VIV_CFMT_XRGB8:
+               cformat = DEC400_CFMT_XRGB8;
+               break;
+           case _VIV_CFMT_AYUV:
+               cformat = DEC400_CFMT_AYUV;
+               break;
+           case _VIV_CFMT_UYVY:
+               cformat = DEC400_CFMT_UYVY;
+               break;
+           case _VIV_CFMT_YUY2:
+               cformat = DEC400_CFMT_YUY2;
+               break;
+           case _VIV_CFMT_YUV_ONLY:
+               cformat = DEC400_CFMT_YUV_ONLY;
+               break;
+           case _VIV_CFMT_UV_MIX:
+               cformat = DEC400_CFMT_UV_MIX;
+               break;
+           case _VIV_CFMT_ARGB4:
+               cformat = DEC400_CFMT_ARGB4;
+               break;
+           case _VIV_CFMT_XRGB4:
+               cformat = DEC400_CFMT_XRGB4;
+               break;
+           case _VIV_CFMT_A1R5G5B5:
+               cformat = DEC400_CFMT_A1R5G5B5;
+               break;
+           case _VIV_CFMT_X1R5G5B5:
+               cformat = DEC400_CFMT_X1R5G5B5;
+               break;
+           case _VIV_CFMT_R5G6B5:
+               cformat = DEC400_CFMT_R5G6B5;
+               break;
+           case _VIV_CFMT_Z24S8:
+               cformat = DEC400_CFMT_Z24S8;
+               break;
+           case _VIV_CFMT_Z24:
+               cformat = DEC400_CFMT_Z24;
+               break;
+           case _VIV_CFMT_Z16:
+               cformat = DEC400_CFMT_Z16;
+               break;
+           case _VIV_CFMT_A2R10G10B10:
+               cformat = DEC400_CFMT_A2R10G10B10;
+               break;
+           case _VIV_CFMT_BAYER:
+               cformat = DEC400_CFMT_BAYER;
+               break;
+           case _VIV_CFMT_SIGNED_BAYER:
+               cformat = DEC400_CFMT_SIGNED_BAYER;
+               break;
        default:
                /* TODO: not support yet */
                WARN_ON(1);
                return;
        }
 
+       /* Dec compress format */
+       read_config |= cformat << COMPRESSION_FORMAT_BIT;
+
        /* ALIGN32_BYTE */
        read_config |= 0x2 << COMPRESSION_ALIGN_MODE_BIT;
 
@@ -211,6 +290,16 @@ config:
 }
 EXPORT_SYMBOL(dcss_dec400d_read_config);
 
+void dcss_dec400d_fast_clear_config(struct dcss_soc *dcss,
+                                   uint32_t fc_value,
+                                   bool enable)
+{
+       struct dcss_dec400d_priv *dec400d = dcss->dec400d_priv;
+
+       dcss_dec400d_write(dec400d, fc_value, DEC400D_CLEAR);
+}
+EXPORT_SYMBOL(dcss_dec400d_fast_clear_config);
+
 void dcss_dec400d_enable(struct dcss_soc *dcss)
 {
        uint32_t control;
index 7afd03c..03330f3 100644 (file)
@@ -25,21 +25,6 @@ struct dcss_client_platformdata {
        struct device_node *of_node;
 };
 
-#define VIV_VIDMEM_METADATA_MAGIC fourcc_code('v', 'i', 'v', 'm')
-
-struct dma_metadata {
-       uint32_t magic;
-       int32_t  ts_buf_fd;
-       void *ts_dma_buf;
-
-       uint32_t fc_enabled;
-       uint32_t fc_value;
-       uint32_t fc_value_upper;
-
-       uint32_t compressed;
-       uint32_t compressed_format;
-};
-
 /* COMMON */
 int dcss_vblank_irq_get(struct dcss_soc *dcss);
 void dcss_vblank_irq_enable(struct dcss_soc *dcss, bool en);
@@ -193,6 +178,10 @@ void dcss_dec400d_addr_set(struct dcss_soc *dcss,
                           uint32_t caddr);
 void dcss_dec400d_read_config(struct dcss_soc *dcss,
                              uint32_t read_id,
-                             bool compress_en);
+                             bool compress_en,
+                             uint32_t compress_format);
+void dcss_dec400d_fast_clear_config(struct dcss_soc *dcss,
+                                    uint32_t fc_value,
+                                    bool enable);
 void dcss_dec400d_enable(struct dcss_soc *dcss);
 #endif /* __IMX_DCSS_H__ */
diff --git a/include/video/viv-metadata.h b/include/video/viv-metadata.h
new file mode 100644 (file)
index 0000000..82b52c4
--- /dev/null
@@ -0,0 +1,74 @@
+/******************************************************************************\
+|*                                                                            *|
+|* Copyright (c) 2007-2018 by Vivante Corp.  All rights reserved.             *|
+|*                                                                            *|
+|* The material in this file is confidential and contains trade secrets of    *|
+|* Vivante Corporation.  This is proprietary information owned by Vivante     *|
+|* Corporation.  No part of this work may be disclosed, reproduced, copied,   *|
+|* transmitted, or used in any way for any purpose, without the express       *|
+|* written permission of Vivante Corporation.                                 *|
+|*                                                                            *|
+\******************************************************************************/
+
+#ifndef __VIV_METADATA_H__
+#define __VIV_METADATA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macro to combine four characters into a Character Code. */
+#define __FOURCC(a, b, c, d) \
+    ((uint32_t)(a) | ((uint32_t)(b) << 8) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
+
+#define VIV_VIDMEM_METADATA_MAGIC __FOURCC('v', 'i', 'v', 'm')
+
+/* Compressed format now was defined same as dec400d, should be general. */
+typedef enum _VIV_COMPRESS_FMT
+{
+    _VIV_CFMT_ARGB8 = 0,
+    _VIV_CFMT_XRGB8,
+    _VIV_CFMT_AYUV,
+    _VIV_CFMT_UYVY,
+    _VIV_CFMT_YUY2,
+    _VIV_CFMT_YUV_ONLY,
+    _VIV_CFMT_UV_MIX,
+    _VIV_CFMT_ARGB4,
+    _VIV_CFMT_XRGB4,
+    _VIV_CFMT_A1R5G5B5,
+    _VIV_CFMT_X1R5G5B5,
+    _VIV_CFMT_R5G6B5,
+    _VIV_CFMT_Z24S8,
+    _VIV_CFMT_Z24,
+    _VIV_CFMT_Z16,
+    _VIV_CFMT_A2R10G10B10,
+    _VIV_CFMT_BAYER,
+    _VIV_CFMT_SIGNED_BAYER,
+    _VIV_CFMT_VAA16,
+    _VIV_CFMT_S8,
+
+    _VIV_CFMT_MAX,
+} _VIV_COMPRESS_FMT;
+
+/* Metadata for cross-device fd share with additional (ts) info. */
+typedef struct _VIV_VIDMEM_METADATA
+{
+    uint32_t magic;
+
+    int32_t  ts_fd;
+    void *   ts_dma_buf;
+
+    uint32_t fc_enabled;
+    uint32_t fc_value;
+    uint32_t fc_value_upper;
+
+    uint32_t compressed;
+    uint32_t compress_format;
+} _VIV_VIDMEM_METADATA;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VIV_METADATA_H__ */
+