The video processor supports a tiled variant of the NV12 format,
known as NV12MT in V4L2 terms. The support was removed in commit
083500baefd5f4c215a5a93aef2492c1aa775828 due to not being a real
pixel format, but rather NV12MT with a special memory layout.

With the introduction of FB modifiers, we can now properly support
this format again.

Tested with a hacked up modetest from libdrm's test suite on
an ODROID-X2 (Exynos4412).

Signed-off-by: Tobias Jakobi <tjak...@math.uni-bielefeld.de>
---
 drivers/gpu/drm/exynos/exynos_drm_drv.h   |  1 +
 drivers/gpu/drm/exynos/exynos_drm_fb.c    |  2 ++
 drivers/gpu/drm/exynos/exynos_drm_plane.c | 27 +++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_mixer.c     |  6 +++++-
 4 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h 
b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index cf6e08c..ee62b0b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -91,6 +91,7 @@ struct exynos_drm_plane {
 #define EXYNOS_DRM_PLANE_CAP_DOUBLE    (1 << 0)
 #define EXYNOS_DRM_PLANE_CAP_SCALE     (1 << 1)
 #define EXYNOS_DRM_PLANE_CAP_ZPOS      (1 << 2)
+#define EXYNOS_DRM_PLANE_CAP_TILE      (1 << 3)
 
 /*
  * Exynos DRM plane configuration structure.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c 
b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index c77a5ac..35b7ab2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -238,4 +238,6 @@ void exynos_drm_mode_config_init(struct drm_device *dev)
 
        dev->mode_config.funcs = &exynos_drm_mode_config_funcs;
        dev->mode_config.helper_private = &exynos_drm_mode_config_helpers;
+
+       dev->mode_config.allow_fb_modifiers = true;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c 
b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index c2f17f3..fa6333d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -180,6 +180,29 @@ static struct drm_plane_funcs exynos_plane_funcs = {
 };
 
 static int
+exynos_drm_plane_check_format(const struct exynos_drm_plane_config *config,
+                             struct exynos_drm_plane_state *state)
+{
+       struct drm_framebuffer *fb = state->base.fb;
+
+       switch (fb->modifier) {
+       case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
+               if (!(config->capabilities & EXYNOS_DRM_PLANE_CAP_TILE))
+                       return -ENOTSUPP;
+               break;
+
+       case 0:
+               break;
+
+       default:
+               DRM_ERROR("unsupported pixel format modifier");
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int
 exynos_drm_plane_check_size(const struct exynos_drm_plane_config *config,
                            struct exynos_drm_plane_state *state)
 {
@@ -223,6 +246,10 @@ static int exynos_plane_atomic_check(struct drm_plane 
*plane,
        /* translate state into exynos_state */
        exynos_plane_mode_set(exynos_state);
 
+       ret = exynos_drm_plane_check_format(exynos_plane->config, exynos_state);
+       if (ret)
+               return ret;
+
        ret = exynos_drm_plane_check_size(exynos_plane->config, exynos_state);
        return ret;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c 
b/drivers/gpu/drm/exynos/exynos_mixer.c
index 77f18f6..35edbf2 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -149,7 +149,8 @@ static const struct exynos_drm_plane_config 
plane_configs[MIXER_WIN_NR] = {
                .pixel_formats = vp_formats,
                .num_pixel_formats = ARRAY_SIZE(vp_formats),
                .capabilities = EXYNOS_DRM_PLANE_CAP_SCALE |
-                               EXYNOS_DRM_PLANE_CAP_ZPOS,
+                               EXYNOS_DRM_PLANE_CAP_ZPOS |
+                               EXYNOS_DRM_PLANE_CAP_TILE,
        },
 };
 
@@ -501,6 +502,9 @@ static void vp_video_buffer(struct mixer_context *ctx,
                return;
        }
 
+       if (fb->modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
+               tiled_mode = true;
+
        luma_addr[0] = exynos_drm_fb_dma_addr(fb, 0);
        chroma_addr[0] = exynos_drm_fb_dma_addr(fb, 1);
 
-- 
2.7.3

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

Reply via email to