diff mbox

[2/2] drm/msm: Support NV12MT format in mdp4

Message ID 1424443346-9935-2-git-send-email-gbeeresh@codeaurora.org (mailing list archive)
State Accepted
Headers show

Commit Message

Beeresh Gopal Feb. 20, 2015, 2:42 p.m. UTC
Using fb modifier flag, support NV12MT format
in MDP4

Change-Id: I3de92b0c3b6d0cb56647aed6e4e35e56eff7adab
Signed-off-by: Beeresh Gopal <gbeeresh@codeaurora.org>
Signed-off-by: Stephane Viau <sviau@codeaurora.org>
---
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c   |  9 +++++++++
 drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | 22 ++++++++++++++++++++++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c   |  5 +++++
 drivers/gpu/drm/msm/msm_drv.c             |  2 ++
 drivers/gpu/drm/msm/msm_kms.h             |  1 +
 include/uapi/drm/drm_fourcc.h             | 14 ++++++++++++++
 6 files changed, 53 insertions(+)

Comments

Daniel Vetter Feb. 22, 2015, 10:34 a.m. UTC | #1
On Fri, Feb 20, 2015 at 3:42 PM, Beeresh Gopal <gbeeresh@codeaurora.org> wrote:
> +/* Samsung framebuffer modifiers */
> +
> +/*
> + * NV12 64x32 Tiled
> + *
> + * 2 planes Y and CbCr, grouped into 64x32 macro tiles,
> + * with a non-standard order in memory (Z-shape).
> + *
> + * Pixel layout identical to DRM_FORMAT_NV21 format:
> + * index 0 = Y plane, [7:0] Y
> + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
> + */
> +#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)

This description mixes layout information with pixel format. Strictly
speaking you could use this for other formats, but since the
description doesn't mention whether this is in bytes or pixels that's
a bit awkward. Or just mandatae that this can only be used with NV12
fourcc (and maybe add a check for that into the core drm code.

Also, is this really samsung and not mpeg?
-Daniel
Stephane Viau March 13, 2015, 2:51 p.m. UTC | #2
Hi Daniel,

> On Fri, Feb 20, 2015 at 3:42 PM, Beeresh Gopal <gbeeresh@codeaurora.org>
> wrote:
>> +/* Samsung framebuffer modifiers */
>> +
>> +/*
>> + * NV12 64x32 Tiled
>> + *
>> + * 2 planes Y and CbCr, grouped into 64x32 macro tiles,
>> + * with a non-standard order in memory (Z-shape).
>> + *
>> + * Pixel layout identical to DRM_FORMAT_NV21 format:
>> + * index 0 = Y plane, [7:0] Y
>> + * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
>> + */
>> +#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
>
> This description mixes layout information with pixel format. Strictly
> speaking you could use this for other formats, but since the
> description doesn't mention whether this is in bytes or pixels that's
> a bit awkward. Or just mandatae that this can only be used with NV12
> fourcc (and maybe add a check for that into the core drm code.

Agreed: I think /* Tiled: 64x32 pixel macroblocks */ - or something along
those lines - as a description should do the trick.

>
> Also, is this really samsung and not mpeg?

From my understanding the VENDOR is actually SAMSUNG for the following
reasons:
 a) V4L2_PIX_FMT_NV12MT has  been introduced[1] for the Samsung?s s5p-fimc
driver (which got renamed into exynos4-is[2])
 b) A search on ?V4L2_PIX_FMT_NV12MT? in the drivers folder only returns
Samsung drivers so far..

[1]
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=4a3c9b4f0df43207eb0b4d0da9cb51e185506bd5
[2]
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=56fa1a6a6a7da91e7ece8b01b0ae8adb2926e434


> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
>

Stéphane
diff mbox

Patch

diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index d81e19d..24c38d4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -157,6 +157,14 @@  static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
 	mdp4_disable(mdp4_kms);
 }
 
+static void mdp4_set_mode_config(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	struct drm_device *dev = mdp4_kms->dev;
+
+	dev->mode_config.allow_fb_modifiers = true;
+}
+
 static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
 		struct drm_encoder *encoder)
 {
@@ -197,6 +205,7 @@  static const struct mdp_kms_funcs kms_funcs = {
 		.complete_commit = mdp4_complete_commit,
 		.get_format      = mdp_get_format,
 		.round_pixclk    = mdp4_round_pixclk,
+		.set_mode_config = mdp4_set_mode_config,
 		.preclose        = mdp4_preclose,
 		.destroy         = mdp4_destroy,
 	},
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
index cde2500..2c2d6a5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c
@@ -33,6 +33,21 @@  struct mdp4_plane {
 };
 #define to_mdp4_plane(x) container_of(x, struct mdp4_plane, base)
 
+/* MDP format helper functions */
+static inline
+enum mdp4_frame_format mdp4_get_frame_format(struct drm_framebuffer *fb)
+{
+	bool is_tile = false;
+
+	if (fb->modifier[1] == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
+		is_tile = true;
+
+	if (fb->pixel_format == DRM_FORMAT_NV12 && is_tile)
+		return FRAME_TILE_YCBCR_420;
+
+	return FRAME_LINEAR;
+}
+
 static void mdp4_plane_set_scanout(struct drm_plane *plane,
 		struct drm_framebuffer *fb);
 static int mdp4_plane_mode_set(struct drm_plane *plane,
@@ -203,6 +218,7 @@  static int mdp4_plane_mode_set(struct drm_plane *plane,
 	uint32_t op_mode = 0;
 	uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
 	uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
+	enum mdp4_frame_format frame_type = mdp4_get_frame_format(fb);
 
 	if (!(crtc && fb)) {
 		DBG("%s: disabled!", mdp4_plane->name);
@@ -302,6 +318,7 @@  static int mdp4_plane_mode_set(struct drm_plane *plane,
 			MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
 			MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) |
 			MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) |
+			MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT(frame_type) |
 			COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT));
 
 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
@@ -322,6 +339,11 @@  static int mdp4_plane_mode_set(struct drm_plane *plane,
 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
 	mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
 
+	if (frame_type != FRAME_LINEAR)
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_SSTILE_FRAME_SIZE(pipe),
+				MDP4_PIPE_SSTILE_FRAME_SIZE_WIDTH(src_w) |
+				MDP4_PIPE_SSTILE_FRAME_SIZE_HEIGHT(src_h));
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 92b61db..9cb5a5d 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -80,6 +80,10 @@  static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
 	mdp5_disable(mdp5_kms);
 }
 
+static void mdp5_set_mode_config(struct msm_kms *kms)
+{
+}
+
 static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate,
 		struct drm_encoder *encoder)
 {
@@ -131,6 +135,7 @@  static const struct mdp_kms_funcs kms_funcs = {
 		.complete_commit = mdp5_complete_commit,
 		.get_format      = mdp_get_format,
 		.round_pixclk    = mdp5_round_pixclk,
+		.set_mode_config = mdp5_set_mode_config,
 		.preclose        = mdp5_preclose,
 		.destroy         = mdp5_destroy,
 	},
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index dfd583f..a72ed0a 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -281,6 +281,8 @@  static int msm_load(struct drm_device *dev, unsigned long flags)
 			dev_err(dev->dev, "kms hw init failed: %d\n", ret);
 			goto fail;
 		}
+
+		kms->funcs->set_mode_config(kms);
 	}
 
 	dev->mode_config.min_width = 0;
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 3a78cb4..d6e3bb4 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -47,6 +47,7 @@  struct msm_kms_funcs {
 	const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
 	long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
 			struct drm_encoder *encoder);
+	void (*set_mode_config)(struct msm_kms *kms);
 	/* cleanup: */
 	void (*preclose)(struct msm_kms *kms, struct drm_file *file);
 	void (*destroy)(struct msm_kms *kms);
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 188e61f..1546302 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -161,4 +161,18 @@ 
  * authoritative source for all of these.
  */
 
+/* Samsung framebuffer modifiers */
+
+/*
+ * NV12 64x32 Tiled
+ *
+ * 2 planes Y and CbCr, grouped into 64x32 macro tiles,
+ * with a non-standard order in memory (Z-shape).
+ *
+ * Pixel layout identical to DRM_FORMAT_NV21 format:
+ * index 0 = Y plane, [7:0] Y
+ * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian
+ */
+#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1)
+
 #endif /* DRM_FOURCC_H */