All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place
@ 2019-03-19 21:57 Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes Maxime Ripard
                   ` (19 more replies)
  0 siblings, 20 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Hi,

DRM comes with an extensive format support to retrieve the various
parameters associated with a given format (such as the subsampling, or the
bits per pixel), as well as some helpers and utilities to ease the driver
development.

v4l2, on the other side, doesn't provide such facilities, leaving each
driver reimplement a subset of the formats parameters for the one supported
by that particular driver. This leads to a lot of duplication and
boilerplate code in the v4l2 drivers.

This series tries to address this by moving the DRM format API into lib and
turning it into a more generic API. In order to do this, we've needed to do
some preliminary changes on the DRM drivers, then moved the API and finally
converted a v4l2 driver to give an example of how such library could be
used.

Let me know what you think,
Maxime

Maxime Ripard (20):
  drm: Remove users of drm_format_num_planes
  drm: Remove users of drm_format_(horz|vert)_chroma_subsampling
  drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
  drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height
  drm: Replace instances of drm_format_info by drm_get_format_info
  lib: Add video format information library
  drm/fb: Move from drm_format_info to image_format_info
  drm/malidp: Convert to generic image format library
  drm/client: Convert to generic image format library
  drm/exynos: Convert to generic image format library
  drm/i915: Convert to generic image format library
  drm/ipuv3: Convert to generic image format library
  drm/msm: Convert to generic image format library
  drm/omap: Convert to generic image format library
  drm/rockchip: Convert to generic image format library
  drm/tegra: Convert to generic image format library
  drm/fourcc: Remove old DRM format API
  lib: image-formats: Add v4l2 formats support
  lib: image-formats: Add more functions
  media: sun6i: Convert to the image format API

 drivers/gpu/drm/Kconfig                             |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c              |   4 +-
 drivers/gpu/drm/arm/malidp_drv.c                    |   5 +-
 drivers/gpu/drm/arm/malidp_hw.c                     |   4 +-
 drivers/gpu/drm/arm/malidp_mw.c                     |   2 +-
 drivers/gpu/drm/arm/malidp_planes.c                 |   8 +-
 drivers/gpu/drm/armada/armada_fb.c                  |   3 +-
 drivers/gpu/drm/armada/armada_overlay.c             |   3 +-
 drivers/gpu/drm/armada/armada_plane.c               |   3 +-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c     |  13 +-
 drivers/gpu/drm/bochs/bochs.h                       |   4 +-
 drivers/gpu/drm/bochs/bochs_hw.c                    |   3 +-
 drivers/gpu/drm/cirrus/cirrus_fbdev.c               |   4 +-
 drivers/gpu/drm/cirrus/cirrus_main.c                |   4 +-
 drivers/gpu/drm/drm_atomic.c                        |   1 +-
 drivers/gpu/drm/drm_client.c                        |   8 +-
 drivers/gpu/drm/drm_crtc.c                          |   1 +-
 drivers/gpu/drm/drm_fb_cma_helper.c                 |   5 +-
 drivers/gpu/drm/drm_fb_helper.c                     |  15 +-
 drivers/gpu/drm/drm_fourcc.c                        | 318 +-----
 drivers/gpu/drm/drm_framebuffer.c                   |  11 +-
 drivers/gpu/drm/drm_gem_framebuffer_helper.c        |   5 +-
 drivers/gpu/drm/drm_plane.c                         |   1 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.c              |   3 +-
 drivers/gpu/drm/exynos/exynos_drm_ipp.c             |   2 +-
 drivers/gpu/drm/exynos/exynos_drm_ipp.h             |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_scaler.c          |   3 +-
 drivers/gpu/drm/gma500/framebuffer.c                |   4 +-
 drivers/gpu/drm/i915/i915_drv.h                     |   6 +-
 drivers/gpu/drm/i915/intel_display.c                |  15 +-
 drivers/gpu/drm/i915/intel_sprite.c                 |   3 +-
 drivers/gpu/drm/imx/ipuv3-plane.c                   |  20 +-
 drivers/gpu/drm/mediatek/mtk_drm_fb.c               |   8 +-
 drivers/gpu/drm/meson/meson_overlay.c               |  14 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c         |  11 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c           |  10 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c           |   4 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c          |  25 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c            |   8 +-
 drivers/gpu/drm/msm/msm_fb.c                        |  18 +-
 drivers/gpu/drm/omapdrm/dss/dispc.c                 |   9 +-
 drivers/gpu/drm/omapdrm/omap_fb.c                   |  15 +-
 drivers/gpu/drm/radeon/radeon_fb.c                  |   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c          |  17 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c         |  14 +-
 drivers/gpu/drm/selftests/Makefile                  |   3 +-
 drivers/gpu/drm/selftests/drm_modeset_selftests.h   |   3 +-
 drivers/gpu/drm/selftests/test-drm_format.c         | 280 +----
 drivers/gpu/drm/selftests/test-drm_modeset_common.h |   3 +-
 drivers/gpu/drm/stm/ltdc.c                          |   2 +-
 drivers/gpu/drm/sun4i/sun4i_backend.c               |   7 +-
 drivers/gpu/drm/sun4i/sun4i_frontend.c              |  19 +-
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c              |   2 +-
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c              |   6 +-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c             |   6 +-
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h             |   5 +-
 drivers/gpu/drm/tegra/fb.c                          |  14 +-
 drivers/gpu/drm/tegra/plane.c                       |   4 +-
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c      |   2 +-
 drivers/gpu/drm/vc4/vc4_plane.c                     |  15 +-
 drivers/gpu/drm/zte/zx_plane.c                      |   6 +-
 drivers/gpu/ipu-v3/ipu-pre.c                        |   3 +-
 drivers/gpu/ipu-v3/ipu-prg.c                        |   3 +-
 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c  |  88 +-
 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h  |  46 +-
 include/drm/drm_fourcc.h                            | 219 +---
 include/drm/drm_framebuffer.h                       |   3 +-
 include/drm/drm_mode_config.h                       |   4 +-
 include/linux/image-formats.h                       | 253 ++++-
 lib/Kconfig                                         |   7 +-
 lib/Makefile                                        |   3 +-
 lib/image-formats-selftests.c                       | 326 +++++-
 lib/image-formats.c                                 | 869 +++++++++++++-
 73 files changed, 1719 insertions(+), 1126 deletions(-)
 delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c
 create mode 100644 include/linux/image-formats.h
 create mode 100644 lib/image-formats-selftests.c
 create mode 100644 lib/image-formats.c

base-commit: 98f41dc3b3eeabfc80d5d5eb1c1a6294ff59b4ec
-- 
git-series 0.9.1

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-20 14:16   ` Paul Kocialkowski
  2019-04-02  9:43   ` Emil Velikov
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                   ` (18 subsequent siblings)
  19 siblings, 2 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

drm_format_num_planes() is basically a lookup in the drm_format_info table
plus an access to the num_planes field of the appropriate entry.

Most drivers are using this function while having access to the entry
already, which means that we will perform an unnecessary lookup. Removing
the call to drm_format_num_planes is therefore more efficient.

Some drivers will not have access to that entry in the function, but in
this case the overhead is minimal (we just have to call drm_format_info()
to perform the lookup) and we can even avoid multiple, inefficient lookups
in some places that need multiple fields from the drm_format_info
structure.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/arm/malidp_mw.c             |  2 +-
 drivers/gpu/drm/armada/armada_fb.c          |  3 ++-
 drivers/gpu/drm/drm_fourcc.c                | 16 ----------------
 drivers/gpu/drm/mediatek/mtk_drm_fb.c       |  6 ++++--
 drivers/gpu/drm/meson/meson_overlay.c       |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c |  9 ++++++---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c    |  3 ++-
 drivers/gpu/drm/msm/msm_fb.c                |  8 ++++++--
 drivers/gpu/drm/omapdrm/omap_fb.c           |  4 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  6 +++---
 drivers/gpu/drm/tegra/fb.c                  |  3 ++-
 drivers/gpu/drm/vc4/vc4_plane.c             |  2 +-
 drivers/gpu/drm/zte/zx_plane.c              |  4 +---
 include/drm/drm_fourcc.h                    |  1 -
 14 files changed, 32 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index 041a64dc7167..91580b7a3781 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -153,7 +153,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
 		return -EINVAL;
 	}
 
-	n_planes = drm_format_num_planes(fb->format->format);
+	n_planes = fb->format->num_planes;
 	for (i = 0; i < n_planes; i++) {
 		struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i);
 		/* memory write buffers are never rotated */
diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
index 058ac7d9920f..a2f6472eb482 100644
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ b/drivers/gpu/drm/armada/armada_fb.c
@@ -87,6 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
 struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 	struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev, mode);
 	struct armada_gem_object *obj;
 	struct armada_framebuffer *dfb;
 	int ret;
@@ -97,7 +98,7 @@ struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 		mode->pitches[2]);
 
 	/* We can only handle a single plane at the moment */
-	if (drm_format_num_planes(mode->pixel_format) > 1 &&
+	if (info->num_planes > 1 &&
 	    (mode->handles[0] != mode->handles[1] ||
 	     mode->handles[0] != mode->handles[2])) {
 		ret = -EINVAL;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index ba7e19d4336c..22c7fa459f65 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -306,22 +306,6 @@ drm_get_format_info(struct drm_device *dev,
 EXPORT_SYMBOL(drm_get_format_info);
 
 /**
- * drm_format_num_planes - get the number of planes for format
- * @format: pixel format (DRM_FORMAT_*)
- *
- * Returns:
- * The number of planes used by the specified pixel format.
- */
-int drm_format_num_planes(uint32_t format)
-{
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
-	return info ? info->num_planes : 1;
-}
-EXPORT_SYMBOL(drm_format_num_planes);
-
-/**
  * drm_format_plane_cpp - determine the bytes per pixel value
  * @format: pixel format (DRM_FORMAT_*)
  * @plane: plane index
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index e20fcaef2851..68fdef8b12bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -32,10 +32,11 @@ static struct drm_framebuffer *mtk_drm_framebuffer_init(struct drm_device *dev,
 					const struct drm_mode_fb_cmd2 *mode,
 					struct drm_gem_object *obj)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev, mode);
 	struct drm_framebuffer *fb;
 	int ret;
 
-	if (drm_format_num_planes(mode->pixel_format) != 1)
+	if (info->num_planes != 1)
 		return ERR_PTR(-EINVAL);
 
 	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
@@ -88,6 +89,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
 					       struct drm_file *file,
 					       const struct drm_mode_fb_cmd2 *cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
 	struct drm_framebuffer *fb;
 	struct drm_gem_object *gem;
 	unsigned int width = cmd->width;
@@ -95,7 +97,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
 	unsigned int size, bpp;
 	int ret;
 
-	if (drm_format_num_planes(cmd->pixel_format) != 1)
+	if (info->num_planes != 1)
 		return ERR_PTR(-EINVAL);
 
 	gem = drm_gem_object_lookup(file, cmd->handles[0]);
diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
index 691a9fd16b36..8ff15d01a8f9 100644
--- a/drivers/gpu/drm/meson/meson_overlay.c
+++ b/drivers/gpu/drm/meson/meson_overlay.c
@@ -466,7 +466,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 	}
 
 	/* Update Canvas with buffer address */
-	priv->viu.vd1_planes = drm_format_num_planes(fb->format->format);
+	priv->viu.vd1_planes = fb->format->num_planes;
 
 	switch (priv->viu.vd1_planes) {
 	case 3:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index 0874f0a53bf9..1aed51b49be4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -1040,10 +1040,11 @@ int dpu_format_check_modified_format(
 		const struct drm_mode_fb_cmd2 *cmd,
 		struct drm_gem_object **bos)
 {
-	int ret, i, num_base_fmt_planes;
+	const struct drm_format_info *info;
 	const struct dpu_format *fmt;
 	struct dpu_hw_fmt_layout layout;
 	uint32_t bos_total_size = 0;
+	int ret, i;
 
 	if (!msm_fmt || !cmd || !bos) {
 		DRM_ERROR("invalid arguments\n");
@@ -1051,14 +1052,16 @@ int dpu_format_check_modified_format(
 	}
 
 	fmt = to_dpu_format(msm_fmt);
-	num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
+	info = drm_format_info(fmt->base.pixel_format);
+	if (!info)
+		return -EINVAL;
 
 	ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height,
 			&layout, cmd->pitches);
 	if (ret)
 		return ret;
 
-	for (i = 0; i < num_base_fmt_planes; i++) {
+	for (i = 0; i < info->num_planes; i++) {
 		if (!bos[i]) {
 			DRM_ERROR("invalid handle for plane %d\n", i);
 			return -EINVAL;
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index 6153514db04c..72ab8d89efa4 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -127,13 +127,14 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 		const struct mdp_format *format,
 		u32 width, bool hdecim)
 {
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(smp);
 	int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
 	int i, hsub, nplanes, nlines;
 	u32 fmt = format->base.pixel_format;
 	uint32_t blkcfg = 0;
 
-	nplanes = drm_format_num_planes(fmt);
+	nplanes = info->num_planes;
 	hsub = drm_format_horz_chroma_subsampling(fmt);
 
 	/* different if BWC (compressed framebuffer?) enabled: */
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 136058978e0f..432beddafb9e 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -106,9 +106,11 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
 struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
 		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct drm_gem_object *bos[4] = {0};
 	struct drm_framebuffer *fb;
-	int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
+	int ret, i, n = info->num_planes;
 
 	for (i = 0; i < n; i++) {
 		bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
@@ -135,6 +137,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
 static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_kms *kms = priv->kms;
 	struct msm_framebuffer *msm_fb = NULL;
@@ -147,7 +151,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
 			(char *)&mode_cmd->pixel_format);
 
-	n = drm_format_num_planes(mode_cmd->pixel_format);
+	n = info->num_planes;
 	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
 	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 4f8eb9d08f99..cfb641363a32 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -298,7 +298,9 @@ void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
 		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	unsigned int num_planes = drm_format_num_planes(mode_cmd->pixel_format);
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
+	unsigned int num_planes = info->num_planes;
 	struct drm_gem_object *bos[4];
 	struct drm_framebuffer *fb;
 	int i;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 97438bbbe389..606d176d5d96 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -74,19 +74,19 @@ static struct drm_framebuffer *
 rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 			const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct drm_framebuffer *fb;
 	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
 	struct drm_gem_object *obj;
 	unsigned int hsub;
 	unsigned int vsub;
-	int num_planes;
+	int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
 	int ret;
 	int i;
 
 	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
 	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
-	num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
-			 ROCKCHIP_MAX_FB_BUFFER);
 
 	for (i = 0; i < num_planes; i++) {
 		unsigned int width = mode_cmd->width / (i ? hsub : 1);
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 0a4ce05e00ab..bc8f9afd1b5f 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -131,6 +131,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 					struct drm_file *file,
 					const struct drm_mode_fb_cmd2 *cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
 	unsigned int hsub, vsub, i;
 	struct tegra_bo *planes[4];
 	struct drm_gem_object *gem;
@@ -140,7 +141,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
 	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
 
-	for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) {
+	for (i = 0; i < info->num_planes; i++) {
 		unsigned int width = cmd->width / (i ? hsub : 1);
 		unsigned int height = cmd->height / (i ? vsub : 1);
 		unsigned int size, bpp;
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 1babfeca0c92..138a9ff23b70 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -537,7 +537,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
 	u32 ctl0_offset = vc4_state->dlist_count;
 	const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
 	u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
-	int num_planes = drm_format_num_planes(format->drm);
+	int num_planes = fb->format->num_planes;
 	u32 h_subsample, v_subsample;
 	bool mix_plane_alpha;
 	bool covers_screen;
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 83d236fd893c..c6a8be444300 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -199,7 +199,6 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
 	u32 dst_x, dst_y, dst_w, dst_h;
 	uint32_t format;
 	int fmt;
-	int num_planes;
 	int i;
 
 	if (!fb)
@@ -218,9 +217,8 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
 	dst_h = drm_rect_height(dst);
 
 	/* Set up data address registers for Y, Cb and Cr planes */
-	num_planes = drm_format_num_planes(format);
 	paddr_reg = layer + VL_Y;
-	for (i = 0; i < num_planes; i++) {
+	for (i = 0; i < fb->format->num_planes; i++) {
 		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
 		paddr = cma_obj->paddr + fb->offsets[i];
 		paddr += src_y * fb->pitches[i];
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index b3d9d88ab290..41779b327d91 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -268,7 +268,6 @@ drm_get_format_info(struct drm_device *dev,
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
-int drm_format_num_planes(uint32_t format);
 int drm_format_plane_cpp(uint32_t format, int plane);
 int drm_format_horz_chroma_subsampling(uint32_t format);
 int drm_format_vert_chroma_subsampling(uint32_t format);
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-20 14:19     ` Paul Kocialkowski
  2019-03-19 21:57   ` Maxime Ripard
                   ` (17 subsequent siblings)
  19 siblings, 1 reply; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

drm_format_horz_chroma_subsampling and drm_format_vert_chroma_subsampling
are basically a lookup in the drm_format_info table plus an access to the
hsub and vsub fields of the appropriate entry.

Most drivers are using this function while having access to the entry
already, which means that we will perform an unnecessary lookup. Removing
the call to these functions is therefore more efficient.

Some drivers will not have access to that entry in the function, but in
this case the overhead is minimal (we just have to call drm_format_info()
to perform the lookup) and we can even avoid multiple, inefficient lookups
in some places that need multiple fields from the drm_format_info
structure.

This is amplified by the fact that most of the time the callers will have
to retrieve both the vsub and hsub fields, meaning that they would perform
twice the lookup.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |  9 +----
 drivers/gpu/drm/drm_fourcc.c                    | 34 +------------------
 drivers/gpu/drm/imx/ipuv3-plane.c               | 15 +++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c       |  9 +----
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c      | 24 +++++--------
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c        |  2 +-
 drivers/gpu/drm/msm/msm_fb.c                    |  8 +---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  9 +----
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c     | 13 ++-----
 drivers/gpu/drm/tegra/fb.c                      |  9 +----
 drivers/gpu/drm/vc4/vc4_plane.c                 | 13 ++-----
 include/drm/drm_fourcc.h                        |  2 +-
 12 files changed, 37 insertions(+), 110 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index e836e2de35ce..fdd607ad27fe 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
 	const struct drm_display_mode *mode;
 	struct drm_crtc_state *crtc_state;
 	unsigned int tmp;
-	int hsub = 1;
-	int vsub = 1;
 	int ret;
 	int i;
 
@@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
 	if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES)
 		return -EINVAL;
 
-	hsub = drm_format_horz_chroma_subsampling(fb->format->format);
-	vsub = drm_format_vert_chroma_subsampling(fb->format->format);
-
 	for (i = 0; i < state->nplanes; i++) {
 		unsigned int offset = 0;
-		int xdiv = i ? hsub : 1;
-		int ydiv = i ? vsub : 1;
+		int xdiv = i ? fb->format->hsub : 1;
+		int ydiv = i ? fb->format->vsub : 1;
 
 		state->bpp[i] = fb->format->cpp[i];
 		if (!state->bpp[i])
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 22c7fa459f65..04be330b7cae 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -326,40 +326,6 @@ int drm_format_plane_cpp(uint32_t format, int plane)
 EXPORT_SYMBOL(drm_format_plane_cpp);
 
 /**
- * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
- * @format: pixel format (DRM_FORMAT_*)
- *
- * Returns:
- * The horizontal chroma subsampling factor for the
- * specified pixel format.
- */
-int drm_format_horz_chroma_subsampling(uint32_t format)
-{
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
-	return info ? info->hsub : 1;
-}
-EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
-
-/**
- * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
- * @format: pixel format (DRM_FORMAT_*)
- *
- * Returns:
- * The vertical chroma subsampling factor for the
- * specified pixel format.
- */
-int drm_format_vert_chroma_subsampling(uint32_t format)
-{
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
-	return info ? info->vsub : 1;
-}
-EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
-
-/**
  * drm_format_plane_width - width of the plane given the first plane
  * @width: width of the first plane
  * @format: pixel format
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 21e964f6ab5c..2530143281b2 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -115,8 +115,8 @@ drm_plane_state_to_ubo(struct drm_plane_state *state)
 	cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
 	BUG_ON(!cma_obj);
 
-	x /= drm_format_horz_chroma_subsampling(fb->format->format);
-	y /= drm_format_vert_chroma_subsampling(fb->format->format);
+	x /= fb->format->hsub;
+	y /= fb->format->vsub;
 
 	return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
 	       fb->format->cpp[1] * x - eba;
@@ -134,8 +134,8 @@ drm_plane_state_to_vbo(struct drm_plane_state *state)
 	cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
 	BUG_ON(!cma_obj);
 
-	x /= drm_format_horz_chroma_subsampling(fb->format->format);
-	y /= drm_format_vert_chroma_subsampling(fb->format->format);
+	x /= fb->format->hsub;
+	y /= fb->format->vsub;
 
 	return cma_obj->paddr + fb->offsets[2] + fb->pitches[2] * y +
 	       fb->format->cpp[2] * x - eba;
@@ -348,7 +348,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
 	struct drm_framebuffer *old_fb = old_state->fb;
 	unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
 	bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
-	int hsub, vsub;
 	int ret;
 
 	/* Ok to disable */
@@ -467,10 +466,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
 		 * The x/y offsets must be even in case of horizontal/vertical
 		 * chroma subsampling.
 		 */
-		hsub = drm_format_horz_chroma_subsampling(fb->format->format);
-		vsub = drm_format_vert_chroma_subsampling(fb->format->format);
-		if (((state->src.x1 >> 16) & (hsub - 1)) ||
-		    ((state->src.y1 >> 16) & (vsub - 1)))
+		if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) ||
+		    ((state->src.y1 >> 16) & (fb->format->vsub - 1)))
 			return -EINVAL;
 		break;
 	case DRM_FORMAT_RGB565_A8:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6aefcd6db46b..a9492c488441 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -553,14 +553,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		const struct dpu_format *fmt, bool color_fill)
 {
-	uint32_t chroma_subsmpl_h, chroma_subsmpl_v;
+	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 
 	/* don't chroma subsample if decimating */
-	chroma_subsmpl_h =
-		drm_format_horz_chroma_subsampling(fmt->base.pixel_format);
-	chroma_subsmpl_v =
-		drm_format_vert_chroma_subsampling(fmt->base.pixel_format);
-
 	/* update scaler. calculate default config for QSEED3 */
 	_dpu_plane_setup_scaler3(pdpu, pstate,
 			drm_rect_width(&pdpu->pipe_cfg.src_rect),
@@ -568,7 +563,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
 			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
 			&pstate->scaler3_cfg, fmt,
-			chroma_subsmpl_h, chroma_subsmpl_v);
+			info->hsub, info->vsub);
 }
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index be13140967b4..9d9fb6c5fd68 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -650,10 +650,10 @@ static int calc_scalex_steps(struct drm_plane *plane,
 		uint32_t pixel_format, uint32_t src, uint32_t dest,
 		uint32_t phasex_steps[COMP_MAX])
 {
+	const struct drm_format_info *info = drm_format_info(pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
 	struct device *dev = mdp5_kms->dev->dev;
 	uint32_t phasex_step;
-	unsigned int hsub;
 	int ret;
 
 	ret = calc_phase_step(src, dest, &phasex_step);
@@ -662,11 +662,9 @@ static int calc_scalex_steps(struct drm_plane *plane,
 		return ret;
 	}
 
-	hsub = drm_format_horz_chroma_subsampling(pixel_format);
-
 	phasex_steps[COMP_0]   = phasex_step;
 	phasex_steps[COMP_3]   = phasex_step;
-	phasex_steps[COMP_1_2] = phasex_step / hsub;
+	phasex_steps[COMP_1_2] = phasex_step / info->hsub;
 
 	return 0;
 }
@@ -675,10 +673,10 @@ static int calc_scaley_steps(struct drm_plane *plane,
 		uint32_t pixel_format, uint32_t src, uint32_t dest,
 		uint32_t phasey_steps[COMP_MAX])
 {
+	const struct drm_format_info *info = drm_format_info(pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
 	struct device *dev = mdp5_kms->dev->dev;
 	uint32_t phasey_step;
-	unsigned int vsub;
 	int ret;
 
 	ret = calc_phase_step(src, dest, &phasey_step);
@@ -687,11 +685,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
 		return ret;
 	}
 
-	vsub = drm_format_vert_chroma_subsampling(pixel_format);
-
 	phasey_steps[COMP_0]   = phasey_step;
 	phasey_steps[COMP_3]   = phasey_step;
-	phasey_steps[COMP_1_2] = phasey_step / vsub;
+	phasey_steps[COMP_1_2] = phasey_step / info->vsub;
 
 	return 0;
 }
@@ -699,8 +695,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
 static uint32_t get_scale_config(const struct mdp_format *format,
 		uint32_t src, uint32_t dst, bool horz)
 {
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
 	bool scaling = format->is_yuv ? true : (src != dst);
-	uint32_t sub, pix_fmt = format->base.pixel_format;
+	uint32_t sub;
 	uint32_t ya_filter, uv_filter;
 	bool yuv = format->is_yuv;
 
@@ -708,8 +705,7 @@ static uint32_t get_scale_config(const struct mdp_format *format,
 		return 0;
 
 	if (yuv) {
-		sub = horz ? drm_format_horz_chroma_subsampling(pix_fmt) :
-			     drm_format_vert_chroma_subsampling(pix_fmt);
+		sub = horz ? info->hsub : info->vsub;
 		uv_filter = ((src / sub) <= dst) ?
 				   SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
 	}
@@ -754,7 +750,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
 	uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
 	uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
 {
-	uint32_t pix_fmt = format->base.pixel_format;
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
 	uint32_t lr, tb, req;
 	int i;
 
@@ -763,8 +759,8 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
 		uint32_t roi_h = src_h;
 
 		if (format->is_yuv && i == COMP_1_2) {
-			roi_w /= drm_format_horz_chroma_subsampling(pix_fmt);
-			roi_h /= drm_format_vert_chroma_subsampling(pix_fmt);
+			roi_w /= info->hsub;
+			roi_h /= info->vsub;
 		}
 
 		lr  = (pe_left[i] >= 0) ?
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index 72ab8d89efa4..b30b2f4efc60 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -135,7 +135,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 	uint32_t blkcfg = 0;
 
 	nplanes = info->num_planes;
-	hsub = drm_format_horz_chroma_subsampling(fmt);
+	hsub = info->hsub;
 
 	/* different if BWC (compressed framebuffer?) enabled: */
 	nlines = 2;
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index 432beddafb9e..f69c0afd6ec6 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -145,16 +145,12 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 	struct drm_framebuffer *fb;
 	const struct msm_format *format;
 	int ret, i, n;
-	unsigned int hsub, vsub;
 
 	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
 			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
 			(char *)&mode_cmd->pixel_format);
 
 	n = info->num_planes;
-	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
-	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
-
 	format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
 			mode_cmd->modifier[0]);
 	if (!format) {
@@ -180,8 +176,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 	}
 
 	for (i = 0; i < n; i++) {
-		unsigned int width = mode_cmd->width / (i ? hsub : 1);
-		unsigned int height = mode_cmd->height / (i ? vsub : 1);
+		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
+		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
 		unsigned int min_size;
 
 		min_size = (height - 1) * mode_cmd->pitches[i]
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 606d176d5d96..c318fae28581 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -79,18 +79,13 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 	struct drm_framebuffer *fb;
 	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
 	struct drm_gem_object *obj;
-	unsigned int hsub;
-	unsigned int vsub;
 	int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
 	int ret;
 	int i;
 
-	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
-	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
-
 	for (i = 0; i < num_planes; i++) {
-		unsigned int width = mode_cmd->width / (i ? hsub : 1);
-		unsigned int height = mode_cmd->height / (i ? vsub : 1);
+		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
+		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
 		unsigned int min_size;
 
 		obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index c7d4c6073ea5..88c3902057f3 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -317,21 +317,18 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
 			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
 			     uint32_t dst_h, uint32_t pixel_format)
 {
+	const struct drm_format_info *info = drm_format_info(pixel_format);
 	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
 	uint16_t cbcr_hor_scl_mode = SCALE_NONE;
 	uint16_t cbcr_ver_scl_mode = SCALE_NONE;
-	int hsub = drm_format_horz_chroma_subsampling(pixel_format);
-	int vsub = drm_format_vert_chroma_subsampling(pixel_format);
-	const struct drm_format_info *info;
 	bool is_yuv = false;
-	uint16_t cbcr_src_w = src_w / hsub;
-	uint16_t cbcr_src_h = src_h / vsub;
+	uint16_t cbcr_src_w = src_w / info->hsub;
+	uint16_t cbcr_src_h = src_h / info->vsub;
 	uint16_t vsu_mode;
 	uint16_t lb_mode;
 	uint32_t val;
 	int vskiplines;
 
-	info = drm_format_info(pixel_format);
 
 	if (info->is_yuv)
 		is_yuv = true;
@@ -819,8 +816,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 		    (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
 
 	if (is_yuv) {
-		int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
-		int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
+		int hsub = fb->format->hsub;
+		int vsub = fb->format->vsub;
 		int bpp = fb->format->cpp[1];
 
 		uv_obj = fb->obj[1];
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index bc8f9afd1b5f..ddf2c764f24c 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -132,18 +132,15 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 					const struct drm_mode_fb_cmd2 *cmd)
 {
 	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
-	unsigned int hsub, vsub, i;
 	struct tegra_bo *planes[4];
 	struct drm_gem_object *gem;
 	struct drm_framebuffer *fb;
+	unsigned int i;
 	int err;
 
-	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
-	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
-
 	for (i = 0; i < info->num_planes; i++) {
-		unsigned int width = cmd->width / (i ? hsub : 1);
-		unsigned int height = cmd->height / (i ? vsub : 1);
+		unsigned int width = cmd->width / (i ? info->hsub : 1);
+		unsigned int height = cmd->height / (i ? info->vsub : 1);
 		unsigned int size, bpp;
 
 		gem = drm_gem_object_lookup(file, cmd->handles[i]);
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 138a9ff23b70..6605c1b7370d 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -310,10 +310,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 	struct drm_framebuffer *fb = state->fb;
 	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
 	u32 subpixel_src_mask = (1 << 16) - 1;
-	u32 format = fb->format->format;
 	int num_planes = fb->format->num_planes;
 	struct drm_crtc_state *crtc_state;
-	u32 h_subsample, v_subsample;
+	u32 h_subsample = fb->format->hsub;
+	u32 v_subsample = fb->format->vsub;
 	int i, ret;
 
 	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
@@ -328,9 +328,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 	if (ret)
 		return ret;
 
-	h_subsample = drm_format_horz_chroma_subsampling(format);
-	v_subsample = drm_format_vert_chroma_subsampling(format);
-
 	for (i = 0; i < num_planes; i++)
 		vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
 
@@ -538,7 +535,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
 	const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
 	u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
 	int num_planes = fb->format->num_planes;
-	u32 h_subsample, v_subsample;
+	u32 h_subsample = fb->format->hsub;
+	u32 v_subsample = fb->format->vsub;
 	bool mix_plane_alpha;
 	bool covers_screen;
 	u32 scl0, scl1, pitch0;
@@ -568,9 +566,6 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
 		scl1 = vc4_get_scl_field(state, 0);
 	}
 
-	h_subsample = drm_format_horz_chroma_subsampling(format->drm);
-	v_subsample = drm_format_vert_chroma_subsampling(format->drm);
-
 	rotation = drm_rotation_simplify(state->rotation,
 					 DRM_MODE_ROTATE_0 |
 					 DRM_MODE_REFLECT_X |
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 41779b327d91..eeec449d6c6a 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -269,8 +269,6 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
 int drm_format_plane_cpp(uint32_t format, int plane);
-int drm_format_horz_chroma_subsampling(uint32_t format);
-int drm_format_vert_chroma_subsampling(uint32_t format);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
 unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

So far, the drm_format_plane_cpp function was operating on the format's
fourcc and was doing a lookup to retrieve the drm_format_info structure and
return the cpp.

However, this is inefficient since in most cases, we will have the
drm_format_info pointer already available so we shouldn't have to perform a
new lookup. Some drm_fourcc functions also already operate on the
drm_format_info pointer for that reason, so the API is quite inconsistent
there.

Let's follow the latter pattern and remove the extra lookup while being a
bit more consistent.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c         | 4 +++-
 drivers/gpu/drm/arm/malidp_hw.c                | 4 +++-
 drivers/gpu/drm/cirrus/cirrus_fbdev.c          | 4 +++-
 drivers/gpu/drm/cirrus/cirrus_main.c           | 4 +++-
 drivers/gpu/drm/drm_client.c                   | 3 ++-
 drivers/gpu/drm/drm_fb_helper.c                | 2 +-
 drivers/gpu/drm/drm_fourcc.c                   | 7 ++-----
 drivers/gpu/drm/i915/intel_sprite.c            | 3 ++-
 drivers/gpu/drm/mediatek/mtk_drm_fb.c          | 2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c      | 3 ++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c       | 2 +-
 drivers/gpu/drm/msm/msm_fb.c                   | 2 +-
 drivers/gpu/drm/radeon/radeon_fb.c             | 4 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c     | 2 +-
 drivers/gpu/drm/stm/ltdc.c                     | 2 +-
 drivers/gpu/drm/tegra/fb.c                     | 2 +-
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c | 2 +-
 drivers/gpu/drm/zte/zx_plane.c                 | 2 +-
 include/drm/drm_fourcc.h                       | 2 +-
 19 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 5cbde74b97dd..48170a843b48 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -123,6 +123,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct amdgpu_device *adev = rfbdev->adev;
 	struct drm_gem_object *gobj = NULL;
 	struct amdgpu_bo *abo = NULL;
@@ -133,7 +135,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 	int height = mode_cmd->height;
 	u32 cpp;
 
-	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
+	cpp = drm_format_plane_cpp(info, 0);
 
 	/* need to align pitch with crtc limits */
 	mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index b9bed1138fa3..07971ad53b29 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -326,12 +326,14 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
 
 static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
 {
+	const struct drm_format_info *info = drm_format_info(fmt);
+
 	/*
 	 * Each layer needs enough rotation memory to fit 8 lines
 	 * worth of pixel data. Required size is then:
 	 *    size = rotated_width * (bpp / 8) * 8;
 	 */
-	return w * drm_format_plane_cpp(fmt, 0) * 8;
+	return w * drm_format_plane_cpp(info, 0) * 8;
 }
 
 static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 39df62acac69..759847bafda8 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -137,6 +137,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 			       const struct drm_mode_fb_cmd2 *mode_cmd,
 			       struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct drm_device *dev = afbdev->helper.dev;
 	struct cirrus_device *cdev = dev->dev_private;
 	u32 bpp;
@@ -144,7 +146,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 	struct drm_gem_object *gobj;
 	int ret = 0;
 
-	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
+	bpp = drm_format_plane_cpp(info, 0) * 8;
 
 	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
 				      bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 57f8fe6d020b..66d0d2c5211d 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -41,13 +41,15 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *filp,
 			       const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct cirrus_device *cdev = dev->dev_private;
 	struct drm_gem_object *obj;
 	struct drm_framebuffer *fb;
 	u32 bpp;
 	int ret;
 
-	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
+	bpp = drm_format_plane_cpp(info, 0) * 8;
 
 	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
 				      bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9b2bd28dde0a..305d6dd5d201 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -242,6 +242,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
 static struct drm_client_buffer *
 drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
 {
+	const struct drm_format_info *info = drm_format_info(format);
 	struct drm_mode_create_dumb dumb_args = { };
 	struct drm_device *dev = client->dev;
 	struct drm_client_buffer *buffer;
@@ -257,7 +258,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
 
 	dumb_args.width = width;
 	dumb_args.height = height;
-	dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
+	dumb_args.bpp = drm_format_plane_cpp(info, 0) * 8;
 	ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
 	if (ret)
 		goto err_delete;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 04d23cb430bf..257a9c995057 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -768,7 +768,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
 					  struct drm_clip_rect *clip)
 {
 	struct drm_framebuffer *fb = fb_helper->fb;
-	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
+	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
 	size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
 	void *src = fb_helper->fbdev->screen_buffer + offset;
 	void *dst = fb_helper->buffer->vaddr + offset;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 04be330b7cae..d8ada4cb689e 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -307,17 +307,14 @@ EXPORT_SYMBOL(drm_get_format_info);
 
 /**
  * drm_format_plane_cpp - determine the bytes per pixel value
- * @format: pixel format (DRM_FORMAT_*)
+ * @format: pixel format info
  * @plane: plane index
  *
  * Returns:
  * The bytes per pixel value for the specified plane.
  */
-int drm_format_plane_cpp(uint32_t format, int plane)
+int drm_format_plane_cpp(const struct drm_format_info *info, int plane)
 {
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
 	if (!info || plane >= info->num_planes)
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b56a1a9ad01d..ee0e99b13532 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -297,7 +297,8 @@ skl_plane_max_stride(struct intel_plane *plane,
 		     u32 pixel_format, u64 modifier,
 		     unsigned int rotation)
 {
-	int cpp = drm_format_plane_cpp(pixel_format, 0);
+	const struct drm_format_info *info = drm_format_info(pixel_format);
+	int cpp = drm_format_plane_cpp(info, 0);
 
 	/*
 	 * "The stride in bytes must not exceed the
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index 68fdef8b12bd..af90c84e9e02 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -104,7 +104,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
 	if (!gem)
 		return ERR_PTR(-ENOENT);
 
-	bpp = drm_format_plane_cpp(cmd->pixel_format, 0);
+	bpp = drm_format_plane_cpp(info, 0);
 	size = (height - 1) * cmd->pitches[0] + width * bpp;
 	size += cmd->offsets[0];
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index b0cf63c4e3d7..aadae21f8818 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -782,6 +782,7 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
 
 static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
 {
+	const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
 	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
@@ -800,7 +801,7 @@ static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
 	width = mdp5_crtc->cursor.width;
 	height = mdp5_crtc->cursor.height;
 
-	stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
+	stride = width * drm_format_plane_cpp(info, 0);
 
 	get_roi(crtc, &roi_w, &roi_h);
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index b30b2f4efc60..03d503d8c3ba 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -158,7 +158,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 	for (i = 0; i < nplanes; i++) {
 		int n, fetch_stride, cpp;
 
-		cpp = drm_format_plane_cpp(fmt, i);
+		cpp = drm_format_plane_cpp(info, i);
 		fetch_stride = width * cpp / (i ? hsub : 1);
 
 		n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index f69c0afd6ec6..ee91058c7974 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -181,7 +181,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 		unsigned int min_size;
 
 		min_size = (height - 1) * mode_cmd->pitches[i]
-			 + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
+			 + width * drm_format_plane_cpp(info, i)
 			 + mode_cmd->offsets[i];
 
 		if (bos[i]->size < min_size) {
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 1179034024ae..88fc1a6e2e43 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -125,6 +125,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct radeon_device *rdev = rfbdev->rdev;
 	struct drm_gem_object *gobj = NULL;
 	struct radeon_bo *rbo = NULL;
@@ -135,7 +137,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
 	int height = mode_cmd->height;
 	u32 cpp;
 
-	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
+	cpp = drm_format_plane_cpp(info, 0);
 
 	/* need to align pitch with crtc limits */
 	mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, cpp,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index c318fae28581..c602cb2f4d3c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -98,7 +98,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 
 		min_size = (height - 1) * mode_cmd->pitches[i] +
 			mode_cmd->offsets[i] +
-			width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
+			width * drm_format_plane_cpp(info, i);
 
 		if (obj->size < min_size) {
 			drm_gem_object_put_unlocked(obj);
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index b1741a9d5be2..b226df7dbf6f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -779,7 +779,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
 
 	/* Configures the color frame buffer pitch in bytes & line length */
 	pitch_in_bytes = fb->pitches[0];
-	line_length = drm_format_plane_cpp(fb->format->format, 0) *
+	line_length = drm_format_plane_cpp(fb->format, 0) *
 		      (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
 	val = ((pitch_in_bytes << 16) | line_length);
 	reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index ddf2c764f24c..0a97458b286a 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -149,7 +149,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 			goto unreference;
 		}
 
-		bpp = drm_format_plane_cpp(cmd->pixel_format, i);
+		bpp = drm_format_plane_cpp(info, i);
 
 		size = (height - 1) * cmd->pitches[i] +
 		       width * bpp + cmd->offsets[i];
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index 2737b6fdadc8..57dda9d1a45d 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
 void tinydrm_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
 		    struct drm_rect *clip)
 {
-	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
+	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
 	unsigned int pitch = fb->pitches[0];
 	void *src = vaddr + (clip->y1 * pitch) + (clip->x1 * cpp);
 	size_t len = (clip->x2 - clip->x1) * cpp;
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index c6a8be444300..41bd0db4e876 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -222,7 +222,7 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
 		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
 		paddr = cma_obj->paddr + fb->offsets[i];
 		paddr += src_y * fb->pitches[i];
-		paddr += src_x * drm_format_plane_cpp(format, i);
+		paddr += src_x * drm_format_plane_cpp(fb->format, i);
 		zx_writel(paddr_reg, paddr);
 		paddr_reg += 4;
 	}
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index eeec449d6c6a..97a58f3e7462 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -268,7 +268,7 @@ drm_get_format_info(struct drm_device *dev,
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
-int drm_format_plane_cpp(uint32_t format, int plane);
+int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
 unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
@ 2019-03-19 21:57   ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

So far, the drm_format_plane_cpp function was operating on the format's
fourcc and was doing a lookup to retrieve the drm_format_info structure and
return the cpp.

However, this is inefficient since in most cases, we will have the
drm_format_info pointer already available so we shouldn't have to perform a
new lookup. Some drm_fourcc functions also already operate on the
drm_format_info pointer for that reason, so the API is quite inconsistent
there.

Let's follow the latter pattern and remove the extra lookup while being a
bit more consistent.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c         | 4 +++-
 drivers/gpu/drm/arm/malidp_hw.c                | 4 +++-
 drivers/gpu/drm/cirrus/cirrus_fbdev.c          | 4 +++-
 drivers/gpu/drm/cirrus/cirrus_main.c           | 4 +++-
 drivers/gpu/drm/drm_client.c                   | 3 ++-
 drivers/gpu/drm/drm_fb_helper.c                | 2 +-
 drivers/gpu/drm/drm_fourcc.c                   | 7 ++-----
 drivers/gpu/drm/i915/intel_sprite.c            | 3 ++-
 drivers/gpu/drm/mediatek/mtk_drm_fb.c          | 2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c      | 3 ++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c       | 2 +-
 drivers/gpu/drm/msm/msm_fb.c                   | 2 +-
 drivers/gpu/drm/radeon/radeon_fb.c             | 4 +++-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c     | 2 +-
 drivers/gpu/drm/stm/ltdc.c                     | 2 +-
 drivers/gpu/drm/tegra/fb.c                     | 2 +-
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c | 2 +-
 drivers/gpu/drm/zte/zx_plane.c                 | 2 +-
 include/drm/drm_fourcc.h                       | 2 +-
 19 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 5cbde74b97dd..48170a843b48 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -123,6 +123,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct amdgpu_device *adev = rfbdev->adev;
 	struct drm_gem_object *gobj = NULL;
 	struct amdgpu_bo *abo = NULL;
@@ -133,7 +135,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 	int height = mode_cmd->height;
 	u32 cpp;
 
-	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
+	cpp = drm_format_plane_cpp(info, 0);
 
 	/* need to align pitch with crtc limits */
 	mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index b9bed1138fa3..07971ad53b29 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -326,12 +326,14 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
 
 static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
 {
+	const struct drm_format_info *info = drm_format_info(fmt);
+
 	/*
 	 * Each layer needs enough rotation memory to fit 8 lines
 	 * worth of pixel data. Required size is then:
 	 *    size = rotated_width * (bpp / 8) * 8;
 	 */
-	return w * drm_format_plane_cpp(fmt, 0) * 8;
+	return w * drm_format_plane_cpp(info, 0) * 8;
 }
 
 static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 39df62acac69..759847bafda8 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -137,6 +137,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 			       const struct drm_mode_fb_cmd2 *mode_cmd,
 			       struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct drm_device *dev = afbdev->helper.dev;
 	struct cirrus_device *cdev = dev->dev_private;
 	u32 bpp;
@@ -144,7 +146,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 	struct drm_gem_object *gobj;
 	int ret = 0;
 
-	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
+	bpp = drm_format_plane_cpp(info, 0) * 8;
 
 	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
 				      bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 57f8fe6d020b..66d0d2c5211d 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -41,13 +41,15 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *filp,
 			       const struct drm_mode_fb_cmd2 *mode_cmd)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct cirrus_device *cdev = dev->dev_private;
 	struct drm_gem_object *obj;
 	struct drm_framebuffer *fb;
 	u32 bpp;
 	int ret;
 
-	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
+	bpp = drm_format_plane_cpp(info, 0) * 8;
 
 	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
 				      bpp, mode_cmd->pitches[0]))
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9b2bd28dde0a..305d6dd5d201 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -242,6 +242,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
 static struct drm_client_buffer *
 drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
 {
+	const struct drm_format_info *info = drm_format_info(format);
 	struct drm_mode_create_dumb dumb_args = { };
 	struct drm_device *dev = client->dev;
 	struct drm_client_buffer *buffer;
@@ -257,7 +258,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
 
 	dumb_args.width = width;
 	dumb_args.height = height;
-	dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
+	dumb_args.bpp = drm_format_plane_cpp(info, 0) * 8;
 	ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
 	if (ret)
 		goto err_delete;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 04d23cb430bf..257a9c995057 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -768,7 +768,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
 					  struct drm_clip_rect *clip)
 {
 	struct drm_framebuffer *fb = fb_helper->fb;
-	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
+	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
 	size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
 	void *src = fb_helper->fbdev->screen_buffer + offset;
 	void *dst = fb_helper->buffer->vaddr + offset;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 04be330b7cae..d8ada4cb689e 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -307,17 +307,14 @@ EXPORT_SYMBOL(drm_get_format_info);
 
 /**
  * drm_format_plane_cpp - determine the bytes per pixel value
- * @format: pixel format (DRM_FORMAT_*)
+ * @format: pixel format info
  * @plane: plane index
  *
  * Returns:
  * The bytes per pixel value for the specified plane.
  */
-int drm_format_plane_cpp(uint32_t format, int plane)
+int drm_format_plane_cpp(const struct drm_format_info *info, int plane)
 {
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
 	if (!info || plane >= info->num_planes)
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index b56a1a9ad01d..ee0e99b13532 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -297,7 +297,8 @@ skl_plane_max_stride(struct intel_plane *plane,
 		     u32 pixel_format, u64 modifier,
 		     unsigned int rotation)
 {
-	int cpp = drm_format_plane_cpp(pixel_format, 0);
+	const struct drm_format_info *info = drm_format_info(pixel_format);
+	int cpp = drm_format_plane_cpp(info, 0);
 
 	/*
 	 * "The stride in bytes must not exceed the
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index 68fdef8b12bd..af90c84e9e02 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -104,7 +104,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
 	if (!gem)
 		return ERR_PTR(-ENOENT);
 
-	bpp = drm_format_plane_cpp(cmd->pixel_format, 0);
+	bpp = drm_format_plane_cpp(info, 0);
 	size = (height - 1) * cmd->pitches[0] + width * bpp;
 	size += cmd->offsets[0];
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index b0cf63c4e3d7..aadae21f8818 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -782,6 +782,7 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
 
 static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
 {
+	const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
 	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
@@ -800,7 +801,7 @@ static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
 	width = mdp5_crtc->cursor.width;
 	height = mdp5_crtc->cursor.height;
 
-	stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
+	stride = width * drm_format_plane_cpp(info, 0);
 
 	get_roi(crtc, &roi_w, &roi_h);
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index b30b2f4efc60..03d503d8c3ba 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -158,7 +158,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 	for (i = 0; i < nplanes; i++) {
 		int n, fetch_stride, cpp;
 
-		cpp = drm_format_plane_cpp(fmt, i);
+		cpp = drm_format_plane_cpp(info, i);
 		fetch_stride = width * cpp / (i ? hsub : 1);
 
 		n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size);
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index f69c0afd6ec6..ee91058c7974 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -181,7 +181,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 		unsigned int min_size;
 
 		min_size = (height - 1) * mode_cmd->pitches[i]
-			 + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
+			 + width * drm_format_plane_cpp(info, i)
 			 + mode_cmd->offsets[i];
 
 		if (bos[i]->size < min_size) {
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 1179034024ae..88fc1a6e2e43 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -125,6 +125,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
 	struct radeon_device *rdev = rfbdev->rdev;
 	struct drm_gem_object *gobj = NULL;
 	struct radeon_bo *rbo = NULL;
@@ -135,7 +137,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
 	int height = mode_cmd->height;
 	u32 cpp;
 
-	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
+	cpp = drm_format_plane_cpp(info, 0);
 
 	/* need to align pitch with crtc limits */
 	mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, cpp,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index c318fae28581..c602cb2f4d3c 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -98,7 +98,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 
 		min_size = (height - 1) * mode_cmd->pitches[i] +
 			mode_cmd->offsets[i] +
-			width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
+			width * drm_format_plane_cpp(info, i);
 
 		if (obj->size < min_size) {
 			drm_gem_object_put_unlocked(obj);
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index b1741a9d5be2..b226df7dbf6f 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -779,7 +779,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
 
 	/* Configures the color frame buffer pitch in bytes & line length */
 	pitch_in_bytes = fb->pitches[0];
-	line_length = drm_format_plane_cpp(fb->format->format, 0) *
+	line_length = drm_format_plane_cpp(fb->format, 0) *
 		      (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
 	val = ((pitch_in_bytes << 16) | line_length);
 	reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index ddf2c764f24c..0a97458b286a 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -149,7 +149,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 			goto unreference;
 		}
 
-		bpp = drm_format_plane_cpp(cmd->pixel_format, i);
+		bpp = drm_format_plane_cpp(info, i);
 
 		size = (height - 1) * cmd->pitches[i] +
 		       width * bpp + cmd->offsets[i];
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index 2737b6fdadc8..57dda9d1a45d 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
 void tinydrm_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
 		    struct drm_rect *clip)
 {
-	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
+	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
 	unsigned int pitch = fb->pitches[0];
 	void *src = vaddr + (clip->y1 * pitch) + (clip->x1 * cpp);
 	size_t len = (clip->x2 - clip->x1) * cpp;
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index c6a8be444300..41bd0db4e876 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -222,7 +222,7 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
 		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
 		paddr = cma_obj->paddr + fb->offsets[i];
 		paddr += src_y * fb->pitches[i];
-		paddr += src_x * drm_format_plane_cpp(format, i);
+		paddr += src_x * drm_format_plane_cpp(fb->format, i);
 		zx_writel(paddr_reg, paddr);
 		paddr_reg += 4;
 	}
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index eeec449d6c6a..97a58f3e7462 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -268,7 +268,7 @@ drm_get_format_info(struct drm_device *dev,
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
-int drm_format_plane_cpp(uint32_t format, int plane);
+int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
 int drm_format_plane_width(int width, uint32_t format, int plane);
 int drm_format_plane_height(int height, uint32_t format, int plane);
 unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (2 preceding siblings ...)
  2019-03-19 21:57   ` Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-20 14:26   ` Paul Kocialkowski
  2019-03-19 21:57 ` [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info Maxime Ripard
                   ` (15 subsequent siblings)
  19 siblings, 1 reply; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

So far, the drm_format_plane_height/width functions were operating on the
format's fourcc and was doing a lookup to retrieve the drm_format_info
structure and return the cpp.

However, this is inefficient since in most cases, we will have the
drm_format_info pointer already available so we shouldn't have to perform a
new lookup. Some drm_fourcc functions also already operate on the
drm_format_info pointer for that reason, so the API is quite inconsistent
there.

Let's follow the latter pattern and remove the extra lookup while being a
bit more consistent.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/drm_fourcc.c          | 16 ++++++----------
 drivers/gpu/drm/meson/meson_overlay.c |  6 +++---
 include/drm/drm_fourcc.h              |  6 ++++--
 3 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index d8ada4cb689e..57389b9753b2 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -325,17 +325,15 @@ EXPORT_SYMBOL(drm_format_plane_cpp);
 /**
  * drm_format_plane_width - width of the plane given the first plane
  * @width: width of the first plane
- * @format: pixel format
+ * @format: pixel format info
  * @plane: plane index
  *
  * Returns:
  * The width of @plane, given that the width of the first plane is @width.
  */
-int drm_format_plane_width(int width, uint32_t format, int plane)
+int drm_format_plane_width(int width, const struct drm_format_info *info,
+			   int plane)
 {
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
 	if (!info || plane >= info->num_planes)
 		return 0;
 
@@ -349,17 +347,15 @@ EXPORT_SYMBOL(drm_format_plane_width);
 /**
  * drm_format_plane_height - height of the plane given the first plane
  * @height: height of the first plane
- * @format: pixel format
+ * @format: pixel format info
  * @plane: plane index
  *
  * Returns:
  * The height of @plane, given that the height of the first plane is @height.
  */
-int drm_format_plane_height(int height, uint32_t format, int plane)
+int drm_format_plane_height(int height, const struct drm_format_info *info,
+			    int plane)
 {
-	const struct drm_format_info *info;
-
-	info = drm_format_info(format);
 	if (!info || plane >= info->num_planes)
 		return 0;
 
diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
index 8ff15d01a8f9..6987c15b6ab9 100644
--- a/drivers/gpu/drm/meson/meson_overlay.c
+++ b/drivers/gpu/drm/meson/meson_overlay.c
@@ -475,7 +475,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_stride2 = fb->pitches[2];
 		priv->viu.vd1_height2 =
 			drm_format_plane_height(fb->height,
-						fb->format->format, 2);
+						fb->format, 2);
 		DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr2,
 			 priv->viu.vd1_stride2,
@@ -487,7 +487,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_stride1 = fb->pitches[1];
 		priv->viu.vd1_height1 =
 			drm_format_plane_height(fb->height,
-						fb->format->format, 1);
+						fb->format, 1);
 		DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr1,
 			 priv->viu.vd1_stride1,
@@ -499,7 +499,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_stride0 = fb->pitches[0];
 		priv->viu.vd1_height0 =
 			drm_format_plane_height(fb->height,
-						fb->format->format, 0);
+						fb->format, 0);
 		DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr0,
 			 priv->viu.vd1_stride0,
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 97a58f3e7462..2291f2618211 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -269,8 +269,10 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
 int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
-int drm_format_plane_width(int width, uint32_t format, int plane);
-int drm_format_plane_height(int height, uint32_t format, int plane);
+int drm_format_plane_width(int width, const struct drm_format_info *info,
+			   int plane);
+int drm_format_plane_height(int height, const struct drm_format_info *info,
+			    int plane);
 unsigned int drm_format_info_block_width(const struct drm_format_info *info,
 					 int plane);
 unsigned int drm_format_info_block_height(const struct drm_format_info *info,
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (3 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-20 14:27   ` Paul Kocialkowski
  2019-03-19 21:57   ` Maxime Ripard
                   ` (14 subsequent siblings)
  19 siblings, 1 reply; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

drm_get_format_info directly calls into drm_format_info, but takes directly
a struct drm_mode_fb_cmd2 pointer, instead of the fourcc directly. It's
shorter to not dereference it, and we can customise the behaviour at the
driver level if we want to, so let's switch to it where it makes sense.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/gma500/framebuffer.c | 2 +-
 drivers/gpu/drm/omapdrm/omap_fb.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index c934b3df1f81..46f0078f7a91 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -232,7 +232,7 @@ static int psb_framebuffer_init(struct drm_device *dev,
 	 * Reject unknown formats, YUV formats, and formats with more than
 	 * 4 bytes per pixel.
 	 */
-	info = drm_format_info(mode_cmd->pixel_format);
+	info = drm_get_format_info(dev, mode_cmd);
 	if (!info || !info->depth || info->cpp[0] > 4)
 		return -EINVAL;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index cfb641363a32..6557b2d6e16e 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -339,7 +339,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
 			(char *)&mode_cmd->pixel_format);
 
-	format = drm_format_info(mode_cmd->pixel_format);
+	format = drm_get_format_info(dev, mode_cmd);
 
 	for (i = 0; i < ARRAY_SIZE(formats); i++) {
 		if (formats[i] == mode_cmd->pixel_format)
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 06/20] lib: Add video format information library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Move the DRM formats API to turn this into a more generic image formats API
to be able to leverage it into some other places of the kernel, such as
v4l2 drivers.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 include/linux/image-formats.h | 240 +++++++++++-
 lib/Kconfig                   |   7 +-
 lib/Makefile                  |   3 +-
 lib/image-formats-selftests.c | 326 +++++++++++++++-
 lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
 5 files changed, 1336 insertions(+)
 create mode 100644 include/linux/image-formats.h
 create mode 100644 lib/image-formats-selftests.c
 create mode 100644 lib/image-formats.c

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
new file mode 100644
index 000000000000..53fd73a71b3d
--- /dev/null
+++ b/include/linux/image-formats.h
@@ -0,0 +1,240 @@
+#ifndef _IMAGE_FORMATS_H_
+#define _IMAGE_FORMATS_H_
+
+#include <linux/types.h>
+
+/**
+ * struct image_format_info - information about a image format
+ */
+struct image_format_info {
+	union {
+		/**
+		 * @drm_fmt:
+		 *
+		 * DRM 4CC format identifier (DRM_FORMAT_*)
+		 */
+		u32 drm_fmt;
+
+		/**
+		 * @format:
+		 *
+		 * DRM 4CC format identifier (DRM_FORMAT_*). Kept
+		 * around for compatibility reasons with the current
+		 * DRM drivers.
+		 */
+		u32 format;
+	};
+
+	/**
+	 * @depth:
+	 *
+	 * Color depth (number of bits per pixel excluding padding bits),
+	 * valid for a subset of RGB formats only. This is a legacy field, do
+	 * not use in new code and set to 0 for new formats.
+	 */
+	u8 depth;
+
+	/** @num_planes: Number of color planes (1 to 3) */
+	u8 num_planes;
+
+	union {
+		/**
+		 * @cpp:
+		 *
+		 * Number of bytes per pixel (per plane), this is aliased with
+		 * @char_per_block. It is deprecated in favour of using the
+		 * triplet @char_per_block, @block_w, @block_h for better
+		 * describing the pixel format.
+		 */
+		u8 cpp[3];
+
+		/**
+		 * @char_per_block:
+		 *
+		 * Number of bytes per block (per plane), where blocks are
+		 * defined as a rectangle of pixels which are stored next to
+		 * each other in a byte aligned memory region. Together with
+		 * @block_w and @block_h this is used to properly describe tiles
+		 * in tiled formats or to describe groups of pixels in packed
+		 * formats for which the memory needed for a single pixel is not
+		 * byte aligned.
+		 *
+		 * @cpp has been kept for historical reasons because there are
+		 * a lot of places in drivers where it's used. In drm core for
+		 * generic code paths the preferred way is to use
+		 * @char_per_block, image_format_block_width() and
+		 * image_format_block_height() which allows handling both
+		 * block and non-block formats in the same way.
+		 *
+		 * For formats that are intended to be used only with non-linear
+		 * modifiers both @cpp and @char_per_block must be 0 in the
+		 * generic format table. Drivers could supply accurate
+		 * information from their drm_mode_config.get_format_info hook
+		 * if they want the core to be validating the pitch.
+		 */
+		u8 char_per_block[3];
+	};
+
+	/**
+	 * @block_w:
+	 *
+	 * Block width in pixels, this is intended to be accessed through
+	 * image_format_block_width()
+	 */
+	u8 block_w[3];
+
+	/**
+	 * @block_h:
+	 *
+	 * Block height in pixels, this is intended to be accessed through
+	 * image_format_block_height()
+	 */
+	u8 block_h[3];
+
+	/** @hsub: Horizontal chroma subsampling factor */
+	u8 hsub;
+	/** @vsub: Vertical chroma subsampling factor */
+	u8 vsub;
+
+	/** @has_alpha: Does the format embeds an alpha component? */
+	bool has_alpha;
+
+	/** @is_yuv: Is it a YUV format? */
+	bool is_yuv;
+};
+
+/**
+ * image_format_info_is_yuv_packed - check that the format info matches a YUV
+ * format with data laid in a single plane
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a packed YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_packed(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 1;
+}
+
+/**
+ * image_format_info_is_yuv_semiplanar - check that the format info matches a YUV
+ * format with data laid in two planes (luminance and chrominance)
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a semiplanar YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_semiplanar(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 2;
+}
+
+/**
+ * image_format_info_is_yuv_planar - check that the format info matches a YUV
+ * format with data laid in three planes (one for each YUV component)
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a planar YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_planar(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 3;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_410 - check that the format info matches a
+ * YUV format with 4:1:0 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:1:0
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_410(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 4 && info->vsub == 4;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_411 - check that the format info matches a
+ * YUV format with 4:1:1 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:1:1
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_411(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 4 && info->vsub == 1;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_420 - check that the format info matches a
+ * YUV format with 4:2:0 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:2:0
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_420(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 2 && info->vsub == 2;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_422 - check that the format info matches a
+ * YUV format with 4:2:2 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:2:2
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_422(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 2 && info->vsub == 1;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_444 - check that the format info matches a
+ * YUV format with 4:4:4 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:4:4
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 1 && info->vsub == 1;
+}
+
+const struct image_format_info *__image_format_drm_lookup(u32 drm);
+const struct image_format_info *image_format_drm_lookup(u32 drm);
+unsigned int image_format_plane_cpp(const struct image_format_info *format,
+				    int plane);
+unsigned int image_format_plane_width(int width,
+				      const struct image_format_info *format,
+				      int plane);
+unsigned int image_format_plane_height(int height,
+				       const struct image_format_info *format,
+				       int plane);
+unsigned int image_format_block_width(const struct image_format_info *format,
+				      int plane);
+unsigned int image_format_block_height(const struct image_format_info *format,
+				       int plane);
+uint64_t image_format_min_pitch(const struct image_format_info *info,
+				int plane, unsigned int buffer_width);
+
+#endif /* _IMAGE_FORMATS_H_ */
diff --git a/lib/Kconfig b/lib/Kconfig
index a9e56539bd11..421acac83b13 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -635,3 +635,10 @@ config GENERIC_LIB_UCMPDI2
 
 config OBJAGG
 	tristate "objagg" if COMPILE_TEST
+
+config IMAGE_FORMATS
+	bool
+
+config IMAGE_FORMATS_SELFTESTS
+	tristate "Test image format functions"
+	depends on IMAGE_FORMATS
diff --git a/lib/Makefile b/lib/Makefile
index e1b59da71418..b1916e6d30da 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -276,3 +276,6 @@ obj-$(CONFIG_GENERIC_LIB_MULDI3) += muldi3.o
 obj-$(CONFIG_GENERIC_LIB_CMPDI2) += cmpdi2.o
 obj-$(CONFIG_GENERIC_LIB_UCMPDI2) += ucmpdi2.o
 obj-$(CONFIG_OBJAGG) += objagg.o
+
+obj-$(CONFIG_IMAGE_FORMATS) += image-formats.o
+obj-$(CONFIG_IMAGE_FORMATS_SELFTESTS) += image-formats-selftests.o
diff --git a/lib/image-formats-selftests.c b/lib/image-formats-selftests.c
new file mode 100644
index 000000000000..8fdc50b15dcc
--- /dev/null
+++ b/lib/image-formats-selftests.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for the image_format functions
+ */
+
+#define pr_fmt(fmt) "image_format: " fmt
+
+#include <linux/errno.h>
+#include <linux/image-formats.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <drm/drm_fourcc.h>
+
+#define FAIL(test, msg, ...) \
+	do { \
+		if (test) { \
+			pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+			return -EINVAL; \
+		} \
+	} while (0)
+
+#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
+
+static int test_image_format_block_width(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_block_width(info, 0) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 1);
+	FAIL_ON(image_format_block_width(info, 2) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 1);
+	FAIL_ON(image_format_block_width(info, 2) != 1);
+	FAIL_ON(image_format_block_width(info, 3) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 2);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	return 0;
+}
+
+static int test_image_format_block_height(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_block_height(info, 0) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 1);
+	FAIL_ON(image_format_block_height(info, 2) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 1);
+	FAIL_ON(image_format_block_height(info, 2) != 1);
+	FAIL_ON(image_format_block_height(info, 3) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 2);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	return 0;
+}
+
+static int test_image_format_min_pitch(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	/* Test 1 plane 8 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_RGB332);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 1 plane 16 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	/* Test 1 plane 24 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_RGB888);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 3);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 6);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 3072);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 5760);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 12288);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 2013);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 3);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 3);
+
+	/* Test 1 plane 32 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_ABGR8888);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 8);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 2560);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 7680);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 16384);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 2684);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 4);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 4);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 2, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 1, 320) != 640);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 1, 512) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 1, 960) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 1, 2048) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 1, 336) != 672);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX + 1);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+	FAIL_ON(image_format_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 3 planes 8 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 2, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 3, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 2, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 1, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 2, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 1, 320) != 320);
+	FAIL_ON(image_format_min_pitch(info, 2, 320) != 320);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 1, 512) != 512);
+	FAIL_ON(image_format_min_pitch(info, 2, 512) != 512);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 1, 960) != 960);
+	FAIL_ON(image_format_min_pitch(info, 2, 960) != 960);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 1, 2048) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 2, 2048) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 1, 336) != 336);
+	FAIL_ON(image_format_min_pitch(info, 2, 336) != 336);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(image_format_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(image_format_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(image_format_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+
+	/* Test tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L2);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	return 0;
+}
+
+#define selftest(test)	{ .name = #test, .func = test, }
+
+static struct image_format_test {
+	char	*name;
+	int	(*func)(void);
+} tests[] = {
+	selftest(test_image_format_block_height),
+	selftest(test_image_format_block_width),
+	selftest(test_image_format_min_pitch),
+};
+
+static int __init image_format_test_init(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		struct image_format_test *test = &tests[i];
+		int ret;
+
+		ret = test->func();
+		if (ret) {
+			pr_err("Failed test %s\n", test->name);
+			return ret;
+		}
+	}
+
+	pr_info("All tests executed properly.\n");
+	return 0;
+}
+
+static void __exit image_format_test_exit(void)
+{
+}
+module_init(image_format_test_init);
+module_exit(image_format_test_exit);
diff --git a/lib/image-formats.c b/lib/image-formats.c
new file mode 100644
index 000000000000..9b9a73220c5d
--- /dev/null
+++ b/lib/image-formats.c
@@ -0,0 +1,760 @@
+#include <linux/bug.h>
+#include <linux/image-formats.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+
+#include <uapi/drm/drm_fourcc.h>
+
+static const struct image_format_info formats[] = {
+	{
+		.drm_fmt = DRM_FORMAT_C8,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB332,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR233,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB565,
+		.depth = 16,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR565,
+		.depth = 16,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 3, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 3, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB565_A8,
+		.depth = 24,
+		.num_planes = 2,
+		.cpp = { 2, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR565_A8,
+		.depth = 24,
+		.num_planes = 2,
+		.cpp = { 2, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 3, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 3, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV410,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 4,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU410,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 4,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV411,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU411,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV420,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU420,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV422,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU422,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV444,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU444,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV12,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV21,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV16,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV61,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV24,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV42,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUYV,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVYU,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_UYVY,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_VYUY,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XYUV8888,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_AYUV,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_Y0L0,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_X0L0,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_Y0L2,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_X0L2,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	},
+};
+
+#define __image_format_lookup(_field, _fmt)			\
+	({							\
+		const struct image_format_info *format = NULL;	\
+		unsigned i;					\
+								\
+		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
+			if (formats[i]._field == _fmt)		\
+				format = &formats[i];		\
+								\
+		format;						\
+	})
+
+/**
+ * __image_format_drm_lookup - query information for a given format
+ * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *__image_format_drm_lookup(u32 drm)
+{
+	return __image_format_lookup(drm_fmt, drm);
+}
+EXPORT_SYMBOL(__image_format_drm_lookup);
+
+/**
+ * image_format_drm_lookup - query information for a given format
+ * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ * Unsupported pixel formats will generate a warning in the kernel log.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *image_format_drm_lookup(u32 drm)
+{
+	const struct image_format_info *format;
+
+	format = __image_format_drm_lookup(drm);
+
+	WARN_ON(!format);
+	return format;
+}
+EXPORT_SYMBOL(image_format_drm_lookup);
+
+/**
+ * image_format_plane_cpp - determine the bytes per pixel value
+ * @format: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The bytes per pixel value for the specified plane.
+ */
+unsigned int image_format_plane_cpp(const struct image_format_info *format,
+				    int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return format->cpp[plane];
+}
+EXPORT_SYMBOL(image_format_plane_cpp);
+
+/**
+ * image_format_plane_width - width of the plane given the first plane
+ * @format: pointer to the image_format
+ * @width: width of the first plane
+ * @plane: plane index
+ *
+ * Returns:
+ * The width of @plane, given that the width of the first plane is @width.
+ */
+unsigned int image_format_plane_width(int width,
+				      const struct image_format_info *format,
+				      int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	if (plane == 0)
+		return width;
+
+	return width / format->hsub;
+}
+EXPORT_SYMBOL(image_format_plane_width);
+
+/**
+ * image_format_plane_height - height of the plane given the first plane
+ * @format: pointer to the image_format
+ * @height: height of the first plane
+ * @plane: plane index
+ *
+ * Returns:
+ * The height of @plane, given that the height of the first plane is @height.
+ */
+unsigned int image_format_plane_height(int height,
+				       const struct image_format_info *format,
+				       int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	if (plane == 0)
+		return height;
+
+	return height / format->vsub;
+}
+EXPORT_SYMBOL(image_format_plane_height);
+
+/**
+ * image_format_block_width - width in pixels of block.
+ * @format: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The width in pixels of a block, depending on the plane index.
+ */
+unsigned int image_format_block_width(const struct image_format_info *format,
+				      int plane)
+{
+	if (!format || plane < 0 || plane >= format->num_planes)
+		return 0;
+
+	if (!format->block_w[plane])
+		return 1;
+
+	return format->block_w[plane];
+}
+EXPORT_SYMBOL(image_format_block_width);
+
+/**
+ * image_format_block_height - height in pixels of a block
+ * @info: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The height in pixels of a block, depending on the plane index.
+ */
+unsigned int image_format_block_height(const struct image_format_info *format,
+				       int plane)
+{
+	if (!format || plane < 0 || plane >= format->num_planes)
+		return 0;
+
+	if (!format->block_h[plane])
+		return 1;
+
+	return format->block_h[plane];
+}
+EXPORT_SYMBOL(image_format_block_height);
+
+/**
+ * image_format_min_pitch - computes the minimum required pitch in bytes
+ * @info: pixel format info
+ * @plane: plane index
+ * @buffer_width: buffer width in pixels
+ *
+ * Returns:
+ * The minimum required pitch in bytes for a buffer by taking into consideration
+ * the pixel format information and the buffer width.
+ */
+uint64_t image_format_min_pitch(const struct image_format_info *info,
+				int plane, unsigned int buffer_width)
+{
+	if (!info || plane < 0 || plane >= info->num_planes)
+		return 0;
+
+	return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],
+			    image_format_block_width(info, plane) *
+			    image_format_block_height(info, plane));
+}
+EXPORT_SYMBOL(image_format_min_pitch);
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 06/20] lib: Add video format information library
@ 2019-03-19 21:57   ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

Move the DRM formats API to turn this into a more generic image formats API
to be able to leverage it into some other places of the kernel, such as
v4l2 drivers.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 include/linux/image-formats.h | 240 +++++++++++-
 lib/Kconfig                   |   7 +-
 lib/Makefile                  |   3 +-
 lib/image-formats-selftests.c | 326 +++++++++++++++-
 lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
 5 files changed, 1336 insertions(+)
 create mode 100644 include/linux/image-formats.h
 create mode 100644 lib/image-formats-selftests.c
 create mode 100644 lib/image-formats.c

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
new file mode 100644
index 000000000000..53fd73a71b3d
--- /dev/null
+++ b/include/linux/image-formats.h
@@ -0,0 +1,240 @@
+#ifndef _IMAGE_FORMATS_H_
+#define _IMAGE_FORMATS_H_
+
+#include <linux/types.h>
+
+/**
+ * struct image_format_info - information about a image format
+ */
+struct image_format_info {
+	union {
+		/**
+		 * @drm_fmt:
+		 *
+		 * DRM 4CC format identifier (DRM_FORMAT_*)
+		 */
+		u32 drm_fmt;
+
+		/**
+		 * @format:
+		 *
+		 * DRM 4CC format identifier (DRM_FORMAT_*). Kept
+		 * around for compatibility reasons with the current
+		 * DRM drivers.
+		 */
+		u32 format;
+	};
+
+	/**
+	 * @depth:
+	 *
+	 * Color depth (number of bits per pixel excluding padding bits),
+	 * valid for a subset of RGB formats only. This is a legacy field, do
+	 * not use in new code and set to 0 for new formats.
+	 */
+	u8 depth;
+
+	/** @num_planes: Number of color planes (1 to 3) */
+	u8 num_planes;
+
+	union {
+		/**
+		 * @cpp:
+		 *
+		 * Number of bytes per pixel (per plane), this is aliased with
+		 * @char_per_block. It is deprecated in favour of using the
+		 * triplet @char_per_block, @block_w, @block_h for better
+		 * describing the pixel format.
+		 */
+		u8 cpp[3];
+
+		/**
+		 * @char_per_block:
+		 *
+		 * Number of bytes per block (per plane), where blocks are
+		 * defined as a rectangle of pixels which are stored next to
+		 * each other in a byte aligned memory region. Together with
+		 * @block_w and @block_h this is used to properly describe tiles
+		 * in tiled formats or to describe groups of pixels in packed
+		 * formats for which the memory needed for a single pixel is not
+		 * byte aligned.
+		 *
+		 * @cpp has been kept for historical reasons because there are
+		 * a lot of places in drivers where it's used. In drm core for
+		 * generic code paths the preferred way is to use
+		 * @char_per_block, image_format_block_width() and
+		 * image_format_block_height() which allows handling both
+		 * block and non-block formats in the same way.
+		 *
+		 * For formats that are intended to be used only with non-linear
+		 * modifiers both @cpp and @char_per_block must be 0 in the
+		 * generic format table. Drivers could supply accurate
+		 * information from their drm_mode_config.get_format_info hook
+		 * if they want the core to be validating the pitch.
+		 */
+		u8 char_per_block[3];
+	};
+
+	/**
+	 * @block_w:
+	 *
+	 * Block width in pixels, this is intended to be accessed through
+	 * image_format_block_width()
+	 */
+	u8 block_w[3];
+
+	/**
+	 * @block_h:
+	 *
+	 * Block height in pixels, this is intended to be accessed through
+	 * image_format_block_height()
+	 */
+	u8 block_h[3];
+
+	/** @hsub: Horizontal chroma subsampling factor */
+	u8 hsub;
+	/** @vsub: Vertical chroma subsampling factor */
+	u8 vsub;
+
+	/** @has_alpha: Does the format embeds an alpha component? */
+	bool has_alpha;
+
+	/** @is_yuv: Is it a YUV format? */
+	bool is_yuv;
+};
+
+/**
+ * image_format_info_is_yuv_packed - check that the format info matches a YUV
+ * format with data laid in a single plane
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a packed YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_packed(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 1;
+}
+
+/**
+ * image_format_info_is_yuv_semiplanar - check that the format info matches a YUV
+ * format with data laid in two planes (luminance and chrominance)
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a semiplanar YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_semiplanar(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 2;
+}
+
+/**
+ * image_format_info_is_yuv_planar - check that the format info matches a YUV
+ * format with data laid in three planes (one for each YUV component)
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a planar YUV format.
+ */
+static inline bool
+image_format_info_is_yuv_planar(const struct image_format_info *info)
+{
+	return info->is_yuv && info->num_planes == 3;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_410 - check that the format info matches a
+ * YUV format with 4:1:0 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:1:0
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_410(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 4 && info->vsub == 4;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_411 - check that the format info matches a
+ * YUV format with 4:1:1 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:1:1
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_411(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 4 && info->vsub == 1;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_420 - check that the format info matches a
+ * YUV format with 4:2:0 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:2:0
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_420(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 2 && info->vsub == 2;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_422 - check that the format info matches a
+ * YUV format with 4:2:2 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:2:2
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_422(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 2 && info->vsub == 1;
+}
+
+/**
+ * image_format_info_is_yuv_sampling_444 - check that the format info matches a
+ * YUV format with 4:4:4 sub-sampling
+ * @info: format info
+ *
+ * Returns:
+ * A boolean indicating whether the format info matches a YUV format with 4:4:4
+ * sub-sampling.
+ */
+static inline bool
+image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
+{
+	return info->is_yuv && info->hsub == 1 && info->vsub == 1;
+}
+
+const struct image_format_info *__image_format_drm_lookup(u32 drm);
+const struct image_format_info *image_format_drm_lookup(u32 drm);
+unsigned int image_format_plane_cpp(const struct image_format_info *format,
+				    int plane);
+unsigned int image_format_plane_width(int width,
+				      const struct image_format_info *format,
+				      int plane);
+unsigned int image_format_plane_height(int height,
+				       const struct image_format_info *format,
+				       int plane);
+unsigned int image_format_block_width(const struct image_format_info *format,
+				      int plane);
+unsigned int image_format_block_height(const struct image_format_info *format,
+				       int plane);
+uint64_t image_format_min_pitch(const struct image_format_info *info,
+				int plane, unsigned int buffer_width);
+
+#endif /* _IMAGE_FORMATS_H_ */
diff --git a/lib/Kconfig b/lib/Kconfig
index a9e56539bd11..421acac83b13 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -635,3 +635,10 @@ config GENERIC_LIB_UCMPDI2
 
 config OBJAGG
 	tristate "objagg" if COMPILE_TEST
+
+config IMAGE_FORMATS
+	bool
+
+config IMAGE_FORMATS_SELFTESTS
+	tristate "Test image format functions"
+	depends on IMAGE_FORMATS
diff --git a/lib/Makefile b/lib/Makefile
index e1b59da71418..b1916e6d30da 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -276,3 +276,6 @@ obj-$(CONFIG_GENERIC_LIB_MULDI3) += muldi3.o
 obj-$(CONFIG_GENERIC_LIB_CMPDI2) += cmpdi2.o
 obj-$(CONFIG_GENERIC_LIB_UCMPDI2) += ucmpdi2.o
 obj-$(CONFIG_OBJAGG) += objagg.o
+
+obj-$(CONFIG_IMAGE_FORMATS) += image-formats.o
+obj-$(CONFIG_IMAGE_FORMATS_SELFTESTS) += image-formats-selftests.o
diff --git a/lib/image-formats-selftests.c b/lib/image-formats-selftests.c
new file mode 100644
index 000000000000..8fdc50b15dcc
--- /dev/null
+++ b/lib/image-formats-selftests.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for the image_format functions
+ */
+
+#define pr_fmt(fmt) "image_format: " fmt
+
+#include <linux/errno.h>
+#include <linux/image-formats.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <drm/drm_fourcc.h>
+
+#define FAIL(test, msg, ...) \
+	do { \
+		if (test) { \
+			pr_err("%s/%u: " msg, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+			return -EINVAL; \
+		} \
+	} while (0)
+
+#define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
+
+static int test_image_format_block_width(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_block_width(info, 0) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 1);
+	FAIL_ON(image_format_block_width(info, 2) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 1);
+	FAIL_ON(image_format_block_width(info, 1) != 1);
+	FAIL_ON(image_format_block_width(info, 2) != 1);
+	FAIL_ON(image_format_block_width(info, 3) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_width(info, 0) != 2);
+	FAIL_ON(image_format_block_width(info, 1) != 0);
+	FAIL_ON(image_format_block_width(info, -1) != 0);
+
+	return 0;
+}
+
+static int test_image_format_block_height(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_block_height(info, 0) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+
+	/* Test 1 plane format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 1);
+	FAIL_ON(image_format_block_height(info, 2) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test 3 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 1);
+	FAIL_ON(image_format_block_height(info, 1) != 1);
+	FAIL_ON(image_format_block_height(info, 2) != 1);
+	FAIL_ON(image_format_block_height(info, 3) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	/* Test a tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L0);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_block_height(info, 0) != 2);
+	FAIL_ON(image_format_block_height(info, 1) != 0);
+	FAIL_ON(image_format_block_height(info, -1) != 0);
+
+	return 0;
+}
+
+static int test_image_format_min_pitch(void)
+{
+	const struct image_format_info *info = NULL;
+
+	/* Test invalid arguments */
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	/* Test 1 plane 8 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_RGB332);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 1 plane 16 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_XRGB4444);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	/* Test 1 plane 24 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_RGB888);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 3);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 6);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 3072);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 5760);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 12288);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 2013);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 3);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 3);
+
+	/* Test 1 plane 32 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_ABGR8888);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 8);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 2560);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 7680);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 16384);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 2684);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 4);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 4);
+
+	/* Test 2 planes format */
+	info = image_format_drm_lookup(DRM_FORMAT_NV12);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 2, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 1, 320) != 640);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 1, 512) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 1, 960) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 1, 2048) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 1, 336) != 672);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX + 1);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1)) !=
+			(uint64_t)(UINT_MAX - 1));
+	FAIL_ON(image_format_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
+			(uint64_t)(UINT_MAX - 1));
+
+	/* Test 3 planes 8 bits per pixel format */
+	info = image_format_drm_lookup(DRM_FORMAT_YUV422);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 2, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 3, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 1, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 2, 1) != 1);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 1, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 2, 2) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 640);
+	FAIL_ON(image_format_min_pitch(info, 1, 320) != 320);
+	FAIL_ON(image_format_min_pitch(info, 2, 320) != 320);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 1024);
+	FAIL_ON(image_format_min_pitch(info, 1, 512) != 512);
+	FAIL_ON(image_format_min_pitch(info, 2, 512) != 512);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 1920);
+	FAIL_ON(image_format_min_pitch(info, 1, 960) != 960);
+	FAIL_ON(image_format_min_pitch(info, 2, 960) != 960);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 4096);
+	FAIL_ON(image_format_min_pitch(info, 1, 2048) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 2, 2048) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 671);
+	FAIL_ON(image_format_min_pitch(info, 1, 336) != 336);
+	FAIL_ON(image_format_min_pitch(info, 2, 336) != 336);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX);
+	FAIL_ON(image_format_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(image_format_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
+			(uint64_t)UINT_MAX / 2 + 1);
+	FAIL_ON(image_format_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(image_format_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+	FAIL_ON(image_format_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
+			(uint64_t)(UINT_MAX - 1) / 2);
+
+	/* Test tiled format */
+	info = image_format_drm_lookup(DRM_FORMAT_X0L2);
+	FAIL_ON(!info);
+	FAIL_ON(image_format_min_pitch(info, 0, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, -1, 0) != 0);
+	FAIL_ON(image_format_min_pitch(info, 1, 0) != 0);
+
+	FAIL_ON(image_format_min_pitch(info, 0, 1) != 2);
+	FAIL_ON(image_format_min_pitch(info, 0, 2) != 4);
+	FAIL_ON(image_format_min_pitch(info, 0, 640) != 1280);
+	FAIL_ON(image_format_min_pitch(info, 0, 1024) != 2048);
+	FAIL_ON(image_format_min_pitch(info, 0, 1920) != 3840);
+	FAIL_ON(image_format_min_pitch(info, 0, 4096) != 8192);
+	FAIL_ON(image_format_min_pitch(info, 0, 671) != 1342);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX) !=
+			(uint64_t)UINT_MAX * 2);
+	FAIL_ON(image_format_min_pitch(info, 0, UINT_MAX - 1) !=
+			(uint64_t)(UINT_MAX - 1) * 2);
+
+	return 0;
+}
+
+#define selftest(test)	{ .name = #test, .func = test, }
+
+static struct image_format_test {
+	char	*name;
+	int	(*func)(void);
+} tests[] = {
+	selftest(test_image_format_block_height),
+	selftest(test_image_format_block_width),
+	selftest(test_image_format_min_pitch),
+};
+
+static int __init image_format_test_init(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(tests); i++) {
+		struct image_format_test *test = &tests[i];
+		int ret;
+
+		ret = test->func();
+		if (ret) {
+			pr_err("Failed test %s\n", test->name);
+			return ret;
+		}
+	}
+
+	pr_info("All tests executed properly.\n");
+	return 0;
+}
+
+static void __exit image_format_test_exit(void)
+{
+}
+module_init(image_format_test_init);
+module_exit(image_format_test_exit);
diff --git a/lib/image-formats.c b/lib/image-formats.c
new file mode 100644
index 000000000000..9b9a73220c5d
--- /dev/null
+++ b/lib/image-formats.c
@@ -0,0 +1,760 @@
+#include <linux/bug.h>
+#include <linux/image-formats.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+
+#include <uapi/drm/drm_fourcc.h>
+
+static const struct image_format_info formats[] = {
+	{
+		.drm_fmt = DRM_FORMAT_C8,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB332,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR233,
+		.depth = 8,
+		.num_planes = 1,
+		.cpp = { 1, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA4444,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR1555,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA5551,
+		.depth = 15,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB565,
+		.depth = 16,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR565,
+		.depth = 16,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 3, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 3, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX8888,
+		.depth = 24,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB565_A8,
+		.depth = 24,
+		.num_planes = 2,
+		.cpp = { 2, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR565_A8,
+		.depth = 24,
+		.num_planes = 2,
+		.cpp = { 2, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR2101010,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA1010102,
+		.depth = 30,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ARGB8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_ABGR8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBA8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRA8888,
+		.depth = 32,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGB888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 3, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGR888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 3, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XRGB8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XBGR8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_RGBX8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_BGRX8888_A8,
+		.depth = 32,
+		.num_planes = 2,
+		.cpp = { 4, 1, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV410,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 4,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU410,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 4,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV411,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU411,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 4,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV420,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU420,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV422,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU422,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUV444,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVU444,
+		.depth = 0,
+		.num_planes = 3,
+		.cpp = { 1, 1, 1 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV12,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV21,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV16,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV61,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV24,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_NV42,
+		.depth = 0,
+		.num_planes = 2,
+		.cpp = { 1, 2, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YUYV,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_YVYU,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_UYVY,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_VYUY,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_XYUV8888,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_AYUV,
+		.depth = 0,
+		.num_planes = 1,
+		.cpp = { 4, 0, 0 },
+		.hsub = 1,
+		.vsub = 1,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_Y0L0,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_X0L0,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_Y0L2,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.has_alpha = true,
+		.is_yuv = true,
+	}, {
+		.drm_fmt = DRM_FORMAT_X0L2,
+		.depth = 0,
+		.num_planes = 1,
+		.char_per_block = { 8, 0, 0 },
+		.block_w = { 2, 0, 0 },
+		.block_h = { 2, 0, 0 },
+		.hsub = 2,
+		.vsub = 2,
+		.is_yuv = true,
+	},
+};
+
+#define __image_format_lookup(_field, _fmt)			\
+	({							\
+		const struct image_format_info *format = NULL;	\
+		unsigned i;					\
+								\
+		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
+			if (formats[i]._field == _fmt)		\
+				format = &formats[i];		\
+								\
+		format;						\
+	})
+
+/**
+ * __image_format_drm_lookup - query information for a given format
+ * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *__image_format_drm_lookup(u32 drm)
+{
+	return __image_format_lookup(drm_fmt, drm);
+}
+EXPORT_SYMBOL(__image_format_drm_lookup);
+
+/**
+ * image_format_drm_lookup - query information for a given format
+ * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ * Unsupported pixel formats will generate a warning in the kernel log.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *image_format_drm_lookup(u32 drm)
+{
+	const struct image_format_info *format;
+
+	format = __image_format_drm_lookup(drm);
+
+	WARN_ON(!format);
+	return format;
+}
+EXPORT_SYMBOL(image_format_drm_lookup);
+
+/**
+ * image_format_plane_cpp - determine the bytes per pixel value
+ * @format: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The bytes per pixel value for the specified plane.
+ */
+unsigned int image_format_plane_cpp(const struct image_format_info *format,
+				    int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return format->cpp[plane];
+}
+EXPORT_SYMBOL(image_format_plane_cpp);
+
+/**
+ * image_format_plane_width - width of the plane given the first plane
+ * @format: pointer to the image_format
+ * @width: width of the first plane
+ * @plane: plane index
+ *
+ * Returns:
+ * The width of @plane, given that the width of the first plane is @width.
+ */
+unsigned int image_format_plane_width(int width,
+				      const struct image_format_info *format,
+				      int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	if (plane == 0)
+		return width;
+
+	return width / format->hsub;
+}
+EXPORT_SYMBOL(image_format_plane_width);
+
+/**
+ * image_format_plane_height - height of the plane given the first plane
+ * @format: pointer to the image_format
+ * @height: height of the first plane
+ * @plane: plane index
+ *
+ * Returns:
+ * The height of @plane, given that the height of the first plane is @height.
+ */
+unsigned int image_format_plane_height(int height,
+				       const struct image_format_info *format,
+				       int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	if (plane == 0)
+		return height;
+
+	return height / format->vsub;
+}
+EXPORT_SYMBOL(image_format_plane_height);
+
+/**
+ * image_format_block_width - width in pixels of block.
+ * @format: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The width in pixels of a block, depending on the plane index.
+ */
+unsigned int image_format_block_width(const struct image_format_info *format,
+				      int plane)
+{
+	if (!format || plane < 0 || plane >= format->num_planes)
+		return 0;
+
+	if (!format->block_w[plane])
+		return 1;
+
+	return format->block_w[plane];
+}
+EXPORT_SYMBOL(image_format_block_width);
+
+/**
+ * image_format_block_height - height in pixels of a block
+ * @info: pointer to the image_format
+ * @plane: plane index
+ *
+ * Returns:
+ * The height in pixels of a block, depending on the plane index.
+ */
+unsigned int image_format_block_height(const struct image_format_info *format,
+				       int plane)
+{
+	if (!format || plane < 0 || plane >= format->num_planes)
+		return 0;
+
+	if (!format->block_h[plane])
+		return 1;
+
+	return format->block_h[plane];
+}
+EXPORT_SYMBOL(image_format_block_height);
+
+/**
+ * image_format_min_pitch - computes the minimum required pitch in bytes
+ * @info: pixel format info
+ * @plane: plane index
+ * @buffer_width: buffer width in pixels
+ *
+ * Returns:
+ * The minimum required pitch in bytes for a buffer by taking into consideration
+ * the pixel format information and the buffer width.
+ */
+uint64_t image_format_min_pitch(const struct image_format_info *info,
+				int plane, unsigned int buffer_width)
+{
+	if (!info || plane < 0 || plane >= info->num_planes)
+		return 0;
+
+	return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],
+			    image_format_block_width(info, plane) *
+			    image_format_block_height(info, plane));
+}
+EXPORT_SYMBOL(image_format_min_pitch);
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 07/20] drm/fb: Move from drm_format_info to image_format_info
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (5 preceding siblings ...)
  2019-03-19 21:57   ` Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 08/20] drm/malidp: Convert to generic image format library Maxime Ripard
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Start converting the DRM drivers by changing the struct drm_framebuffer
structure to hold a pointer to image_format_info instead, and converting
everyone that depends on it.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/Kconfig                         |  1 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c          |  4 ++--
 drivers/gpu/drm/arm/malidp_drv.c                |  2 +-
 drivers/gpu/drm/arm/malidp_planes.c             |  8 ++++----
 drivers/gpu/drm/armada/armada_fb.c              |  2 +-
 drivers/gpu/drm/armada/armada_overlay.c         |  3 ++-
 drivers/gpu/drm/armada/armada_plane.c           |  3 ++-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |  4 +++-
 drivers/gpu/drm/bochs/bochs.h                   |  4 +++-
 drivers/gpu/drm/bochs/bochs_hw.c                |  3 ++-
 drivers/gpu/drm/cirrus/cirrus_fbdev.c           |  4 ++--
 drivers/gpu/drm/cirrus/cirrus_main.c            |  4 ++--
 drivers/gpu/drm/drm_atomic.c                    |  1 +-
 drivers/gpu/drm/drm_client.c                    |  1 +-
 drivers/gpu/drm/drm_crtc.c                      |  1 +-
 drivers/gpu/drm/drm_fb_cma_helper.c             |  5 +++--
 drivers/gpu/drm/drm_fb_helper.c                 | 15 +++++++-------
 drivers/gpu/drm/drm_fourcc.c                    |  8 ++++----
 drivers/gpu/drm/drm_framebuffer.c               | 11 +++++-----
 drivers/gpu/drm/drm_gem_framebuffer_helper.c    |  5 +++--
 drivers/gpu/drm/drm_plane.c                     |  1 +-
 drivers/gpu/drm/exynos/exynos_drm_fb.c          |  3 ++-
 drivers/gpu/drm/gma500/framebuffer.c            |  2 +-
 drivers/gpu/drm/i915/i915_drv.h                 |  6 ++++--
 drivers/gpu/drm/i915/intel_display.c            | 11 +++++-----
 drivers/gpu/drm/imx/ipuv3-plane.c               |  5 +++--
 drivers/gpu/drm/mediatek/mtk_drm_fb.c           |  4 ++--
 drivers/gpu/drm/meson/meson_overlay.c           | 12 +++++------
 drivers/gpu/drm/msm/msm_fb.c                    |  8 ++++----
 drivers/gpu/drm/omapdrm/omap_fb.c               |  6 +++---
 drivers/gpu/drm/radeon/radeon_fb.c              |  4 ++--
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  4 ++--
 drivers/gpu/drm/stm/ltdc.c                      |  2 +-
 drivers/gpu/drm/sun4i/sun4i_backend.c           |  7 ++++---
 drivers/gpu/drm/sun4i/sun4i_frontend.c          | 19 +++++++++---------
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c          |  2 ++-
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c          |  6 ++++--
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.c         |  6 ++++--
 drivers/gpu/drm/sun4i/sun8i_vi_scaler.h         |  5 +++--
 drivers/gpu/drm/tegra/fb.c                      |  2 +-
 drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c  |  2 +-
 drivers/gpu/drm/zte/zx_plane.c                  |  2 +-
 include/drm/drm_fourcc.h                        |  4 +++-
 include/drm/drm_framebuffer.h                   |  3 ++-
 include/drm/drm_mode_config.h                   |  4 ++--
 45 files changed, 126 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index bd943a71756c..7992a95ea965 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -12,6 +12,7 @@ menuconfig DRM
 	select FB_CMDLINE
 	select I2C
 	select I2C_ALGOBIT
+	select IMAGE_FORMATS
 	select DMA_SHARED_BUFFER
 	select SYNC_FILE
 	help
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
index 48170a843b48..2d2e091da19b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
@@ -123,8 +123,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct amdgpu_device *adev = rfbdev->adev;
 	struct drm_gem_object *gobj = NULL;
 	struct amdgpu_bo *abo = NULL;
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index ab50ad06e271..fec4fe15a71b 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -264,7 +264,7 @@ static bool
 malidp_verify_afbc_framebuffer_caps(struct drm_device *dev,
 				    const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 
 	if ((mode_cmd->modifier[0] >> 56) != DRM_FORMAT_MOD_VENDOR_ARM) {
 		DRM_DEBUG_KMS("Unknown modifier (not Arm)\n");
diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c
index c9a6d3e0cada..6d2dad4642be 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -415,7 +415,7 @@ static int malidp_de_plane_check(struct drm_plane *plane,
 	for (i = 0; i < ms->n_planes; i++) {
 		u8 alignment = malidp_hw_get_pitch_align(mp->hwdev, rotated);
 
-		if ((fb->pitches[i] * drm_format_info_block_height(fb->format, i))
+		if ((fb->pitches[i] * image_format_block_height(fb->format, i))
 				& (alignment - 1)) {
 			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
 				      fb->pitches[i], i);
@@ -423,8 +423,8 @@ static int malidp_de_plane_check(struct drm_plane *plane,
 		}
 	}
 
-	block_w = drm_format_info_block_width(fb->format, 0);
-	block_h = drm_format_info_block_height(fb->format, 0);
+	block_w = image_format_block_width(fb->format, 0);
+	block_h = image_format_block_height(fb->format, 0);
 	if (fb->width % block_w || fb->height % block_h) {
 		DRM_DEBUG_KMS("Buffer width/height needs to be a multiple of tile sizes");
 		return -EINVAL;
@@ -512,7 +512,7 @@ static void malidp_de_set_plane_pitches(struct malidp_plane *mp,
 	 * in a tile.
 	 */
 	for (i = 0; i < num_strides; ++i) {
-		unsigned int block_h = drm_format_info_block_height(mp->base.state->fb->format, i);
+		unsigned int block_h = image_format_block_height(mp->base.state->fb->format, i);
 
 		malidp_hw_write(mp->hwdev, pitches[i] * block_h,
 				mp->layer->base +
diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
index a2f6472eb482..10e9ab534658 100644
--- a/drivers/gpu/drm/armada/armada_fb.c
+++ b/drivers/gpu/drm/armada/armada_fb.c
@@ -87,7 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
 struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 	struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev, mode);
+	const struct image_format_info *info = drm_get_format_info(dev, mode);
 	struct armada_gem_object *obj;
 	struct armada_framebuffer *dfb;
 	int ret;
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 8d770641fcc4..8574fa02879d 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -12,6 +12,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
 #include <drm/armada_drm.h>
+#include <linux/image-formats.h>
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_fb.h"
@@ -107,7 +108,7 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
 	if (old_state->src.x1 != state->src.x1 ||
 	    old_state->src.y1 != state->src.y1 ||
 	    old_state->fb != state->fb) {
-		const struct drm_format_info *format;
+		const struct image_format_info *format;
 		u16 src_x, pitches[3];
 		u32 addrs[2][3];
 
diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c
index 9f36423dd394..91cf01317098 100644
--- a/drivers/gpu/drm/armada/armada_plane.c
+++ b/drivers/gpu/drm/armada/armada_plane.c
@@ -10,6 +10,7 @@
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <linux/image-formats.h>
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_fb.h"
@@ -39,7 +40,7 @@ void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3],
 	u16 pitches[3], bool interlaced)
 {
 	struct drm_framebuffer *fb = state->fb;
-	const struct drm_format_info *format = fb->format;
+	const struct image_format_info *format = fb->format;
 	unsigned int num_planes = format->num_planes;
 	unsigned int x = state->src.x1 >> 16;
 	unsigned int y = state->src.y1 >> 16;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index fdd607ad27fe..550a47c09408 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -17,6 +17,8 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/image-formats.h>
+
 #include "atmel_hlcdc_dc.h"
 
 /**
@@ -360,7 +362,7 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
 {
 	unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id;
 	const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
-	const struct drm_format_info *format = state->base.fb->format;
+	const struct image_format_info *format = state->base.fb->format;
 
 	/*
 	 * Rotation optimization is not working on RGB888 (rotation is still
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 03711394f1ed..7dbcf664c0f1 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -110,6 +110,8 @@ static inline u64 bochs_bo_mmap_offset(struct bochs_bo *bo)
 
 /* ---------------------------------------------------------------------- */
 
+struct image_format_info;
+
 /* bochs_hw.c */
 int bochs_hw_init(struct drm_device *dev);
 void bochs_hw_fini(struct drm_device *dev);
@@ -117,7 +119,7 @@ void bochs_hw_fini(struct drm_device *dev);
 void bochs_hw_setmode(struct bochs_device *bochs,
 		      struct drm_display_mode *mode);
 void bochs_hw_setformat(struct bochs_device *bochs,
-			const struct drm_format_info *format);
+			const struct image_format_info *format);
 void bochs_hw_setbase(struct bochs_device *bochs,
 		      int x, int y, u64 addr);
 int bochs_hw_load_edid(struct bochs_device *bochs);
diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c
index 3e04b2f0ec08..8f6a04b2d373 100644
--- a/drivers/gpu/drm/bochs/bochs_hw.c
+++ b/drivers/gpu/drm/bochs/bochs_hw.c
@@ -5,6 +5,7 @@
  * (at your option) any later version.
  */
 
+#include <linux/image-formats.h>
 #include "bochs.h"
 
 /* ---------------------------------------------------------------------- */
@@ -234,7 +235,7 @@ void bochs_hw_setmode(struct bochs_device *bochs,
 }
 
 void bochs_hw_setformat(struct bochs_device *bochs,
-			const struct drm_format_info *format)
+			const struct image_format_info *format)
 {
 	DRM_DEBUG_DRIVER("format %c%c%c%c\n",
 			 (format->format >>  0) & 0xff,
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index 759847bafda8..a0bef1337761 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -137,8 +137,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
 			       const struct drm_mode_fb_cmd2 *mode_cmd,
 			       struct drm_gem_object **gobj_p)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct drm_device *dev = afbdev->helper.dev;
 	struct cirrus_device *cdev = dev->dev_private;
 	u32 bpp;
diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
index 66d0d2c5211d..8afc6a351ecd 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
@@ -41,8 +41,8 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
 			       struct drm_file *filp,
 			       const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct cirrus_device *cdev = dev->dev_private;
 	struct drm_gem_object *obj;
 	struct drm_framebuffer *fb;
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 5eb40130fafb..6a0aff2bd7f4 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -32,6 +32,7 @@
 #include <drm/drm_mode.h>
 #include <drm/drm_print.h>
 #include <drm/drm_writeback.h>
+#include <linux/image-formats.h>
 #include <linux/sync_file.h>
 
 #include "drm_crtc_internal.h"
diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 305d6dd5d201..9df52b7fd074 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -3,6 +3,7 @@
  * Copyright 2018 Noralf Trønnes
  */
 
+#include <linux/image-formats.h>
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 7dabbaf033a1..2a6d811b19df 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -30,6 +30,7 @@
  *      Jesse Barnes <jesse.barnes@intel.com>
  */
 #include <linux/ctype.h>
+#include <linux/image-formats.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/export.h>
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 5f8074ffe7d9..f6573a3ee90b 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -22,6 +22,7 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_plane.h>
+#include <linux/image-formats.h>
 #include <linux/module.h>
 
 /**
@@ -74,8 +75,8 @@ dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
 	struct drm_gem_cma_object *obj;
 	dma_addr_t paddr;
 	u8 h_div = 1, v_div = 1;
-	u32 block_w = drm_format_info_block_width(fb->format, plane);
-	u32 block_h = drm_format_info_block_height(fb->format, plane);
+	u32 block_w = image_format_block_width(fb->format, plane);
+	u32 block_h = image_format_block_height(fb->format, plane);
 	u32 block_size = fb->format->char_per_block[plane];
 	u32 sample_x;
 	u32 sample_y;
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 257a9c995057..c91200af3fdd 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -31,6 +31,7 @@
 
 #include <linux/console.h>
 #include <linux/dma-buf.h>
+#include <linux/image-formats.h>
 #include <linux/kernel.h>
 #include <linux/sysrq.h>
 #include <linux/slab.h>
@@ -768,7 +769,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
 					  struct drm_clip_rect *clip)
 {
 	struct drm_framebuffer *fb = fb_helper->fb;
-	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
+	unsigned int cpp = image_format_plane_cpp(fb->format, 0);
 	size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
 	void *src = fb_helper->fbdev->screen_buffer + offset;
 	void *dst = fb_helper->buffer->vaddr + offset;
@@ -1698,8 +1699,8 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 		var->pixclock = 0;
 	}
 
-	if ((drm_format_info_block_width(fb->format, 0) > 1) ||
-	    (drm_format_info_block_height(fb->format, 0) > 1))
+	if ((image_format_block_width(fb->format, 0) > 1) ||
+	    (image_format_block_height(fb->format, 0) > 1))
 		return -EINVAL;
 
 	/*
@@ -1934,9 +1935,9 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
 		DRM_DEBUG("test CRTC %d primary plane\n", i);
 
 		for (j = 0; j < plane->format_count; j++) {
-			const struct drm_format_info *fmt;
+			const struct image_format_info *fmt;
 
-			fmt = drm_format_info(plane->format_types[j]);
+			fmt = image_format_drm_lookup(plane->format_types[j]);
 
 			/*
 			 * Do not consider YUV or other complicated formats
@@ -2086,8 +2087,8 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe
 {
 	struct drm_framebuffer *fb = fb_helper->fb;
 
-	WARN_ON((drm_format_info_block_width(fb->format, 0) > 1) ||
-		(drm_format_info_block_height(fb->format, 0) > 1));
+	WARN_ON((image_format_block_width(fb->format, 0) > 1) ||
+		(image_format_block_height(fb->format, 0) > 1));
 	info->pseudo_palette = fb_helper->pseudo_palette;
 	info->var.xres_virtual = fb->width;
 	info->var.yres_virtual = fb->height;
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 57389b9753b2..6ddb1c28be49 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -286,20 +286,20 @@ EXPORT_SYMBOL(drm_format_info);
  * @mode_cmd: metadata from the userspace fb creation request
  *
  * Returns:
- * The instance of struct drm_format_info that describes the pixel format, or
+ * The instance of struct image_format_info that describes the pixel format, or
  * NULL if the format is unsupported.
  */
-const struct drm_format_info *
+const struct image_format_info *
 drm_get_format_info(struct drm_device *dev,
 		    const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = NULL;
+	const struct image_format_info *info = NULL;
 
 	if (dev->mode_config.funcs->get_format_info)
 		info = dev->mode_config.funcs->get_format_info(mode_cmd);
 
 	if (!info)
-		info = drm_format_info(mode_cmd->pixel_format);
+		info = image_format_drm_lookup(mode_cmd->pixel_format);
 
 	return info;
 }
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index d8d75e25f6fb..90c77a6633be 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -21,6 +21,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/image-formats.h>
 #include <drm/drmP.h>
 #include <drm/drm_auth.h>
 #include <drm/drm_framebuffer.h>
@@ -146,7 +147,7 @@ int drm_mode_addfb_ioctl(struct drm_device *dev,
 }
 
 static int fb_plane_width(int width,
-			  const struct drm_format_info *format, int plane)
+			  const struct image_format_info *format, int plane)
 {
 	if (plane == 0)
 		return width;
@@ -155,7 +156,7 @@ static int fb_plane_width(int width,
 }
 
 static int fb_plane_height(int height,
-			   const struct drm_format_info *format, int plane)
+			   const struct image_format_info *format, int plane)
 {
 	if (plane == 0)
 		return height;
@@ -166,11 +167,11 @@ static int fb_plane_height(int height,
 static int framebuffer_check(struct drm_device *dev,
 			     const struct drm_mode_fb_cmd2 *r)
 {
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	int i;
 
 	/* check if the format is supported at all */
-	info = __drm_format_info(r->pixel_format);
+	info = __image_format_drm_lookup(r->pixel_format);
 	if (!info) {
 		struct drm_format_name_buf format_name;
 
@@ -197,7 +198,7 @@ static int framebuffer_check(struct drm_device *dev,
 		unsigned int width = fb_plane_width(r->width, info, i);
 		unsigned int height = fb_plane_height(r->height, info, i);
 		unsigned int block_size = info->char_per_block[i];
-		u64 min_pitch = drm_format_info_min_pitch(info, i, width);
+		u64 min_pitch = image_format_min_pitch(info, i, width);
 
 		if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
 			DRM_DEBUG_KMS("Format requires non-linear modifier for plane %d\n", i);
diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index 65edb1ccb185..a2a01afeba3e 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -11,6 +11,7 @@
 
 #include <linux/dma-buf.h>
 #include <linux/dma-fence.h>
+#include <linux/image-formats.h>
 #include <linux/reservation.h>
 #include <linux/slab.h>
 
@@ -149,7 +150,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
 			     const struct drm_mode_fb_cmd2 *mode_cmd,
 			     const struct drm_framebuffer_funcs *funcs)
 {
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	struct drm_gem_object *objs[4];
 	struct drm_framebuffer *fb;
 	int ret, i;
@@ -171,7 +172,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
 		}
 
 		min_size = (height - 1) * mode_cmd->pitches[i]
-			 + drm_format_info_min_pitch(info, i, width)
+			 + image_format_min_pitch(info, i, width)
 			 + mode_cmd->offsets[i];
 
 		if (objs[i]->size < min_size) {
diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 4cfb56893b7f..b67be56e71cc 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -20,6 +20,7 @@
  * OF THIS SOFTWARE.
  */
 
+#include <linux/image-formats.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 1f11ab0f8e9d..be41d986e481 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -19,6 +19,7 @@
 #include <drm/drm_fb_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_probe_helper.h>
+#include <linux/image-formats.h>
 #include <uapi/drm/exynos_drm.h>
 
 #include "exynos_drm_drv.h"
@@ -98,7 +99,7 @@ static struct drm_framebuffer *
 exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 		      const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev, mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev, mode_cmd);
 	struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
 	struct drm_framebuffer *fb;
 	int i;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 46f0078f7a91..f160e3c257c1 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -225,7 +225,7 @@ static int psb_framebuffer_init(struct drm_device *dev,
 					const struct drm_mode_fb_cmd2 *mode_cmd,
 					struct gtt_range *gt)
 {
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	int ret;
 
 	/*
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 9adc7bb9e69c..6a085185e7fc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -379,6 +379,8 @@ enum fb_op_origin {
 	ORIGIN_DIRTYFB,
 };
 
+struct image_format_info;
+
 struct intel_fbc {
 	/* This is always the inner lock when overlapping with struct_mutex and
 	 * it's the outer lock when overlapping with stolen_lock. */
@@ -435,7 +437,7 @@ struct intel_fbc {
 		} plane;
 
 		struct {
-			const struct drm_format_info *format;
+			const struct image_format_info *format;
 			unsigned int stride;
 		} fb;
 	} state_cache;
@@ -458,7 +460,7 @@ struct intel_fbc {
 		} crtc;
 
 		struct {
-			const struct drm_format_info *format;
+			const struct image_format_info *format;
 			unsigned int stride;
 		} fb;
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ccb616351bba..86febe2ee510 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -25,6 +25,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/image-formats.h>
 #include <linux/input.h>
 #include <linux/intel-iommu.h>
 #include <linux/kernel.h>
@@ -2443,15 +2444,15 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
  * us a ratio of one byte in the CCS for each 8x16 pixels in the
  * main surface.
  */
-static const struct drm_format_info ccs_formats[] = {
+static const struct image_format_info ccs_formats[] = {
 	{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
 	{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
 	{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
 	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
 };
 
-static const struct drm_format_info *
-lookup_format_info(const struct drm_format_info formats[],
+static const struct image_format_info *
+lookup_format_info(const struct image_format_info formats[],
 		   int num_formats, u32 format)
 {
 	int i;
@@ -2464,7 +2465,7 @@ lookup_format_info(const struct drm_format_info formats[],
 	return NULL;
 }
 
-static const struct drm_format_info *
+static const struct image_format_info *
 intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
 {
 	switch (cmd->modifier[0]) {
@@ -4982,7 +4983,7 @@ static int
 skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 		  unsigned int scaler_user, int *scaler_id,
 		  int src_w, int src_h, int dst_w, int dst_h,
-		  const struct drm_format_info *format, bool need_scaler)
+		  const struct image_format_info *format, bool need_scaler)
 {
 	struct intel_crtc_scaler_state *scaler_state =
 		&crtc_state->scaler_state;
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 2530143281b2..6bbacba90661 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -12,6 +12,7 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <linux/image-formats.h>
 
 #include "video/imx-ipu-v3.h"
 #include "imx-drm.h"
@@ -549,7 +550,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
 	unsigned long alpha_eba = 0;
 	enum ipu_color_space ics;
 	unsigned int axi_id = 0;
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	u8 burstsize, num_bursts;
 	u32 width, height;
 	int active;
@@ -626,7 +627,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
 
 	width = drm_rect_width(&state->src) >> 16;
 	height = drm_rect_height(&state->src) >> 16;
-	info = drm_format_info(fb->format->format);
+	info = fb->format;
 	ipu_calculate_bursts(width, info->cpp[0], fb->pitches[0],
 			     &burstsize, &num_bursts);
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
index af90c84e9e02..ee71d96dc0cd 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
@@ -32,7 +32,7 @@ static struct drm_framebuffer *mtk_drm_framebuffer_init(struct drm_device *dev,
 					const struct drm_mode_fb_cmd2 *mode,
 					struct drm_gem_object *obj)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev, mode);
+	const struct image_format_info *info = drm_get_format_info(dev, mode);
 	struct drm_framebuffer *fb;
 	int ret;
 
@@ -89,7 +89,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
 					       struct drm_file *file,
 					       const struct drm_mode_fb_cmd2 *cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
+	const struct image_format_info *info = drm_get_format_info(dev, cmd);
 	struct drm_framebuffer *fb;
 	struct drm_gem_object *gem;
 	unsigned int width = cmd->width;
diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
index 6987c15b6ab9..b84187da6426 100644
--- a/drivers/gpu/drm/meson/meson_overlay.c
+++ b/drivers/gpu/drm/meson/meson_overlay.c
@@ -474,8 +474,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_addr2 = gem->paddr + fb->offsets[2];
 		priv->viu.vd1_stride2 = fb->pitches[2];
 		priv->viu.vd1_height2 =
-			drm_format_plane_height(fb->height,
-						fb->format, 2);
+			image_format_plane_height(fb->height,
+						  fb->format, 2);
 		DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr2,
 			 priv->viu.vd1_stride2,
@@ -486,8 +486,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_addr1 = gem->paddr + fb->offsets[1];
 		priv->viu.vd1_stride1 = fb->pitches[1];
 		priv->viu.vd1_height1 =
-			drm_format_plane_height(fb->height,
-						fb->format, 1);
+			image_format_plane_height(fb->height,
+						  fb->format, 1);
 		DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr1,
 			 priv->viu.vd1_stride1,
@@ -498,8 +498,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
 		priv->viu.vd1_addr0 = gem->paddr + fb->offsets[0];
 		priv->viu.vd1_stride0 = fb->pitches[0];
 		priv->viu.vd1_height0 =
-			drm_format_plane_height(fb->height,
-						fb->format, 0);
+			image_format_plane_height(fb->height,
+						  fb->format, 0);
 		DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n",
 			 priv->viu.vd1_addr0,
 			 priv->viu.vd1_stride0,
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index ee91058c7974..296fb89cdbd0 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -106,8 +106,8 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
 struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
 		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct drm_gem_object *bos[4] = {0};
 	struct drm_framebuffer *fb;
 	int ret, i, n = info->num_planes;
@@ -137,8 +137,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
 static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
 		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct msm_drm_private *priv = dev->dev_private;
 	struct msm_kms *kms = priv->kms;
 	struct msm_framebuffer *msm_fb = NULL;
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 6557b2d6e16e..1d4143adf829 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -298,8 +298,8 @@ void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
 		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	unsigned int num_planes = info->num_planes;
 	struct drm_gem_object *bos[4];
 	struct drm_framebuffer *fb;
@@ -329,7 +329,7 @@ struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
 struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
 		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
 {
-	const struct drm_format_info *format = NULL;
+	const struct image_format_info *format = NULL;
 	struct omap_framebuffer *omap_fb = NULL;
 	struct drm_framebuffer *fb = NULL;
 	unsigned int pitch = mode_cmd->pitches[0];
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 88fc1a6e2e43..4c50166546ca 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -125,8 +125,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
 					 struct drm_mode_fb_cmd2 *mode_cmd,
 					 struct drm_gem_object **gobj_p)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct radeon_device *rdev = rfbdev->rdev;
 	struct drm_gem_object *gobj = NULL;
 	struct radeon_bo *rbo = NULL;
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index c602cb2f4d3c..abb6783eb38e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -74,8 +74,8 @@ static struct drm_framebuffer *
 rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 			const struct drm_mode_fb_cmd2 *mode_cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev,
-								 mode_cmd);
+	const struct image_format_info *info = drm_get_format_info(dev,
+								   mode_cmd);
 	struct drm_framebuffer *fb;
 	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
 	struct drm_gem_object *obj;
diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
index b226df7dbf6f..6afd8dcb3fd9 100644
--- a/drivers/gpu/drm/stm/ltdc.c
+++ b/drivers/gpu/drm/stm/ltdc.c
@@ -779,7 +779,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
 
 	/* Configures the color frame buffer pitch in bytes & line length */
 	pitch_in_bytes = fb->pitches[0];
-	line_length = drm_format_plane_cpp(fb->format, 0) *
+	line_length = image_format_plane_cpp(fb->format, 0) *
 		      (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
 	val = ((pitch_in_bytes << 16) | line_length);
 	reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
index 4c0d51f73237..f84c5edb234a 100644
--- a/drivers/gpu/drm/sun4i/sun4i_backend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
@@ -20,6 +20,7 @@
 #include <drm/drm_probe_helper.h>
 
 #include <linux/component.h>
+#include <linux/image-formats.h>
 #include <linux/list.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
@@ -203,7 +204,7 @@ static int sun4i_backend_update_yuv_format(struct sun4i_backend *backend,
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
-	const struct drm_format_info *format = fb->format;
+	const struct image_format_info *format = fb->format;
 	const uint32_t fmt = format->format;
 	u32 val = SUN4I_BACKEND_IYUVCTL_EN;
 	int i;
@@ -222,8 +223,8 @@ static int sun4i_backend_update_yuv_format(struct sun4i_backend *backend,
 			   SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN);
 
 	/* TODO: Add support for the multi-planar YUV formats */
-	if (drm_format_info_is_yuv_packed(format) &&
-	    drm_format_info_is_yuv_sampling_422(format))
+	if (image_format_info_is_yuv_packed(format) &&
+	    image_format_info_is_yuv_sampling_422(format))
 		val |= SUN4I_BACKEND_IYUVCTL_FBFMT_PACKED_YUV422;
 	else
 		DRM_DEBUG_DRIVER("Unsupported YUV format (0x%x)\n", fmt);
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c
index 346c8071bd38..389637e9ec9d 100644
--- a/drivers/gpu/drm/sun4i/sun4i_frontend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c
@@ -9,6 +9,7 @@
 
 #include <linux/clk.h>
 #include <linux/component.h>
+#include <linux/image-formats.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
@@ -241,18 +242,18 @@ void sun4i_frontend_update_buffer(struct sun4i_frontend *frontend,
 EXPORT_SYMBOL(sun4i_frontend_update_buffer);
 
 static int
-sun4i_frontend_drm_format_to_input_fmt(const struct drm_format_info *format,
+sun4i_frontend_drm_format_to_input_fmt(const struct image_format_info *format,
 				       u32 *val)
 {
 	if (!format->is_yuv)
 		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_RGB;
-	else if (drm_format_info_is_yuv_sampling_411(format))
+	else if (image_format_info_is_yuv_sampling_411(format))
 		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV411;
-	else if (drm_format_info_is_yuv_sampling_420(format))
+	else if (image_format_info_is_yuv_sampling_420(format))
 		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV420;
-	else if (drm_format_info_is_yuv_sampling_422(format))
+	else if (image_format_info_is_yuv_sampling_422(format))
 		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV422;
-	else if (drm_format_info_is_yuv_sampling_444(format))
+	else if (image_format_info_is_yuv_sampling_444(format))
 		*val = SUN4I_FRONTEND_INPUT_FMT_DATA_FMT_YUV444;
 	else
 		return -EINVAL;
@@ -261,7 +262,7 @@ sun4i_frontend_drm_format_to_input_fmt(const struct drm_format_info *format,
 }
 
 static int
-sun4i_frontend_drm_format_to_input_mode(const struct drm_format_info *format,
+sun4i_frontend_drm_format_to_input_mode(const struct image_format_info *format,
 					uint64_t modifier, u32 *val)
 {
 	bool tiled = (modifier == DRM_FORMAT_MOD_ALLWINNER_TILED);
@@ -287,11 +288,11 @@ sun4i_frontend_drm_format_to_input_mode(const struct drm_format_info *format,
 }
 
 static int
-sun4i_frontend_drm_format_to_input_sequence(const struct drm_format_info *format,
+sun4i_frontend_drm_format_to_input_sequence(const struct image_format_info *format,
 					    u32 *val)
 {
 	/* Planar formats have an explicit input sequence. */
-	if (drm_format_info_is_yuv_planar(format)) {
+	if (image_format_info_is_yuv_planar(format)) {
 		*val = 0;
 		return 0;
 	}
@@ -401,7 +402,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
-	const struct drm_format_info *format = fb->format;
+	const struct image_format_info *format = fb->format;
 	uint64_t modifier = fb->modifier;
 	u32 out_fmt_val;
 	u32 in_fmt_val, in_mod_val, in_ps_val;
diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
index a342ec8b131e..bbd4a2d34eb7 100644
--- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
@@ -23,6 +23,8 @@
 #include <drm/drm_probe_helper.h>
 #include <drm/drmP.h>
 
+#include <linux/image-formats.h>
+
 #include "sun8i_ui_layer.h"
 #include "sun8i_mixer.h"
 #include "sun8i_ui_scaler.h"
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
index 8a0616238467..85b1b55ef342 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c
@@ -17,6 +17,8 @@
 #include <drm/drm_probe_helper.h>
 #include <drm/drmP.h>
 
+#include <linux/image-formats.h>
+
 #include "sun8i_vi_layer.h"
 #include "sun8i_mixer.h"
 #include "sun8i_vi_scaler.h"
@@ -75,7 +77,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
 				       unsigned int zpos)
 {
 	struct drm_plane_state *state = plane->state;
-	const struct drm_format_info *format = state->fb->format;
+	const struct image_format_info *format = state->fb->format;
 	u32 src_w, src_h, dst_w, dst_h;
 	u32 bld_base, ch_base;
 	u32 outsize, insize;
@@ -219,7 +221,7 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,
 {
 	struct drm_plane_state *state = plane->state;
 	struct drm_framebuffer *fb = state->fb;
-	const struct drm_format_info *format = fb->format;
+	const struct image_format_info *format = fb->format;
 	struct drm_gem_cma_object *gem;
 	u32 dx, dy, src_x, src_y;
 	dma_addr_t paddr;
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
index 7ba75011adf9..1d22331af5fe 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.c
@@ -9,6 +9,8 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/image-formats.h>
+
 #include "sun8i_vi_scaler.h"
 
 static const u32 lan3coefftab32_left[480] = {
@@ -869,7 +871,7 @@ static int sun8i_vi_scaler_coef_index(unsigned int step)
 
 static void sun8i_vi_scaler_set_coeff(struct regmap *map, u32 base,
 				      u32 hstep, u32 vstep,
-				      const struct drm_format_info *format)
+				      const struct image_format_info *format)
 {
 	const u32 *ch_left, *ch_right, *cy;
 	int offset, i;
@@ -926,7 +928,7 @@ void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable)
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
 			   u32 hscale, u32 vscale, u32 hphase, u32 vphase,
-			   const struct drm_format_info *format)
+			   const struct image_format_info *format)
 {
 	u32 chphase, cvphase;
 	u32 insize, outsize;
diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
index 68f6593b369a..878a689e532a 100644
--- a/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
+++ b/drivers/gpu/drm/sun4i/sun8i_vi_scaler.h
@@ -9,7 +9,6 @@
 #ifndef _SUN8I_VI_SCALER_H_
 #define _SUN8I_VI_SCALER_H_
 
-#include <drm/drm_fourcc.h>
 #include "sun8i_mixer.h"
 
 #define DE2_VI_SCALER_UNIT_BASE 0x20000
@@ -69,10 +68,12 @@
 #define SUN50I_SCALER_VSU_ANGLE_SHIFT(x)		(((x) << 16) & 0xF)
 #define SUN50I_SCALER_VSU_ANGLE_OFFSET(x)		((x) & 0xFF)
 
+struct image_format_info;
+
 void sun8i_vi_scaler_enable(struct sun8i_mixer *mixer, int layer, bool enable);
 void sun8i_vi_scaler_setup(struct sun8i_mixer *mixer, int layer,
 			   u32 src_w, u32 src_h, u32 dst_w, u32 dst_h,
 			   u32 hscale, u32 vscale, u32 hphase, u32 vphase,
-			   const struct drm_format_info *format);
+			   const struct image_format_info *format);
 
 #endif
diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
index 0a97458b286a..591a9ede5b9a 100644
--- a/drivers/gpu/drm/tegra/fb.c
+++ b/drivers/gpu/drm/tegra/fb.c
@@ -131,7 +131,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
 					struct drm_file *file,
 					const struct drm_mode_fb_cmd2 *cmd)
 {
-	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
+	const struct image_format_info *info = drm_get_format_info(dev, cmd);
 	struct tegra_bo *planes[4];
 	struct drm_gem_object *gem;
 	struct drm_framebuffer *fb;
diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
index 57dda9d1a45d..32f8d312b426 100644
--- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
+++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
@@ -36,7 +36,7 @@ MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
 void tinydrm_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
 		    struct drm_rect *clip)
 {
-	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
+	unsigned int cpp = image_format_plane_cpp(fb->format, 0);
 	unsigned int pitch = fb->pitches[0];
 	void *src = vaddr + (clip->y1 * pitch) + (clip->x1 * cpp);
 	size_t len = (clip->x2 - clip->x1) * cpp;
diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 41bd0db4e876..054149b57410 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -222,7 +222,7 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
 		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
 		paddr = cma_obj->paddr + fb->offsets[i];
 		paddr += src_y * fb->pitches[i];
-		paddr += src_x * drm_format_plane_cpp(fb->format, i);
+		paddr += src_x * image_format_plane_cpp(fb->format, i);
 		zx_writel(paddr_reg, paddr);
 		paddr_reg += 4;
 	}
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 2291f2618211..7cc7b99a6569 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -49,6 +49,7 @@
 
 struct drm_device;
 struct drm_mode_fb_cmd2;
+struct image_format_info;
 
 /**
  * struct drm_format_info - information about a DRM format
@@ -262,7 +263,8 @@ drm_format_info_is_yuv_sampling_444(const struct drm_format_info *info)
 
 const struct drm_format_info *__drm_format_info(u32 format);
 const struct drm_format_info *drm_format_info(u32 format);
-const struct drm_format_info *
+
+const struct image_format_info *
 drm_get_format_info(struct drm_device *dev,
 		    const struct drm_mode_fb_cmd2 *mode_cmd);
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
index f0b34c977ec5..dc7dc48c8580 100644
--- a/include/drm/drm_framebuffer.h
+++ b/include/drm/drm_framebuffer.h
@@ -24,6 +24,7 @@
 #define __DRM_FRAMEBUFFER_H__
 
 #include <linux/ctype.h>
+#include <linux/image-formats.h>
 #include <linux/list.h>
 #include <linux/sched.h>
 
@@ -134,7 +135,7 @@ struct drm_framebuffer {
 	/**
 	 * @format: framebuffer format information
 	 */
-	const struct drm_format_info *format;
+	const struct image_format_info *format;
 	/**
 	 * @funcs: framebuffer vfunc table
 	 */
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7f60e8eb269a..74421d2fefbc 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -35,7 +35,7 @@ struct drm_file;
 struct drm_device;
 struct drm_atomic_state;
 struct drm_mode_fb_cmd2;
-struct drm_format_info;
+struct image_format_info;
 struct drm_display_mode;
 
 /**
@@ -89,7 +89,7 @@ struct drm_mode_config_funcs {
 	 * The format information specific to the given fb metadata, or
 	 * NULL if none is found.
 	 */
-	const struct drm_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
+	const struct image_format_info *(*get_format_info)(const struct drm_mode_fb_cmd2 *mode_cmd);
 
 	/**
 	 * @output_poll_changed:
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 08/20] drm/malidp: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (6 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 07/20] drm/fb: Move from drm_format_info to image_format_info Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 09/20] drm/client: " Maxime Ripard
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/arm/malidp_drv.c | 3 ++-
 drivers/gpu/drm/arm/malidp_hw.c  | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index fec4fe15a71b..1fcbe364a137 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -10,6 +10,7 @@
  * ARM Mali DP500/DP550/DP650 KMS/DRM driver
  */
 
+#include <linux/image-formats.h>
 #include <linux/module.h>
 #include <linux/clk.h>
 #include <linux/component.h>
@@ -314,7 +315,7 @@ malidp_verify_afbc_framebuffer_size(struct drm_device *dev,
 				    const struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	int n_superblocks = 0;
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	struct drm_gem_object *objs = NULL;
 	u32 afbc_superblock_size = 0, afbc_superblock_height = 0;
 	u32 afbc_superblock_width = 0, afbc_size = 0;
diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
index 07971ad53b29..d25bc4af1bc9 100644
--- a/drivers/gpu/drm/arm/malidp_hw.c
+++ b/drivers/gpu/drm/arm/malidp_hw.c
@@ -326,14 +326,14 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
 
 static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
 {
-	const struct drm_format_info *info = drm_format_info(fmt);
+	const struct image_format_info *info = image_format_drm_lookup(fmt);
 
 	/*
 	 * Each layer needs enough rotation memory to fit 8 lines
 	 * worth of pixel data. Required size is then:
 	 *    size = rotated_width * (bpp / 8) * 8;
 	 */
-	return w * drm_format_plane_cpp(info, 0) * 8;
+	return w * image_format_plane_cpp(info, 0) * 8;
 }
 
 static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 09/20] drm/client: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (7 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 08/20] drm/malidp: Convert to generic image format library Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 10/20] drm/exynos: " Maxime Ripard
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert the rest of
the DRM core to use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/drm_client.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9df52b7fd074..a48181e18934 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -243,7 +243,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
 static struct drm_client_buffer *
 drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 	struct drm_mode_create_dumb dumb_args = { };
 	struct drm_device *dev = client->dev;
 	struct drm_client_buffer *buffer;
@@ -259,7 +259,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
 
 	dumb_args.width = width;
 	dumb_args.height = height;
-	dumb_args.bpp = drm_format_plane_cpp(info, 0) * 8;
+	dumb_args.bpp = image_format_plane_cpp(info, 0) * 8;
 	ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
 	if (ret)
 		goto err_delete;
@@ -319,10 +319,10 @@ static int drm_client_buffer_addfb(struct drm_client_buffer *buffer,
 {
 	struct drm_client_dev *client = buffer->client;
 	struct drm_mode_fb_cmd fb_req = { };
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	int ret;
 
-	info = drm_format_info(format);
+	info = image_format_drm_lookup(format);
 	fb_req.bpp = info->cpp[0] * 8;
 	fb_req.depth = info->depth;
 	fb_req.width = width;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 10/20] drm/exynos: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (8 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 09/20] drm/client: " Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 11/20] drm/i915: " Maxime Ripard
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/exynos/exynos_drm_ipp.c    | 2 +-
 drivers/gpu/drm/exynos/exynos_drm_ipp.h    | 4 +++-
 drivers/gpu/drm/exynos/exynos_drm_scaler.c | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
index 23226a0212e8..ba012840fe07 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c
@@ -562,7 +562,7 @@ static int exynos_drm_ipp_check_format(struct exynos_drm_ipp_task *task,
 	if (buf->buf.width == 0 || buf->buf.height == 0)
 		return -EINVAL;
 
-	buf->format = drm_format_info(buf->buf.fourcc);
+	buf->format = image_format_drm_lookup(buf->buf.fourcc);
 	for (i = 0; i < buf->format->num_planes; i++) {
 		unsigned int width = (i == 0) ? buf->buf.width :
 			     DIV_ROUND_UP(buf->buf.width, buf->format->hsub);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.h b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
index 0b27d4a9bf94..c6cd21f185e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_ipp.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.h
@@ -71,12 +71,14 @@ struct exynos_drm_ipp {
 	wait_queue_head_t done_wq;
 };
 
+struct image_format_info;
+
 struct exynos_drm_ipp_buffer {
 	struct drm_exynos_ipp_task_buffer buf;
 	struct drm_exynos_ipp_task_rect rect;
 
 	struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
-	const struct drm_format_info *format;
+	const struct image_format_info *format;
 	dma_addr_t dma_addr[MAX_FB_BUFFER];
 };
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_scaler.c b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
index ed1dd1aec902..c9791a2013cf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_scaler.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_scaler.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/component.h>
 #include <linux/err.h>
+#include <linux/image-formats.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
@@ -301,7 +302,7 @@ static inline void scaler_set_rotation(struct scaler_context *scaler,
 }
 
 static inline void scaler_set_csc(struct scaler_context *scaler,
-	const struct drm_format_info *fmt)
+	const struct image_format_info *fmt)
 {
 	static const u32 csc_mtx[2][3][3] = {
 		{ /* YCbCr to RGB */
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 11/20] drm/i915: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (9 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 10/20] drm/exynos: " Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57   ` Maxime Ripard
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/i915/intel_display.c | 4 ++--
 drivers/gpu/drm/i915/intel_sprite.c  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 86febe2ee510..37c7f6bbf650 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7997,7 +7997,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc,
 
 	pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
 	fourcc = i9xx_format_to_fourcc(pixel_format);
-	fb->format = drm_format_info(fourcc);
+	fb->format = image_format_drm_lookup(fourcc);
 
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
 		offset = I915_READ(DSPOFFSET(i9xx_plane));
@@ -9078,7 +9078,7 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 
 	fourcc = skl_format_to_fourcc(pixel_format,
 				      val & PLANE_CTL_ORDER_RGBX, alpha);
-	fb->format = drm_format_info(fourcc);
+	fb->format = image_format_drm_lookup(fourcc);
 
 	tiling = val & PLANE_CTL_TILED_MASK;
 	switch (tiling) {
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ee0e99b13532..aaae2bd4ed05 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -297,8 +297,8 @@ skl_plane_max_stride(struct intel_plane *plane,
 		     u32 pixel_format, u64 modifier,
 		     unsigned int rotation)
 {
-	const struct drm_format_info *info = drm_format_info(pixel_format);
-	int cpp = drm_format_plane_cpp(info, 0);
+	const struct image_format_info *info = image_format_drm_lookup(pixel_format);
+	int cpp = image_format_plane_cpp(info, 0);
 
 	/*
 	 * "The stride in bytes must not exceed the
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 12/20] drm/ipuv3: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/ipu-v3/ipu-pre.c | 3 ++-
 drivers/gpu/ipu-v3/ipu-prg.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c
index 4a28f3fbb0a2..d561295abee0 100644
--- a/drivers/gpu/ipu-v3/ipu-pre.c
+++ b/drivers/gpu/ipu-v3/ipu-pre.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/genalloc.h>
+#include <linux/image-formats.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -174,7 +175,7 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
 		       unsigned int height, unsigned int stride, u32 format,
 		       uint64_t modifier, unsigned int bufaddr)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 	u32 active_bpp = info->cpp[0] >> 1;
 	u32 val;
 
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c
index 38a3a9764e49..608a9213025d 100644
--- a/drivers/gpu/ipu-v3/ipu-prg.c
+++ b/drivers/gpu/ipu-v3/ipu-prg.c
@@ -14,6 +14,7 @@
 #include <drm/drm_fourcc.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/image-formats.h>
 #include <linux/iopoll.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
@@ -132,7 +133,7 @@ EXPORT_SYMBOL_GPL(ipu_prg_present);
 bool ipu_prg_format_supported(struct ipu_soc *ipu, uint32_t format,
 			      uint64_t modifier)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 
 	if (info->num_planes != 1)
 		return false;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 12/20] drm/ipuv3: Convert to generic image format library
@ 2019-03-19 21:57   ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/ipu-v3/ipu-pre.c | 3 ++-
 drivers/gpu/ipu-v3/ipu-prg.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c
index 4a28f3fbb0a2..d561295abee0 100644
--- a/drivers/gpu/ipu-v3/ipu-pre.c
+++ b/drivers/gpu/ipu-v3/ipu-pre.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/genalloc.h>
+#include <linux/image-formats.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -174,7 +175,7 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width,
 		       unsigned int height, unsigned int stride, u32 format,
 		       uint64_t modifier, unsigned int bufaddr)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 	u32 active_bpp = info->cpp[0] >> 1;
 	u32 val;
 
diff --git a/drivers/gpu/ipu-v3/ipu-prg.c b/drivers/gpu/ipu-v3/ipu-prg.c
index 38a3a9764e49..608a9213025d 100644
--- a/drivers/gpu/ipu-v3/ipu-prg.c
+++ b/drivers/gpu/ipu-v3/ipu-prg.c
@@ -14,6 +14,7 @@
 #include <drm/drm_fourcc.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/image-formats.h>
 #include <linux/iopoll.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
@@ -132,7 +133,7 @@ EXPORT_SYMBOL_GPL(ipu_prg_present);
 bool ipu_prg_format_supported(struct ipu_soc *ipu, uint32_t format,
 			      uint64_t modifier)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 
 	if (info->num_planes != 1)
 		return false;
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 13/20] drm/msm: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (11 preceding siblings ...)
  2019-03-19 21:57   ` Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 14/20] drm/omap: " Maxime Ripard
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c |  6 ++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  3 ++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c   |  3 ++-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c  |  9 +++++----
 drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c    |  3 ++-
 5 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index 1aed51b49be4..8c3c953b05d9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -12,6 +12,8 @@
 
 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
 
+#include <linux/image-formats.h>
+
 #include <uapi/drm/drm_fourcc.h>
 
 #include "msm_media_info.h"
@@ -1040,7 +1042,7 @@ int dpu_format_check_modified_format(
 		const struct drm_mode_fb_cmd2 *cmd,
 		struct drm_gem_object **bos)
 {
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 	const struct dpu_format *fmt;
 	struct dpu_hw_fmt_layout layout;
 	uint32_t bos_total_size = 0;
@@ -1052,7 +1054,7 @@ int dpu_format_check_modified_format(
 	}
 
 	fmt = to_dpu_format(msm_fmt);
-	info = drm_format_info(fmt->base.pixel_format);
+	info = image_format_drm_lookup(fmt->base.pixel_format);
 	if (!info)
 		return -EINVAL;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index a9492c488441..1dfaa306ed4b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -20,6 +20,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/dma-buf.h>
+#include <linux/image-formats.h>
 
 #include <drm/drm_atomic_uapi.h>
 
@@ -553,7 +554,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		const struct dpu_format *fmt, bool color_fill)
 {
-	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(fmt->base.pixel_format);
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
index aadae21f8818..542c22c4febe 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
@@ -16,6 +16,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/image-formats.h>
 #include <linux/sort.h>
 #include <drm/drm_mode.h>
 #include <drm/drm_crtc.h>
@@ -782,7 +783,7 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
 
 static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
 {
-	const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
+	const struct image_format_info *info = image_format_drm_lookup(DRM_FORMAT_ARGB8888);
 	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
 	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
 	struct mdp5_kms *mdp5_kms = get_kms(crtc);
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index 9d9fb6c5fd68..00091637a00c 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -17,6 +17,7 @@
  */
 
 #include <drm/drm_print.h>
+#include <linux/image-formats.h>
 #include "mdp5_kms.h"
 
 struct mdp5_plane {
@@ -650,7 +651,7 @@ static int calc_scalex_steps(struct drm_plane *plane,
 		uint32_t pixel_format, uint32_t src, uint32_t dest,
 		uint32_t phasex_steps[COMP_MAX])
 {
-	const struct drm_format_info *info = drm_format_info(pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
 	struct device *dev = mdp5_kms->dev->dev;
 	uint32_t phasex_step;
@@ -673,7 +674,7 @@ static int calc_scaley_steps(struct drm_plane *plane,
 		uint32_t pixel_format, uint32_t src, uint32_t dest,
 		uint32_t phasey_steps[COMP_MAX])
 {
-	const struct drm_format_info *info = drm_format_info(pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(plane);
 	struct device *dev = mdp5_kms->dev->dev;
 	uint32_t phasey_step;
@@ -695,7 +696,7 @@ static int calc_scaley_steps(struct drm_plane *plane,
 static uint32_t get_scale_config(const struct mdp_format *format,
 		uint32_t src, uint32_t dst, bool horz)
 {
-	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(format->base.pixel_format);
 	bool scaling = format->is_yuv ? true : (src != dst);
 	uint32_t sub;
 	uint32_t ya_filter, uv_filter;
@@ -750,7 +751,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
 	uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
 	uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
 {
-	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(format->base.pixel_format);
 	uint32_t lr, tb, req;
 	int i;
 
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
index 03d503d8c3ba..b96ff05d7909 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -16,6 +16,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/image-formats.h>
 #include <drm/drm_util.h>
 
 #include "mdp5_kms.h"
@@ -127,7 +128,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
 		const struct mdp_format *format,
 		u32 width, bool hdecim)
 {
-	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(format->base.pixel_format);
 	struct mdp5_kms *mdp5_kms = get_kms(smp);
 	int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
 	int i, hsub, nplanes, nlines;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 14/20] drm/omap: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (12 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 13/20] drm/msm: " Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 15/20] drm/rockchip: " Maxime Ripard
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/omapdrm/dss/dispc.c |  9 +++++----
 drivers/gpu/drm/omapdrm/omap_fb.c   |  7 ++++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c
index ba82d916719c..bf60d49ad6ca 100644
--- a/drivers/gpu/drm/omapdrm/dss/dispc.c
+++ b/drivers/gpu/drm/omapdrm/dss/dispc.c
@@ -25,6 +25,7 @@
 #include <linux/vmalloc.h>
 #include <linux/export.h>
 #include <linux/clk.h>
+#include <linux/image-formats.h>
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/seq_file.h>
@@ -1898,9 +1899,9 @@ static void dispc_ovl_set_scaling_uv(struct dispc_device *dispc,
 	int scale_x = out_width != orig_width;
 	int scale_y = out_height != orig_height;
 	bool chroma_upscale = plane != OMAP_DSS_WB;
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 
-	info = drm_format_info(fourcc);
+	info = image_format_drm_lookup(fourcc);
 
 	if (!dispc_has_feature(dispc, FEAT_HANDLE_UV_SEPARATE))
 		return;
@@ -2623,9 +2624,9 @@ static int dispc_ovl_setup_common(struct dispc_device *dispc,
 	bool ilace = !!(vm->flags & DISPLAY_FLAGS_INTERLACED);
 	unsigned long pclk = dispc_plane_pclk_rate(dispc, plane);
 	unsigned long lclk = dispc_plane_lclk_rate(dispc, plane);
-	const struct drm_format_info *info;
+	const struct image_format_info *info;
 
-	info = drm_format_info(fourcc);
+	info = image_format_drm_lookup(fourcc);
 
 	/* when setting up WB, dispc_plane_pclk_rate() returns 0 */
 	if (plane == OMAP_DSS_WB)
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index 1d4143adf829..8caecfc8d1db 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -15,6 +15,7 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <linux/image-formats.h>
 #include <linux/seq_file.h>
 
 #include <drm/drm_crtc.h>
@@ -60,7 +61,7 @@ struct plane {
 struct omap_framebuffer {
 	struct drm_framebuffer base;
 	int pin_count;
-	const struct drm_format_info *format;
+	const struct image_format_info *format;
 	struct plane planes[2];
 	/* lock for pinning (pin_count and planes.dma_addr) */
 	struct mutex lock;
@@ -72,7 +73,7 @@ static const struct drm_framebuffer_funcs omap_framebuffer_funcs = {
 };
 
 static u32 get_linear_addr(struct drm_framebuffer *fb,
-		const struct drm_format_info *format, int n, int x, int y)
+		const struct image_format_info *format, int n, int x, int y)
 {
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
 	struct plane *plane = &omap_fb->planes[n];
@@ -126,7 +127,7 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
 		struct drm_plane_state *state, struct omap_overlay_info *info)
 {
 	struct omap_framebuffer *omap_fb = to_omap_framebuffer(fb);
-	const struct drm_format_info *format = omap_fb->format;
+	const struct image_format_info *format = omap_fb->format;
 	struct plane *plane = &omap_fb->planes[0];
 	u32 x, y, orient = 0;
 
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 15/20] drm/rockchip: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (13 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 14/20] drm/omap: " Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57   ` Maxime Ripard
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 88c3902057f3..8f4cfadfd6cd 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -29,6 +29,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/image-formats.h>
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
@@ -317,7 +318,7 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
 			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
 			     uint32_t dst_h, uint32_t pixel_format)
 {
-	const struct drm_format_info *info = drm_format_info(pixel_format);
+	const struct image_format_info *info = image_format_drm_lookup(pixel_format);
 	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
 	uint16_t cbcr_hor_scl_mode = SCALE_NONE;
 	uint16_t cbcr_ver_scl_mode = SCALE_NONE;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 16/20] drm/tegra: Convert to generic image format library
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/tegra/plane.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index d068e8aa3553..e1d82cbdabe8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -6,6 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/image-formats.h>
+
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -76,7 +78,7 @@ static bool tegra_plane_format_mod_supported(struct drm_plane *plane,
 					     uint32_t format,
 					     uint64_t modifier)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 16/20] drm/tegra: Convert to generic image format library
@ 2019-03-19 21:57   ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

Now that we have a generic image format libary, let's convert drivers to
use it so that we can deprecate the old DRM one.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/tegra/plane.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index d068e8aa3553..e1d82cbdabe8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -6,6 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/image-formats.h>
+
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
@@ -76,7 +78,7 @@ static bool tegra_plane_format_mod_supported(struct drm_plane *plane,
 					     uint32_t format,
 					     uint64_t modifier)
 {
-	const struct drm_format_info *info = drm_format_info(format);
+	const struct image_format_info *info = image_format_drm_lookup(format);
 
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 17/20] drm/fourcc: Remove old DRM format API
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (15 preceding siblings ...)
  2019-03-19 21:57   ` Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support Maxime Ripard
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Now that all the clients of the old drm_format* API have been converted to
the generic one, let's remove it.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/gpu/drm/Kconfig                             |   1 +-
 drivers/gpu/drm/drm_fourcc.c                        | 253 +------------
 drivers/gpu/drm/selftests/Makefile                  |   3 +-
 drivers/gpu/drm/selftests/drm_modeset_selftests.h   |   3 +-
 drivers/gpu/drm/selftests/test-drm_format.c         | 280 +-------------
 drivers/gpu/drm/selftests/test-drm_modeset_common.h |   3 +-
 include/drm/drm_fourcc.h                            | 216 +----------
 7 files changed, 2 insertions(+), 757 deletions(-)
 delete mode 100644 drivers/gpu/drm/selftests/test-drm_format.c

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 7992a95ea965..cfc50fc92497 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -54,6 +54,7 @@ config DRM_DEBUG_SELFTEST
 	tristate "kselftests for DRM"
 	depends on DRM
 	depends on DEBUG_KERNEL
+	select IMAGE_FORMATS_SELFTESTS
 	select PRIME_NUMBERS
 	select DRM_LIB_RANDOM
 	select DRM_KMS_HELPER
diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
index 6ddb1c28be49..4f262e1a202a 100644
--- a/drivers/gpu/drm/drm_fourcc.c
+++ b/drivers/gpu/drm/drm_fourcc.c
@@ -150,136 +150,6 @@ const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf
 }
 EXPORT_SYMBOL(drm_get_format_name);
 
-/*
- * Internal function to query information for a given format. See
- * drm_format_info() for the public API.
- */
-const struct drm_format_info *__drm_format_info(u32 format)
-{
-	static const struct drm_format_info formats[] = {
-		{ .format = DRM_FORMAT_C8,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGB332,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGR233,		.depth = 8,  .num_planes = 1, .cpp = { 1, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XRGB4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XBGR4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGBX4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGRX4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_ARGB4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_ABGR4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGBA4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGRA4444,	.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_XRGB1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XBGR1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGBX5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGRX5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_ARGB1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_ABGR1555,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGBA5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGRA5551,	.depth = 15, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGB565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGR565,		.depth = 16, .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGB888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGR888,		.depth = 24, .num_planes = 1, .cpp = { 3, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XRGB8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XBGR8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGBX8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGRX8888,	.depth = 24, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGB565_A8,	.depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGR565_A8,	.depth = 24, .num_planes = 2, .cpp = { 2, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_XRGB2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_XBGR2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_RGBX1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_BGRX1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1 },
-		{ .format = DRM_FORMAT_ARGB2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_ABGR2101010,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGBA1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGRA1010102,	.depth = 30, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_ARGB8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_ABGR8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGBA8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGRA8888,	.depth = 32, .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGB888_A8,	.depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGR888_A8,	.depth = 32, .num_planes = 2, .cpp = { 3, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_XRGB8888_A8,	.depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_XBGR8888_A8,	.depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_RGBX8888_A8,	.depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_BGRX8888_A8,	.depth = 32, .num_planes = 2, .cpp = { 4, 1, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true },
-		{ .format = DRM_FORMAT_YUV410,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVU410,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 4, .is_yuv = true },
-		{ .format = DRM_FORMAT_YUV411,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVU411,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 4, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YUV420,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVU420,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_YUV422,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVU422,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YUV444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVU444,		.depth = 0,  .num_planes = 3, .cpp = { 1, 1, 1 }, .hsub = 1, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV12,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV21,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV16,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV61,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV24,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_NV42,		.depth = 0,  .num_planes = 2, .cpp = { 1, 2, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YUYV,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_YVYU,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_UYVY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_VYUY,		.depth = 0,  .num_planes = 1, .cpp = { 2, 0, 0 }, .hsub = 2, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_XYUV8888,	.depth = 0,  .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .is_yuv = true },
-		{ .format = DRM_FORMAT_AYUV,		.depth = 0,  .num_planes = 1, .cpp = { 4, 0, 0 }, .hsub = 1, .vsub = 1, .has_alpha = true, .is_yuv = true },
-		{ .format = DRM_FORMAT_Y0L0,		.depth = 0,  .num_planes = 1,
-		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },
-		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
-		{ .format = DRM_FORMAT_X0L0,		.depth = 0,  .num_planes = 1,
-		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },
-		  .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_Y0L2,		.depth = 0,  .num_planes = 1,
-		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },
-		  .hsub = 2, .vsub = 2, .has_alpha = true, .is_yuv = true },
-		{ .format = DRM_FORMAT_X0L2,		.depth = 0,  .num_planes = 1,
-		  .char_per_block = { 8, 0, 0 }, .block_w = { 2, 0, 0 }, .block_h = { 2, 0, 0 },
-		  .hsub = 2, .vsub = 2, .is_yuv = true },
-		{ .format = DRM_FORMAT_P010,            .depth = 0,  .num_planes = 2,
-		  .char_per_block = { 2, 4, 0 }, .block_w = { 1, 0, 0 }, .block_h = { 1, 0, 0 },
-		  .hsub = 2, .vsub = 2, .is_yuv = true},
-		{ .format = DRM_FORMAT_P012,		.depth = 0,  .num_planes = 2,
-		  .char_per_block = { 2, 4, 0 }, .block_w = { 1, 0, 0 }, .block_h = { 1, 0, 0 },
-		   .hsub = 2, .vsub = 2, .is_yuv = true},
-		{ .format = DRM_FORMAT_P016,		.depth = 0,  .num_planes = 2,
-		  .char_per_block = { 2, 4, 0 }, .block_w = { 1, 0, 0 }, .block_h = { 1, 0, 0 },
-		  .hsub = 2, .vsub = 2, .is_yuv = true},
-	};
-
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
-		if (formats[i].format == format)
-			return &formats[i];
-	}
-
-	return NULL;
-}
-
-/**
- * drm_format_info - query information for a given format
- * @format: pixel format (DRM_FORMAT_*)
- *
- * The caller should only pass a supported pixel format to this function.
- * Unsupported pixel formats will generate a warning in the kernel log.
- *
- * Returns:
- * The instance of struct drm_format_info that describes the pixel format, or
- * NULL if the format is unsupported.
- */
-const struct drm_format_info *drm_format_info(u32 format)
-{
-	const struct drm_format_info *info;
-
-	info = __drm_format_info(format);
-	WARN_ON(!info);
-	return info;
-}
-EXPORT_SYMBOL(drm_format_info);
-
 /**
  * drm_get_format_info - query information for a given framebuffer configuration
  * @dev: DRM device
@@ -304,126 +174,3 @@ drm_get_format_info(struct drm_device *dev,
 	return info;
 }
 EXPORT_SYMBOL(drm_get_format_info);
-
-/**
- * drm_format_plane_cpp - determine the bytes per pixel value
- * @format: pixel format info
- * @plane: plane index
- *
- * Returns:
- * The bytes per pixel value for the specified plane.
- */
-int drm_format_plane_cpp(const struct drm_format_info *info, int plane)
-{
-	if (!info || plane >= info->num_planes)
-		return 0;
-
-	return info->cpp[plane];
-}
-EXPORT_SYMBOL(drm_format_plane_cpp);
-
-/**
- * drm_format_plane_width - width of the plane given the first plane
- * @width: width of the first plane
- * @format: pixel format info
- * @plane: plane index
- *
- * Returns:
- * The width of @plane, given that the width of the first plane is @width.
- */
-int drm_format_plane_width(int width, const struct drm_format_info *info,
-			   int plane)
-{
-	if (!info || plane >= info->num_planes)
-		return 0;
-
-	if (plane == 0)
-		return width;
-
-	return width / info->hsub;
-}
-EXPORT_SYMBOL(drm_format_plane_width);
-
-/**
- * drm_format_plane_height - height of the plane given the first plane
- * @height: height of the first plane
- * @format: pixel format info
- * @plane: plane index
- *
- * Returns:
- * The height of @plane, given that the height of the first plane is @height.
- */
-int drm_format_plane_height(int height, const struct drm_format_info *info,
-			    int plane)
-{
-	if (!info || plane >= info->num_planes)
-		return 0;
-
-	if (plane == 0)
-		return height;
-
-	return height / info->vsub;
-}
-EXPORT_SYMBOL(drm_format_plane_height);
-
-/**
- * drm_format_info_block_width - width in pixels of block.
- * @info: pixel format info
- * @plane: plane index
- *
- * Returns:
- * The width in pixels of a block, depending on the plane index.
- */
-unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-					 int plane)
-{
-	if (!info || plane < 0 || plane >= info->num_planes)
-		return 0;
-
-	if (!info->block_w[plane])
-		return 1;
-	return info->block_w[plane];
-}
-EXPORT_SYMBOL(drm_format_info_block_width);
-
-/**
- * drm_format_info_block_height - height in pixels of a block
- * @info: pixel format info
- * @plane: plane index
- *
- * Returns:
- * The height in pixels of a block, depending on the plane index.
- */
-unsigned int drm_format_info_block_height(const struct drm_format_info *info,
-					  int plane)
-{
-	if (!info || plane < 0 || plane >= info->num_planes)
-		return 0;
-
-	if (!info->block_h[plane])
-		return 1;
-	return info->block_h[plane];
-}
-EXPORT_SYMBOL(drm_format_info_block_height);
-
-/**
- * drm_format_info_min_pitch - computes the minimum required pitch in bytes
- * @info: pixel format info
- * @plane: plane index
- * @buffer_width: buffer width in pixels
- *
- * Returns:
- * The minimum required pitch in bytes for a buffer by taking into consideration
- * the pixel format information and the buffer width.
- */
-uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
-				   int plane, unsigned int buffer_width)
-{
-	if (!info || plane < 0 || plane >= info->num_planes)
-		return 0;
-
-	return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],
-			    drm_format_info_block_width(info, plane) *
-			    drm_format_info_block_height(info, plane));
-}
-EXPORT_SYMBOL(drm_format_info_min_pitch);
diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile
index 1bb73dc4c88c..e32921691662 100644
--- a/drivers/gpu/drm/selftests/Makefile
+++ b/drivers/gpu/drm/selftests/Makefile
@@ -1,5 +1,4 @@
 test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \
-                      test-drm_format.o test-drm_framebuffer.o \
-		      test-drm_damage_helper.o
+                      test-drm_framebuffer.o test-drm_damage_helper.o
 
 obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o
diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
index 464753746013..4a2ef84c2762 100644
--- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h
+++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h
@@ -7,9 +7,6 @@
  * Tests are executed in order by igt/drm_selftests_helper
  */
 selftest(check_plane_state, igt_check_plane_state)
-selftest(check_drm_format_block_width, igt_check_drm_format_block_width)
-selftest(check_drm_format_block_height, igt_check_drm_format_block_height)
-selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch)
 selftest(check_drm_framebuffer_create, igt_check_drm_framebuffer_create)
 selftest(damage_iter_no_damage, igt_damage_iter_no_damage)
 selftest(damage_iter_no_damage_fractional_src, igt_damage_iter_no_damage_fractional_src)
diff --git a/drivers/gpu/drm/selftests/test-drm_format.c b/drivers/gpu/drm/selftests/test-drm_format.c
deleted file mode 100644
index c5e212afa27a..000000000000
--- a/drivers/gpu/drm/selftests/test-drm_format.c
+++ /dev/null
@@ -1,280 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Test cases for the drm_format functions
- */
-
-#define pr_fmt(fmt) "drm_format: " fmt
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-
-#include <drm/drm_fourcc.h>
-
-#include "test-drm_modeset_common.h"
-
-int igt_check_drm_format_block_width(void *ignored)
-{
-	const struct drm_format_info *info = NULL;
-
-	/* Test invalid arguments */
-	FAIL_ON(drm_format_info_block_width(info, 0) != 0);
-	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
-	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
-
-	/* Test 1 plane format */
-	info = drm_format_info(DRM_FORMAT_XRGB4444);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
-	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
-
-	/* Test 2 planes format */
-	info = drm_format_info(DRM_FORMAT_NV12);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 2) != 0);
-	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
-
-	/* Test 3 planes format */
-	info = drm_format_info(DRM_FORMAT_YUV422);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_width(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 1) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 2) != 1);
-	FAIL_ON(drm_format_info_block_width(info, 3) != 0);
-	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
-
-	/* Test a tiled format */
-	info = drm_format_info(DRM_FORMAT_X0L0);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_width(info, 0) != 2);
-	FAIL_ON(drm_format_info_block_width(info, 1) != 0);
-	FAIL_ON(drm_format_info_block_width(info, -1) != 0);
-
-	return 0;
-}
-
-int igt_check_drm_format_block_height(void *ignored)
-{
-	const struct drm_format_info *info = NULL;
-
-	/* Test invalid arguments */
-	FAIL_ON(drm_format_info_block_height(info, 0) != 0);
-	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
-	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
-
-	/* Test 1 plane format */
-	info = drm_format_info(DRM_FORMAT_XRGB4444);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
-	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
-
-	/* Test 2 planes format */
-	info = drm_format_info(DRM_FORMAT_NV12);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 2) != 0);
-	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
-
-	/* Test 3 planes format */
-	info = drm_format_info(DRM_FORMAT_YUV422);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_height(info, 0) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 1) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 2) != 1);
-	FAIL_ON(drm_format_info_block_height(info, 3) != 0);
-	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
-
-	/* Test a tiled format */
-	info = drm_format_info(DRM_FORMAT_X0L0);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_block_height(info, 0) != 2);
-	FAIL_ON(drm_format_info_block_height(info, 1) != 0);
-	FAIL_ON(drm_format_info_block_height(info, -1) != 0);
-
-	return 0;
-}
-
-int igt_check_drm_format_min_pitch(void *ignored)
-{
-	const struct drm_format_info *info = NULL;
-
-	/* Test invalid arguments */
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	/* Test 1 plane 8 bits per pixel format */
-	info = drm_format_info(DRM_FORMAT_RGB332);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
-			(uint64_t)(UINT_MAX - 1));
-
-	/* Test 1 plane 16 bits per pixel format */
-	info = drm_format_info(DRM_FORMAT_XRGB4444);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX * 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
-			(uint64_t)(UINT_MAX - 1) * 2);
-
-	/* Test 1 plane 24 bits per pixel format */
-	info = drm_format_info(DRM_FORMAT_RGB888);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 3);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 6);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1920);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 3072);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 5760);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 12288);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2013);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX * 3);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
-			(uint64_t)(UINT_MAX - 1) * 3);
-
-	/* Test 1 plane 32 bits per pixel format */
-	info = drm_format_info(DRM_FORMAT_ABGR8888);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 4);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 8);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 2560);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 4096);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 7680);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 16384);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 2684);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX * 4);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
-			(uint64_t)(UINT_MAX - 1) * 4);
-
-	/* Test 2 planes format */
-	info = drm_format_info(DRM_FORMAT_NV12);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 640);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 1024);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 1920);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 4096);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 672);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
-			(uint64_t)UINT_MAX + 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1)) !=
-			(uint64_t)(UINT_MAX - 1));
-	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) /  2) !=
-			(uint64_t)(UINT_MAX - 1));
-
-	/* Test 3 planes 8 bits per pixel format */
-	info = drm_format_info(DRM_FORMAT_YUV422);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 3, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 1) != 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 1) != 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 2) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 2) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 640);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 320) != 320);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 320) != 320);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 1024);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 512) != 512);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 512) != 512);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 1920);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 960) != 960);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 960) != 960);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 4096);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 2048) != 2048);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 2048) != 2048);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 671);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 336) != 336);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, 336) != 336);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, UINT_MAX / 2 + 1) !=
-			(uint64_t)UINT_MAX / 2 + 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, UINT_MAX / 2 + 1) !=
-			(uint64_t)UINT_MAX / 2 + 1);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, (UINT_MAX - 1) / 2) !=
-			(uint64_t)(UINT_MAX - 1) / 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, (UINT_MAX - 1) / 2) !=
-			(uint64_t)(UINT_MAX - 1) / 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 2, (UINT_MAX - 1) / 2) !=
-			(uint64_t)(UINT_MAX - 1) / 2);
-
-	/* Test tiled format */
-	info = drm_format_info(DRM_FORMAT_X0L2);
-	FAIL_ON(!info);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, -1, 0) != 0);
-	FAIL_ON(drm_format_info_min_pitch(info, 1, 0) != 0);
-
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1) != 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 2) != 4);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 640) != 1280);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1024) != 2048);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 1920) != 3840);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 4096) != 8192);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, 671) != 1342);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX) !=
-			(uint64_t)UINT_MAX * 2);
-	FAIL_ON(drm_format_info_min_pitch(info, 0, UINT_MAX - 1) !=
-			(uint64_t)(UINT_MAX - 1) * 2);
-
-	return 0;
-}
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
index 8c76f09c12d1..fb2b8fbd7566 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
@@ -14,9 +14,6 @@
 #define FAIL_ON(x) FAIL((x), "%s", "FAIL_ON(" __stringify(x) ")\n")
 
 int igt_check_plane_state(void *ignored);
-int igt_check_drm_format_block_width(void *ignored);
-int igt_check_drm_format_block_height(void *ignored);
-int igt_check_drm_format_min_pitch(void *ignored);
 int igt_check_drm_framebuffer_create(void *ignored);
 int igt_damage_iter_no_damage(void *ignored);
 int igt_damage_iter_no_damage_fractional_src(void *ignored);
diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
index 7cc7b99a6569..8ca45b2be9ca 100644
--- a/include/drm/drm_fourcc.h
+++ b/include/drm/drm_fourcc.h
@@ -52,91 +52,6 @@ struct drm_mode_fb_cmd2;
 struct image_format_info;
 
 /**
- * struct drm_format_info - information about a DRM format
- */
-struct drm_format_info {
-	/** @format: 4CC format identifier (DRM_FORMAT_*) */
-	u32 format;
-
-	/**
-	 * @depth:
-	 *
-	 * Color depth (number of bits per pixel excluding padding bits),
-	 * valid for a subset of RGB formats only. This is a legacy field, do
-	 * not use in new code and set to 0 for new formats.
-	 */
-	u8 depth;
-
-	/** @num_planes: Number of color planes (1 to 3) */
-	u8 num_planes;
-
-	union {
-		/**
-		 * @cpp:
-		 *
-		 * Number of bytes per pixel (per plane), this is aliased with
-		 * @char_per_block. It is deprecated in favour of using the
-		 * triplet @char_per_block, @block_w, @block_h for better
-		 * describing the pixel format.
-		 */
-		u8 cpp[3];
-
-		/**
-		 * @char_per_block:
-		 *
-		 * Number of bytes per block (per plane), where blocks are
-		 * defined as a rectangle of pixels which are stored next to
-		 * each other in a byte aligned memory region. Together with
-		 * @block_w and @block_h this is used to properly describe tiles
-		 * in tiled formats or to describe groups of pixels in packed
-		 * formats for which the memory needed for a single pixel is not
-		 * byte aligned.
-		 *
-		 * @cpp has been kept for historical reasons because there are
-		 * a lot of places in drivers where it's used. In drm core for
-		 * generic code paths the preferred way is to use
-		 * @char_per_block, drm_format_info_block_width() and
-		 * drm_format_info_block_height() which allows handling both
-		 * block and non-block formats in the same way.
-		 *
-		 * For formats that are intended to be used only with non-linear
-		 * modifiers both @cpp and @char_per_block must be 0 in the
-		 * generic format table. Drivers could supply accurate
-		 * information from their drm_mode_config.get_format_info hook
-		 * if they want the core to be validating the pitch.
-		 */
-		u8 char_per_block[3];
-	};
-
-	/**
-	 * @block_w:
-	 *
-	 * Block width in pixels, this is intended to be accessed through
-	 * drm_format_info_block_width()
-	 */
-	u8 block_w[3];
-
-	/**
-	 * @block_h:
-	 *
-	 * Block height in pixels, this is intended to be accessed through
-	 * drm_format_info_block_height()
-	 */
-	u8 block_h[3];
-
-	/** @hsub: Horizontal chroma subsampling factor */
-	u8 hsub;
-	/** @vsub: Vertical chroma subsampling factor */
-	u8 vsub;
-
-	/** @has_alpha: Does the format embeds an alpha component? */
-	bool has_alpha;
-
-	/** @is_yuv: Is it a YUV format? */
-	bool is_yuv;
-};
-
-/**
  * struct drm_format_name_buf - name of a DRM format
  * @str: string buffer containing the format name
  */
@@ -144,143 +59,12 @@ struct drm_format_name_buf {
 	char str[32];
 };
 
-/**
- * drm_format_info_is_yuv_packed - check that the format info matches a YUV
- * format with data laid in a single plane
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a packed YUV format.
- */
-static inline bool
-drm_format_info_is_yuv_packed(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->num_planes == 1;
-}
-
-/**
- * drm_format_info_is_yuv_semiplanar - check that the format info matches a YUV
- * format with data laid in two planes (luminance and chrominance)
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a semiplanar YUV format.
- */
-static inline bool
-drm_format_info_is_yuv_semiplanar(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->num_planes == 2;
-}
-
-/**
- * drm_format_info_is_yuv_planar - check that the format info matches a YUV
- * format with data laid in three planes (one for each YUV component)
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a planar YUV format.
- */
-static inline bool
-drm_format_info_is_yuv_planar(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->num_planes == 3;
-}
-
-/**
- * drm_format_info_is_yuv_sampling_410 - check that the format info matches a
- * YUV format with 4:1:0 sub-sampling
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a YUV format with 4:1:0
- * sub-sampling.
- */
-static inline bool
-drm_format_info_is_yuv_sampling_410(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->hsub == 4 && info->vsub == 4;
-}
-
-/**
- * drm_format_info_is_yuv_sampling_411 - check that the format info matches a
- * YUV format with 4:1:1 sub-sampling
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a YUV format with 4:1:1
- * sub-sampling.
- */
-static inline bool
-drm_format_info_is_yuv_sampling_411(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->hsub == 4 && info->vsub == 1;
-}
-
-/**
- * drm_format_info_is_yuv_sampling_420 - check that the format info matches a
- * YUV format with 4:2:0 sub-sampling
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a YUV format with 4:2:0
- * sub-sampling.
- */
-static inline bool
-drm_format_info_is_yuv_sampling_420(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->hsub == 2 && info->vsub == 2;
-}
-
-/**
- * drm_format_info_is_yuv_sampling_422 - check that the format info matches a
- * YUV format with 4:2:2 sub-sampling
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a YUV format with 4:2:2
- * sub-sampling.
- */
-static inline bool
-drm_format_info_is_yuv_sampling_422(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->hsub == 2 && info->vsub == 1;
-}
-
-/**
- * drm_format_info_is_yuv_sampling_444 - check that the format info matches a
- * YUV format with 4:4:4 sub-sampling
- * @info: format info
- *
- * Returns:
- * A boolean indicating whether the format info matches a YUV format with 4:4:4
- * sub-sampling.
- */
-static inline bool
-drm_format_info_is_yuv_sampling_444(const struct drm_format_info *info)
-{
-	return info->is_yuv && info->hsub == 1 && info->vsub == 1;
-}
-
-const struct drm_format_info *__drm_format_info(u32 format);
-const struct drm_format_info *drm_format_info(u32 format);
-
 const struct image_format_info *
 drm_get_format_info(struct drm_device *dev,
 		    const struct drm_mode_fb_cmd2 *mode_cmd);
 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
 				     uint32_t bpp, uint32_t depth);
-int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
-int drm_format_plane_width(int width, const struct drm_format_info *info,
-			   int plane);
-int drm_format_plane_height(int height, const struct drm_format_info *info,
-			    int plane);
-unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-					 int plane);
-unsigned int drm_format_info_block_height(const struct drm_format_info *info,
-					  int plane);
-uint64_t drm_format_info_min_pitch(const struct drm_format_info *info,
-				   int plane, unsigned int buffer_width);
 const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf *buf);
 
 #endif /* __DRM_FOURCC_H__ */
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (16 preceding siblings ...)
  2019-03-19 21:57 ` [RFC PATCH 17/20] drm/fourcc: Remove old DRM format API Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  2019-03-19 23:29   ` Nicolas Dufresne
                     ` (2 more replies)
  2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 20/20] media: sun6i: Convert to the image format API Maxime Ripard
  19 siblings, 3 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

V4L2 uses different fourcc's than DRM, and has a different set of formats.
For now, let's add the v4l2 fourcc's for the already existing formats.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 include/linux/image-formats.h |  9 +++++-
 lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 76 insertions(+)

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
index 53fd73a71b3d..fbc3a4501ebd 100644
--- a/include/linux/image-formats.h
+++ b/include/linux/image-formats.h
@@ -26,6 +26,13 @@ struct image_format_info {
 	};
 
 	/**
+	 * @v4l2_fmt:
+	 *
+	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
+	 */
+	u32 v4l2_fmt;
+
+	/**
 	 * @depth:
 	 *
 	 * Color depth (number of bits per pixel excluding padding bits),
@@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
 
 const struct image_format_info *__image_format_drm_lookup(u32 drm);
 const struct image_format_info *image_format_drm_lookup(u32 drm);
+const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
+const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
 unsigned int image_format_plane_cpp(const struct image_format_info *format,
 				    int plane);
 unsigned int image_format_plane_width(int width,
diff --git a/lib/image-formats.c b/lib/image-formats.c
index 9b9a73220c5d..39f1d38ae861 100644
--- a/lib/image-formats.c
+++ b/lib/image-formats.c
@@ -8,6 +8,7 @@
 static const struct image_format_info formats[] = {
 	{
 		.drm_fmt = DRM_FORMAT_C8,
+		.v4l2_fmt = V4L2_PIX_FMT_GREY,
 		.depth = 8,
 		.num_planes = 1,
 		.cpp = { 1, 0, 0 },
@@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_RGB332,
+		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
 		.depth = 8,
 		.num_planes = 1,
 		.cpp = { 1, 0, 0 },
@@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_XRGB4444,
+		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_ARGB4444,
+		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
 		.has_alpha = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_XRGB1555,
+		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
 		.depth = 15,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_ARGB1555,
+		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
 		.depth = 15,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
 		.has_alpha = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_RGB565,
+		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
 		.depth = 16,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_RGB888,
+		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
 		.depth = 24,
 		.num_planes = 1,
 		.cpp = { 3, 0, 0 },
@@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_BGR888,
+		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
 		.depth = 24,
 		.num_planes = 1,
 		.cpp = { 3, 0, 0 },
@@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
 		.vsub = 1,
 	}, {
 		.drm_fmt = DRM_FORMAT_XRGB8888,
+		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
 		.depth = 24,
 		.num_planes = 1,
 		.cpp = { 4, 0, 0 },
@@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
 		.has_alpha = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_ARGB8888,
+		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
 		.depth = 32,
 		.num_planes = 1,
 		.cpp = { 4, 0, 0 },
@@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
 		.has_alpha = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YUV410,
+		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YVU410,
+		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YUV420,
+		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YVU420,
+		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YUV422,
+		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YVU422,
+		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YUV444,
+		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YVU444,
+		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
 		.depth = 0,
 		.num_planes = 3,
 		.cpp = { 1, 1, 1 },
@@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV12,
+		.v4l2_fmt = V4L2_PIX_FMT_NV12,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV21,
+		.v4l2_fmt = V4L2_PIX_FMT_NV21,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV16,
+		.v4l2_fmt = V4L2_PIX_FMT_NV16,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV61,
+		.v4l2_fmt = V4L2_PIX_FMT_NV61,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV24,
+		.v4l2_fmt = V4L2_PIX_FMT_NV24,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_NV42,
+		.v4l2_fmt = V4L2_PIX_FMT_NV42,
 		.depth = 0,
 		.num_planes = 2,
 		.cpp = { 1, 2, 0 },
@@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YUYV,
+		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_YVYU,
+		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_UYVY,
+		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
 		.is_yuv = true,
 	}, {
 		.drm_fmt = DRM_FORMAT_VYUY,
+		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
 		.depth = 0,
 		.num_planes = 1,
 		.cpp = { 2, 0, 0 },
@@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
 EXPORT_SYMBOL(image_format_drm_lookup);
 
 /**
+ * __image_format_v4l2_lookup - query information for a given format
+ * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
+{
+	return __image_format_lookup(v4l2_fmt, v4l2);
+}
+EXPORT_SYMBOL(__image_format_v4l2_lookup);
+
+/**
+ * image_format_v4l2_lookup - query information for a given format
+ * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
+ *
+ * The caller should only pass a supported pixel format to this function.
+ * Unsupported pixel formats will generate a warning in the kernel log.
+ *
+ * Returns:
+ * The instance of struct image_format_info that describes the pixel format, or
+ * NULL if the format is unsupported.
+ */
+const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
+{
+	const struct image_format_info *format;
+
+	format = __image_format_v4l2_lookup(v4l2);
+
+	WARN_ON(!format);
+	return format;
+}
+EXPORT_SYMBOL(image_format_v4l2_lookup);
+
+/**
  * image_format_plane_cpp - determine the bytes per pixel value
  * @format: pointer to the image_format
  * @plane: plane index
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 19/20] lib: image-formats: Add more functions
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
@ 2019-03-19 21:57   ` Maxime Ripard
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
                     ` (18 subsequent siblings)
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

V4L2 drivers typically need a few more helpers compared to DRM drivers, so
let's add them.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 include/linux/image-formats.h |  4 +++-
 lib/image-formats.c           | 42 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+)

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
index fbc3a4501ebd..f1d4a2a03cc0 100644
--- a/include/linux/image-formats.h
+++ b/include/linux/image-formats.h
@@ -236,9 +236,13 @@ unsigned int image_format_plane_cpp(const struct image_format_info *format,
 unsigned int image_format_plane_width(int width,
 				      const struct image_format_info *format,
 				      int plane);
+unsigned int image_format_plane_stride(const struct image_format_info *format,
+				       int width, int plane);
 unsigned int image_format_plane_height(int height,
 				       const struct image_format_info *format,
 				       int plane);
+unsigned int image_format_plane_size(const struct image_format_info *format,
+				     int width, int height, int plane);
 unsigned int image_format_block_width(const struct image_format_info *format,
 				      int plane);
 unsigned int image_format_block_height(const struct image_format_info *format,
diff --git a/lib/image-formats.c b/lib/image-formats.c
index 39f1d38ae861..c4e213a89edb 100644
--- a/lib/image-formats.c
+++ b/lib/image-formats.c
@@ -740,6 +740,26 @@ unsigned int image_format_plane_width(int width,
 EXPORT_SYMBOL(image_format_plane_width);
 
 /**
+ * image_format_plane_stride - determine the stride value
+ * @format: pointer to the image_format
+ * @width: plane width
+ * @plane: plane index
+ *
+ * Returns:
+ * The bytes per pixel value for the specified plane.
+ */
+unsigned int image_format_plane_stride(const struct image_format_info *format,
+				       unsigned int width, int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return image_format_plane_width(width, format, plane) *
+		image_format_plane_cpp(format, plane);
+}
+EXPORT_SYMBOL(image_format_plane_stride);
+
+/**
  * image_format_plane_height - height of the plane given the first plane
  * @format: pointer to the image_format
  * @height: height of the first plane
@@ -763,6 +783,28 @@ unsigned int image_format_plane_height(int height,
 EXPORT_SYMBOL(image_format_plane_height);
 
 /**
+ * image_format_plane_size - determine the size value
+ * @format: pointer to the image_format
+ * @width: plane width
+ * @height: plane width
+ * @plane: plane index
+ *
+ * Returns:
+ * The size of the plane buffer.
+ */
+unsigned int image_format_plane_size(const struct image_format_info *format,
+				     unsigned int width, unsigned int height,
+				     int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return image_format_plane_stride(format, width, plane) *
+		image_format_plane_height(format, height, plane);
+}
+EXPORT_SYMBOL(image_format_plane_size);
+
+/**
  * image_format_block_width - width in pixels of block.
  * @format: pointer to the image_format
  * @plane: plane index
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 19/20] lib: image-formats: Add more functions
@ 2019-03-19 21:57   ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

V4L2 drivers typically need a few more helpers compared to DRM drivers, so
let's add them.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 include/linux/image-formats.h |  4 +++-
 lib/image-formats.c           | 42 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 46 insertions(+)

diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
index fbc3a4501ebd..f1d4a2a03cc0 100644
--- a/include/linux/image-formats.h
+++ b/include/linux/image-formats.h
@@ -236,9 +236,13 @@ unsigned int image_format_plane_cpp(const struct image_format_info *format,
 unsigned int image_format_plane_width(int width,
 				      const struct image_format_info *format,
 				      int plane);
+unsigned int image_format_plane_stride(const struct image_format_info *format,
+				       int width, int plane);
 unsigned int image_format_plane_height(int height,
 				       const struct image_format_info *format,
 				       int plane);
+unsigned int image_format_plane_size(const struct image_format_info *format,
+				     int width, int height, int plane);
 unsigned int image_format_block_width(const struct image_format_info *format,
 				      int plane);
 unsigned int image_format_block_height(const struct image_format_info *format,
diff --git a/lib/image-formats.c b/lib/image-formats.c
index 39f1d38ae861..c4e213a89edb 100644
--- a/lib/image-formats.c
+++ b/lib/image-formats.c
@@ -740,6 +740,26 @@ unsigned int image_format_plane_width(int width,
 EXPORT_SYMBOL(image_format_plane_width);
 
 /**
+ * image_format_plane_stride - determine the stride value
+ * @format: pointer to the image_format
+ * @width: plane width
+ * @plane: plane index
+ *
+ * Returns:
+ * The bytes per pixel value for the specified plane.
+ */
+unsigned int image_format_plane_stride(const struct image_format_info *format,
+				       unsigned int width, int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return image_format_plane_width(width, format, plane) *
+		image_format_plane_cpp(format, plane);
+}
+EXPORT_SYMBOL(image_format_plane_stride);
+
+/**
  * image_format_plane_height - height of the plane given the first plane
  * @format: pointer to the image_format
  * @height: height of the first plane
@@ -763,6 +783,28 @@ unsigned int image_format_plane_height(int height,
 EXPORT_SYMBOL(image_format_plane_height);
 
 /**
+ * image_format_plane_size - determine the size value
+ * @format: pointer to the image_format
+ * @width: plane width
+ * @height: plane width
+ * @plane: plane index
+ *
+ * Returns:
+ * The size of the plane buffer.
+ */
+unsigned int image_format_plane_size(const struct image_format_info *format,
+				     unsigned int width, unsigned int height,
+				     int plane)
+{
+	if (!format || plane >= format->num_planes)
+		return 0;
+
+	return image_format_plane_stride(format, width, plane) *
+		image_format_plane_height(format, height, plane);
+}
+EXPORT_SYMBOL(image_format_plane_size);
+
+/**
  * image_format_block_width - width in pixels of block.
  * @format: pointer to the image_format
  * @plane: plane index
-- 
git-series 0.9.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [RFC PATCH 20/20] media: sun6i: Convert to the image format API
  2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
                   ` (18 preceding siblings ...)
  2019-03-19 21:57   ` Maxime Ripard
@ 2019-03-19 21:57 ` Maxime Ripard
  19 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-19 21:57 UTC (permalink / raw)
  To: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Maxime Ripard, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

The image format API allows us to remove some of the computation we need to
handle the various video formats.

Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c | 88 +++------------
 drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h | 46 +--------
 2 files changed, 22 insertions(+), 112 deletions(-)

diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
index 6950585edb5a..d4693efb9e02 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c
@@ -466,72 +466,27 @@ static void sun6i_csi_set_format(struct sun6i_csi_dev *sdev)
 static void sun6i_csi_set_window(struct sun6i_csi_dev *sdev)
 {
 	struct sun6i_csi_config *config = &sdev->csi.config;
-	u32 bytesperline_y;
-	u32 bytesperline_c;
+	const struct image_format_info *info =
+		image_format_v4l2_lookup(config->pixelformat);
 	int *planar_offset = sdev->planar_offset;
-	u32 width = config->width;
-	u32 height = config->height;
-	u32 hor_len = width;
+	u32 bytesperline_y = image_format_plane_stride(info, config->width, 0);
+	u32 bytesperline_c = image_format_plane_stride(info, config->width, 1);
+	unsigned int i;
 
-	switch (config->pixelformat) {
-	case V4L2_PIX_FMT_YUYV:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_VYUY:
-		dev_dbg(sdev->dev,
-			"Horizontal length should be 2 times of width for packed YUV formats!\n");
-		hor_len = width * 2;
-		break;
-	default:
-		break;
+	offset = 0;
+	for (i = 0; i < info->num_planes; i++) {
+		planar_offset[i] = offset;
+
+		offset += info_format_plane_size(info, config->width,
+						 config->height, i);
 	}
 
 	regmap_write(sdev->regmap, CSI_CH_HSIZE_REG,
-		     CSI_CH_HSIZE_HOR_LEN(hor_len) |
+		     CSI_CH_HSIZE_HOR_LEN(bytesperline_c) |
 		     CSI_CH_HSIZE_HOR_START(0));
 	regmap_write(sdev->regmap, CSI_CH_VSIZE_REG,
-		     CSI_CH_VSIZE_VER_LEN(height) |
+		     CSI_CH_VSIZE_VER_LEN(config->height) |
 		     CSI_CH_VSIZE_VER_START(0));
-
-	planar_offset[0] = 0;
-	switch (config->pixelformat) {
-	case V4L2_PIX_FMT_HM12:
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-		bytesperline_y = width;
-		bytesperline_c = width;
-		planar_offset[1] = bytesperline_y * height;
-		planar_offset[2] = -1;
-		break;
-	case V4L2_PIX_FMT_YUV420:
-	case V4L2_PIX_FMT_YVU420:
-		bytesperline_y = width;
-		bytesperline_c = width / 2;
-		planar_offset[1] = bytesperline_y * height;
-		planar_offset[2] = planar_offset[1] +
-				bytesperline_c * height / 2;
-		break;
-	case V4L2_PIX_FMT_YUV422P:
-		bytesperline_y = width;
-		bytesperline_c = width / 2;
-		planar_offset[1] = bytesperline_y * height;
-		planar_offset[2] = planar_offset[1] +
-				bytesperline_c * height;
-		break;
-	default: /* raw */
-		dev_dbg(sdev->dev,
-			"Calculating pixelformat(0x%x)'s bytesperline as a packed format\n",
-			config->pixelformat);
-		bytesperline_y = (sun6i_csi_get_bpp(config->pixelformat) *
-				  config->width) / 8;
-		bytesperline_c = 0;
-		planar_offset[1] = -1;
-		planar_offset[2] = -1;
-		break;
-	}
-
 	regmap_write(sdev->regmap, CSI_CH_BUF_LEN_REG,
 		     CSI_CH_BUF_LEN_BUF_LEN_C(bytesperline_c) |
 		     CSI_CH_BUF_LEN_BUF_LEN_Y(bytesperline_y));
@@ -557,15 +512,16 @@ int sun6i_csi_update_config(struct sun6i_csi *csi,
 void sun6i_csi_update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr)
 {
 	struct sun6i_csi_dev *sdev = sun6i_csi_to_dev(csi);
+	struct sun6i_csi_config *config = &sdev->csi.config;
+	const struct image_format_info *info =
+		image_format_v4l2_lookup(config->pixelformat);
+	unsigned int i;
+
+	for (i = 0; i < info->num_planes; i++) {
+		regmap_write(sdev->regmap, CSI_CH_BUF_REG(i, 0),
+			     (addr + sdev->planar_offset[i]) >> 2);
 
-	regmap_write(sdev->regmap, CSI_CH_F0_BUFA_REG,
-		     (addr + sdev->planar_offset[0]) >> 2);
-	if (sdev->planar_offset[1] != -1)
-		regmap_write(sdev->regmap, CSI_CH_F1_BUFA_REG,
-			     (addr + sdev->planar_offset[1]) >> 2);
-	if (sdev->planar_offset[2] != -1)
-		regmap_write(sdev->regmap, CSI_CH_F2_BUFA_REG,
-			     (addr + sdev->planar_offset[2]) >> 2);
+	}
 }
 
 void sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
index 0bb000712c33..3c57ec89b108 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.h
@@ -86,50 +86,4 @@ void sun6i_csi_update_buf_addr(struct sun6i_csi *csi, dma_addr_t addr);
  */
 void sun6i_csi_set_stream(struct sun6i_csi *csi, bool enable);
 
-/* get bpp form v4l2 pixformat */
-static inline int sun6i_csi_get_bpp(unsigned int pixformat)
-{
-	switch (pixformat) {
-	case V4L2_PIX_FMT_SBGGR8:
-	case V4L2_PIX_FMT_SGBRG8:
-	case V4L2_PIX_FMT_SGRBG8:
-	case V4L2_PIX_FMT_SRGGB8:
-		return 8;
-	case V4L2_PIX_FMT_SBGGR10:
-	case V4L2_PIX_FMT_SGBRG10:
-	case V4L2_PIX_FMT_SGRBG10:
-	case V4L2_PIX_FMT_SRGGB10:
-		return 10;
-	case V4L2_PIX_FMT_SBGGR12:
-	case V4L2_PIX_FMT_SGBRG12:
-	case V4L2_PIX_FMT_SGRBG12:
-	case V4L2_PIX_FMT_SRGGB12:
-	case V4L2_PIX_FMT_HM12:
-	case V4L2_PIX_FMT_NV12:
-	case V4L2_PIX_FMT_NV21:
-	case V4L2_PIX_FMT_YUV420:
-	case V4L2_PIX_FMT_YVU420:
-		return 12;
-	case V4L2_PIX_FMT_YUYV:
-	case V4L2_PIX_FMT_YVYU:
-	case V4L2_PIX_FMT_UYVY:
-	case V4L2_PIX_FMT_VYUY:
-	case V4L2_PIX_FMT_NV16:
-	case V4L2_PIX_FMT_NV61:
-	case V4L2_PIX_FMT_YUV422P:
-		return 16;
-	case V4L2_PIX_FMT_RGB24:
-	case V4L2_PIX_FMT_BGR24:
-		return 24;
-	case V4L2_PIX_FMT_RGB32:
-	case V4L2_PIX_FMT_BGR32:
-		return 32;
-	default:
-		WARN(1, "Unsupported pixformat: 0x%x\n", pixformat);
-		break;
-	}
-
-	return 0;
-}
-
 #endif /* __SUN6I_CSI_H__ */
-- 
git-series 0.9.1

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 21:57 ` [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support Maxime Ripard
@ 2019-03-19 23:29   ` Nicolas Dufresne
  2019-03-20 14:27     ` Ville Syrjälä
  2019-03-20 18:15     ` Brian Starkey
  2019-03-22 19:55   ` Nicolas Dufresne
  2019-04-11  7:12   ` Hans Verkuil
  2 siblings, 2 replies; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-19 23:29 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> V4L2 uses different fourcc's than DRM, and has a different set of formats.
> For now, let's add the v4l2 fourcc's for the already existing formats.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  include/linux/image-formats.h |  9 +++++-
>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+)
> 
> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> index 53fd73a71b3d..fbc3a4501ebd 100644
> --- a/include/linux/image-formats.h
> +++ b/include/linux/image-formats.h
> @@ -26,6 +26,13 @@ struct image_format_info {
>  	};
>  
>  	/**
> +	 * @v4l2_fmt:
> +	 *
> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> +	 */
> +	u32 v4l2_fmt;
> +
> +	/**
>  	 * @depth:
>  	 *
>  	 * Color depth (number of bits per pixel excluding padding bits),
> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>  
>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>  const struct image_format_info *image_format_drm_lookup(u32 drm);
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>  				    int plane);
>  unsigned int image_format_plane_width(int width,
> diff --git a/lib/image-formats.c b/lib/image-formats.c
> index 9b9a73220c5d..39f1d38ae861 100644
> --- a/lib/image-formats.c
> +++ b/lib/image-formats.c
> @@ -8,6 +8,7 @@
>  static const struct image_format_info formats[] = {
>  	{
>  		.drm_fmt = DRM_FORMAT_C8,
> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB332,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB565,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
>  		.depth = 16,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB888,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_BGR888,
> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,


All RGB mapping should be surrounded by ifdef, because many (not all)
DRM formats represent the order of component when placed in a CPU
register, unlike V4L2 which uses memory order. I've pick this one
randomly, but this one on most system, little endian, will match
V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
multiple places, notably in GStreamer:

https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45

>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
>  		.depth = 32,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV12,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV21,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV16,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV61,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV24,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV42,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUYV,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVYU,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_UYVY,
> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_VYUY,
> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>  EXPORT_SYMBOL(image_format_drm_lookup);
>  
>  /**
> + * __image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> +{
> +	return __image_format_lookup(v4l2_fmt, v4l2);
> +}
> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> +
> +/**
> + * image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> +{
> +	const struct image_format_info *format;
> +
> +	format = __image_format_v4l2_lookup(v4l2);
> +
> +	WARN_ON(!format);
> +	return format;
> +}
> +EXPORT_SYMBOL(image_format_v4l2_lookup);
> +
> +/**
>   * image_format_plane_cpp - determine the bytes per pixel value
>   * @format: pointer to the image_format
>   * @plane: plane index


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/20] lib: Add video format information library
  2019-03-19 21:57   ` Maxime Ripard
  (?)
@ 2019-03-20 13:39   ` Boris Brezillon
  2019-03-21  8:20       ` Maxime Ripard
  -1 siblings, 1 reply; 69+ messages in thread
From: Boris Brezillon @ 2019-03-20 13:39 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, linux-kernel, dri-devel,
	Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media

On Tue, 19 Mar 2019 22:57:11 +0100
Maxime Ripard <maxime.ripard@bootlin.com> wrote:

> Move the DRM formats API to turn this into a more generic image formats API
> to be able to leverage it into some other places of the kernel, such as
> v4l2 drivers.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  include/linux/image-formats.h | 240 +++++++++++-
>  lib/Kconfig                   |   7 +-
>  lib/Makefile                  |   3 +-
>  lib/image-formats-selftests.c | 326 +++++++++++++++-
>  lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
>  5 files changed, 1336 insertions(+)
>  create mode 100644 include/linux/image-formats.h
>  create mode 100644 lib/image-formats-selftests.c
>  create mode 100644 lib/image-formats.c
> 

[...]

> --- /dev/null
> +++ b/lib/image-formats.c
> @@ -0,0 +1,760 @@
> +#include <linux/bug.h>
> +#include <linux/image-formats.h>
> +#include <linux/kernel.h>
> +#include <linux/math64.h>
> +
> +#include <uapi/drm/drm_fourcc.h>
> +
> +static const struct image_format_info formats[] = {
> +	{

...

> +	},
> +};
> +
> +#define __image_format_lookup(_field, _fmt)			\
> +	({							\
> +		const struct image_format_info *format = NULL;	\
> +		unsigned i;					\
> +								\
> +		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
> +			if (formats[i]._field == _fmt)		\
> +				format = &formats[i];		\
> +								\
> +		format;						\
> +	})
> +
> +/**
> + * __image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> +{
> +	return __image_format_lookup(drm_fmt, drm);
> +}
> +EXPORT_SYMBOL(__image_format_drm_lookup);
> +
> +/**
> + * image_format_drm_lookup - query information for a given format
> + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_drm_lookup(u32 drm)
> +{
> +	const struct image_format_info *format;
> +
> +	format = __image_format_drm_lookup(drm);
> +
> +	WARN_ON(!format);
> +	return format;
> +}
> +EXPORT_SYMBOL(image_format_drm_lookup);

I think this function and the DRM formats table should be moved in
drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
remaining functions can IMHO be placed in include/linux/image-formats.h
as static inline funcs. This way you can get rid of lib/image-formats.c
and the associated Kconfig entry.

> +
> +/**
> + * image_format_plane_cpp - determine the bytes per pixel value
> + * @format: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The bytes per pixel value for the specified plane.
> + */
> +unsigned int image_format_plane_cpp(const struct image_format_info *format,
> +				    int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	return format->cpp[plane];
> +}
> +EXPORT_SYMBOL(image_format_plane_cpp);
> +
> +/**
> + * image_format_plane_width - width of the plane given the first plane
> + * @format: pointer to the image_format
> + * @width: width of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The width of @plane, given that the width of the first plane is @width.
> + */
> +unsigned int image_format_plane_width(int width,
> +				      const struct image_format_info *format,
> +				      int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	if (plane == 0)
> +		return width;
> +
> +	return width / format->hsub;
> +}
> +EXPORT_SYMBOL(image_format_plane_width);
> +
> +/**
> + * image_format_plane_height - height of the plane given the first plane
> + * @format: pointer to the image_format
> + * @height: height of the first plane
> + * @plane: plane index
> + *
> + * Returns:
> + * The height of @plane, given that the height of the first plane is @height.
> + */
> +unsigned int image_format_plane_height(int height,
> +				       const struct image_format_info *format,
> +				       int plane)
> +{
> +	if (!format || plane >= format->num_planes)
> +		return 0;
> +
> +	if (plane == 0)
> +		return height;
> +
> +	return height / format->vsub;
> +}
> +EXPORT_SYMBOL(image_format_plane_height);
> +
> +/**
> + * image_format_block_width - width in pixels of block.
> + * @format: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The width in pixels of a block, depending on the plane index.
> + */
> +unsigned int image_format_block_width(const struct image_format_info *format,
> +				      int plane)
> +{
> +	if (!format || plane < 0 || plane >= format->num_planes)
> +		return 0;
> +
> +	if (!format->block_w[plane])
> +		return 1;
> +
> +	return format->block_w[plane];
> +}
> +EXPORT_SYMBOL(image_format_block_width);
> +
> +/**
> + * image_format_block_height - height in pixels of a block
> + * @info: pointer to the image_format
> + * @plane: plane index
> + *
> + * Returns:
> + * The height in pixels of a block, depending on the plane index.
> + */
> +unsigned int image_format_block_height(const struct image_format_info *format,
> +				       int plane)
> +{
> +	if (!format || plane < 0 || plane >= format->num_planes)
> +		return 0;
> +
> +	if (!format->block_h[plane])
> +		return 1;
> +
> +	return format->block_h[plane];
> +}
> +EXPORT_SYMBOL(image_format_block_height);
> +
> +/**
> + * image_format_min_pitch - computes the minimum required pitch in bytes
> + * @info: pixel format info
> + * @plane: plane index
> + * @buffer_width: buffer width in pixels
> + *
> + * Returns:
> + * The minimum required pitch in bytes for a buffer by taking into consideration
> + * the pixel format information and the buffer width.
> + */
> +uint64_t image_format_min_pitch(const struct image_format_info *info,
> +				int plane, unsigned int buffer_width)
> +{
> +	if (!info || plane < 0 || plane >= info->num_planes)
> +		return 0;
> +
> +	return DIV_ROUND_UP_ULL((u64)buffer_width * info->char_per_block[plane],
> +			    image_format_block_width(info, plane) *
> +			    image_format_block_height(info, plane));
> +}
> +EXPORT_SYMBOL(image_format_min_pitch);


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
  2019-03-19 21:57 ` [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes Maxime Ripard
@ 2019-03-20 14:16   ` Paul Kocialkowski
  2019-04-02  9:43   ` Emil Velikov
  1 sibling, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:16 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	dri-devel, linux-kernel, linux-media

Hi,

On Tue, 2019-03-19 at 22:57 +0100, Maxime Ripard wrote:
> drm_format_num_planes() is basically a lookup in the drm_format_info table
> plus an access to the num_planes field of the appropriate entry.
> 
> Most drivers are using this function while having access to the entry
> already, which means that we will perform an unnecessary lookup. Removing
> the call to drm_format_num_planes is therefore more efficient.
> 
> Some drivers will not have access to that entry in the function, but in
> this case the overhead is minimal (we just have to call drm_format_info()
> to perform the lookup) and we can even avoid multiple, inefficient lookups
> in some places that need multiple fields from the drm_format_info
> structure.

Great, happy to see drm_format_num_planes getting nuked!

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  drivers/gpu/drm/arm/malidp_mw.c             |  2 +-
>  drivers/gpu/drm/armada/armada_fb.c          |  3 ++-
>  drivers/gpu/drm/drm_fourcc.c                | 16 ----------------
>  drivers/gpu/drm/mediatek/mtk_drm_fb.c       |  6 ++++--
>  drivers/gpu/drm/meson/meson_overlay.c       |  2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c |  9 ++++++---
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c    |  3 ++-
>  drivers/gpu/drm/msm/msm_fb.c                |  8 ++++++--
>  drivers/gpu/drm/omapdrm/omap_fb.c           |  4 +++-
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  |  6 +++---
>  drivers/gpu/drm/tegra/fb.c                  |  3 ++-
>  drivers/gpu/drm/vc4/vc4_plane.c             |  2 +-
>  drivers/gpu/drm/zte/zx_plane.c              |  4 +---
>  include/drm/drm_fourcc.h                    |  1 -
>  14 files changed, 32 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
> index 041a64dc7167..91580b7a3781 100644
> --- a/drivers/gpu/drm/arm/malidp_mw.c
> +++ b/drivers/gpu/drm/arm/malidp_mw.c
> @@ -153,7 +153,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
>  		return -EINVAL;
>  	}
>  
> -	n_planes = drm_format_num_planes(fb->format->format);
> +	n_planes = fb->format->num_planes;
>  	for (i = 0; i < n_planes; i++) {
>  		struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i);
>  		/* memory write buffers are never rotated */
> diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c
> index 058ac7d9920f..a2f6472eb482 100644
> --- a/drivers/gpu/drm/armada/armada_fb.c
> +++ b/drivers/gpu/drm/armada/armada_fb.c
> @@ -87,6 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
>  struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
>  	struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev, mode);
>  	struct armada_gem_object *obj;
>  	struct armada_framebuffer *dfb;
>  	int ret;
> @@ -97,7 +98,7 @@ struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
>  		mode->pitches[2]);
>  
>  	/* We can only handle a single plane at the moment */
> -	if (drm_format_num_planes(mode->pixel_format) > 1 &&
> +	if (info->num_planes > 1 &&
>  	    (mode->handles[0] != mode->handles[1] ||
>  	     mode->handles[0] != mode->handles[2])) {
>  		ret = -EINVAL;
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index ba7e19d4336c..22c7fa459f65 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -306,22 +306,6 @@ drm_get_format_info(struct drm_device *dev,
>  EXPORT_SYMBOL(drm_get_format_info);
>  
>  /**
> - * drm_format_num_planes - get the number of planes for format
> - * @format: pixel format (DRM_FORMAT_*)
> - *
> - * Returns:
> - * The number of planes used by the specified pixel format.
> - */
> -int drm_format_num_planes(uint32_t format)
> -{
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
> -	return info ? info->num_planes : 1;
> -}
> -EXPORT_SYMBOL(drm_format_num_planes);
> -
> -/**
>   * drm_format_plane_cpp - determine the bytes per pixel value
>   * @format: pixel format (DRM_FORMAT_*)
>   * @plane: plane index
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> index e20fcaef2851..68fdef8b12bd 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> @@ -32,10 +32,11 @@ static struct drm_framebuffer *mtk_drm_framebuffer_init(struct drm_device *dev,
>  					const struct drm_mode_fb_cmd2 *mode,
>  					struct drm_gem_object *obj)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev, mode);
>  	struct drm_framebuffer *fb;
>  	int ret;
>  
> -	if (drm_format_num_planes(mode->pixel_format) != 1)
> +	if (info->num_planes != 1)
>  		return ERR_PTR(-EINVAL);
>  
>  	fb = kzalloc(sizeof(*fb), GFP_KERNEL);
> @@ -88,6 +89,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
>  					       struct drm_file *file,
>  					       const struct drm_mode_fb_cmd2 *cmd)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
>  	struct drm_framebuffer *fb;
>  	struct drm_gem_object *gem;
>  	unsigned int width = cmd->width;
> @@ -95,7 +97,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
>  	unsigned int size, bpp;
>  	int ret;
>  
> -	if (drm_format_num_planes(cmd->pixel_format) != 1)
> +	if (info->num_planes != 1)
>  		return ERR_PTR(-EINVAL);
>  
>  	gem = drm_gem_object_lookup(file, cmd->handles[0]);
> diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
> index 691a9fd16b36..8ff15d01a8f9 100644
> --- a/drivers/gpu/drm/meson/meson_overlay.c
> +++ b/drivers/gpu/drm/meson/meson_overlay.c
> @@ -466,7 +466,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
>  	}
>  
>  	/* Update Canvas with buffer address */
> -	priv->viu.vd1_planes = drm_format_num_planes(fb->format->format);
> +	priv->viu.vd1_planes = fb->format->num_planes;
>  
>  	switch (priv->viu.vd1_planes) {
>  	case 3:
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> index 0874f0a53bf9..1aed51b49be4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> @@ -1040,10 +1040,11 @@ int dpu_format_check_modified_format(
>  		const struct drm_mode_fb_cmd2 *cmd,
>  		struct drm_gem_object **bos)
>  {
> -	int ret, i, num_base_fmt_planes;
> +	const struct drm_format_info *info;
>  	const struct dpu_format *fmt;
>  	struct dpu_hw_fmt_layout layout;
>  	uint32_t bos_total_size = 0;
> +	int ret, i;
>  
>  	if (!msm_fmt || !cmd || !bos) {
>  		DRM_ERROR("invalid arguments\n");
> @@ -1051,14 +1052,16 @@ int dpu_format_check_modified_format(
>  	}
>  
>  	fmt = to_dpu_format(msm_fmt);
> -	num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
> +	info = drm_format_info(fmt->base.pixel_format);
> +	if (!info)
> +		return -EINVAL;
>  
>  	ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height,
>  			&layout, cmd->pitches);
>  	if (ret)
>  		return ret;
>  
> -	for (i = 0; i < num_base_fmt_planes; i++) {
> +	for (i = 0; i < info->num_planes; i++) {
>  		if (!bos[i]) {
>  			DRM_ERROR("invalid handle for plane %d\n", i);
>  			return -EINVAL;
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> index 6153514db04c..72ab8d89efa4 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> @@ -127,13 +127,14 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
>  		const struct mdp_format *format,
>  		u32 width, bool hdecim)
>  {
> +	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
>  	struct mdp5_kms *mdp5_kms = get_kms(smp);
>  	int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
>  	int i, hsub, nplanes, nlines;
>  	u32 fmt = format->base.pixel_format;
>  	uint32_t blkcfg = 0;
>  
> -	nplanes = drm_format_num_planes(fmt);
> +	nplanes = info->num_planes;
>  	hsub = drm_format_horz_chroma_subsampling(fmt);
>  
>  	/* different if BWC (compressed framebuffer?) enabled: */
> diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
> index 136058978e0f..432beddafb9e 100644
> --- a/drivers/gpu/drm/msm/msm_fb.c
> +++ b/drivers/gpu/drm/msm/msm_fb.c
> @@ -106,9 +106,11 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
>  struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
>  		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct drm_gem_object *bos[4] = {0};
>  	struct drm_framebuffer *fb;
> -	int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
> +	int ret, i, n = info->num_planes;
>  
>  	for (i = 0; i < n; i++) {
>  		bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
> @@ -135,6 +137,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
>  static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct msm_drm_private *priv = dev->dev_private;
>  	struct msm_kms *kms = priv->kms;
>  	struct msm_framebuffer *msm_fb = NULL;
> @@ -147,7 +151,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
>  			(char *)&mode_cmd->pixel_format);
>  
> -	n = drm_format_num_planes(mode_cmd->pixel_format);
> +	n = info->num_planes;
>  	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
>  	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
>  
> diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
> index 4f8eb9d08f99..cfb641363a32 100644
> --- a/drivers/gpu/drm/omapdrm/omap_fb.c
> +++ b/drivers/gpu/drm/omapdrm/omap_fb.c
> @@ -298,7 +298,9 @@ void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
>  struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
>  		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
>  {
> -	unsigned int num_planes = drm_format_num_planes(mode_cmd->pixel_format);
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
> +	unsigned int num_planes = info->num_planes;
>  	struct drm_gem_object *bos[4];
>  	struct drm_framebuffer *fb;
>  	int i;
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 97438bbbe389..606d176d5d96 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -74,19 +74,19 @@ static struct drm_framebuffer *
>  rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
>  			const struct drm_mode_fb_cmd2 *mode_cmd)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct drm_framebuffer *fb;
>  	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
>  	struct drm_gem_object *obj;
>  	unsigned int hsub;
>  	unsigned int vsub;
> -	int num_planes;
> +	int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
>  	int ret;
>  	int i;
>  
>  	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
>  	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
> -	num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
> -			 ROCKCHIP_MAX_FB_BUFFER);
>  
>  	for (i = 0; i < num_planes; i++) {
>  		unsigned int width = mode_cmd->width / (i ? hsub : 1);
> diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
> index 0a4ce05e00ab..bc8f9afd1b5f 100644
> --- a/drivers/gpu/drm/tegra/fb.c
> +++ b/drivers/gpu/drm/tegra/fb.c
> @@ -131,6 +131,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
>  					struct drm_file *file,
>  					const struct drm_mode_fb_cmd2 *cmd)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
>  	unsigned int hsub, vsub, i;
>  	struct tegra_bo *planes[4];
>  	struct drm_gem_object *gem;
> @@ -140,7 +141,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
>  	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
>  	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
>  
> -	for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) {
> +	for (i = 0; i < info->num_planes; i++) {
>  		unsigned int width = cmd->width / (i ? hsub : 1);
>  		unsigned int height = cmd->height / (i ? vsub : 1);
>  		unsigned int size, bpp;
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 1babfeca0c92..138a9ff23b70 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -537,7 +537,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>  	u32 ctl0_offset = vc4_state->dlist_count;
>  	const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
>  	u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
> -	int num_planes = drm_format_num_planes(format->drm);
> +	int num_planes = fb->format->num_planes;
>  	u32 h_subsample, v_subsample;
>  	bool mix_plane_alpha;
>  	bool covers_screen;
> diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
> index 83d236fd893c..c6a8be444300 100644
> --- a/drivers/gpu/drm/zte/zx_plane.c
> +++ b/drivers/gpu/drm/zte/zx_plane.c
> @@ -199,7 +199,6 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
>  	u32 dst_x, dst_y, dst_w, dst_h;
>  	uint32_t format;
>  	int fmt;
> -	int num_planes;
>  	int i;
>  
>  	if (!fb)
> @@ -218,9 +217,8 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
>  	dst_h = drm_rect_height(dst);
>  
>  	/* Set up data address registers for Y, Cb and Cr planes */
> -	num_planes = drm_format_num_planes(format);
>  	paddr_reg = layer + VL_Y;
> -	for (i = 0; i < num_planes; i++) {
> +	for (i = 0; i < fb->format->num_planes; i++) {
>  		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
>  		paddr = cma_obj->paddr + fb->offsets[i];
>  		paddr += src_y * fb->pitches[i];
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index b3d9d88ab290..41779b327d91 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -268,7 +268,6 @@ drm_get_format_info(struct drm_device *dev,
>  uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
>  uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
>  				     uint32_t bpp, uint32_t depth);
> -int drm_format_num_planes(uint32_t format);
>  int drm_format_plane_cpp(uint32_t format, int plane);
>  int drm_format_horz_chroma_subsampling(uint32_t format);
>  int drm_format_vert_chroma_subsampling(uint32_t format);
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling
  2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
@ 2019-03-20 14:19     ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:19 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	dri-devel, linux-kernel, linux-media

Hi,

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> drm_format_horz_chroma_subsampling and drm_format_vert_chroma_subsampling
> are basically a lookup in the drm_format_info table plus an access to the
> hsub and vsub fields of the appropriate entry.
> 
> Most drivers are using this function while having access to the entry
> already, which means that we will perform an unnecessary lookup. Removing
> the call to these functions is therefore more efficient.
> 
> Some drivers will not have access to that entry in the function, but in
> this case the overhead is minimal (we just have to call drm_format_info()
> to perform the lookup) and we can even avoid multiple, inefficient lookups
> in some places that need multiple fields from the drm_format_info
> structure.
> 
> This is amplified by the fact that most of the time the callers will have
> to retrieve both the vsub and hsub fields, meaning that they would perform
> twice the lookup.

Cheers for nuking these two as well!

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |  9 +----
>  drivers/gpu/drm/drm_fourcc.c                    | 34 +------------------
>  drivers/gpu/drm/imx/ipuv3-plane.c               | 15 +++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c       |  9 +----
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c      | 24 +++++--------
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c        |  2 +-
>  drivers/gpu/drm/msm/msm_fb.c                    |  8 +---
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  9 +----
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c     | 13 ++-----
>  drivers/gpu/drm/tegra/fb.c                      |  9 +----
>  drivers/gpu/drm/vc4/vc4_plane.c                 | 13 ++-----
>  include/drm/drm_fourcc.h                        |  2 +-
>  12 files changed, 37 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index e836e2de35ce..fdd607ad27fe 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	const struct drm_display_mode *mode;
>  	struct drm_crtc_state *crtc_state;
>  	unsigned int tmp;
> -	int hsub = 1;
> -	int vsub = 1;
>  	int ret;
>  	int i;
>  
> @@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES)
>  		return -EINVAL;
>  
> -	hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -	vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> -
>  	for (i = 0; i < state->nplanes; i++) {
>  		unsigned int offset = 0;
> -		int xdiv = i ? hsub : 1;
> -		int ydiv = i ? vsub : 1;
> +		int xdiv = i ? fb->format->hsub : 1;
> +		int ydiv = i ? fb->format->vsub : 1;
>  
>  		state->bpp[i] = fb->format->cpp[i];
>  		if (!state->bpp[i])
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 22c7fa459f65..04be330b7cae 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -326,40 +326,6 @@ int drm_format_plane_cpp(uint32_t format, int plane)
>  EXPORT_SYMBOL(drm_format_plane_cpp);
>  
>  /**
> - * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
> - * @format: pixel format (DRM_FORMAT_*)
> - *
> - * Returns:
> - * The horizontal chroma subsampling factor for the
> - * specified pixel format.
> - */
> -int drm_format_horz_chroma_subsampling(uint32_t format)
> -{
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
> -	return info ? info->hsub : 1;
> -}
> -EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
> -
> -/**
> - * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
> - * @format: pixel format (DRM_FORMAT_*)
> - *
> - * Returns:
> - * The vertical chroma subsampling factor for the
> - * specified pixel format.
> - */
> -int drm_format_vert_chroma_subsampling(uint32_t format)
> -{
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
> -	return info ? info->vsub : 1;
> -}
> -EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
> -
> -/**
>   * drm_format_plane_width - width of the plane given the first plane
>   * @width: width of the first plane
>   * @format: pixel format
> diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
> index 21e964f6ab5c..2530143281b2 100644
> --- a/drivers/gpu/drm/imx/ipuv3-plane.c
> +++ b/drivers/gpu/drm/imx/ipuv3-plane.c
> @@ -115,8 +115,8 @@ drm_plane_state_to_ubo(struct drm_plane_state *state)
>  	cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
>  	BUG_ON(!cma_obj);
>  
> -	x /= drm_format_horz_chroma_subsampling(fb->format->format);
> -	y /= drm_format_vert_chroma_subsampling(fb->format->format);
> +	x /= fb->format->hsub;
> +	y /= fb->format->vsub;
>  
>  	return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
>  	       fb->format->cpp[1] * x - eba;
> @@ -134,8 +134,8 @@ drm_plane_state_to_vbo(struct drm_plane_state *state)
>  	cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
>  	BUG_ON(!cma_obj);
>  
> -	x /= drm_format_horz_chroma_subsampling(fb->format->format);
> -	y /= drm_format_vert_chroma_subsampling(fb->format->format);
> +	x /= fb->format->hsub;
> +	y /= fb->format->vsub;
>  
>  	return cma_obj->paddr + fb->offsets[2] + fb->pitches[2] * y +
>  	       fb->format->cpp[2] * x - eba;
> @@ -348,7 +348,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>  	struct drm_framebuffer *old_fb = old_state->fb;
>  	unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
>  	bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
> -	int hsub, vsub;
>  	int ret;
>  
>  	/* Ok to disable */
> @@ -467,10 +466,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>  		 * The x/y offsets must be even in case of horizontal/vertical
>  		 * chroma subsampling.
>  		 */
> -		hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -		vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> -		if (((state->src.x1 >> 16) & (hsub - 1)) ||
> -		    ((state->src.y1 >> 16) & (vsub - 1)))
> +		if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) ||
> +		    ((state->src.y1 >> 16) & (fb->format->vsub - 1)))
>  			return -EINVAL;
>  		break;
>  	case DRM_FORMAT_RGB565_A8:
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 6aefcd6db46b..a9492c488441 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -553,14 +553,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>  		struct dpu_plane_state *pstate,
>  		const struct dpu_format *fmt, bool color_fill)
>  {
> -	uint32_t chroma_subsmpl_h, chroma_subsmpl_v;
> +	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
>  
>  	/* don't chroma subsample if decimating */
> -	chroma_subsmpl_h =
> -		drm_format_horz_chroma_subsampling(fmt->base.pixel_format);
> -	chroma_subsmpl_v =
> -		drm_format_vert_chroma_subsampling(fmt->base.pixel_format);
> -
>  	/* update scaler. calculate default config for QSEED3 */
>  	_dpu_plane_setup_scaler3(pdpu, pstate,
>  			drm_rect_width(&pdpu->pipe_cfg.src_rect),
> @@ -568,7 +563,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>  			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
>  			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
>  			&pstate->scaler3_cfg, fmt,
> -			chroma_subsmpl_h, chroma_subsmpl_v);
> +			info->hsub, info->vsub);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> index be13140967b4..9d9fb6c5fd68 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> @@ -650,10 +650,10 @@ static int calc_scalex_steps(struct drm_plane *plane,
>  		uint32_t pixel_format, uint32_t src, uint32_t dest,
>  		uint32_t phasex_steps[COMP_MAX])
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	struct mdp5_kms *mdp5_kms = get_kms(plane);
>  	struct device *dev = mdp5_kms->dev->dev;
>  	uint32_t phasex_step;
> -	unsigned int hsub;
>  	int ret;
>  
>  	ret = calc_phase_step(src, dest, &phasex_step);
> @@ -662,11 +662,9 @@ static int calc_scalex_steps(struct drm_plane *plane,
>  		return ret;
>  	}
>  
> -	hsub = drm_format_horz_chroma_subsampling(pixel_format);
> -
>  	phasex_steps[COMP_0]   = phasex_step;
>  	phasex_steps[COMP_3]   = phasex_step;
> -	phasex_steps[COMP_1_2] = phasex_step / hsub;
> +	phasex_steps[COMP_1_2] = phasex_step / info->hsub;
>  
>  	return 0;
>  }
> @@ -675,10 +673,10 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  		uint32_t pixel_format, uint32_t src, uint32_t dest,
>  		uint32_t phasey_steps[COMP_MAX])
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	struct mdp5_kms *mdp5_kms = get_kms(plane);
>  	struct device *dev = mdp5_kms->dev->dev;
>  	uint32_t phasey_step;
> -	unsigned int vsub;
>  	int ret;
>  
>  	ret = calc_phase_step(src, dest, &phasey_step);
> @@ -687,11 +685,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  		return ret;
>  	}
>  
> -	vsub = drm_format_vert_chroma_subsampling(pixel_format);
> -
>  	phasey_steps[COMP_0]   = phasey_step;
>  	phasey_steps[COMP_3]   = phasey_step;
> -	phasey_steps[COMP_1_2] = phasey_step / vsub;
> +	phasey_steps[COMP_1_2] = phasey_step / info->vsub;
>  
>  	return 0;
>  }
> @@ -699,8 +695,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  static uint32_t get_scale_config(const struct mdp_format *format,
>  		uint32_t src, uint32_t dst, bool horz)
>  {
> +	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
>  	bool scaling = format->is_yuv ? true : (src != dst);
> -	uint32_t sub, pix_fmt = format->base.pixel_format;
> +	uint32_t sub;
>  	uint32_t ya_filter, uv_filter;
>  	bool yuv = format->is_yuv;
>  
> @@ -708,8 +705,7 @@ static uint32_t get_scale_config(const struct mdp_format *format,
>  		return 0;
>  
>  	if (yuv) {
> -		sub = horz ? drm_format_horz_chroma_subsampling(pix_fmt) :
> -			     drm_format_vert_chroma_subsampling(pix_fmt);
> +		sub = horz ? info->hsub : info->vsub;
>  		uv_filter = ((src / sub) <= dst) ?
>  				   SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
>  	}
> @@ -754,7 +750,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
>  	uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
>  	uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
>  {
> -	uint32_t pix_fmt = format->base.pixel_format;
> +	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
>  	uint32_t lr, tb, req;
>  	int i;
>  
> @@ -763,8 +759,8 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
>  		uint32_t roi_h = src_h;
>  
>  		if (format->is_yuv && i == COMP_1_2) {
> -			roi_w /= drm_format_horz_chroma_subsampling(pix_fmt);
> -			roi_h /= drm_format_vert_chroma_subsampling(pix_fmt);
> +			roi_w /= info->hsub;
> +			roi_h /= info->vsub;
>  		}
>  
>  		lr  = (pe_left[i] >= 0) ?
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> index 72ab8d89efa4..b30b2f4efc60 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> @@ -135,7 +135,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
>  	uint32_t blkcfg = 0;
>  
>  	nplanes = info->num_planes;
> -	hsub = drm_format_horz_chroma_subsampling(fmt);
> +	hsub = info->hsub;
>  
>  	/* different if BWC (compressed framebuffer?) enabled: */
>  	nlines = 2;
> diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
> index 432beddafb9e..f69c0afd6ec6 100644
> --- a/drivers/gpu/drm/msm/msm_fb.c
> +++ b/drivers/gpu/drm/msm/msm_fb.c
> @@ -145,16 +145,12 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  	struct drm_framebuffer *fb;
>  	const struct msm_format *format;
>  	int ret, i, n;
> -	unsigned int hsub, vsub;
>  
>  	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
>  			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
>  			(char *)&mode_cmd->pixel_format);
>  
>  	n = info->num_planes;
> -	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
> -
>  	format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
>  			mode_cmd->modifier[0]);
>  	if (!format) {
> @@ -180,8 +176,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  	}
>  
>  	for (i = 0; i < n; i++) {
> -		unsigned int width = mode_cmd->width / (i ? hsub : 1);
> -		unsigned int height = mode_cmd->height / (i ? vsub : 1);
> +		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>  		unsigned int min_size;
>  
>  		min_size = (height - 1) * mode_cmd->pitches[i]
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 606d176d5d96..c318fae28581 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -79,18 +79,13 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
>  	struct drm_framebuffer *fb;
>  	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
>  	struct drm_gem_object *obj;
> -	unsigned int hsub;
> -	unsigned int vsub;
>  	int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
>  	int ret;
>  	int i;
>  
> -	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
> -
>  	for (i = 0; i < num_planes; i++) {
> -		unsigned int width = mode_cmd->width / (i ? hsub : 1);
> -		unsigned int height = mode_cmd->height / (i ? vsub : 1);
> +		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>  		unsigned int min_size;
>  
>  		obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index c7d4c6073ea5..88c3902057f3 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -317,21 +317,18 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
>  			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
>  			     uint32_t dst_h, uint32_t pixel_format)
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
>  	uint16_t cbcr_hor_scl_mode = SCALE_NONE;
>  	uint16_t cbcr_ver_scl_mode = SCALE_NONE;
> -	int hsub = drm_format_horz_chroma_subsampling(pixel_format);
> -	int vsub = drm_format_vert_chroma_subsampling(pixel_format);
> -	const struct drm_format_info *info;
>  	bool is_yuv = false;
> -	uint16_t cbcr_src_w = src_w / hsub;
> -	uint16_t cbcr_src_h = src_h / vsub;
> +	uint16_t cbcr_src_w = src_w / info->hsub;
> +	uint16_t cbcr_src_h = src_h / info->vsub;
>  	uint16_t vsu_mode;
>  	uint16_t lb_mode;
>  	uint32_t val;
>  	int vskiplines;
>  
> -	info = drm_format_info(pixel_format);
>  
>  	if (info->is_yuv)
>  		is_yuv = true;
> @@ -819,8 +816,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
>  		    (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
>  
>  	if (is_yuv) {
> -		int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -		int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> +		int hsub = fb->format->hsub;
> +		int vsub = fb->format->vsub;
>  		int bpp = fb->format->cpp[1];
>  
>  		uv_obj = fb->obj[1];
> diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
> index bc8f9afd1b5f..ddf2c764f24c 100644
> --- a/drivers/gpu/drm/tegra/fb.c
> +++ b/drivers/gpu/drm/tegra/fb.c
> @@ -132,18 +132,15 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
>  					const struct drm_mode_fb_cmd2 *cmd)
>  {
>  	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
> -	unsigned int hsub, vsub, i;
>  	struct tegra_bo *planes[4];
>  	struct drm_gem_object *gem;
>  	struct drm_framebuffer *fb;
> +	unsigned int i;
>  	int err;
>  
> -	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
> -
>  	for (i = 0; i < info->num_planes; i++) {
> -		unsigned int width = cmd->width / (i ? hsub : 1);
> -		unsigned int height = cmd->height / (i ? vsub : 1);
> +		unsigned int width = cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = cmd->height / (i ? info->vsub : 1);
>  		unsigned int size, bpp;
>  
>  		gem = drm_gem_object_lookup(file, cmd->handles[i]);
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 138a9ff23b70..6605c1b7370d 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -310,10 +310,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
>  	struct drm_framebuffer *fb = state->fb;
>  	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
>  	u32 subpixel_src_mask = (1 << 16) - 1;
> -	u32 format = fb->format->format;
>  	int num_planes = fb->format->num_planes;
>  	struct drm_crtc_state *crtc_state;
> -	u32 h_subsample, v_subsample;
> +	u32 h_subsample = fb->format->hsub;
> +	u32 v_subsample = fb->format->vsub;
>  	int i, ret;
>  
>  	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
> @@ -328,9 +328,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
>  	if (ret)
>  		return ret;
>  
> -	h_subsample = drm_format_horz_chroma_subsampling(format);
> -	v_subsample = drm_format_vert_chroma_subsampling(format);
> -
>  	for (i = 0; i < num_planes; i++)
>  		vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
>  
> @@ -538,7 +535,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>  	const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
>  	u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
>  	int num_planes = fb->format->num_planes;
> -	u32 h_subsample, v_subsample;
> +	u32 h_subsample = fb->format->hsub;
> +	u32 v_subsample = fb->format->vsub;
>  	bool mix_plane_alpha;
>  	bool covers_screen;
>  	u32 scl0, scl1, pitch0;
> @@ -568,9 +566,6 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>  		scl1 = vc4_get_scl_field(state, 0);
>  	}
>  
> -	h_subsample = drm_format_horz_chroma_subsampling(format->drm);
> -	v_subsample = drm_format_vert_chroma_subsampling(format->drm);
> -
>  	rotation = drm_rotation_simplify(state->rotation,
>  					 DRM_MODE_ROTATE_0 |
>  					 DRM_MODE_REFLECT_X |
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 41779b327d91..eeec449d6c6a 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -269,8 +269,6 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
>  uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
>  				     uint32_t bpp, uint32_t depth);
>  int drm_format_plane_cpp(uint32_t format, int plane);
> -int drm_format_horz_chroma_subsampling(uint32_t format);
> -int drm_format_vert_chroma_subsampling(uint32_t format);
>  int drm_format_plane_width(int width, uint32_t format, int plane);
>  int drm_format_plane_height(int height, uint32_t format, int plane);
>  unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling
@ 2019-03-20 14:19     ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:19 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media

Hi,

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> drm_format_horz_chroma_subsampling and drm_format_vert_chroma_subsampling
> are basically a lookup in the drm_format_info table plus an access to the
> hsub and vsub fields of the appropriate entry.
> 
> Most drivers are using this function while having access to the entry
> already, which means that we will perform an unnecessary lookup. Removing
> the call to these functions is therefore more efficient.
> 
> Some drivers will not have access to that entry in the function, but in
> this case the overhead is minimal (we just have to call drm_format_info()
> to perform the lookup) and we can even avoid multiple, inefficient lookups
> in some places that need multiple fields from the drm_format_info
> structure.
> 
> This is amplified by the fact that most of the time the callers will have
> to retrieve both the vsub and hsub fields, meaning that they would perform
> twice the lookup.

Cheers for nuking these two as well!

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c |  9 +----
>  drivers/gpu/drm/drm_fourcc.c                    | 34 +------------------
>  drivers/gpu/drm/imx/ipuv3-plane.c               | 15 +++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c       |  9 +----
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c      | 24 +++++--------
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c        |  2 +-
>  drivers/gpu/drm/msm/msm_fb.c                    |  8 +---
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c      |  9 +----
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c     | 13 ++-----
>  drivers/gpu/drm/tegra/fb.c                      |  9 +----
>  drivers/gpu/drm/vc4/vc4_plane.c                 | 13 ++-----
>  include/drm/drm_fourcc.h                        |  2 +-
>  12 files changed, 37 insertions(+), 110 deletions(-)
> 
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index e836e2de35ce..fdd607ad27fe 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	const struct drm_display_mode *mode;
>  	struct drm_crtc_state *crtc_state;
>  	unsigned int tmp;
> -	int hsub = 1;
> -	int vsub = 1;
>  	int ret;
>  	int i;
>  
> @@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
>  	if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES)
>  		return -EINVAL;
>  
> -	hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -	vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> -
>  	for (i = 0; i < state->nplanes; i++) {
>  		unsigned int offset = 0;
> -		int xdiv = i ? hsub : 1;
> -		int ydiv = i ? vsub : 1;
> +		int xdiv = i ? fb->format->hsub : 1;
> +		int ydiv = i ? fb->format->vsub : 1;
>  
>  		state->bpp[i] = fb->format->cpp[i];
>  		if (!state->bpp[i])
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 22c7fa459f65..04be330b7cae 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -326,40 +326,6 @@ int drm_format_plane_cpp(uint32_t format, int plane)
>  EXPORT_SYMBOL(drm_format_plane_cpp);
>  
>  /**
> - * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
> - * @format: pixel format (DRM_FORMAT_*)
> - *
> - * Returns:
> - * The horizontal chroma subsampling factor for the
> - * specified pixel format.
> - */
> -int drm_format_horz_chroma_subsampling(uint32_t format)
> -{
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
> -	return info ? info->hsub : 1;
> -}
> -EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
> -
> -/**
> - * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
> - * @format: pixel format (DRM_FORMAT_*)
> - *
> - * Returns:
> - * The vertical chroma subsampling factor for the
> - * specified pixel format.
> - */
> -int drm_format_vert_chroma_subsampling(uint32_t format)
> -{
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
> -	return info ? info->vsub : 1;
> -}
> -EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
> -
> -/**
>   * drm_format_plane_width - width of the plane given the first plane
>   * @width: width of the first plane
>   * @format: pixel format
> diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
> index 21e964f6ab5c..2530143281b2 100644
> --- a/drivers/gpu/drm/imx/ipuv3-plane.c
> +++ b/drivers/gpu/drm/imx/ipuv3-plane.c
> @@ -115,8 +115,8 @@ drm_plane_state_to_ubo(struct drm_plane_state *state)
>  	cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
>  	BUG_ON(!cma_obj);
>  
> -	x /= drm_format_horz_chroma_subsampling(fb->format->format);
> -	y /= drm_format_vert_chroma_subsampling(fb->format->format);
> +	x /= fb->format->hsub;
> +	y /= fb->format->vsub;
>  
>  	return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
>  	       fb->format->cpp[1] * x - eba;
> @@ -134,8 +134,8 @@ drm_plane_state_to_vbo(struct drm_plane_state *state)
>  	cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
>  	BUG_ON(!cma_obj);
>  
> -	x /= drm_format_horz_chroma_subsampling(fb->format->format);
> -	y /= drm_format_vert_chroma_subsampling(fb->format->format);
> +	x /= fb->format->hsub;
> +	y /= fb->format->vsub;
>  
>  	return cma_obj->paddr + fb->offsets[2] + fb->pitches[2] * y +
>  	       fb->format->cpp[2] * x - eba;
> @@ -348,7 +348,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>  	struct drm_framebuffer *old_fb = old_state->fb;
>  	unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
>  	bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
> -	int hsub, vsub;
>  	int ret;
>  
>  	/* Ok to disable */
> @@ -467,10 +466,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
>  		 * The x/y offsets must be even in case of horizontal/vertical
>  		 * chroma subsampling.
>  		 */
> -		hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -		vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> -		if (((state->src.x1 >> 16) & (hsub - 1)) ||
> -		    ((state->src.y1 >> 16) & (vsub - 1)))
> +		if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) ||
> +		    ((state->src.y1 >> 16) & (fb->format->vsub - 1)))
>  			return -EINVAL;
>  		break;
>  	case DRM_FORMAT_RGB565_A8:
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 6aefcd6db46b..a9492c488441 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -553,14 +553,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>  		struct dpu_plane_state *pstate,
>  		const struct dpu_format *fmt, bool color_fill)
>  {
> -	uint32_t chroma_subsmpl_h, chroma_subsmpl_v;
> +	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
>  
>  	/* don't chroma subsample if decimating */
> -	chroma_subsmpl_h =
> -		drm_format_horz_chroma_subsampling(fmt->base.pixel_format);
> -	chroma_subsmpl_v =
> -		drm_format_vert_chroma_subsampling(fmt->base.pixel_format);
> -
>  	/* update scaler. calculate default config for QSEED3 */
>  	_dpu_plane_setup_scaler3(pdpu, pstate,
>  			drm_rect_width(&pdpu->pipe_cfg.src_rect),
> @@ -568,7 +563,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>  			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
>  			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
>  			&pstate->scaler3_cfg, fmt,
> -			chroma_subsmpl_h, chroma_subsmpl_v);
> +			info->hsub, info->vsub);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> index be13140967b4..9d9fb6c5fd68 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
> @@ -650,10 +650,10 @@ static int calc_scalex_steps(struct drm_plane *plane,
>  		uint32_t pixel_format, uint32_t src, uint32_t dest,
>  		uint32_t phasex_steps[COMP_MAX])
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	struct mdp5_kms *mdp5_kms = get_kms(plane);
>  	struct device *dev = mdp5_kms->dev->dev;
>  	uint32_t phasex_step;
> -	unsigned int hsub;
>  	int ret;
>  
>  	ret = calc_phase_step(src, dest, &phasex_step);
> @@ -662,11 +662,9 @@ static int calc_scalex_steps(struct drm_plane *plane,
>  		return ret;
>  	}
>  
> -	hsub = drm_format_horz_chroma_subsampling(pixel_format);
> -
>  	phasex_steps[COMP_0]   = phasex_step;
>  	phasex_steps[COMP_3]   = phasex_step;
> -	phasex_steps[COMP_1_2] = phasex_step / hsub;
> +	phasex_steps[COMP_1_2] = phasex_step / info->hsub;
>  
>  	return 0;
>  }
> @@ -675,10 +673,10 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  		uint32_t pixel_format, uint32_t src, uint32_t dest,
>  		uint32_t phasey_steps[COMP_MAX])
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	struct mdp5_kms *mdp5_kms = get_kms(plane);
>  	struct device *dev = mdp5_kms->dev->dev;
>  	uint32_t phasey_step;
> -	unsigned int vsub;
>  	int ret;
>  
>  	ret = calc_phase_step(src, dest, &phasey_step);
> @@ -687,11 +685,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  		return ret;
>  	}
>  
> -	vsub = drm_format_vert_chroma_subsampling(pixel_format);
> -
>  	phasey_steps[COMP_0]   = phasey_step;
>  	phasey_steps[COMP_3]   = phasey_step;
> -	phasey_steps[COMP_1_2] = phasey_step / vsub;
> +	phasey_steps[COMP_1_2] = phasey_step / info->vsub;
>  
>  	return 0;
>  }
> @@ -699,8 +695,9 @@ static int calc_scaley_steps(struct drm_plane *plane,
>  static uint32_t get_scale_config(const struct mdp_format *format,
>  		uint32_t src, uint32_t dst, bool horz)
>  {
> +	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
>  	bool scaling = format->is_yuv ? true : (src != dst);
> -	uint32_t sub, pix_fmt = format->base.pixel_format;
> +	uint32_t sub;
>  	uint32_t ya_filter, uv_filter;
>  	bool yuv = format->is_yuv;
>  
> @@ -708,8 +705,7 @@ static uint32_t get_scale_config(const struct mdp_format *format,
>  		return 0;
>  
>  	if (yuv) {
> -		sub = horz ? drm_format_horz_chroma_subsampling(pix_fmt) :
> -			     drm_format_vert_chroma_subsampling(pix_fmt);
> +		sub = horz ? info->hsub : info->vsub;
>  		uv_filter = ((src / sub) <= dst) ?
>  				   SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
>  	}
> @@ -754,7 +750,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
>  	uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
>  	uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
>  {
> -	uint32_t pix_fmt = format->base.pixel_format;
> +	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
>  	uint32_t lr, tb, req;
>  	int i;
>  
> @@ -763,8 +759,8 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
>  		uint32_t roi_h = src_h;
>  
>  		if (format->is_yuv && i == COMP_1_2) {
> -			roi_w /= drm_format_horz_chroma_subsampling(pix_fmt);
> -			roi_h /= drm_format_vert_chroma_subsampling(pix_fmt);
> +			roi_w /= info->hsub;
> +			roi_h /= info->vsub;
>  		}
>  
>  		lr  = (pe_left[i] >= 0) ?
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> index 72ab8d89efa4..b30b2f4efc60 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> @@ -135,7 +135,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
>  	uint32_t blkcfg = 0;
>  
>  	nplanes = info->num_planes;
> -	hsub = drm_format_horz_chroma_subsampling(fmt);
> +	hsub = info->hsub;
>  
>  	/* different if BWC (compressed framebuffer?) enabled: */
>  	nlines = 2;
> diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
> index 432beddafb9e..f69c0afd6ec6 100644
> --- a/drivers/gpu/drm/msm/msm_fb.c
> +++ b/drivers/gpu/drm/msm/msm_fb.c
> @@ -145,16 +145,12 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  	struct drm_framebuffer *fb;
>  	const struct msm_format *format;
>  	int ret, i, n;
> -	unsigned int hsub, vsub;
>  
>  	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
>  			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
>  			(char *)&mode_cmd->pixel_format);
>  
>  	n = info->num_planes;
> -	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
> -
>  	format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
>  			mode_cmd->modifier[0]);
>  	if (!format) {
> @@ -180,8 +176,8 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  	}
>  
>  	for (i = 0; i < n; i++) {
> -		unsigned int width = mode_cmd->width / (i ? hsub : 1);
> -		unsigned int height = mode_cmd->height / (i ? vsub : 1);
> +		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>  		unsigned int min_size;
>  
>  		min_size = (height - 1) * mode_cmd->pitches[i]
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 606d176d5d96..c318fae28581 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -79,18 +79,13 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
>  	struct drm_framebuffer *fb;
>  	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
>  	struct drm_gem_object *obj;
> -	unsigned int hsub;
> -	unsigned int vsub;
>  	int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
>  	int ret;
>  	int i;
>  
> -	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
> -
>  	for (i = 0; i < num_planes; i++) {
> -		unsigned int width = mode_cmd->width / (i ? hsub : 1);
> -		unsigned int height = mode_cmd->height / (i ? vsub : 1);
> +		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>  		unsigned int min_size;
>  
>  		obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index c7d4c6073ea5..88c3902057f3 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -317,21 +317,18 @@ static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
>  			     uint32_t src_w, uint32_t src_h, uint32_t dst_w,
>  			     uint32_t dst_h, uint32_t pixel_format)
>  {
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
>  	uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
>  	uint16_t cbcr_hor_scl_mode = SCALE_NONE;
>  	uint16_t cbcr_ver_scl_mode = SCALE_NONE;
> -	int hsub = drm_format_horz_chroma_subsampling(pixel_format);
> -	int vsub = drm_format_vert_chroma_subsampling(pixel_format);
> -	const struct drm_format_info *info;
>  	bool is_yuv = false;
> -	uint16_t cbcr_src_w = src_w / hsub;
> -	uint16_t cbcr_src_h = src_h / vsub;
> +	uint16_t cbcr_src_w = src_w / info->hsub;
> +	uint16_t cbcr_src_h = src_h / info->vsub;
>  	uint16_t vsu_mode;
>  	uint16_t lb_mode;
>  	uint32_t val;
>  	int vskiplines;
>  
> -	info = drm_format_info(pixel_format);
>  
>  	if (info->is_yuv)
>  		is_yuv = true;
> @@ -819,8 +816,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
>  		    (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
>  
>  	if (is_yuv) {
> -		int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
> -		int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
> +		int hsub = fb->format->hsub;
> +		int vsub = fb->format->vsub;
>  		int bpp = fb->format->cpp[1];
>  
>  		uv_obj = fb->obj[1];
> diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
> index bc8f9afd1b5f..ddf2c764f24c 100644
> --- a/drivers/gpu/drm/tegra/fb.c
> +++ b/drivers/gpu/drm/tegra/fb.c
> @@ -132,18 +132,15 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
>  					const struct drm_mode_fb_cmd2 *cmd)
>  {
>  	const struct drm_format_info *info = drm_get_format_info(dev, cmd);
> -	unsigned int hsub, vsub, i;
>  	struct tegra_bo *planes[4];
>  	struct drm_gem_object *gem;
>  	struct drm_framebuffer *fb;
> +	unsigned int i;
>  	int err;
>  
> -	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
> -	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
> -
>  	for (i = 0; i < info->num_planes; i++) {
> -		unsigned int width = cmd->width / (i ? hsub : 1);
> -		unsigned int height = cmd->height / (i ? vsub : 1);
> +		unsigned int width = cmd->width / (i ? info->hsub : 1);
> +		unsigned int height = cmd->height / (i ? info->vsub : 1);
>  		unsigned int size, bpp;
>  
>  		gem = drm_gem_object_lookup(file, cmd->handles[i]);
> diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
> index 138a9ff23b70..6605c1b7370d 100644
> --- a/drivers/gpu/drm/vc4/vc4_plane.c
> +++ b/drivers/gpu/drm/vc4/vc4_plane.c
> @@ -310,10 +310,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
>  	struct drm_framebuffer *fb = state->fb;
>  	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
>  	u32 subpixel_src_mask = (1 << 16) - 1;
> -	u32 format = fb->format->format;
>  	int num_planes = fb->format->num_planes;
>  	struct drm_crtc_state *crtc_state;
> -	u32 h_subsample, v_subsample;
> +	u32 h_subsample = fb->format->hsub;
> +	u32 v_subsample = fb->format->vsub;
>  	int i, ret;
>  
>  	crtc_state = drm_atomic_get_existing_crtc_state(state->state,
> @@ -328,9 +328,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
>  	if (ret)
>  		return ret;
>  
> -	h_subsample = drm_format_horz_chroma_subsampling(format);
> -	v_subsample = drm_format_vert_chroma_subsampling(format);
> -
>  	for (i = 0; i < num_planes; i++)
>  		vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
>  
> @@ -538,7 +535,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>  	const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
>  	u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
>  	int num_planes = fb->format->num_planes;
> -	u32 h_subsample, v_subsample;
> +	u32 h_subsample = fb->format->hsub;
> +	u32 v_subsample = fb->format->vsub;
>  	bool mix_plane_alpha;
>  	bool covers_screen;
>  	u32 scl0, scl1, pitch0;
> @@ -568,9 +566,6 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
>  		scl1 = vc4_get_scl_field(state, 0);
>  	}
>  
> -	h_subsample = drm_format_horz_chroma_subsampling(format->drm);
> -	v_subsample = drm_format_vert_chroma_subsampling(format->drm);
> -
>  	rotation = drm_rotation_simplify(state->rotation,
>  					 DRM_MODE_ROTATE_0 |
>  					 DRM_MODE_REFLECT_X |
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 41779b327d91..eeec449d6c6a 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -269,8 +269,6 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
>  uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
>  				     uint32_t bpp, uint32_t depth);
>  int drm_format_plane_cpp(uint32_t format, int plane);
> -int drm_format_horz_chroma_subsampling(uint32_t format);
> -int drm_format_vert_chroma_subsampling(uint32_t format);
>  int drm_format_plane_width(int width, uint32_t format, int plane);
>  int drm_format_plane_height(int height, uint32_t format, int plane);
>  unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
  2019-03-19 21:57   ` Maxime Ripard
  (?)
@ 2019-03-20 14:24   ` Paul Kocialkowski
  2019-03-21 10:13       ` Maxime Ripard
  -1 siblings, 1 reply; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:24 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	dri-devel, linux-kernel, linux-media

Hi,

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> So far, the drm_format_plane_cpp function was operating on the format's
> fourcc and was doing a lookup to retrieve the drm_format_info structure and
> return the cpp.
> 
> However, this is inefficient since in most cases, we will have the
> drm_format_info pointer already available so we shouldn't have to perform a
> new lookup. Some drm_fourcc functions also already operate on the
> drm_format_info pointer for that reason, so the API is quite inconsistent
> there.

Well, it seems that drm_fourcc functions that take a drm_format_info
have a drm_format_info prefix, so having this would be more consistent.

And given what the helper does, I think it would make good sense to
switch it over to an inline drm_format_info_plane_cpp helper.

What do you think?

Cheers,

Paul

> Let's follow the latter pattern and remove the extra lookup while being a
> bit more consistent.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c         | 4 +++-
>  drivers/gpu/drm/arm/malidp_hw.c                | 4 +++-
>  drivers/gpu/drm/cirrus/cirrus_fbdev.c          | 4 +++-
>  drivers/gpu/drm/cirrus/cirrus_main.c           | 4 +++-
>  drivers/gpu/drm/drm_client.c                   | 3 ++-
>  drivers/gpu/drm/drm_fb_helper.c                | 2 +-
>  drivers/gpu/drm/drm_fourcc.c                   | 7 ++-----
>  drivers/gpu/drm/i915/intel_sprite.c            | 3 ++-
>  drivers/gpu/drm/mediatek/mtk_drm_fb.c          | 2 +-
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c      | 3 ++-
>  drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c       | 2 +-
>  drivers/gpu/drm/msm/msm_fb.c                   | 2 +-
>  drivers/gpu/drm/radeon/radeon_fb.c             | 4 +++-
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c     | 2 +-
>  drivers/gpu/drm/stm/ltdc.c                     | 2 +-
>  drivers/gpu/drm/tegra/fb.c                     | 2 +-
>  drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c | 2 +-
>  drivers/gpu/drm/zte/zx_plane.c                 | 2 +-
>  include/drm/drm_fourcc.h                       | 2 +-
>  19 files changed, 33 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> index 5cbde74b97dd..48170a843b48 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c
> @@ -123,6 +123,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>  					 struct drm_mode_fb_cmd2 *mode_cmd,
>  					 struct drm_gem_object **gobj_p)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct amdgpu_device *adev = rfbdev->adev;
>  	struct drm_gem_object *gobj = NULL;
>  	struct amdgpu_bo *abo = NULL;
> @@ -133,7 +135,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev,
>  	int height = mode_cmd->height;
>  	u32 cpp;
>  
> -	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
> +	cpp = drm_format_plane_cpp(info, 0);
>  
>  	/* need to align pitch with crtc limits */
>  	mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
> diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c
> index b9bed1138fa3..07971ad53b29 100644
> --- a/drivers/gpu/drm/arm/malidp_hw.c
> +++ b/drivers/gpu/drm/arm/malidp_hw.c
> @@ -326,12 +326,14 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode *
>  
>  static int malidp500_rotmem_required(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt)
>  {
> +	const struct drm_format_info *info = drm_format_info(fmt);
> +
>  	/*
>  	 * Each layer needs enough rotation memory to fit 8 lines
>  	 * worth of pixel data. Required size is then:
>  	 *    size = rotated_width * (bpp / 8) * 8;
>  	 */
> -	return w * drm_format_plane_cpp(fmt, 0) * 8;
> +	return w * drm_format_plane_cpp(info, 0) * 8;
>  }
>  
>  static void malidp500_se_write_pp_coefftab(struct malidp_hw_device *hwdev,
> diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> index 39df62acac69..759847bafda8 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
> @@ -137,6 +137,8 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
>  			       const struct drm_mode_fb_cmd2 *mode_cmd,
>  			       struct drm_gem_object **gobj_p)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct drm_device *dev = afbdev->helper.dev;
>  	struct cirrus_device *cdev = dev->dev_private;
>  	u32 bpp;
> @@ -144,7 +146,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev,
>  	struct drm_gem_object *gobj;
>  	int ret = 0;
>  
> -	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
> +	bpp = drm_format_plane_cpp(info, 0) * 8;
>  
>  	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
>  				      bpp, mode_cmd->pitches[0]))
> diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
> index 57f8fe6d020b..66d0d2c5211d 100644
> --- a/drivers/gpu/drm/cirrus/cirrus_main.c
> +++ b/drivers/gpu/drm/cirrus/cirrus_main.c
> @@ -41,13 +41,15 @@ cirrus_user_framebuffer_create(struct drm_device *dev,
>  			       struct drm_file *filp,
>  			       const struct drm_mode_fb_cmd2 *mode_cmd)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct cirrus_device *cdev = dev->dev_private;
>  	struct drm_gem_object *obj;
>  	struct drm_framebuffer *fb;
>  	u32 bpp;
>  	int ret;
>  
> -	bpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0) * 8;
> +	bpp = drm_format_plane_cpp(info, 0) * 8;
>  
>  	if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
>  				      bpp, mode_cmd->pitches[0]))
> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> index 9b2bd28dde0a..305d6dd5d201 100644
> --- a/drivers/gpu/drm/drm_client.c
> +++ b/drivers/gpu/drm/drm_client.c
> @@ -242,6 +242,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer)
>  static struct drm_client_buffer *
>  drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
>  {
> +	const struct drm_format_info *info = drm_format_info(format);
>  	struct drm_mode_create_dumb dumb_args = { };
>  	struct drm_device *dev = client->dev;
>  	struct drm_client_buffer *buffer;
> @@ -257,7 +258,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u
>  
>  	dumb_args.width = width;
>  	dumb_args.height = height;
> -	dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
> +	dumb_args.bpp = drm_format_plane_cpp(info, 0) * 8;
>  	ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
>  	if (ret)
>  		goto err_delete;
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 04d23cb430bf..257a9c995057 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -768,7 +768,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper,
>  					  struct drm_clip_rect *clip)
>  {
>  	struct drm_framebuffer *fb = fb_helper->fb;
> -	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
> +	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
>  	size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
>  	void *src = fb_helper->fbdev->screen_buffer + offset;
>  	void *dst = fb_helper->buffer->vaddr + offset;
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index 04be330b7cae..d8ada4cb689e 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -307,17 +307,14 @@ EXPORT_SYMBOL(drm_get_format_info);
>  
>  /**
>   * drm_format_plane_cpp - determine the bytes per pixel value
> - * @format: pixel format (DRM_FORMAT_*)
> + * @format: pixel format info
>   * @plane: plane index
>   *
>   * Returns:
>   * The bytes per pixel value for the specified plane.
>   */
> -int drm_format_plane_cpp(uint32_t format, int plane)
> +int drm_format_plane_cpp(const struct drm_format_info *info, int plane)
>  {
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
>  	if (!info || plane >= info->num_planes)
>  		return 0;
>  
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index b56a1a9ad01d..ee0e99b13532 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -297,7 +297,8 @@ skl_plane_max_stride(struct intel_plane *plane,
>  		     u32 pixel_format, u64 modifier,
>  		     unsigned int rotation)
>  {
> -	int cpp = drm_format_plane_cpp(pixel_format, 0);
> +	const struct drm_format_info *info = drm_format_info(pixel_format);
> +	int cpp = drm_format_plane_cpp(info, 0);
>  
>  	/*
>  	 * "The stride in bytes must not exceed the
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_fb.c b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> index 68fdef8b12bd..af90c84e9e02 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_fb.c
> @@ -104,7 +104,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
>  	if (!gem)
>  		return ERR_PTR(-ENOENT);
>  
> -	bpp = drm_format_plane_cpp(cmd->pixel_format, 0);
> +	bpp = drm_format_plane_cpp(info, 0);
>  	size = (height - 1) * cmd->pitches[0] + width * bpp;
>  	size += cmd->offsets[0];
>  
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> index b0cf63c4e3d7..aadae21f8818 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c
> @@ -782,6 +782,7 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
>  
>  static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
>  {
> +	const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
>  	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
>  	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
>  	struct mdp5_kms *mdp5_kms = get_kms(crtc);
> @@ -800,7 +801,7 @@ static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
>  	width = mdp5_crtc->cursor.width;
>  	height = mdp5_crtc->cursor.height;
>  
> -	stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
> +	stride = width * drm_format_plane_cpp(info, 0);
>  
>  	get_roi(crtc, &roi_w, &roi_h);
>  
> diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> index b30b2f4efc60..03d503d8c3ba 100644
> --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
> @@ -158,7 +158,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
>  	for (i = 0; i < nplanes; i++) {
>  		int n, fetch_stride, cpp;
>  
> -		cpp = drm_format_plane_cpp(fmt, i);
> +		cpp = drm_format_plane_cpp(info, i);
>  		fetch_stride = width * cpp / (i ? hsub : 1);
>  
>  		n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size);
> diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
> index f69c0afd6ec6..ee91058c7974 100644
> --- a/drivers/gpu/drm/msm/msm_fb.c
> +++ b/drivers/gpu/drm/msm/msm_fb.c
> @@ -181,7 +181,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
>  		unsigned int min_size;
>  
>  		min_size = (height - 1) * mode_cmd->pitches[i]
> -			 + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
> +			 + width * drm_format_plane_cpp(info, i)
>  			 + mode_cmd->offsets[i];
>  
>  		if (bos[i]->size < min_size) {
> diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
> index 1179034024ae..88fc1a6e2e43 100644
> --- a/drivers/gpu/drm/radeon/radeon_fb.c
> +++ b/drivers/gpu/drm/radeon/radeon_fb.c
> @@ -125,6 +125,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
>  					 struct drm_mode_fb_cmd2 *mode_cmd,
>  					 struct drm_gem_object **gobj_p)
>  {
> +	const struct drm_format_info *info = drm_get_format_info(dev,
> +								 mode_cmd);
>  	struct radeon_device *rdev = rfbdev->rdev;
>  	struct drm_gem_object *gobj = NULL;
>  	struct radeon_bo *rbo = NULL;
> @@ -135,7 +137,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev,
>  	int height = mode_cmd->height;
>  	u32 cpp;
>  
> -	cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
> +	cpp = drm_format_plane_cpp(info, 0);
>  
>  	/* need to align pitch with crtc limits */
>  	mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, cpp,
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index c318fae28581..c602cb2f4d3c 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -98,7 +98,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
>  
>  		min_size = (height - 1) * mode_cmd->pitches[i] +
>  			mode_cmd->offsets[i] +
> -			width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
> +			width * drm_format_plane_cpp(info, i);
>  
>  		if (obj->size < min_size) {
>  			drm_gem_object_put_unlocked(obj);
> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> index b1741a9d5be2..b226df7dbf6f 100644
> --- a/drivers/gpu/drm/stm/ltdc.c
> +++ b/drivers/gpu/drm/stm/ltdc.c
> @@ -779,7 +779,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane,
>  
>  	/* Configures the color frame buffer pitch in bytes & line length */
>  	pitch_in_bytes = fb->pitches[0];
> -	line_length = drm_format_plane_cpp(fb->format->format, 0) *
> +	line_length = drm_format_plane_cpp(fb->format, 0) *
>  		      (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
>  	val = ((pitch_in_bytes << 16) | line_length);
>  	reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
> diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c
> index ddf2c764f24c..0a97458b286a 100644
> --- a/drivers/gpu/drm/tegra/fb.c
> +++ b/drivers/gpu/drm/tegra/fb.c
> @@ -149,7 +149,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
>  			goto unreference;
>  		}
>  
> -		bpp = drm_format_plane_cpp(cmd->pixel_format, i);
> +		bpp = drm_format_plane_cpp(info, i);
>  
>  		size = (height - 1) * cmd->pitches[i] +
>  		       width * bpp + cmd->offsets[i];
> diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
> index 2737b6fdadc8..57dda9d1a45d 100644
> --- a/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
> +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
> @@ -36,7 +36,7 @@ MODULE_PARM_DESC(spi_max, "Set a lower SPI max transfer size");
>  void tinydrm_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
>  		    struct drm_rect *clip)
>  {
> -	unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
> +	unsigned int cpp = drm_format_plane_cpp(fb->format, 0);
>  	unsigned int pitch = fb->pitches[0];
>  	void *src = vaddr + (clip->y1 * pitch) + (clip->x1 * cpp);
>  	size_t len = (clip->x2 - clip->x1) * cpp;
> diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
> index c6a8be444300..41bd0db4e876 100644
> --- a/drivers/gpu/drm/zte/zx_plane.c
> +++ b/drivers/gpu/drm/zte/zx_plane.c
> @@ -222,7 +222,7 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane,
>  		cma_obj = drm_fb_cma_get_gem_obj(fb, i);
>  		paddr = cma_obj->paddr + fb->offsets[i];
>  		paddr += src_y * fb->pitches[i];
> -		paddr += src_x * drm_format_plane_cpp(format, i);
> +		paddr += src_x * drm_format_plane_cpp(fb->format, i);
>  		zx_writel(paddr_reg, paddr);
>  		paddr_reg += 4;
>  	}
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index eeec449d6c6a..97a58f3e7462 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -268,7 +268,7 @@ drm_get_format_info(struct drm_device *dev,
>  uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
>  uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
>  				     uint32_t bpp, uint32_t depth);
> -int drm_format_plane_cpp(uint32_t format, int plane);
> +int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
>  int drm_format_plane_width(int width, uint32_t format, int plane);
>  int drm_format_plane_height(int height, uint32_t format, int plane);
>  unsigned int drm_format_info_block_width(const struct drm_format_info *info,
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height
  2019-03-19 21:57 ` [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height Maxime Ripard
@ 2019-03-20 14:26   ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:26 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	dri-devel, linux-kernel, linux-media

Hi,

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> So far, the drm_format_plane_height/width functions were operating on the
> format's fourcc and was doing a lookup to retrieve the drm_format_info
> structure and return the cpp.
> 
> However, this is inefficient since in most cases, we will have the
> drm_format_info pointer already available so we shouldn't have to perform a
> new lookup. Some drm_fourcc functions also already operate on the
> drm_format_info pointer for that reason, so the API is quite inconsistent
> there.

Same comment as for the previous patch, I think having a
drm_format_info prefix and switching to an inline helper would make
good sense.

Cheers,

Paul

> Let's follow the latter pattern and remove the extra lookup while being a
> bit more consistent.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  drivers/gpu/drm/drm_fourcc.c          | 16 ++++++----------
>  drivers/gpu/drm/meson/meson_overlay.c |  6 +++---
>  include/drm/drm_fourcc.h              |  6 ++++--
>  3 files changed, 13 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index d8ada4cb689e..57389b9753b2 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -325,17 +325,15 @@ EXPORT_SYMBOL(drm_format_plane_cpp);
>  /**
>   * drm_format_plane_width - width of the plane given the first plane
>   * @width: width of the first plane
> - * @format: pixel format
> + * @format: pixel format info
>   * @plane: plane index
>   *
>   * Returns:
>   * The width of @plane, given that the width of the first plane is @width.
>   */
> -int drm_format_plane_width(int width, uint32_t format, int plane)
> +int drm_format_plane_width(int width, const struct drm_format_info *info,
> +			   int plane)
>  {
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
>  	if (!info || plane >= info->num_planes)
>  		return 0;
>  
> @@ -349,17 +347,15 @@ EXPORT_SYMBOL(drm_format_plane_width);
>  /**
>   * drm_format_plane_height - height of the plane given the first plane
>   * @height: height of the first plane
> - * @format: pixel format
> + * @format: pixel format info
>   * @plane: plane index
>   *
>   * Returns:
>   * The height of @plane, given that the height of the first plane is @height.
>   */
> -int drm_format_plane_height(int height, uint32_t format, int plane)
> +int drm_format_plane_height(int height, const struct drm_format_info *info,
> +			    int plane)
>  {
> -	const struct drm_format_info *info;
> -
> -	info = drm_format_info(format);
>  	if (!info || plane >= info->num_planes)
>  		return 0;
>  
> diff --git a/drivers/gpu/drm/meson/meson_overlay.c b/drivers/gpu/drm/meson/meson_overlay.c
> index 8ff15d01a8f9..6987c15b6ab9 100644
> --- a/drivers/gpu/drm/meson/meson_overlay.c
> +++ b/drivers/gpu/drm/meson/meson_overlay.c
> @@ -475,7 +475,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
>  		priv->viu.vd1_stride2 = fb->pitches[2];
>  		priv->viu.vd1_height2 =
>  			drm_format_plane_height(fb->height,
> -						fb->format->format, 2);
> +						fb->format, 2);
>  		DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n",
>  			 priv->viu.vd1_addr2,
>  			 priv->viu.vd1_stride2,
> @@ -487,7 +487,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
>  		priv->viu.vd1_stride1 = fb->pitches[1];
>  		priv->viu.vd1_height1 =
>  			drm_format_plane_height(fb->height,
> -						fb->format->format, 1);
> +						fb->format, 1);
>  		DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n",
>  			 priv->viu.vd1_addr1,
>  			 priv->viu.vd1_stride1,
> @@ -499,7 +499,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane,
>  		priv->viu.vd1_stride0 = fb->pitches[0];
>  		priv->viu.vd1_height0 =
>  			drm_format_plane_height(fb->height,
> -						fb->format->format, 0);
> +						fb->format, 0);
>  		DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n",
>  			 priv->viu.vd1_addr0,
>  			 priv->viu.vd1_stride0,
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 97a58f3e7462..2291f2618211 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -269,8 +269,10 @@ uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
>  uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
>  				     uint32_t bpp, uint32_t depth);
>  int drm_format_plane_cpp(const struct drm_format_info *info, int plane);
> -int drm_format_plane_width(int width, uint32_t format, int plane);
> -int drm_format_plane_height(int height, uint32_t format, int plane);
> +int drm_format_plane_width(int width, const struct drm_format_info *info,
> +			   int plane);
> +int drm_format_plane_height(int height, const struct drm_format_info *info,
> +			    int plane);
>  unsigned int drm_format_info_block_width(const struct drm_format_info *info,
>  					 int plane);
>  unsigned int drm_format_info_block_height(const struct drm_format_info *info,
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 23:29   ` Nicolas Dufresne
@ 2019-03-20 14:27     ` Ville Syrjälä
  2019-03-20 15:51       ` Nicolas Dufresne
  2019-03-20 18:15     ` Brian Starkey
  1 sibling, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-20 14:27 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media

On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > For now, let's add the v4l2 fourcc's for the already existing formats.
> > 
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  include/linux/image-formats.h |  9 +++++-
> >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 76 insertions(+)
> > 
> > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > index 53fd73a71b3d..fbc3a4501ebd 100644
> > --- a/include/linux/image-formats.h
> > +++ b/include/linux/image-formats.h
> > @@ -26,6 +26,13 @@ struct image_format_info {
> >  	};
> >  
> >  	/**
> > +	 * @v4l2_fmt:
> > +	 *
> > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > +	 */
> > +	u32 v4l2_fmt;
> > +
> > +	/**
> >  	 * @depth:
> >  	 *
> >  	 * Color depth (number of bits per pixel excluding padding bits),
> > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> >  
> >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> >  				    int plane);
> >  unsigned int image_format_plane_width(int width,
> > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > index 9b9a73220c5d..39f1d38ae861 100644
> > --- a/lib/image-formats.c
> > +++ b/lib/image-formats.c
> > @@ -8,6 +8,7 @@
> >  static const struct image_format_info formats[] = {
> >  	{
> >  		.drm_fmt = DRM_FORMAT_C8,
> > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> >  		.depth = 8,
> >  		.num_planes = 1,
> >  		.cpp = { 1, 0, 0 },
> > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_RGB332,
> > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> >  		.depth = 8,
> >  		.num_planes = 1,
> >  		.cpp = { 1, 0, 0 },
> > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> >  		.has_alpha = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> >  		.depth = 15,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> >  		.depth = 15,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> >  		.has_alpha = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_RGB565,
> > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> >  		.depth = 16,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_RGB888,
> > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> >  		.depth = 24,
> >  		.num_planes = 1,
> >  		.cpp = { 3, 0, 0 },
> > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_BGR888,
> > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> >  		.depth = 24,
> >  		.num_planes = 1,
> >  		.cpp = { 3, 0, 0 },
> > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> >  		.vsub = 1,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> 
> 
> All RGB mapping should be surrounded by ifdef, because many (not all)
> DRM formats represent the order of component when placed in a CPU
> register, unlike V4L2 which uses memory order. I've pick this one

DRM formats are explicitly defined as little endian.

> randomly, but this one on most system, little endian, will match
> V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> multiple places, notably in GStreamer:
> 
> https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> 
> >  		.depth = 24,
> >  		.num_planes = 1,
> >  		.cpp = { 4, 0, 0 },
> > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> >  		.has_alpha = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> >  		.depth = 32,
> >  		.num_planes = 1,
> >  		.cpp = { 4, 0, 0 },
> > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> >  		.has_alpha = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YUV410,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YVU410,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YUV420,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YVU420,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YUV422,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YVU422,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YUV444,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YVU444,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> >  		.depth = 0,
> >  		.num_planes = 3,
> >  		.cpp = { 1, 1, 1 },
> > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV12,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV21,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV16,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV61,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV24,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_NV42,
> > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> >  		.depth = 0,
> >  		.num_planes = 2,
> >  		.cpp = { 1, 2, 0 },
> > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YUYV,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_YVYU,
> > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_UYVY,
> > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> >  		.is_yuv = true,
> >  	}, {
> >  		.drm_fmt = DRM_FORMAT_VYUY,
> > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> >  		.depth = 0,
> >  		.num_planes = 1,
> >  		.cpp = { 2, 0, 0 },
> > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> >  EXPORT_SYMBOL(image_format_drm_lookup);
> >  
> >  /**
> > + * __image_format_v4l2_lookup - query information for a given format
> > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > +{
> > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > +}
> > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > +
> > +/**
> > + * image_format_v4l2_lookup - query information for a given format
> > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + * Unsupported pixel formats will generate a warning in the kernel log.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > +{
> > +	const struct image_format_info *format;
> > +
> > +	format = __image_format_v4l2_lookup(v4l2);
> > +
> > +	WARN_ON(!format);
> > +	return format;
> > +}
> > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > +
> > +/**
> >   * image_format_plane_cpp - determine the bytes per pixel value
> >   * @format: pointer to the image_format
> >   * @plane: plane index
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info
  2019-03-19 21:57 ` [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info Maxime Ripard
@ 2019-03-20 14:27   ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-20 14:27 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	dri-devel, linux-kernel, linux-media

Hi,

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> drm_get_format_info directly calls into drm_format_info, but takes directly
> a struct drm_mode_fb_cmd2 pointer, instead of the fourcc directly. It's
> shorter to not dereference it, and we can customise the behaviour at the
> driver level if we want to, so let's switch to it where it makes sense.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>

Makes good sense to me!

Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>

Cheers,

Paul

> ---
>  drivers/gpu/drm/gma500/framebuffer.c | 2 +-
>  drivers/gpu/drm/omapdrm/omap_fb.c    | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
> index c934b3df1f81..46f0078f7a91 100644
> --- a/drivers/gpu/drm/gma500/framebuffer.c
> +++ b/drivers/gpu/drm/gma500/framebuffer.c
> @@ -232,7 +232,7 @@ static int psb_framebuffer_init(struct drm_device *dev,
>  	 * Reject unknown formats, YUV formats, and formats with more than
>  	 * 4 bytes per pixel.
>  	 */
> -	info = drm_format_info(mode_cmd->pixel_format);
> +	info = drm_get_format_info(dev, mode_cmd);
>  	if (!info || !info->depth || info->cpp[0] > 4)
>  		return -EINVAL;
>  
> diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
> index cfb641363a32..6557b2d6e16e 100644
> --- a/drivers/gpu/drm/omapdrm/omap_fb.c
> +++ b/drivers/gpu/drm/omapdrm/omap_fb.c
> @@ -339,7 +339,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev,
>  			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
>  			(char *)&mode_cmd->pixel_format);
>  
> -	format = drm_format_info(mode_cmd->pixel_format);
> +	format = drm_get_format_info(dev, mode_cmd);
>  
>  	for (i = 0; i < ARRAY_SIZE(formats); i++) {
>  		if (formats[i] == mode_cmd->pixel_format)
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 14:27     ` Ville Syrjälä
@ 2019-03-20 15:51       ` Nicolas Dufresne
  2019-03-20 16:09         ` Ville Syrjälä
  0 siblings, 1 reply; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-20 15:51 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media

[-- Attachment #1: Type: text/plain, Size: 12812 bytes --]

Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > 
> > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > ---
> > >  include/linux/image-formats.h |  9 +++++-
> > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > >  2 files changed, 76 insertions(+)
> > > 
> > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > --- a/include/linux/image-formats.h
> > > +++ b/include/linux/image-formats.h
> > > @@ -26,6 +26,13 @@ struct image_format_info {
> > >  	};
> > >  
> > >  	/**
> > > +	 * @v4l2_fmt:
> > > +	 *
> > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > +	 */
> > > +	u32 v4l2_fmt;
> > > +
> > > +	/**
> > >  	 * @depth:
> > >  	 *
> > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > >  
> > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > >  				    int plane);
> > >  unsigned int image_format_plane_width(int width,
> > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > index 9b9a73220c5d..39f1d38ae861 100644
> > > --- a/lib/image-formats.c
> > > +++ b/lib/image-formats.c
> > > @@ -8,6 +8,7 @@
> > >  static const struct image_format_info formats[] = {
> > >  	{
> > >  		.drm_fmt = DRM_FORMAT_C8,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > >  		.depth = 8,
> > >  		.num_planes = 1,
> > >  		.cpp = { 1, 0, 0 },
> > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > >  		.depth = 8,
> > >  		.num_planes = 1,
> > >  		.cpp = { 1, 0, 0 },
> > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > >  		.has_alpha = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > >  		.depth = 15,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > >  		.depth = 15,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > >  		.has_alpha = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > >  		.depth = 16,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > >  		.depth = 24,
> > >  		.num_planes = 1,
> > >  		.cpp = { 3, 0, 0 },
> > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > >  		.depth = 24,
> > >  		.num_planes = 1,
> > >  		.cpp = { 3, 0, 0 },
> > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > >  		.vsub = 1,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > 
> > All RGB mapping should be surrounded by ifdef, because many (not all)
> > DRM formats represent the order of component when placed in a CPU
> > register, unlike V4L2 which uses memory order. I've pick this one
> 
> DRM formats are explicitly defined as little endian.

Yes, that means the same thing. The mapping has nothing to do with the
buffer bytes order, unlike V4L2 (and most streaming stack) do. Though
the mapping in DRM isn't consistent. Again, this mapping is not
correct, it will result in swapped colors.

> 
> > randomly, but this one on most system, little endian, will match
> > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > multiple places, notably in GStreamer:
> > 
> > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > 
> > >  		.depth = 24,
> > >  		.num_planes = 1,
> > >  		.cpp = { 4, 0, 0 },
> > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > >  		.has_alpha = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > >  		.depth = 32,
> > >  		.num_planes = 1,
> > >  		.cpp = { 4, 0, 0 },
> > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > >  		.has_alpha = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > >  		.depth = 0,
> > >  		.num_planes = 3,
> > >  		.cpp = { 1, 1, 1 },
> > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > >  		.depth = 0,
> > >  		.num_planes = 2,
> > >  		.cpp = { 1, 2, 0 },
> > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > >  		.is_yuv = true,
> > >  	}, {
> > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > >  		.depth = 0,
> > >  		.num_planes = 1,
> > >  		.cpp = { 2, 0, 0 },
> > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > >  
> > >  /**
> > > + * __image_format_v4l2_lookup - query information for a given format
> > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > +{
> > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > +}
> > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > +
> > > +/**
> > > + * image_format_v4l2_lookup - query information for a given format
> > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > +{
> > > +	const struct image_format_info *format;
> > > +
> > > +	format = __image_format_v4l2_lookup(v4l2);
> > > +
> > > +	WARN_ON(!format);
> > > +	return format;
> > > +}
> > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > +
> > > +/**
> > >   * image_format_plane_cpp - determine the bytes per pixel value
> > >   * @format: pointer to the image_format
> > >   * @plane: plane index
> > 
> > _______________________________________________
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 15:51       ` Nicolas Dufresne
@ 2019-03-20 16:09         ` Ville Syrjälä
  2019-03-20 16:30           ` Nicolas Dufresne
  0 siblings, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-20 16:09 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Thomas Petazzoni, Maxime Ripard, linux-kernel, dri-devel,
	Paul Kocialkowski, David Airlie, Hans Verkuil, Sean Paul,
	Laurent Pinchart, Sakari Ailus, Daniel Vetter,
	Mauro Carvalho Chehab, linux-media

On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > 
> > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > ---
> > > >  include/linux/image-formats.h |  9 +++++-
> > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > >  2 files changed, 76 insertions(+)
> > > > 
> > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > --- a/include/linux/image-formats.h
> > > > +++ b/include/linux/image-formats.h
> > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > >  	};
> > > >  
> > > >  	/**
> > > > +	 * @v4l2_fmt:
> > > > +	 *
> > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > +	 */
> > > > +	u32 v4l2_fmt;
> > > > +
> > > > +	/**
> > > >  	 * @depth:
> > > >  	 *
> > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > >  
> > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > >  				    int plane);
> > > >  unsigned int image_format_plane_width(int width,
> > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > --- a/lib/image-formats.c
> > > > +++ b/lib/image-formats.c
> > > > @@ -8,6 +8,7 @@
> > > >  static const struct image_format_info formats[] = {
> > > >  	{
> > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > >  		.depth = 8,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 1, 0, 0 },
> > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > >  		.depth = 8,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 1, 0, 0 },
> > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > >  		.has_alpha = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > >  		.depth = 15,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > >  		.depth = 15,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > >  		.has_alpha = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > >  		.depth = 16,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > >  		.depth = 24,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 3, 0, 0 },
> > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > >  		.depth = 24,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 3, 0, 0 },
> > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > >  		.vsub = 1,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > 
> > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > DRM formats represent the order of component when placed in a CPU
> > > register, unlike V4L2 which uses memory order. I've pick this one
> > 
> > DRM formats are explicitly defined as little endian.
> 
> Yes, that means the same thing. The mapping has nothing to do with the
> buffer bytes order, unlike V4L2 (and most streaming stack) do.

It has everything to do with byte order. Little endian means the least
significant byte is stored in the first byte in memory.

Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.

> 
> > 
> > > randomly, but this one on most system, little endian, will match
> > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > multiple places, notably in GStreamer:
> > > 
> > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > 
> > > >  		.depth = 24,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 4, 0, 0 },
> > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > >  		.has_alpha = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > >  		.depth = 32,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 4, 0, 0 },
> > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > >  		.has_alpha = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > >  		.depth = 0,
> > > >  		.num_planes = 3,
> > > >  		.cpp = { 1, 1, 1 },
> > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > >  		.depth = 0,
> > > >  		.num_planes = 2,
> > > >  		.cpp = { 1, 2, 0 },
> > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > >  		.is_yuv = true,
> > > >  	}, {
> > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > >  		.depth = 0,
> > > >  		.num_planes = 1,
> > > >  		.cpp = { 2, 0, 0 },
> > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > >  
> > > >  /**
> > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > + *
> > > > + * The caller should only pass a supported pixel format to this function.
> > > > + *
> > > > + * Returns:
> > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > + * NULL if the format is unsupported.
> > > > + */
> > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > +{
> > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > +}
> > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > +
> > > > +/**
> > > > + * image_format_v4l2_lookup - query information for a given format
> > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > + *
> > > > + * The caller should only pass a supported pixel format to this function.
> > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > + *
> > > > + * Returns:
> > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > + * NULL if the format is unsupported.
> > > > + */
> > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > +{
> > > > +	const struct image_format_info *format;
> > > > +
> > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > +
> > > > +	WARN_ON(!format);
> > > > +	return format;
> > > > +}
> > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > +
> > > > +/**
> > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > >   * @format: pointer to the image_format
> > > >   * @plane: plane index
> > > 
> > > _______________________________________________
> > > dri-devel mailing list
> > > dri-devel@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 16:09         ` Ville Syrjälä
@ 2019-03-20 16:30           ` Nicolas Dufresne
  2019-03-20 16:41             ` Ville Syrjälä
  0 siblings, 1 reply; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-20 16:30 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 15167 bytes --]

Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > 
> > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > ---
> > > > >  include/linux/image-formats.h |  9 +++++-
> > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > >  2 files changed, 76 insertions(+)
> > > > > 
> > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > --- a/include/linux/image-formats.h
> > > > > +++ b/include/linux/image-formats.h
> > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > >  	};
> > > > >  
> > > > >  	/**
> > > > > +	 * @v4l2_fmt:
> > > > > +	 *
> > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > +	 */
> > > > > +	u32 v4l2_fmt;
> > > > > +
> > > > > +	/**
> > > > >  	 * @depth:
> > > > >  	 *
> > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > >  
> > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > >  				    int plane);
> > > > >  unsigned int image_format_plane_width(int width,
> > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > --- a/lib/image-formats.c
> > > > > +++ b/lib/image-formats.c
> > > > > @@ -8,6 +8,7 @@
> > > > >  static const struct image_format_info formats[] = {
> > > > >  	{
> > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > >  		.depth = 8,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 1, 0, 0 },
> > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > >  		.depth = 8,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 1, 0, 0 },
> > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.has_alpha = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > >  		.depth = 15,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > >  		.depth = 15,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.has_alpha = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > >  		.depth = 16,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > >  		.depth = 24,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 3, 0, 0 },
> > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > >  		.depth = 24,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 3, 0, 0 },
> > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.vsub = 1,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > 
> > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > DRM formats represent the order of component when placed in a CPU
> > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > 
> > > DRM formats are explicitly defined as little endian.
> > 
> > Yes, that means the same thing. The mapping has nothing to do with the
> > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> 
> It has everything to do with byte order. Little endian means the least
> significant byte is stored in the first byte in memory.
> 
> Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.

That's basically what I said, as it's define for Little Endian rather
then buffer order, you have to make the mapping conditional. It
basically mean that in memory, the DRM format physically differ
depending on CPU endian. Last time we have run this on PPC / Big
Endian, the mapping was XRGB/XRGB, we checked that up multiple time
with the DRM maintainers and was told this is exactly what it's suppose
to do, hence this endian dependant mapping all over the place. If you
make up that this isn't right, you are breaking userspace, and people
don't like that.

So the mapping should be:
Little: DRM XRGB / V4L2 XBGR
Big:    DRM XRGB / V4L2 XRGB

> 
> > > > randomly, but this one on most system, little endian, will match
> > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > multiple places, notably in GStreamer:
> > > > 
> > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > 
> > > > >  		.depth = 24,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 4, 0, 0 },
> > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.has_alpha = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > >  		.depth = 32,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 4, 0, 0 },
> > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.has_alpha = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 3,
> > > > >  		.cpp = { 1, 1, 1 },
> > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 2,
> > > > >  		.cpp = { 1, 2, 0 },
> > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > >  		.is_yuv = true,
> > > > >  	}, {
> > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > >  		.depth = 0,
> > > > >  		.num_planes = 1,
> > > > >  		.cpp = { 2, 0, 0 },
> > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > >  
> > > > >  /**
> > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > + *
> > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > + *
> > > > > + * Returns:
> > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > + * NULL if the format is unsupported.
> > > > > + */
> > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > +{
> > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > +}
> > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > +
> > > > > +/**
> > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > + *
> > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > + *
> > > > > + * Returns:
> > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > + * NULL if the format is unsupported.
> > > > > + */
> > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > +{
> > > > > +	const struct image_format_info *format;
> > > > > +
> > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > +
> > > > > +	WARN_ON(!format);
> > > > > +	return format;
> > > > > +}
> > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > +
> > > > > +/**
> > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > >   * @format: pointer to the image_format
> > > > >   * @plane: plane index
> > > > 
> > > > _______________________________________________
> > > > dri-devel mailing list
> > > > dri-devel@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 16:30           ` Nicolas Dufresne
@ 2019-03-20 16:41             ` Ville Syrjälä
  2019-03-20 18:27               ` Nicolas Dufresne
  0 siblings, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-20 16:41 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Thomas Petazzoni, Maxime Ripard, linux-kernel, dri-devel,
	Paul Kocialkowski, David Airlie, Hans Verkuil, Sean Paul,
	Laurent Pinchart, Sakari Ailus, Daniel Vetter, Daniel Stone,
	Mauro Carvalho Chehab, linux-media

On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > 
> > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > ---
> > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > >  2 files changed, 76 insertions(+)
> > > > > > 
> > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > --- a/include/linux/image-formats.h
> > > > > > +++ b/include/linux/image-formats.h
> > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > >  	};
> > > > > >  
> > > > > >  	/**
> > > > > > +	 * @v4l2_fmt:
> > > > > > +	 *
> > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > +	 */
> > > > > > +	u32 v4l2_fmt;
> > > > > > +
> > > > > > +	/**
> > > > > >  	 * @depth:
> > > > > >  	 *
> > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > >  
> > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > >  				    int plane);
> > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > --- a/lib/image-formats.c
> > > > > > +++ b/lib/image-formats.c
> > > > > > @@ -8,6 +8,7 @@
> > > > > >  static const struct image_format_info formats[] = {
> > > > > >  	{
> > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > >  		.depth = 8,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > >  		.depth = 8,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.has_alpha = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > >  		.depth = 15,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > >  		.depth = 15,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.has_alpha = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > >  		.depth = 16,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > >  		.depth = 24,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > >  		.depth = 24,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.vsub = 1,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > 
> > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > DRM formats represent the order of component when placed in a CPU
> > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > 
> > > > DRM formats are explicitly defined as little endian.
> > > 
> > > Yes, that means the same thing. The mapping has nothing to do with the
> > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > 
> > It has everything to do with byte order. Little endian means the least
> > significant byte is stored in the first byte in memory.
> > 
> > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> 
> That's basically what I said, as it's define for Little Endian rather
> then buffer order, you have to make the mapping conditional. It
> basically mean that in memory, the DRM format physically differ
> depending on CPU endian.

No. It is always little endian no matter what the CPU is.

> Last time we have run this on PPC / Big
> Endian, the mapping was XRGB/XRGB, we checked that up multiple time
> with the DRM maintainers and was told this is exactly what it's suppose
> to do, hence this endian dependant mapping all over the place. If you
> make up that this isn't right, you are breaking userspace, and people
> don't like that.

Someone recently added those DRM_FORMAT_HOST variants to allow
the legacy addfb1 to create pick the format based on host
endianness. I thought that was the only conclusion from the
little vs. big endian drm fourcc wars.

> 
> So the mapping should be:
> Little: DRM XRGB / V4L2 XBGR
> Big:    DRM XRGB / V4L2 XRGB
> 
> > 
> > > > > randomly, but this one on most system, little endian, will match
> > > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > > multiple places, notably in GStreamer:
> > > > > 
> > > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > > 
> > > > > >  		.depth = 24,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.has_alpha = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > > >  		.depth = 32,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.has_alpha = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 3,
> > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 2,
> > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > > >  		.is_yuv = true,
> > > > > >  	}, {
> > > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > > >  		.depth = 0,
> > > > > >  		.num_planes = 1,
> > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > > >  
> > > > > >  /**
> > > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > + *
> > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > + *
> > > > > > + * Returns:
> > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > + * NULL if the format is unsupported.
> > > > > > + */
> > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > > +{
> > > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > > +
> > > > > > +/**
> > > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > + *
> > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > > + *
> > > > > > + * Returns:
> > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > + * NULL if the format is unsupported.
> > > > > > + */
> > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > > +{
> > > > > > +	const struct image_format_info *format;
> > > > > > +
> > > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > > +
> > > > > > +	WARN_ON(!format);
> > > > > > +	return format;
> > > > > > +}
> > > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > > +
> > > > > > +/**
> > > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > > >   * @format: pointer to the image_format
> > > > > >   * @plane: plane index
> > > > > 
> > > > > _______________________________________________
> > > > > dri-devel mailing list
> > > > > dri-devel@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> > 



-- 
Ville Syrjälä
Intel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 23:29   ` Nicolas Dufresne
  2019-03-20 14:27     ` Ville Syrjälä
@ 2019-03-20 18:15     ` Brian Starkey
  2019-03-21 15:47       ` Maxime Ripard
  1 sibling, 1 reply; 69+ messages in thread
From: Brian Starkey @ 2019-03-20 18:15 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, Paul Kocialkowski, dri-devel,
	linux-kernel, linux-media, nd

On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> All RGB mapping should be surrounded by ifdef, because many (not all)
> DRM formats represent the order of component when placed in a CPU
> register, unlike V4L2 which uses memory order. I've pick this one
> randomly, but this one on most system, little endian, will match
> V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> multiple places, notably in GStreamer:
> 
> https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> 

I do sort-of wonder if it's worth trying to switch to common fourccs
between DRM and V4L2 (and whatever else there is).

The V4L2 formats list is quite incomplete and a little quirky in
places (V4L2_PIX_FORMAT_XBGR32 and V4L2_PIX_FORMAT_XRGB32 naming
inconsistency being one. 'X' isn't even next to 'B' in XBGR32).

At least for newly-added formats, not using a common definition
doesn't make a lot of sense to me. Longer term, I also don't really
see any downsides to unification.

-Brian

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 16:41             ` Ville Syrjälä
@ 2019-03-20 18:27               ` Nicolas Dufresne
  2019-03-20 18:39                 ` Ville Syrjälä
  0 siblings, 1 reply; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-20 18:27 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 17364 bytes --]

Le mercredi 20 mars 2019 à 18:41 +0200, Ville Syrjälä a écrit :
> On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > > 
> > > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > > ---
> > > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > > >  2 files changed, 76 insertions(+)
> > > > > > > 
> > > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > > --- a/include/linux/image-formats.h
> > > > > > > +++ b/include/linux/image-formats.h
> > > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > > >  	};
> > > > > > >  
> > > > > > >  	/**
> > > > > > > +	 * @v4l2_fmt:
> > > > > > > +	 *
> > > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > > +	 */
> > > > > > > +	u32 v4l2_fmt;
> > > > > > > +
> > > > > > > +	/**
> > > > > > >  	 * @depth:
> > > > > > >  	 *
> > > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > > >  
> > > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > > >  				    int plane);
> > > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > > --- a/lib/image-formats.c
> > > > > > > +++ b/lib/image-formats.c
> > > > > > > @@ -8,6 +8,7 @@
> > > > > > >  static const struct image_format_info formats[] = {
> > > > > > >  	{
> > > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > > >  		.depth = 8,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > > >  		.depth = 8,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.has_alpha = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > > >  		.depth = 15,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > > >  		.depth = 15,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.has_alpha = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > > >  		.depth = 16,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > > >  		.depth = 24,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > > >  		.depth = 24,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.vsub = 1,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > > 
> > > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > > DRM formats represent the order of component when placed in a CPU
> > > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > > 
> > > > > DRM formats are explicitly defined as little endian.
> > > > 
> > > > Yes, that means the same thing. The mapping has nothing to do with the
> > > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > > 
> > > It has everything to do with byte order. Little endian means the least
> > > significant byte is stored in the first byte in memory.
> > > 
> > > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> > 
> > That's basically what I said, as it's define for Little Endian rather
> > then buffer order, you have to make the mapping conditional. It
> > basically mean that in memory, the DRM format physically differ
> > depending on CPU endian.
> 
> No. It is always little endian no matter what the CPU is.

I'm sorry, this is in your ABI, we don't add layers of ifdef in
userspace code just for the fun of it. If you redefine this now you are
breaking userspace. I agree there is very little to no Big Endian on
DRM side anymore, but what historically was mapped per CPU cannot be
changed by you now.

> 
> > Last time we have run this on PPC / Big
> > Endian, the mapping was XRGB/XRGB, we checked that up multiple time
> > with the DRM maintainers and was told this is exactly what it's suppose
> > to do, hence this endian dependant mapping all over the place. If you
> > make up that this isn't right, you are breaking userspace, and people
> > don't like that.
> 
> Someone recently added those DRM_FORMAT_HOST variants to allow
> the legacy addfb1 to create pick the format based on host
> endianness. I thought that was the only conclusion from the
> little vs. big endian drm fourcc wars.
> 
> > So the mapping should be:
> > Little: DRM XRGB / V4L2 XBGR
> > Big:    DRM XRGB / V4L2 XRGB
> > 
> > > > > > randomly, but this one on most system, little endian, will match
> > > > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > > > multiple places, notably in GStreamer:
> > > > > > 
> > > > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > > > 
> > > > > > >  		.depth = 24,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.has_alpha = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > > > >  		.depth = 32,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.has_alpha = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 3,
> > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 2,
> > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > > > >  		.is_yuv = true,
> > > > > > >  	}, {
> > > > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > > > >  		.depth = 0,
> > > > > > >  		.num_planes = 1,
> > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > > > >  
> > > > > > >  /**
> > > > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > + *
> > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > + *
> > > > > > > + * Returns:
> > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > + * NULL if the format is unsupported.
> > > > > > > + */
> > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > > > +{
> > > > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > > > +}
> > > > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > > > +
> > > > > > > +/**
> > > > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > + *
> > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > > > + *
> > > > > > > + * Returns:
> > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > + * NULL if the format is unsupported.
> > > > > > > + */
> > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > > > +{
> > > > > > > +	const struct image_format_info *format;
> > > > > > > +
> > > > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > > > +
> > > > > > > +	WARN_ON(!format);
> > > > > > > +	return format;
> > > > > > > +}
> > > > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > > > +
> > > > > > > +/**
> > > > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > > > >   * @format: pointer to the image_format
> > > > > > >   * @plane: plane index
> > > > > > 
> > > > > > _______________________________________________
> > > > > > dri-devel mailing list
> > > > > > dri-devel@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 18:27               ` Nicolas Dufresne
@ 2019-03-20 18:39                 ` Ville Syrjälä
  2019-03-21 16:04                     ` Paul Kocialkowski
  0 siblings, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-20 18:39 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media, Daniel Stone

On Wed, Mar 20, 2019 at 02:27:59PM -0400, Nicolas Dufresne wrote:
> Le mercredi 20 mars 2019 à 18:41 +0200, Ville Syrjälä a écrit :
> > On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> > > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > > > 
> > > > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > > > ---
> > > > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > > > >  2 files changed, 76 insertions(+)
> > > > > > > > 
> > > > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > > > --- a/include/linux/image-formats.h
> > > > > > > > +++ b/include/linux/image-formats.h
> > > > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > > > >  	};
> > > > > > > >  
> > > > > > > >  	/**
> > > > > > > > +	 * @v4l2_fmt:
> > > > > > > > +	 *
> > > > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > > > +	 */
> > > > > > > > +	u32 v4l2_fmt;
> > > > > > > > +
> > > > > > > > +	/**
> > > > > > > >  	 * @depth:
> > > > > > > >  	 *
> > > > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > > > >  
> > > > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > > > >  				    int plane);
> > > > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > > > --- a/lib/image-formats.c
> > > > > > > > +++ b/lib/image-formats.c
> > > > > > > > @@ -8,6 +8,7 @@
> > > > > > > >  static const struct image_format_info formats[] = {
> > > > > > > >  	{
> > > > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > > > >  		.depth = 8,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > > > >  		.depth = 8,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.has_alpha = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > > > >  		.depth = 15,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > > > >  		.depth = 15,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.has_alpha = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > > > >  		.depth = 16,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > > > >  		.depth = 24,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > > > >  		.depth = 24,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.vsub = 1,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > > > 
> > > > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > > > DRM formats represent the order of component when placed in a CPU
> > > > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > > > 
> > > > > > DRM formats are explicitly defined as little endian.
> > > > > 
> > > > > Yes, that means the same thing. The mapping has nothing to do with the
> > > > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > > > 
> > > > It has everything to do with byte order. Little endian means the least
> > > > significant byte is stored in the first byte in memory.
> > > > 
> > > > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > > > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> > > 
> > > That's basically what I said, as it's define for Little Endian rather
> > > then buffer order, you have to make the mapping conditional. It
> > > basically mean that in memory, the DRM format physically differ
> > > depending on CPU endian.
> > 
> > No. It is always little endian no matter what the CPU is.
> 
> I'm sorry, this is in your ABI, we don't add layers of ifdef in
> userspace code just for the fun of it. If you redefine this now you are
> breaking userspace. I agree there is very little to no Big Endian on
> DRM side anymore, but what historically was mapped per CPU cannot be
> changed by you now.

It was always little endian.

> 
> > 
> > > Last time we have run this on PPC / Big
> > > Endian, the mapping was XRGB/XRGB, we checked that up multiple time
> > > with the DRM maintainers and was told this is exactly what it's suppose
> > > to do, hence this endian dependant mapping all over the place. If you
> > > make up that this isn't right, you are breaking userspace, and people
> > > don't like that.
> > 
> > Someone recently added those DRM_FORMAT_HOST variants to allow
> > the legacy addfb1 to create pick the format based on host
> > endianness. I thought that was the only conclusion from the
> > little vs. big endian drm fourcc wars.
> > 
> > > So the mapping should be:
> > > Little: DRM XRGB / V4L2 XBGR
> > > Big:    DRM XRGB / V4L2 XRGB
> > > 
> > > > > > > randomly, but this one on most system, little endian, will match
> > > > > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > > > > multiple places, notably in GStreamer:
> > > > > > > 
> > > > > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > > > > 
> > > > > > > >  		.depth = 24,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.has_alpha = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > > > > >  		.depth = 32,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.has_alpha = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 3,
> > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 2,
> > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > > > > >  		.is_yuv = true,
> > > > > > > >  	}, {
> > > > > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > > > > >  		.depth = 0,
> > > > > > > >  		.num_planes = 1,
> > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > > > > >  
> > > > > > > >  /**
> > > > > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > + *
> > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > + *
> > > > > > > > + * Returns:
> > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > + */
> > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > +{
> > > > > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > > > > +}
> > > > > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > > > > +
> > > > > > > > +/**
> > > > > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > + *
> > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > > > > + *
> > > > > > > > + * Returns:
> > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > + */
> > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > +{
> > > > > > > > +	const struct image_format_info *format;
> > > > > > > > +
> > > > > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > > > > +
> > > > > > > > +	WARN_ON(!format);
> > > > > > > > +	return format;
> > > > > > > > +}
> > > > > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > > > > +
> > > > > > > > +/**
> > > > > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > > > > >   * @format: pointer to the image_format
> > > > > > > >   * @plane: plane index
> > > > > > > 
> > > > > > > _______________________________________________
> > > > > > > dri-devel mailing list
> > > > > > > dri-devel@lists.freedesktop.org
> > > > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
> > 



-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/20] lib: Add video format information library
  2019-03-20 13:39   ` Boris Brezillon
@ 2019-03-21  8:20       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-21  8:20 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, linux-kernel, dri-devel,
	Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media

[-- Attachment #1: Type: text/plain, Size: 3518 bytes --]

Hi Boris,

On Wed, Mar 20, 2019 at 02:39:44PM +0100, Boris Brezillon wrote:
> On Tue, 19 Mar 2019 22:57:11 +0100
> Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> > Move the DRM formats API to turn this into a more generic image formats API
> > to be able to leverage it into some other places of the kernel, such as
> > v4l2 drivers.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  include/linux/image-formats.h | 240 +++++++++++-
> >  lib/Kconfig                   |   7 +-
> >  lib/Makefile                  |   3 +-
> >  lib/image-formats-selftests.c | 326 +++++++++++++++-
> >  lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
> >  5 files changed, 1336 insertions(+)
> >  create mode 100644 include/linux/image-formats.h
> >  create mode 100644 lib/image-formats-selftests.c
> >  create mode 100644 lib/image-formats.c
> >
>
> [...]
>
> > --- /dev/null
> > +++ b/lib/image-formats.c
> > @@ -0,0 +1,760 @@
> > +#include <linux/bug.h>
> > +#include <linux/image-formats.h>
> > +#include <linux/kernel.h>
> > +#include <linux/math64.h>
> > +
> > +#include <uapi/drm/drm_fourcc.h>
> > +
> > +static const struct image_format_info formats[] = {
> > +	{
>
> ...
>
> > +	},
> > +};
> > +
> > +#define __image_format_lookup(_field, _fmt)			\
> > +	({							\
> > +		const struct image_format_info *format = NULL;	\
> > +		unsigned i;					\
> > +								\
> > +		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
> > +			if (formats[i]._field == _fmt)		\
> > +				format = &formats[i];		\
> > +								\
> > +		format;						\
> > +	})
> > +
> > +/**
> > + * __image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> > +{
> > +	return __image_format_lookup(drm_fmt, drm);
> > +}
> > +EXPORT_SYMBOL(__image_format_drm_lookup);
> > +
> > +/**
> > + * image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + * Unsupported pixel formats will generate a warning in the kernel log.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *image_format_drm_lookup(u32 drm)
> > +{
> > +	const struct image_format_info *format;
> > +
> > +	format = __image_format_drm_lookup(drm);
> > +
> > +	WARN_ON(!format);
> > +	return format;
> > +}
> > +EXPORT_SYMBOL(image_format_drm_lookup);
>
> I think this function and the DRM formats table should be moved in
> drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
> remaining functions can IMHO be placed in include/linux/image-formats.h
> as static inline funcs. This way you can get rid of lib/image-formats.c
> and the associated Kconfig entry.

I'm not quite sure what you mean. The whole point of the series is to
split out that table out of DRM so that we can use it in other places,
so surely putting it back into DRM defeats the purpose?

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/20] lib: Add video format information library
@ 2019-03-21  8:20       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-21  8:20 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Thomas Petazzoni, David Airlie, linux-kernel, dri-devel,
	Paul Kocialkowski, Hans Verkuil, Sean Paul, Laurent Pinchart,
	Sakari Ailus, Daniel Vetter, Mauro Carvalho Chehab, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 3518 bytes --]

Hi Boris,

On Wed, Mar 20, 2019 at 02:39:44PM +0100, Boris Brezillon wrote:
> On Tue, 19 Mar 2019 22:57:11 +0100
> Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> > Move the DRM formats API to turn this into a more generic image formats API
> > to be able to leverage it into some other places of the kernel, such as
> > v4l2 drivers.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> >  include/linux/image-formats.h | 240 +++++++++++-
> >  lib/Kconfig                   |   7 +-
> >  lib/Makefile                  |   3 +-
> >  lib/image-formats-selftests.c | 326 +++++++++++++++-
> >  lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
> >  5 files changed, 1336 insertions(+)
> >  create mode 100644 include/linux/image-formats.h
> >  create mode 100644 lib/image-formats-selftests.c
> >  create mode 100644 lib/image-formats.c
> >
>
> [...]
>
> > --- /dev/null
> > +++ b/lib/image-formats.c
> > @@ -0,0 +1,760 @@
> > +#include <linux/bug.h>
> > +#include <linux/image-formats.h>
> > +#include <linux/kernel.h>
> > +#include <linux/math64.h>
> > +
> > +#include <uapi/drm/drm_fourcc.h>
> > +
> > +static const struct image_format_info formats[] = {
> > +	{
>
> ...
>
> > +	},
> > +};
> > +
> > +#define __image_format_lookup(_field, _fmt)			\
> > +	({							\
> > +		const struct image_format_info *format = NULL;	\
> > +		unsigned i;					\
> > +								\
> > +		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
> > +			if (formats[i]._field == _fmt)		\
> > +				format = &formats[i];		\
> > +								\
> > +		format;						\
> > +	})
> > +
> > +/**
> > + * __image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> > +{
> > +	return __image_format_lookup(drm_fmt, drm);
> > +}
> > +EXPORT_SYMBOL(__image_format_drm_lookup);
> > +
> > +/**
> > + * image_format_drm_lookup - query information for a given format
> > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > + *
> > + * The caller should only pass a supported pixel format to this function.
> > + * Unsupported pixel formats will generate a warning in the kernel log.
> > + *
> > + * Returns:
> > + * The instance of struct image_format_info that describes the pixel format, or
> > + * NULL if the format is unsupported.
> > + */
> > +const struct image_format_info *image_format_drm_lookup(u32 drm)
> > +{
> > +	const struct image_format_info *format;
> > +
> > +	format = __image_format_drm_lookup(drm);
> > +
> > +	WARN_ON(!format);
> > +	return format;
> > +}
> > +EXPORT_SYMBOL(image_format_drm_lookup);
>
> I think this function and the DRM formats table should be moved in
> drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
> remaining functions can IMHO be placed in include/linux/image-formats.h
> as static inline funcs. This way you can get rid of lib/image-formats.c
> and the associated Kconfig entry.

I'm not quite sure what you mean. The whole point of the series is to
split out that table out of DRM so that we can use it in other places,
so surely putting it back into DRM defeats the purpose?

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 06/20] lib: Add video format information library
  2019-03-21  8:20       ` Maxime Ripard
  (?)
@ 2019-03-21  8:40       ` Boris Brezillon
  -1 siblings, 0 replies; 69+ messages in thread
From: Boris Brezillon @ 2019-03-21  8:40 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, linux-kernel, dri-devel,
	Paul Kocialkowski, Hans Verkuil, Laurent Pinchart,
	Thomas Petazzoni, linux-media

On Thu, 21 Mar 2019 09:20:41 +0100
Maxime Ripard <maxime.ripard@bootlin.com> wrote:

> Hi Boris,
> 
> On Wed, Mar 20, 2019 at 02:39:44PM +0100, Boris Brezillon wrote:
> > On Tue, 19 Mar 2019 22:57:11 +0100
> > Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> >  
> > > Move the DRM formats API to turn this into a more generic image formats API
> > > to be able to leverage it into some other places of the kernel, such as
> > > v4l2 drivers.
> > >
> > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > ---
> > >  include/linux/image-formats.h | 240 +++++++++++-
> > >  lib/Kconfig                   |   7 +-
> > >  lib/Makefile                  |   3 +-
> > >  lib/image-formats-selftests.c | 326 +++++++++++++++-
> > >  lib/image-formats.c           | 760 +++++++++++++++++++++++++++++++++++-
> > >  5 files changed, 1336 insertions(+)
> > >  create mode 100644 include/linux/image-formats.h
> > >  create mode 100644 lib/image-formats-selftests.c
> > >  create mode 100644 lib/image-formats.c
> > >  
> >
> > [...]
> >  
> > > --- /dev/null
> > > +++ b/lib/image-formats.c
> > > @@ -0,0 +1,760 @@
> > > +#include <linux/bug.h>
> > > +#include <linux/image-formats.h>
> > > +#include <linux/kernel.h>
> > > +#include <linux/math64.h>
> > > +
> > > +#include <uapi/drm/drm_fourcc.h>
> > > +
> > > +static const struct image_format_info formats[] = {
> > > +	{  
> >
> > ...
> >  
> > > +	},
> > > +};
> > > +
> > > +#define __image_format_lookup(_field, _fmt)			\
> > > +	({							\
> > > +		const struct image_format_info *format = NULL;	\
> > > +		unsigned i;					\
> > > +								\
> > > +		for (i = 0; i < ARRAY_SIZE(formats); i++)	\
> > > +			if (formats[i]._field == _fmt)		\
> > > +				format = &formats[i];		\
> > > +								\
> > > +		format;						\
> > > +	})
> > > +
> > > +/**
> > > + * __image_format_drm_lookup - query information for a given format
> > > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *__image_format_drm_lookup(u32 drm)
> > > +{
> > > +	return __image_format_lookup(drm_fmt, drm);
> > > +}
> > > +EXPORT_SYMBOL(__image_format_drm_lookup);
> > > +
> > > +/**
> > > + * image_format_drm_lookup - query information for a given format
> > > + * @drm: DRM fourcc pixel format (DRM_FORMAT_*)
> > > + *
> > > + * The caller should only pass a supported pixel format to this function.
> > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > + *
> > > + * Returns:
> > > + * The instance of struct image_format_info that describes the pixel format, or
> > > + * NULL if the format is unsupported.
> > > + */
> > > +const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > +{
> > > +	const struct image_format_info *format;
> > > +
> > > +	format = __image_format_drm_lookup(drm);
> > > +
> > > +	WARN_ON(!format);
> > > +	return format;
> > > +}
> > > +EXPORT_SYMBOL(image_format_drm_lookup);  
> >
> > I think this function and the DRM formats table should be moved in
> > drivers/gpu/drm/drm_image_format.c since they are DRM specific. The
> > remaining functions can IMHO be placed in include/linux/image-formats.h
> > as static inline funcs. This way you can get rid of lib/image-formats.c
> > and the associated Kconfig entry.  
> 
> I'm not quite sure what you mean. The whole point of the series is to
> split out that table out of DRM so that we can use it in other places,
> so surely putting it back into DRM defeats the purpose?

Sorry, I hadn't read the patch series entirely when replying to this
email. I thought you were planning to create one table for DRM formats
and one for V4L ones and then just use the common infra to have a
generic image_format representation, hence my suggestion.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
  2019-03-20 14:24   ` Paul Kocialkowski
@ 2019-03-21 10:13       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-21 10:13 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, dri-devel, linux-kernel,
	linux-media

[-- Attachment #1: Type: text/plain, Size: 1104 bytes --]

On Wed, Mar 20, 2019 at 03:24:26PM +0100, Paul Kocialkowski wrote:
> Hi,
>
> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > So far, the drm_format_plane_cpp function was operating on the format's
> > fourcc and was doing a lookup to retrieve the drm_format_info structure and
> > return the cpp.
> >
> > However, this is inefficient since in most cases, we will have the
> > drm_format_info pointer already available so we shouldn't have to perform a
> > new lookup. Some drm_fourcc functions also already operate on the
> > drm_format_info pointer for that reason, so the API is quite inconsistent
> > there.
>
> Well, it seems that drm_fourcc functions that take a drm_format_info
> have a drm_format_info prefix, so having this would be more consistent.
>
> And given what the helper does, I think it would make good sense to
> switch it over to an inline drm_format_info_plane_cpp helper.
>
> What do you think?

That makes total sense, I'll change it. Thanks!
Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp
@ 2019-03-21 10:13       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-21 10:13 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: Thomas Petazzoni, David Airlie, linux-kernel, dri-devel,
	Hans Verkuil, Sean Paul, Laurent Pinchart, Sakari Ailus,
	Daniel Vetter, Mauro Carvalho Chehab, linux-media


[-- Attachment #1.1: Type: text/plain, Size: 1104 bytes --]

On Wed, Mar 20, 2019 at 03:24:26PM +0100, Paul Kocialkowski wrote:
> Hi,
>
> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > So far, the drm_format_plane_cpp function was operating on the format's
> > fourcc and was doing a lookup to retrieve the drm_format_info structure and
> > return the cpp.
> >
> > However, this is inefficient since in most cases, we will have the
> > drm_format_info pointer already available so we shouldn't have to perform a
> > new lookup. Some drm_fourcc functions also already operate on the
> > drm_format_info pointer for that reason, so the API is quite inconsistent
> > there.
>
> Well, it seems that drm_fourcc functions that take a drm_format_info
> have a drm_format_info prefix, so having this would be more consistent.
>
> And given what the helper does, I think it would make good sense to
> switch it over to an inline drm_format_info_plane_cpp helper.
>
> What do you think?

That makes total sense, I'll change it. Thanks!
Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 159 bytes --]

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 18:15     ` Brian Starkey
@ 2019-03-21 15:47       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-03-21 15:47 UTC (permalink / raw)
  To: Brian Starkey
  Cc: Nicolas Dufresne, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, Paul Kocialkowski, dri-devel,
	linux-kernel, linux-media, nd

[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]

On Wed, Mar 20, 2019 at 06:15:54PM +0000, Brian Starkey wrote:
> On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > All RGB mapping should be surrounded by ifdef, because many (not all)
> > DRM formats represent the order of component when placed in a CPU
> > register, unlike V4L2 which uses memory order. I've pick this one
> > randomly, but this one on most system, little endian, will match
> > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > multiple places, notably in GStreamer:
> >
> > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
>
> I do sort-of wonder if it's worth trying to switch to common fourccs
> between DRM and V4L2 (and whatever else there is).
>
> The V4L2 formats list is quite incomplete and a little quirky in
> places (V4L2_PIX_FORMAT_XBGR32 and V4L2_PIX_FORMAT_XRGB32 naming
> inconsistency being one. 'X' isn't even next to 'B' in XBGR32).
>
> At least for newly-added formats, not using a common definition
> doesn't make a lot of sense to me. Longer term, I also don't really
> see any downsides to unification.

Eventually, I agree that that his where we should be heading. Moving
the existing formats support to a common place will help with that.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-20 18:39                 ` Ville Syrjälä
@ 2019-03-21 16:04                     ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-21 16:04 UTC (permalink / raw)
  To: Ville Syrjälä, Nicolas Dufresne
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	linux-media, Daniel Stone

Hi,

Le mercredi 20 mars 2019 à 20:39 +0200, Ville Syrjälä a écrit :
> On Wed, Mar 20, 2019 at 02:27:59PM -0400, Nicolas Dufresne wrote:
> > Le mercredi 20 mars 2019 à 18:41 +0200, Ville Syrjälä a écrit :
> > > On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> > > > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > > > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > > > > ---
> > > > > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > > > > >  2 files changed, 76 insertions(+)
> > > > > > > > > 
> > > > > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > > > > --- a/include/linux/image-formats.h
> > > > > > > > > +++ b/include/linux/image-formats.h
> > > > > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > > > > >  	};
> > > > > > > > >  
> > > > > > > > >  	/**
> > > > > > > > > +	 * @v4l2_fmt:
> > > > > > > > > +	 *
> > > > > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > > > > +	 */
> > > > > > > > > +	u32 v4l2_fmt;
> > > > > > > > > +
> > > > > > > > > +	/**
> > > > > > > > >  	 * @depth:
> > > > > > > > >  	 *
> > > > > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > > > > >  
> > > > > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > > > > >  				    int plane);
> > > > > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > > > > --- a/lib/image-formats.c
> > > > > > > > > +++ b/lib/image-formats.c
> > > > > > > > > @@ -8,6 +8,7 @@
> > > > > > > > >  static const struct image_format_info formats[] = {
> > > > > > > > >  	{
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > > > > >  		.depth = 8,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > > > > >  		.depth = 8,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > > > > >  		.depth = 15,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > > > > >  		.depth = 15,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > > > > >  		.depth = 16,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > > > > 
> > > > > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > > > > DRM formats represent the order of component when placed in a CPU
> > > > > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > > > > 
> > > > > > > DRM formats are explicitly defined as little endian.
> > > > > > 
> > > > > > Yes, that means the same thing. The mapping has nothing to do with the
> > > > > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > > > > 
> > > > > It has everything to do with byte order. Little endian means the least
> > > > > significant byte is stored in the first byte in memory.
> > > > > 
> > > > > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > > > > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> > > > 
> > > > That's basically what I said, as it's define for Little Endian rather
> > > > then buffer order, you have to make the mapping conditional. It
> > > > basically mean that in memory, the DRM format physically differ
> > > > depending on CPU endian.
> > > 
> > > No. It is always little endian no matter what the CPU is.
> > 
> > I'm sorry, this is in your ABI, we don't add layers of ifdef in
> > userspace code just for the fun of it. If you redefine this now you are
> > breaking userspace. I agree there is very little to no Big Endian on
> > DRM side anymore, but what historically was mapped per CPU cannot be
> > changed by you now.
> 
> It was always little endian.

I'm not sure what it's worth, but there is a "pixel format guide"
project that is all about matching formats from one API to another: 
https://afrantzis.com/pixel-format-guide/ (and it has an associated
tool too).

On the page about DRM, it seems that they got the word that DRM formats
are the native pixel order in little-endian systems:
https://afrantzis.com/pixel-format-guide/drm.html

Perhaps some drivers have been abusing the format definitions, leading
to the inconsistencies that Nicolas could witness?

Cheers,

Paul

> > > > Last time we have run this on PPC / Big
> > > > Endian, the mapping was XRGB/XRGB, we checked that up multiple time
> > > > with the DRM maintainers and was told this is exactly what it's suppose
> > > > to do, hence this endian dependant mapping all over the place. If you
> > > > make up that this isn't right, you are breaking userspace, and people
> > > > don't like that.
> > > 
> > > Someone recently added those DRM_FORMAT_HOST variants to allow
> > > the legacy addfb1 to create pick the format based on host
> > > endianness. I thought that was the only conclusion from the
> > > little vs. big endian drm fourcc wars.
> > > 
> > > > So the mapping should be:
> > > > Little: DRM XRGB / V4L2 XBGR
> > > > Big:    DRM XRGB / V4L2 XRGB
> > > > 
> > > > > > > > randomly, but this one on most system, little endian, will match
> > > > > > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > > > > > multiple places, notably in GStreamer:
> > > > > > > > 
> > > > > > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > > > > > 
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > > > > > >  		.depth = 32,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > > > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > > > > > >  
> > > > > > > > >  /**
> > > > > > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > > + *
> > > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > > + *
> > > > > > > > > + * Returns:
> > > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > > + */
> > > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > > +{
> > > > > > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > > > > > +
> > > > > > > > > +/**
> > > > > > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > > + *
> > > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > > > > > + *
> > > > > > > > > + * Returns:
> > > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > > + */
> > > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > > +{
> > > > > > > > > +	const struct image_format_info *format;
> > > > > > > > > +
> > > > > > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > > > > > +
> > > > > > > > > +	WARN_ON(!format);
> > > > > > > > > +	return format;
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > > > > > +
> > > > > > > > > +/**
> > > > > > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > > > > > >   * @format: pointer to the image_format
> > > > > > > > >   * @plane: plane index
> > > > > > > > 
> > > > > > > > _______________________________________________
> > > > > > > > dri-devel mailing list
> > > > > > > > dri-devel@lists.freedesktop.org
> > > > > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
@ 2019-03-21 16:04                     ` Paul Kocialkowski
  0 siblings, 0 replies; 69+ messages in thread
From: Paul Kocialkowski @ 2019-03-21 16:04 UTC (permalink / raw)
  To: Ville Syrjälä, Nicolas Dufresne
  Cc: Thomas Petazzoni, Maxime Ripard, linux-kernel, dri-devel,
	David Airlie, Hans Verkuil, Sean Paul, Laurent Pinchart,
	Sakari Ailus, Daniel Vetter, Daniel Stone, Mauro Carvalho Chehab,
	linux-media

Hi,

Le mercredi 20 mars 2019 à 20:39 +0200, Ville Syrjälä a écrit :
> On Wed, Mar 20, 2019 at 02:27:59PM -0400, Nicolas Dufresne wrote:
> > Le mercredi 20 mars 2019 à 18:41 +0200, Ville Syrjälä a écrit :
> > > On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> > > > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > > > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > > > > ---
> > > > > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > > > > >  2 files changed, 76 insertions(+)
> > > > > > > > > 
> > > > > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > > > > --- a/include/linux/image-formats.h
> > > > > > > > > +++ b/include/linux/image-formats.h
> > > > > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > > > > >  	};
> > > > > > > > >  
> > > > > > > > >  	/**
> > > > > > > > > +	 * @v4l2_fmt:
> > > > > > > > > +	 *
> > > > > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > > > > +	 */
> > > > > > > > > +	u32 v4l2_fmt;
> > > > > > > > > +
> > > > > > > > > +	/**
> > > > > > > > >  	 * @depth:
> > > > > > > > >  	 *
> > > > > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > > > > >  
> > > > > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > > > > >  				    int plane);
> > > > > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > > > > --- a/lib/image-formats.c
> > > > > > > > > +++ b/lib/image-formats.c
> > > > > > > > > @@ -8,6 +8,7 @@
> > > > > > > > >  static const struct image_format_info formats[] = {
> > > > > > > > >  	{
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > > > > >  		.depth = 8,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > > > > >  		.depth = 8,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > > > > >  		.depth = 15,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > > > > >  		.depth = 15,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > > > > >  		.depth = 16,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.vsub = 1,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > > > > 
> > > > > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > > > > DRM formats represent the order of component when placed in a CPU
> > > > > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > > > > 
> > > > > > > DRM formats are explicitly defined as little endian.
> > > > > > 
> > > > > > Yes, that means the same thing. The mapping has nothing to do with the
> > > > > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > > > > 
> > > > > It has everything to do with byte order. Little endian means the least
> > > > > significant byte is stored in the first byte in memory.
> > > > > 
> > > > > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > > > > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> > > > 
> > > > That's basically what I said, as it's define for Little Endian rather
> > > > then buffer order, you have to make the mapping conditional. It
> > > > basically mean that in memory, the DRM format physically differ
> > > > depending on CPU endian.
> > > 
> > > No. It is always little endian no matter what the CPU is.
> > 
> > I'm sorry, this is in your ABI, we don't add layers of ifdef in
> > userspace code just for the fun of it. If you redefine this now you are
> > breaking userspace. I agree there is very little to no Big Endian on
> > DRM side anymore, but what historically was mapped per CPU cannot be
> > changed by you now.
> 
> It was always little endian.

I'm not sure what it's worth, but there is a "pixel format guide"
project that is all about matching formats from one API to another: 
https://afrantzis.com/pixel-format-guide/ (and it has an associated
tool too).

On the page about DRM, it seems that they got the word that DRM formats
are the native pixel order in little-endian systems:
https://afrantzis.com/pixel-format-guide/drm.html

Perhaps some drivers have been abusing the format definitions, leading
to the inconsistencies that Nicolas could witness?

Cheers,

Paul

> > > > Last time we have run this on PPC / Big
> > > > Endian, the mapping was XRGB/XRGB, we checked that up multiple time
> > > > with the DRM maintainers and was told this is exactly what it's suppose
> > > > to do, hence this endian dependant mapping all over the place. If you
> > > > make up that this isn't right, you are breaking userspace, and people
> > > > don't like that.
> > > 
> > > Someone recently added those DRM_FORMAT_HOST variants to allow
> > > the legacy addfb1 to create pick the format based on host
> > > endianness. I thought that was the only conclusion from the
> > > little vs. big endian drm fourcc wars.
> > > 
> > > > So the mapping should be:
> > > > Little: DRM XRGB / V4L2 XBGR
> > > > Big:    DRM XRGB / V4L2 XRGB
> > > > 
> > > > > > > > randomly, but this one on most system, little endian, will match
> > > > > > > > V4L2_PIX_FMT_XBGR32. This type of complex mapping can be found in
> > > > > > > > multiple places, notably in GStreamer:
> > > > > > > > 
> > > > > > > > https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/sys/kms/gstkmsutils.c#L45
> > > > > > > > 
> > > > > > > > >  		.depth = 24,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > > @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB8888,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> > > > > > > > >  		.depth = 32,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 4, 0, 0 },
> > > > > > > > > @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.has_alpha = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV410,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU410,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV420,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU420,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV422,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU422,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUV444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVU444,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 3,
> > > > > > > > >  		.cpp = { 1, 1, 1 },
> > > > > > > > > @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV12,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV21,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV16,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV61,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV24,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_NV42,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 2,
> > > > > > > > >  		.cpp = { 1, 2, 0 },
> > > > > > > > > @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YUYV,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_YVYU,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_UYVY,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > >  		.is_yuv = true,
> > > > > > > > >  	}, {
> > > > > > > > >  		.drm_fmt = DRM_FORMAT_VYUY,
> > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
> > > > > > > > >  		.depth = 0,
> > > > > > > > >  		.num_planes = 1,
> > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
> > > > > > > > >  EXPORT_SYMBOL(image_format_drm_lookup);
> > > > > > > > >  
> > > > > > > > >  /**
> > > > > > > > > + * __image_format_v4l2_lookup - query information for a given format
> > > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > > + *
> > > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > > + *
> > > > > > > > > + * Returns:
> > > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > > + */
> > > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > > +{
> > > > > > > > > +	return __image_format_lookup(v4l2_fmt, v4l2);
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> > > > > > > > > +
> > > > > > > > > +/**
> > > > > > > > > + * image_format_v4l2_lookup - query information for a given format
> > > > > > > > > + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> > > > > > > > > + *
> > > > > > > > > + * The caller should only pass a supported pixel format to this function.
> > > > > > > > > + * Unsupported pixel formats will generate a warning in the kernel log.
> > > > > > > > > + *
> > > > > > > > > + * Returns:
> > > > > > > > > + * The instance of struct image_format_info that describes the pixel format, or
> > > > > > > > > + * NULL if the format is unsupported.
> > > > > > > > > + */
> > > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> > > > > > > > > +{
> > > > > > > > > +	const struct image_format_info *format;
> > > > > > > > > +
> > > > > > > > > +	format = __image_format_v4l2_lookup(v4l2);
> > > > > > > > > +
> > > > > > > > > +	WARN_ON(!format);
> > > > > > > > > +	return format;
> > > > > > > > > +}
> > > > > > > > > +EXPORT_SYMBOL(image_format_v4l2_lookup);
> > > > > > > > > +
> > > > > > > > > +/**
> > > > > > > > >   * image_format_plane_cpp - determine the bytes per pixel value
> > > > > > > > >   * @format: pointer to the image_format
> > > > > > > > >   * @plane: plane index
> > > > > > > > 
> > > > > > > > _______________________________________________
> > > > > > > > dri-devel mailing list
> > > > > > > > dri-devel@lists.freedesktop.org
> > > > > > > > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
-- 
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-21 16:04                     ` Paul Kocialkowski
  (?)
@ 2019-03-21 16:35                     ` Ville Syrjälä
  2019-03-21 19:14                       ` Nicolas Dufresne
  -1 siblings, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-21 16:35 UTC (permalink / raw)
  To: Paul Kocialkowski
  Cc: Nicolas Dufresne, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

On Thu, Mar 21, 2019 at 05:04:19PM +0100, Paul Kocialkowski wrote:
> Hi,
> 
> Le mercredi 20 mars 2019 à 20:39 +0200, Ville Syrjälä a écrit :
> > On Wed, Mar 20, 2019 at 02:27:59PM -0400, Nicolas Dufresne wrote:
> > > Le mercredi 20 mars 2019 à 18:41 +0200, Ville Syrjälä a écrit :
> > > > On Wed, Mar 20, 2019 at 12:30:25PM -0400, Nicolas Dufresne wrote:
> > > > > Le mercredi 20 mars 2019 à 18:09 +0200, Ville Syrjälä a écrit :
> > > > > > On Wed, Mar 20, 2019 at 11:51:58AM -0400, Nicolas Dufresne wrote:
> > > > > > > Le mercredi 20 mars 2019 à 16:27 +0200, Ville Syrjälä a écrit :
> > > > > > > > On Tue, Mar 19, 2019 at 07:29:18PM -0400, Nicolas Dufresne wrote:
> > > > > > > > > Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > > > > > > > > > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > > > > > > > > > For now, let's add the v4l2 fourcc's for the already existing formats.
> > > > > > > > > > 
> > > > > > > > > > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > > > > > > > > > ---
> > > > > > > > > >  include/linux/image-formats.h |  9 +++++-
> > > > > > > > > >  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
> > > > > > > > > >  2 files changed, 76 insertions(+)
> > > > > > > > > > 
> > > > > > > > > > diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> > > > > > > > > > index 53fd73a71b3d..fbc3a4501ebd 100644
> > > > > > > > > > --- a/include/linux/image-formats.h
> > > > > > > > > > +++ b/include/linux/image-formats.h
> > > > > > > > > > @@ -26,6 +26,13 @@ struct image_format_info {
> > > > > > > > > >  	};
> > > > > > > > > >  
> > > > > > > > > >  	/**
> > > > > > > > > > +	 * @v4l2_fmt:
> > > > > > > > > > +	 *
> > > > > > > > > > +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> > > > > > > > > > +	 */
> > > > > > > > > > +	u32 v4l2_fmt;
> > > > > > > > > > +
> > > > > > > > > > +	/**
> > > > > > > > > >  	 * @depth:
> > > > > > > > > >  	 *
> > > > > > > > > >  	 * Color depth (number of bits per pixel excluding padding bits),
> > > > > > > > > > @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
> > > > > > > > > >  
> > > > > > > > > >  const struct image_format_info *__image_format_drm_lookup(u32 drm);
> > > > > > > > > >  const struct image_format_info *image_format_drm_lookup(u32 drm);
> > > > > > > > > > +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > > > +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
> > > > > > > > > >  unsigned int image_format_plane_cpp(const struct image_format_info *format,
> > > > > > > > > >  				    int plane);
> > > > > > > > > >  unsigned int image_format_plane_width(int width,
> > > > > > > > > > diff --git a/lib/image-formats.c b/lib/image-formats.c
> > > > > > > > > > index 9b9a73220c5d..39f1d38ae861 100644
> > > > > > > > > > --- a/lib/image-formats.c
> > > > > > > > > > +++ b/lib/image-formats.c
> > > > > > > > > > @@ -8,6 +8,7 @@
> > > > > > > > > >  static const struct image_format_info formats[] = {
> > > > > > > > > >  	{
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_C8,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
> > > > > > > > > >  		.depth = 8,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > > @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB332,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
> > > > > > > > > >  		.depth = 8,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 1, 0, 0 },
> > > > > > > > > > @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB4444,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> > > > > > > > > >  		.depth = 0,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > > @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB4444,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> > > > > > > > > >  		.depth = 0,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > > @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.has_alpha = true,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB1555,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> > > > > > > > > >  		.depth = 15,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > > @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_ARGB1555,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> > > > > > > > > >  		.depth = 15,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > > @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.has_alpha = true,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB565,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> > > > > > > > > >  		.depth = 16,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 2, 0, 0 },
> > > > > > > > > > @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_RGB888,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> > > > > > > > > >  		.depth = 24,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > > @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_BGR888,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> > > > > > > > > >  		.depth = 24,
> > > > > > > > > >  		.num_planes = 1,
> > > > > > > > > >  		.cpp = { 3, 0, 0 },
> > > > > > > > > > @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
> > > > > > > > > >  		.vsub = 1,
> > > > > > > > > >  	}, {
> > > > > > > > > >  		.drm_fmt = DRM_FORMAT_XRGB8888,
> > > > > > > > > > +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> > > > > > > > > 
> > > > > > > > > All RGB mapping should be surrounded by ifdef, because many (not all)
> > > > > > > > > DRM formats represent the order of component when placed in a CPU
> > > > > > > > > register, unlike V4L2 which uses memory order. I've pick this one
> > > > > > > > 
> > > > > > > > DRM formats are explicitly defined as little endian.
> > > > > > > 
> > > > > > > Yes, that means the same thing. The mapping has nothing to do with the
> > > > > > > buffer bytes order, unlike V4L2 (and most streaming stack) do.
> > > > > > 
> > > > > > It has everything to do with byte order. Little endian means the least
> > > > > > significant byte is stored in the first byte in memory.
> > > > > > 
> > > > > > Based on https://www.kernel.org/doc/html/v4.15/media/uapi/v4l/pixfmt-packed-rgb.html
> > > > > > drm XRGB888 is actually v4l XBGR32, not XRGB32 as claimed by this patch.
> > > > > 
> > > > > That's basically what I said, as it's define for Little Endian rather
> > > > > then buffer order, you have to make the mapping conditional. It
> > > > > basically mean that in memory, the DRM format physically differ
> > > > > depending on CPU endian.
> > > > 
> > > > No. It is always little endian no matter what the CPU is.
> > > 
> > > I'm sorry, this is in your ABI, we don't add layers of ifdef in
> > > userspace code just for the fun of it. If you redefine this now you are
> > > breaking userspace. I agree there is very little to no Big Endian on
> > > DRM side anymore, but what historically was mapped per CPU cannot be
> > > changed by you now.
> > 
> > It was always little endian.
> 
> I'm not sure what it's worth, but there is a "pixel format guide"
> project that is all about matching formats from one API to another: 
> https://afrantzis.com/pixel-format-guide/ (and it has an associated
> tool too).
> 
> On the page about DRM, it seems that they got the word that DRM formats
> are the native pixel order in little-endian systems:
> https://afrantzis.com/pixel-format-guide/drm.html

Looks consistent with the official word in drm_fourcc.h.

$ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
Format: V4L2_PIX_FMT_XBGR32
Is compatible on all systems with:
        DRM_FORMAT_XRGB8888
Is compatible on little-endian systems with:
Is compatible on big-endian systems with:

$ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
Format: DRM_FORMAT_XRGB8888
Is compatible on all systems with:
        V4L2_PIX_FMT_XBGR32
Is compatible on little-endian systems with:
Is compatible on big-endian systems with:

Even works both ways :)

> 
> Perhaps some drivers have been abusing the format definitions, leading
> to the inconsistencies that Nicolas could witness?

That is quite possible, perhaps even likely. No one really
seems interested in making sure big endian systems actually
work properly. I believe the usual approach is to hack
around semi-rnadomly until the correct colors accidentally
appear on the screen.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-21 16:35                     ` Ville Syrjälä
@ 2019-03-21 19:14                       ` Nicolas Dufresne
  2019-03-21 21:44                         ` Ville Syrjälä
  2019-03-22 14:42                         ` Ville Syrjälä
  0 siblings, 2 replies; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-21 19:14 UTC (permalink / raw)
  To: Ville Syrjälä, Paul Kocialkowski
  Cc: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, linux-kernel,
	dri-devel, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 3076 bytes --]

Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > I'm not sure what it's worth, but there is a "pixel format guide"
> > project that is all about matching formats from one API to another: 
> > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > tool too).
> > 
> > On the page about DRM, it seems that they got the word that DRM formats
> > are the native pixel order in little-endian systems:
> > https://afrantzis.com/pixel-format-guide/drm.html
> 
> Looks consistent with the official word in drm_fourcc.h.
> 
> $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> Format: V4L2_PIX_FMT_XBGR32
> Is compatible on all systems with:
>         DRM_FORMAT_XRGB8888
> Is compatible on little-endian systems with:
> Is compatible on big-endian systems with:
> 
> $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> Format: DRM_FORMAT_XRGB8888
> Is compatible on all systems with:
>         V4L2_PIX_FMT_XBGR32
> Is compatible on little-endian systems with:
> Is compatible on big-endian systems with:
> 
> Even works both ways :)
> 
> > Perhaps some drivers have been abusing the format definitions, leading
> > to the inconsistencies that Nicolas could witness?
> 
> That is quite possible, perhaps even likely. No one really
> seems interested in making sure big endian systems actually
> work properly. I believe the usual approach is to hack
> around semi-rnadomly until the correct colors accidentally
> appear on the screen.

We did not hack around randomly. The code in GStreamer is exactly what
the DRM and Wayland dev told us to do (they provided the initial
patches to make it work). These are initially patches from Intel for
what it's worth (see the wlvideoformat.c header [0]). Even though I
just notice that in this file, it seems that we ended up with a
different mapping order for WL and DRM format in 24bit RGB (no
padding), clearly is a bug. That being said, there is no logical
meaning for little endian 24bit RGB, you can't load a pixel on CPU in a
single op. Just saying since I would not know which one of the two
mapping here is right. I would probably have to go testing what DRM
drivers do, which may not mean anything. I would also ask and get
contradictory answers.

I have never myself tested these on big endian drivers though, as you
say, nobody seems to care about graphics on those anymore. So the easy
statement is to say they are little endian, like you just did, and
ignore the legacy, but there is some catch. YUV formats has been added
without applying this rules. So V4L2 YUYV match YUYV in DRM format name
instead of little endian UYVY. (at least 4 tested drivers implements it
this way). Same for NV12, for which little endian CPU representation
would swap the UV paid on a 16bit word.

To me, all the YUV stuff is the right way, because this is what the
rest of the world is doing, it's not ambiguous.

[0] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/wayland/wlvideoformat.c#L86



Nicolas

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-21 19:14                       ` Nicolas Dufresne
@ 2019-03-21 21:44                         ` Ville Syrjälä
  2019-03-22 18:24                           ` Nicolas Dufresne
  2019-03-22 14:42                         ` Ville Syrjälä
  1 sibling, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-21 21:44 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > project that is all about matching formats from one API to another: 
> > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > tool too).
> > > 
> > > On the page about DRM, it seems that they got the word that DRM formats
> > > are the native pixel order in little-endian systems:
> > > https://afrantzis.com/pixel-format-guide/drm.html
> > 
> > Looks consistent with the official word in drm_fourcc.h.
> > 
> > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > Format: V4L2_PIX_FMT_XBGR32
> > Is compatible on all systems with:
> >         DRM_FORMAT_XRGB8888
> > Is compatible on little-endian systems with:
> > Is compatible on big-endian systems with:
> > 
> > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > Format: DRM_FORMAT_XRGB8888
> > Is compatible on all systems with:
> >         V4L2_PIX_FMT_XBGR32
> > Is compatible on little-endian systems with:
> > Is compatible on big-endian systems with:
> > 
> > Even works both ways :)
> > 
> > > Perhaps some drivers have been abusing the format definitions, leading
> > > to the inconsistencies that Nicolas could witness?
> > 
> > That is quite possible, perhaps even likely. No one really
> > seems interested in making sure big endian systems actually
> > work properly. I believe the usual approach is to hack
> > around semi-rnadomly until the correct colors accidentally
> > appear on the screen.
> 
> We did not hack around randomly. The code in GStreamer is exactly what
> the DRM and Wayland dev told us to do (they provided the initial
> patches to make it work). These are initially patches from Intel for
> what it's worth (see the wlvideoformat.c header [0]). Even though I
> just notice that in this file, it seems that we ended up with a
> different mapping order for WL and DRM format in 24bit RGB (no
> padding), clearly is a bug. That being said, there is no logical
> meaning for little endian 24bit RGB, you can't load a pixel on CPU in a
> single op.

To me little endian just means "little end comes first". So if
you think of things as just a stream of bytes CPU word size
etc. doesn't matter. And I guess if you really wanted to you
could even make a CPU with 24bit word size. 

Anyways, to make things more clear drm_fourcc.h could probably
document things better by showing explicitly which bits go into
which byte.

I don't know who did what patches for whatever project, but
clearly something has been lost in translation at some point.

> Just saying since I would not know which one of the two
> mapping here is right. I would probably have to go testing what DRM
> drivers do, which may not mean anything. I would also ask and get
> contradictory answers.
> 
> I have never myself tested these on big endian drivers though, as you
> say, nobody seems to care about graphics on those anymore. So the easy
> statement is to say they are little endian, like you just did, and
> ignore the legacy, but there is some catch. YUV formats has been added
> without applying this rules.

All drm formats follow the same rule (ignoring the recently added
non-byte aligned stuff which I guess don't really follow any rules).

> So V4L2 YUYV match YUYV in DRM format name
> instead of little endian UYVY. (at least 4 tested drivers implements it
> this way). Same for NV12, for which little endian CPU representation
> would swap the UV paid on a 16bit word.

DRM NV12 and YUYV (YUY2) match the NV12 and YUY2 defined here
https://docs.microsoft.com/en-us/windows/desktop/medfound/recommended-8-bit-yuv-formats-for-video-rendering

> 
> To me, all the YUV stuff is the right way, because this is what the
> rest of the world is doing, it's not ambiguous.
> 
> [0] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/wayland/wlvideoformat.c#L86
> 
> 
> 
> Nicolas

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-21 19:14                       ` Nicolas Dufresne
  2019-03-21 21:44                         ` Ville Syrjälä
@ 2019-03-22 14:42                         ` Ville Syrjälä
  2019-03-22 18:11                           ` Nicolas Dufresne
  1 sibling, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-22 14:42 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > project that is all about matching formats from one API to another: 
> > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > tool too).
> > > 
> > > On the page about DRM, it seems that they got the word that DRM formats
> > > are the native pixel order in little-endian systems:
> > > https://afrantzis.com/pixel-format-guide/drm.html
> > 
> > Looks consistent with the official word in drm_fourcc.h.
> > 
> > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > Format: V4L2_PIX_FMT_XBGR32
> > Is compatible on all systems with:
> >         DRM_FORMAT_XRGB8888
> > Is compatible on little-endian systems with:
> > Is compatible on big-endian systems with:
> > 
> > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > Format: DRM_FORMAT_XRGB8888
> > Is compatible on all systems with:
> >         V4L2_PIX_FMT_XBGR32
> > Is compatible on little-endian systems with:
> > Is compatible on big-endian systems with:
> > 
> > Even works both ways :)
> > 
> > > Perhaps some drivers have been abusing the format definitions, leading
> > > to the inconsistencies that Nicolas could witness?
> > 
> > That is quite possible, perhaps even likely. No one really
> > seems interested in making sure big endian systems actually
> > work properly. I believe the usual approach is to hack
> > around semi-rnadomly until the correct colors accidentally
> > appear on the screen.
> 
> We did not hack around randomly.

BTW I didn't mean to imply it was you who hacked around randomly.
Sorry if you got that impression.

What I was trying to convey is the following sequence of events:
1. random person X gets their hand on a big endian machine for
   a while
2. colors are wrong
3. they hack stuff until the colors are correct in their
   current use case
4. they move on to more interesting things

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-22 14:42                         ` Ville Syrjälä
@ 2019-03-22 18:11                           ` Nicolas Dufresne
  0 siblings, 0 replies; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-22 18:11 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 2296 bytes --]

Le vendredi 22 mars 2019 à 16:42 +0200, Ville Syrjälä a écrit :
> On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> > Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > > project that is all about matching formats from one API to another: 
> > > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > > tool too).
> > > > 
> > > > On the page about DRM, it seems that they got the word that DRM formats
> > > > are the native pixel order in little-endian systems:
> > > > https://afrantzis.com/pixel-format-guide/drm.html
> > > 
> > > Looks consistent with the official word in drm_fourcc.h.
> > > 
> > > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > > Format: V4L2_PIX_FMT_XBGR32
> > > Is compatible on all systems with:
> > >         DRM_FORMAT_XRGB8888
> > > Is compatible on little-endian systems with:
> > > Is compatible on big-endian systems with:
> > > 
> > > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > > Format: DRM_FORMAT_XRGB8888
> > > Is compatible on all systems with:
> > >         V4L2_PIX_FMT_XBGR32
> > > Is compatible on little-endian systems with:
> > > Is compatible on big-endian systems with:
> > > 
> > > Even works both ways :)
> > > 
> > > > Perhaps some drivers have been abusing the format definitions, leading
> > > > to the inconsistencies that Nicolas could witness?
> > > 
> > > That is quite possible, perhaps even likely. No one really
> > > seems interested in making sure big endian systems actually
> > > work properly. I believe the usual approach is to hack
> > > around semi-rnadomly until the correct colors accidentally
> > > appear on the screen.
> > 
> > We did not hack around randomly.
> 
> BTW I didn't mean to imply it was you who hacked around randomly.
> Sorry if you got that impression.
> 
> What I was trying to convey is the following sequence of events:
> 1. random person X gets their hand on a big endian machine for
>    a while
> 2. colors are wrong
> 3. they hack stuff until the colors are correct in their
>    current use case
> 4. they move on to more interesting things

Thanks for clarification.

Nicolas

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-21 21:44                         ` Ville Syrjälä
@ 2019-03-22 18:24                           ` Nicolas Dufresne
  2019-03-22 18:44                             ` Ville Syrjälä
  0 siblings, 1 reply; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-22 18:24 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 5377 bytes --]

Le jeudi 21 mars 2019 à 23:44 +0200, Ville Syrjälä a écrit :
> On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> > Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > > project that is all about matching formats from one API to another: 
> > > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > > tool too).
> > > > 
> > > > On the page about DRM, it seems that they got the word that DRM formats
> > > > are the native pixel order in little-endian systems:
> > > > https://afrantzis.com/pixel-format-guide/drm.html
> > > 
> > > Looks consistent with the official word in drm_fourcc.h.
> > > 
> > > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > > Format: V4L2_PIX_FMT_XBGR32
> > > Is compatible on all systems with:
> > >         DRM_FORMAT_XRGB8888
> > > Is compatible on little-endian systems with:
> > > Is compatible on big-endian systems with:
> > > 
> > > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > > Format: DRM_FORMAT_XRGB8888
> > > Is compatible on all systems with:
> > >         V4L2_PIX_FMT_XBGR32
> > > Is compatible on little-endian systems with:
> > > Is compatible on big-endian systems with:
> > > 
> > > Even works both ways :)
> > > 
> > > > Perhaps some drivers have been abusing the format definitions, leading
> > > > to the inconsistencies that Nicolas could witness?
> > > 
> > > That is quite possible, perhaps even likely. No one really
> > > seems interested in making sure big endian systems actually
> > > work properly. I believe the usual approach is to hack
> > > around semi-rnadomly until the correct colors accidentally
> > > appear on the screen.
> > 
> > We did not hack around randomly. The code in GStreamer is exactly what
> > the DRM and Wayland dev told us to do (they provided the initial
> > patches to make it work). These are initially patches from Intel for
> > what it's worth (see the wlvideoformat.c header [0]). Even though I
> > just notice that in this file, it seems that we ended up with a
> > different mapping order for WL and DRM format in 24bit RGB (no
> > padding), clearly is a bug. That being said, there is no logical
> > meaning for little endian 24bit RGB, you can't load a pixel on CPU in a
> > single op.
> 
> To me little endian just means "little end comes first". So if
> you think of things as just a stream of bytes CPU word size
> etc. doesn't matter. And I guess if you really wanted to you
> could even make a CPU with 24bit word size. 
> 
> Anyways, to make things more clear drm_fourcc.h could probably
> document things better by showing explicitly which bits go into
> which byte.
> 
> I don't know who did what patches for whatever project, but
> clearly something has been lost in translation at some point.
> 
> > Just saying since I would not know which one of the two
> > mapping here is right. I would probably have to go testing what DRM
> > drivers do, which may not mean anything. I would also ask and get
> > contradictory answers.
> > 
> > I have never myself tested these on big endian drivers though, as you
> > say, nobody seems to care about graphics on those anymore. So the easy
> > statement is to say they are little endian, like you just did, and
> > ignore the legacy, but there is some catch. YUV formats has been added
> > without applying this rules.
> 
> All drm formats follow the same rule (ignoring the recently added
> non-byte aligned stuff which I guess don't really follow any rules).
> 
> > So V4L2 YUYV match YUYV in DRM format name
> > instead of little endian UYVY. (at least 4 tested drivers implements it
> > this way). Same for NV12, for which little endian CPU representation
> > would swap the UV paid on a 16bit word.
> 
> DRM NV12 and YUYV (YUY2) match the NV12 and YUY2 defined here
> https://docs.microsoft.com/en-us/windows/desktop/medfound/recommended-8-bit-yuv-formats-for-video-rendering

Problem is that these are all expressed MSB first like (the way V4L2
and GStreamer do appart for the padding X, which is usually first in
V4L2). Let's say you have 2 pixels of YUYV in a 32bit buffer.

   buf[0] = Y
   buf[1] = U
   buf[2] = Y
   buf[3] = V

While with LSB first (was this what you wanted to say ?), this format
would be VYUY as:

  buf[0] = V
  buf[1] = Y
  buf[2] = U
  buf[3] = Y

But I tested this format on i915, xlnx, msm and imx drm drivers, and
they are all mapped as MSB. The LSB version of NV12 is called NV21 in
MS pixel formats. It would be really confusing if the LSB rule was to
be applied to these format in my opinion, because the names don't
explicitly express the placement for the components.

Anyway, to cut short, as per currently tested implementation of DRM
driver, we can keep the RGB mapping static (reversed) for now, but for
Maxime, who probably have no clue about all this, the YUYV mapping is
correct in this patch (in as of currently tested drivers).

> 
> > To me, all the YUV stuff is the right way, because this is what the
> > rest of the world is doing, it's not ambiguous.
> > 
> > [0] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/wayland/wlvideoformat.c#L86
> > 
> > 
> > 
> > Nicolas

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-22 18:24                           ` Nicolas Dufresne
@ 2019-03-22 18:44                             ` Ville Syrjälä
  2019-03-22 19:25                               ` Nicolas Dufresne
  0 siblings, 1 reply; 69+ messages in thread
From: Ville Syrjälä @ 2019-03-22 18:44 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

On Fri, Mar 22, 2019 at 02:24:29PM -0400, Nicolas Dufresne wrote:
> Le jeudi 21 mars 2019 à 23:44 +0200, Ville Syrjälä a écrit :
> > On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> > > Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > > > project that is all about matching formats from one API to another: 
> > > > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > > > tool too).
> > > > > 
> > > > > On the page about DRM, it seems that they got the word that DRM formats
> > > > > are the native pixel order in little-endian systems:
> > > > > https://afrantzis.com/pixel-format-guide/drm.html
> > > > 
> > > > Looks consistent with the official word in drm_fourcc.h.
> > > > 
> > > > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > > > Format: V4L2_PIX_FMT_XBGR32
> > > > Is compatible on all systems with:
> > > >         DRM_FORMAT_XRGB8888
> > > > Is compatible on little-endian systems with:
> > > > Is compatible on big-endian systems with:
> > > > 
> > > > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > > > Format: DRM_FORMAT_XRGB8888
> > > > Is compatible on all systems with:
> > > >         V4L2_PIX_FMT_XBGR32
> > > > Is compatible on little-endian systems with:
> > > > Is compatible on big-endian systems with:
> > > > 
> > > > Even works both ways :)
> > > > 
> > > > > Perhaps some drivers have been abusing the format definitions, leading
> > > > > to the inconsistencies that Nicolas could witness?
> > > > 
> > > > That is quite possible, perhaps even likely. No one really
> > > > seems interested in making sure big endian systems actually
> > > > work properly. I believe the usual approach is to hack
> > > > around semi-rnadomly until the correct colors accidentally
> > > > appear on the screen.
> > > 
> > > We did not hack around randomly. The code in GStreamer is exactly what
> > > the DRM and Wayland dev told us to do (they provided the initial
> > > patches to make it work). These are initially patches from Intel for
> > > what it's worth (see the wlvideoformat.c header [0]). Even though I
> > > just notice that in this file, it seems that we ended up with a
> > > different mapping order for WL and DRM format in 24bit RGB (no
> > > padding), clearly is a bug. That being said, there is no logical
> > > meaning for little endian 24bit RGB, you can't load a pixel on CPU in a
> > > single op.
> > 
> > To me little endian just means "little end comes first". So if
> > you think of things as just a stream of bytes CPU word size
> > etc. doesn't matter. And I guess if you really wanted to you
> > could even make a CPU with 24bit word size. 
> > 
> > Anyways, to make things more clear drm_fourcc.h could probably
> > document things better by showing explicitly which bits go into
> > which byte.
> > 
> > I don't know who did what patches for whatever project, but
> > clearly something has been lost in translation at some point.
> > 
> > > Just saying since I would not know which one of the two
> > > mapping here is right. I would probably have to go testing what DRM
> > > drivers do, which may not mean anything. I would also ask and get
> > > contradictory answers.
> > > 
> > > I have never myself tested these on big endian drivers though, as you
> > > say, nobody seems to care about graphics on those anymore. So the easy
> > > statement is to say they are little endian, like you just did, and
> > > ignore the legacy, but there is some catch. YUV formats has been added
> > > without applying this rules.
> > 
> > All drm formats follow the same rule (ignoring the recently added
> > non-byte aligned stuff which I guess don't really follow any rules).
> > 
> > > So V4L2 YUYV match YUYV in DRM format name
> > > instead of little endian UYVY. (at least 4 tested drivers implements it
> > > this way). Same for NV12, for which little endian CPU representation
> > > would swap the UV paid on a 16bit word.
> > 
> > DRM NV12 and YUYV (YUY2) match the NV12 and YUY2 defined here
> > https://docs.microsoft.com/en-us/windows/desktop/medfound/recommended-8-bit-yuv-formats-for-video-rendering
> 
> Problem is that these are all expressed MSB first like (the way V4L2
> and GStreamer do appart for the padding X, which is usually first in
> V4L2). Let's say you have 2 pixels of YUYV in a 32bit buffer.
> 
>    buf[0] = Y
>    buf[1] = U
>    buf[2] = Y
>    buf[3] = V

This is drm YUYV (aka. YUY2). Well, assuming buf[] is made up of bytes.

> 
> While with LSB first (was this what you wanted to say ?), this format
> would be VYUY as:
> 
>   buf[0] = V
>   buf[1] = Y
>   buf[2] = U
>   buf[3] = Y

This is VYUY as far as drm is concerned.

> 
> But I tested this format on i915, xlnx, msm and imx drm drivers, and
> they are all mapped as MSB. The LSB version of NV12 is called NV21 in
> MS pixel formats. It would be really confusing if the LSB rule was to
> be applied to these format in my opinion, because the names don't
> explicitly express the placement for the components.

The names don't really mean anything. Don't try to give any any special
meaning. They're just that, names. The fact that we used fourccs for
them was a mistake IMO. IIRC I objected but ended up going with them
to get the bikeshed painted at all.

And yes, the fact that we used a different naming scheme for packed YUV
vs. RGB was probably a mistake by me. But it was done long ago and we
have to live with it. Fortunately the mess has gotten much worse since
then and we are even more inconsistent now. We now YUV formats where
the A vs. X variants use totally different naming schemes.

> 
> Anyway, to cut short, as per currently tested implementation of DRM
> driver, we can keep the RGB mapping static (reversed) for now, but for
> Maxime, who probably have no clue about all this, the YUYV mapping is
> correct in this patch (in as of currently tested drivers).
> 
> > 
> > > To me, all the YUV stuff is the right way, because this is what the
> > > rest of the world is doing, it's not ambiguous.
> > > 
> > > [0] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/wayland/wlvideoformat.c#L86
> > > 
> > > 
> > > 
> > > Nicolas



-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-22 18:44                             ` Ville Syrjälä
@ 2019-03-22 19:25                               ` Nicolas Dufresne
  0 siblings, 0 replies; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-22 19:25 UTC (permalink / raw)
  To: Ville Syrjälä
  Cc: Paul Kocialkowski, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab,
	Sakari Ailus, linux-kernel, dri-devel, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, linux-media, Daniel Stone

[-- Attachment #1: Type: text/plain, Size: 7037 bytes --]

Le vendredi 22 mars 2019 à 20:44 +0200, Ville Syrjälä a écrit :
> On Fri, Mar 22, 2019 at 02:24:29PM -0400, Nicolas Dufresne wrote:
> > Le jeudi 21 mars 2019 à 23:44 +0200, Ville Syrjälä a écrit :
> > > On Thu, Mar 21, 2019 at 03:14:06PM -0400, Nicolas Dufresne wrote:
> > > > Le jeudi 21 mars 2019 à 18:35 +0200, Ville Syrjälä a écrit :
> > > > > > I'm not sure what it's worth, but there is a "pixel format guide"
> > > > > > project that is all about matching formats from one API to another: 
> > > > > > https://afrantzis.com/pixel-format-guide/ (and it has an associated
> > > > > > tool too).
> > > > > > 
> > > > > > On the page about DRM, it seems that they got the word that DRM formats
> > > > > > are the native pixel order in little-endian systems:
> > > > > > https://afrantzis.com/pixel-format-guide/drm.html
> > > > > 
> > > > > Looks consistent with the official word in drm_fourcc.h.
> > > > > 
> > > > > $ python3 -m pfg find-compatible V4L2_PIX_FMT_XBGR32 drm
> > > > > Format: V4L2_PIX_FMT_XBGR32
> > > > > Is compatible on all systems with:
> > > > >         DRM_FORMAT_XRGB8888
> > > > > Is compatible on little-endian systems with:
> > > > > Is compatible on big-endian systems with:
> > > > > 
> > > > > $ python3 -m pfg find-compatible DRM_FORMAT_XRGB8888 v4l2
> > > > > Format: DRM_FORMAT_XRGB8888
> > > > > Is compatible on all systems with:
> > > > >         V4L2_PIX_FMT_XBGR32
> > > > > Is compatible on little-endian systems with:
> > > > > Is compatible on big-endian systems with:
> > > > > 
> > > > > Even works both ways :)
> > > > > 
> > > > > > Perhaps some drivers have been abusing the format definitions, leading
> > > > > > to the inconsistencies that Nicolas could witness?
> > > > > 
> > > > > That is quite possible, perhaps even likely. No one really
> > > > > seems interested in making sure big endian systems actually
> > > > > work properly. I believe the usual approach is to hack
> > > > > around semi-rnadomly until the correct colors accidentally
> > > > > appear on the screen.
> > > > 
> > > > We did not hack around randomly. The code in GStreamer is exactly what
> > > > the DRM and Wayland dev told us to do (they provided the initial
> > > > patches to make it work). These are initially patches from Intel for
> > > > what it's worth (see the wlvideoformat.c header [0]). Even though I
> > > > just notice that in this file, it seems that we ended up with a
> > > > different mapping order for WL and DRM format in 24bit RGB (no
> > > > padding), clearly is a bug. That being said, there is no logical
> > > > meaning for little endian 24bit RGB, you can't load a pixel on CPU in a
> > > > single op.
> > > 
> > > To me little endian just means "little end comes first". So if
> > > you think of things as just a stream of bytes CPU word size
> > > etc. doesn't matter. And I guess if you really wanted to you
> > > could even make a CPU with 24bit word size. 
> > > 
> > > Anyways, to make things more clear drm_fourcc.h could probably
> > > document things better by showing explicitly which bits go into
> > > which byte.
> > > 
> > > I don't know who did what patches for whatever project, but
> > > clearly something has been lost in translation at some point.
> > > 
> > > > Just saying since I would not know which one of the two
> > > > mapping here is right. I would probably have to go testing what DRM
> > > > drivers do, which may not mean anything. I would also ask and get
> > > > contradictory answers.
> > > > 
> > > > I have never myself tested these on big endian drivers though, as you
> > > > say, nobody seems to care about graphics on those anymore. So the easy
> > > > statement is to say they are little endian, like you just did, and
> > > > ignore the legacy, but there is some catch. YUV formats has been added
> > > > without applying this rules.
> > > 
> > > All drm formats follow the same rule (ignoring the recently added
> > > non-byte aligned stuff which I guess don't really follow any rules).
> > > 
> > > > So V4L2 YUYV match YUYV in DRM format name
> > > > instead of little endian UYVY. (at least 4 tested drivers implements it
> > > > this way). Same for NV12, for which little endian CPU representation
> > > > would swap the UV paid on a 16bit word.
> > > 
> > > DRM NV12 and YUYV (YUY2) match the NV12 and YUY2 defined here
> > > https://docs.microsoft.com/en-us/windows/desktop/medfound/recommended-8-bit-yuv-formats-for-video-rendering
> > 
> > Problem is that these are all expressed MSB first like (the way V4L2
> > and GStreamer do appart for the padding X, which is usually first in
> > V4L2). Let's say you have 2 pixels of YUYV in a 32bit buffer.
> > 
> >    buf[0] = Y
> >    buf[1] = U
> >    buf[2] = Y
> >    buf[3] = V
> 
> This is drm YUYV (aka. YUY2). Well, assuming buf[] is made up of bytes.
> 
> > While with LSB first (was this what you wanted to say ?), this format
> > would be VYUY as:
> > 
> >   buf[0] = V
> >   buf[1] = Y
> >   buf[2] = U
> >   buf[3] = Y
> 
> This is VYUY as far as drm is concerned.
> 
> > But I tested this format on i915, xlnx, msm and imx drm drivers, and
> > they are all mapped as MSB. The LSB version of NV12 is called NV21 in
> > MS pixel formats. It would be really confusing if the LSB rule was to
> > be applied to these format in my opinion, because the names don't
> > explicitly express the placement for the components.
> 
> The names don't really mean anything. Don't try to give any any special
> meaning. They're just that, names. The fact that we used fourccs for
> them was a mistake IMO. IIRC I objected but ended up going with them
> to get the bikeshed painted at all.

I can only agree with you. Note, it was not obvious to me that when you
said the format are little endian you refered to the description next
to the format name inside drm_fourcc.h.

> 
> And yes, the fact that we used a different naming scheme for packed YUV
> vs. RGB was probably a mistake by me. But it was done long ago and we
> have to live with it. Fortunately the mess has gotten much worse since
> then and we are even more inconsistent now. We now YUV formats where
> the A vs. X variants use totally different naming schemes.

Ok, so now that we are set, I'll retake this patch and simply comment
next to each badly mapped format.

> 
> > Anyway, to cut short, as per currently tested implementation of DRM
> > driver, we can keep the RGB mapping static (reversed) for now, but for
> > Maxime, who probably have no clue about all this, the YUYV mapping is
> > correct in this patch (in as of currently tested drivers).
> > 
> > > > To me, all the YUV stuff is the right way, because this is what the
> > > > rest of the world is doing, it's not ambiguous.
> > > > 
> > > > [0] https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/wayland/wlvideoformat.c#L86
> > > > 
> > > > 
> > > > 
> > > > Nicolas
> 
> 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 21:57 ` [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support Maxime Ripard
  2019-03-19 23:29   ` Nicolas Dufresne
@ 2019-03-22 19:55   ` Nicolas Dufresne
  2019-04-01 14:44     ` Maxime Ripard
  2019-04-11  7:38     ` Hans Verkuil
  2019-04-11  7:12   ` Hans Verkuil
  2 siblings, 2 replies; 69+ messages in thread
From: Nicolas Dufresne @ 2019-03-22 19:55 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

[-- Attachment #1: Type: text/plain, Size: 11346 bytes --]

Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> V4L2 uses different fourcc's than DRM, and has a different set of formats.
> For now, let's add the v4l2 fourcc's for the already existing formats.

Hopefully I get the fixup right this time, see inline.

> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  include/linux/image-formats.h |  9 +++++-
>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+)
> 
> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> index 53fd73a71b3d..fbc3a4501ebd 100644
> --- a/include/linux/image-formats.h
> +++ b/include/linux/image-formats.h
> @@ -26,6 +26,13 @@ struct image_format_info {
>  	};
>  
>  	/**
> +	 * @v4l2_fmt:
> +	 *
> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> +	 */
> +	u32 v4l2_fmt;
> +
> +	/**
>  	 * @depth:
>  	 *
>  	 * Color depth (number of bits per pixel excluding padding bits),
> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>  
>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>  const struct image_format_info *image_format_drm_lookup(u32 drm);
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>  				    int plane);
>  unsigned int image_format_plane_width(int width,
> diff --git a/lib/image-formats.c b/lib/image-formats.c
> index 9b9a73220c5d..39f1d38ae861 100644
> --- a/lib/image-formats.c
> +++ b/lib/image-formats.c
> @@ -8,6 +8,7 @@
>  static const struct image_format_info formats[] = {
>  	{
>  		.drm_fmt = DRM_FORMAT_C8,
> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB332,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,

Not completely sure, looks like in the V4L2 variant, the padding is on
the 4 MSB of the second byte, which makes it incompatible. There is no
other equivalent.

>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,

Similarly.

>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,

Same swapping, can't find a match.

>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,

Same.

>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB565,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,

-> V4L2_PIX_FMT_RGB565X

Was added later, as what you expect is not compatible.

>  		.depth = 16,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB888,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,

-> V4L2_PIX_FMT_BGR24

>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_BGR888,
> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,

-> V4L2_PIX_FMT_RGB24

>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,

-> V4L2_PIX_FMT_XBGR32

>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,

-> V4L2_PIX_FMT_ABGR32

>  		.depth = 32,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,

There is two valid matches in V4L2 for this format, not sure how this
will be handled. The M variant is to be used with MPLANE v4l2_buffer
when num_planes is bigger then 1.

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,

Same.

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,

Same.

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,

Same. 

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,

Same.

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,

Same.

>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV12,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,

V4L2_PIX_FMT_NV12M is the mplane variant. Depending on how you handle,
which should be concistant picking one up.

>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV21,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,

Same, NV12M for mplane.

>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV16,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,

Same, NV16M.

>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV61,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,

Same, NV61M.

>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV24,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,

For extra fun, the M variant has not been added yet.

>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV42,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUYV,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVYU,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_UYVY,
> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_VYUY,
> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>  EXPORT_SYMBOL(image_format_drm_lookup);
>  
>  /**
> + * __image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> +{
> +	return __image_format_lookup(v4l2_fmt, v4l2);
> +}
> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> +
> +/**
> + * image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> +{
> +	const struct image_format_info *format;
> +
> +	format = __image_format_v4l2_lookup(v4l2);
> +
> +	WARN_ON(!format);
> +	return format;
> +}
> +EXPORT_SYMBOL(image_format_v4l2_lookup);
> +
> +/**
>   * image_format_plane_cpp - determine the bytes per pixel value
>   * @format: pointer to the image_format
>   * @plane: plane index

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-22 19:55   ` Nicolas Dufresne
@ 2019-04-01 14:44     ` Maxime Ripard
  2019-04-11  7:24       ` Hans Verkuil
  2019-04-11  7:38     ` Hans Verkuil
  1 sibling, 1 reply; 69+ messages in thread
From: Maxime Ripard @ 2019-04-01 14:44 UTC (permalink / raw)
  To: Nicolas Dufresne
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, Paul Kocialkowski, dri-devel,
	linux-kernel, linux-media

[-- Attachment #1: Type: text/plain, Size: 706 bytes --]

Hi Nicolas,

On Fri, Mar 22, 2019 at 03:55:19PM -0400, Nicolas Dufresne wrote:
> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
> > V4L2 uses different fourcc's than DRM, and has a different set of formats.
> > For now, let's add the v4l2 fourcc's for the already existing formats.
>
> Hopefully I get the fixup right this time, see inline.

Thanks a lot for that extensive review.

About the single vs multi-planar issue, I'd be inclined with just
supporting single-planar formats for now, and extend it later to deal
with multiplanar formats.

Would that work for everyone?

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
  2019-03-19 21:57 ` [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes Maxime Ripard
  2019-03-20 14:16   ` Paul Kocialkowski
@ 2019-04-02  9:43   ` Emil Velikov
  2019-04-02 14:51     ` Maxime Ripard
  1 sibling, 1 reply; 69+ messages in thread
From: Emil Velikov @ 2019-04-02  9:43 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus,
	Linux-Kernel@Vger. Kernel. Org, ML dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

Hi Maxime,

On Tue, 19 Mar 2019 at 21:57, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> drm_format_num_planes() is basically a lookup in the drm_format_info table
> plus an access to the num_planes field of the appropriate entry.
>
> Most drivers are using this function while having access to the entry
> already, which means that we will perform an unnecessary lookup. Removing
> the call to drm_format_num_planes is therefore more efficient.
>
> Some drivers will not have access to that entry in the function, but in
> this case the overhead is minimal (we just have to call drm_format_info()
> to perform the lookup) and we can even avoid multiple, inefficient lookups
> in some places that need multiple fields from the drm_format_info
> structure.
>
I'm not fan of the duplicated loop-ups either.

> -int drm_format_num_planes(uint32_t format)
> -{
> -       const struct drm_format_info *info;
> -
> -       info = drm_format_info(format);
> -       return info ? info->num_planes : 1;
> -}
> -EXPORT_SYMBOL(drm_format_num_planes);
> -
The existing users are not updated to cater for the num_planes != 0
case... Which seems non-existent scenario since all the current format
descriptions have 1+ planes.
Should we add a test (alike the ones in 6/20) to ensure, that no entry
has 0 planes? Is it even worth it or I'm a bit too paranoid?

The above comments apply to 2/20.

With the name suggestions by Paul, patches 1 to 5 (incl.) are:
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>

HTH
Emil

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
  2019-04-02  9:43   ` Emil Velikov
@ 2019-04-02 14:51     ` Maxime Ripard
  2019-04-04 16:24       ` Emil Velikov
  0 siblings, 1 reply; 69+ messages in thread
From: Maxime Ripard @ 2019-04-02 14:51 UTC (permalink / raw)
  To: Emil Velikov
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus,
	Linux-Kernel@Vger. Kernel. Org, ML dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

[-- Attachment #1: Type: text/plain, Size: 2129 bytes --]

Hi Emil,

On Tue, Apr 02, 2019 at 10:43:31AM +0100, Emil Velikov wrote:
> On Tue, 19 Mar 2019 at 21:57, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > drm_format_num_planes() is basically a lookup in the drm_format_info table
> > plus an access to the num_planes field of the appropriate entry.
> >
> > Most drivers are using this function while having access to the entry
> > already, which means that we will perform an unnecessary lookup. Removing
> > the call to drm_format_num_planes is therefore more efficient.
> >
> > Some drivers will not have access to that entry in the function, but in
> > this case the overhead is minimal (we just have to call drm_format_info()
> > to perform the lookup) and we can even avoid multiple, inefficient lookups
> > in some places that need multiple fields from the drm_format_info
> > structure.
> >
>
> I'm not fan of the duplicated loop-ups either.
>
> > -int drm_format_num_planes(uint32_t format)
> > -{
> > -       const struct drm_format_info *info;
> > -
> > -       info = drm_format_info(format);
> > -       return info ? info->num_planes : 1;
> > -}
> > -EXPORT_SYMBOL(drm_format_num_planes);
> > -
>
> The existing users are not updated to cater for the num_planes != 0
> case... Which seems non-existent scenario since all the current format
> descriptions have 1+ planes.
> Should we add a test (alike the ones in 6/20) to ensure, that no entry
> has 0 planes? Is it even worth it or I'm a bit too paranoid?
>
> The above comments apply to 2/20.

I'm not entirely sure what you mean. num_planes is returned as is in
the drm_format_num_planes function and it doesn't check for the
num_planes value itself.

That being said, we could definitely add some more tests to check that
we haven't falling into the situation you describe, since most of the
drivers indeed don't check for that value themselves. But that seems
pretty othorgonal to me?

> With the name suggestions by Paul, patches 1 to 5 (incl.) are:
> Reviewed-by: Emil Velikov <emil.velikov@collabora.com>

Thanks!
Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes
  2019-04-02 14:51     ` Maxime Ripard
@ 2019-04-04 16:24       ` Emil Velikov
  0 siblings, 0 replies; 69+ messages in thread
From: Emil Velikov @ 2019-04-04 16:24 UTC (permalink / raw)
  To: Maxime Ripard
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus,
	Linux-Kernel@Vger. Kernel. Org, ML dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

On Tue, 2 Apr 2019 at 15:51, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
>
> Hi Emil,
>
> On Tue, Apr 02, 2019 at 10:43:31AM +0100, Emil Velikov wrote:
> > On Tue, 19 Mar 2019 at 21:57, Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > > drm_format_num_planes() is basically a lookup in the drm_format_info table
> > > plus an access to the num_planes field of the appropriate entry.
> > >
> > > Most drivers are using this function while having access to the entry
> > > already, which means that we will perform an unnecessary lookup. Removing
> > > the call to drm_format_num_planes is therefore more efficient.
> > >
> > > Some drivers will not have access to that entry in the function, but in
> > > this case the overhead is minimal (we just have to call drm_format_info()
> > > to perform the lookup) and we can even avoid multiple, inefficient lookups
> > > in some places that need multiple fields from the drm_format_info
> > > structure.
> > >
> >
> > I'm not fan of the duplicated loop-ups either.
> >
> > > -int drm_format_num_planes(uint32_t format)
> > > -{
> > > -       const struct drm_format_info *info;
> > > -
> > > -       info = drm_format_info(format);
> > > -       return info ? info->num_planes : 1;
> > > -}
> > > -EXPORT_SYMBOL(drm_format_num_planes);
> > > -
> >
> > The existing users are not updated to cater for the num_planes != 0
> > case... Which seems non-existent scenario since all the current format
> > descriptions have 1+ planes.
> > Should we add a test (alike the ones in 6/20) to ensure, that no entry
> > has 0 planes? Is it even worth it or I'm a bit too paranoid?
> >
> > The above comments apply to 2/20.
>
> I'm not entirely sure what you mean. num_planes is returned as is in
> the drm_format_num_planes function and it doesn't check for the
> num_planes value itself.
>
> That being said, we could definitely add some more tests to check that
> we haven't falling into the situation you describe, since most of the
> drivers indeed don't check for that value themselves. But that seems
> pretty othorgonal to me?
>
Hmm I misread the old function as "return info->num_planes ?
info->num_planes : 1;"

Pardon for the noise.
-Emil

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-19 21:57 ` [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support Maxime Ripard
  2019-03-19 23:29   ` Nicolas Dufresne
  2019-03-22 19:55   ` Nicolas Dufresne
@ 2019-04-11  7:12   ` Hans Verkuil
  2019-04-11  7:15       ` Hans Verkuil
  2 siblings, 1 reply; 69+ messages in thread
From: Hans Verkuil @ 2019-04-11  7:12 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

Hi Maxime,

Some comments below...

On 3/19/19 10:57 PM, Maxime Ripard wrote:
> V4L2 uses different fourcc's than DRM, and has a different set of formats.
> For now, let's add the v4l2 fourcc's for the already existing formats.
> 
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
>  include/linux/image-formats.h |  9 +++++-
>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>  2 files changed, 76 insertions(+)
> 
> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
> index 53fd73a71b3d..fbc3a4501ebd 100644
> --- a/include/linux/image-formats.h
> +++ b/include/linux/image-formats.h
> @@ -26,6 +26,13 @@ struct image_format_info {
>  	};
>  
>  	/**
> +	 * @v4l2_fmt:
> +	 *
> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
> +	 */
> +	u32 v4l2_fmt;
> +
> +	/**
>  	 * @depth:
>  	 *
>  	 * Color depth (number of bits per pixel excluding padding bits),
> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>  
>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>  const struct image_format_info *image_format_drm_lookup(u32 drm);
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>  				    int plane);
>  unsigned int image_format_plane_width(int width,
> diff --git a/lib/image-formats.c b/lib/image-formats.c
> index 9b9a73220c5d..39f1d38ae861 100644
> --- a/lib/image-formats.c
> +++ b/lib/image-formats.c
> @@ -8,6 +8,7 @@
>  static const struct image_format_info formats[] = {
>  	{
>  		.drm_fmt = DRM_FORMAT_C8,
> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB332,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>  		.depth = 8,
>  		.num_planes = 1,
>  		.cpp = { 1, 0, 0 },
> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB4444,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB1555,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
>  		.depth = 15,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB565,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
>  		.depth = 16,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_RGB888,
> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,

The V4L2 pixelformats describe the order of the components in memory, and as
such are independent of the CPU endianness. How is that for the DRM formats?

Will the order of DRM_FORMAT_RGB888 in memory differ between little and big
endian systems?

Mind you, V4L2 drivers are frankly never tested on big endian systems and I
suspect many if not all will fail miserably on details like this.

>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_BGR888,
> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 3, 0, 0 },
> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>  		.vsub = 1,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_XRGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
>  		.depth = 24,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_ARGB8888,
> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
>  		.depth = 32,
>  		.num_planes = 1,
>  		.cpp = { 4, 0, 0 },
> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>  		.has_alpha = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU410,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU420,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU422,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUV444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVU444,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
>  		.depth = 0,
>  		.num_planes = 3,
>  		.cpp = { 1, 1, 1 },
> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV12,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV21,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV16,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV61,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV24,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_NV42,
> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>  		.depth = 0,
>  		.num_planes = 2,
>  		.cpp = { 1, 2, 0 },
> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YUYV,
> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_YVYU,
> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_UYVY,
> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>  		.is_yuv = true,
>  	}, {
>  		.drm_fmt = DRM_FORMAT_VYUY,
> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>  		.depth = 0,
>  		.num_planes = 1,
>  		.cpp = { 2, 0, 0 },
> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>  EXPORT_SYMBOL(image_format_drm_lookup);
>  
>  /**
> + * __image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
> +{
> +	return __image_format_lookup(v4l2_fmt, v4l2);
> +}
> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
> +
> +/**
> + * image_format_v4l2_lookup - query information for a given format
> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
> + *
> + * The caller should only pass a supported pixel format to this function.
> + * Unsupported pixel formats will generate a warning in the kernel log.
> + *
> + * Returns:
> + * The instance of struct image_format_info that describes the pixel format, or
> + * NULL if the format is unsupported.
> + */
> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
> +{
> +	const struct image_format_info *format;
> +
> +	format = __image_format_v4l2_lookup(v4l2);
> +
> +	WARN_ON(!format);
> +	return format;
> +}
> +EXPORT_SYMBOL(image_format_v4l2_lookup);
> +
> +/**
>   * image_format_plane_cpp - determine the bytes per pixel value
>   * @format: pointer to the image_format
>   * @plane: plane index
> 

Anyway, I think this is a great improvement!

Regards,

	Hans

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-04-11  7:12   ` Hans Verkuil
@ 2019-04-11  7:15       ` Hans Verkuil
  0 siblings, 0 replies; 69+ messages in thread
From: Hans Verkuil @ 2019-04-11  7:15 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

On 4/11/19 9:12 AM, Hans Verkuil wrote:
> Hi Maxime,
> 
> Some comments below...
> 
> On 3/19/19 10:57 PM, Maxime Ripard wrote:
>> V4L2 uses different fourcc's than DRM, and has a different set of formats.
>> For now, let's add the v4l2 fourcc's for the already existing formats.
>>
>> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
>> ---
>>  include/linux/image-formats.h |  9 +++++-
>>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>>  2 files changed, 76 insertions(+)
>>
>> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
>> index 53fd73a71b3d..fbc3a4501ebd 100644
>> --- a/include/linux/image-formats.h
>> +++ b/include/linux/image-formats.h
>> @@ -26,6 +26,13 @@ struct image_format_info {
>>  	};
>>  
>>  	/**
>> +	 * @v4l2_fmt:
>> +	 *
>> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
>> +	 */
>> +	u32 v4l2_fmt;
>> +
>> +	/**
>>  	 * @depth:
>>  	 *
>>  	 * Color depth (number of bits per pixel excluding padding bits),
>> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>>  
>>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>>  const struct image_format_info *image_format_drm_lookup(u32 drm);
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>>  				    int plane);
>>  unsigned int image_format_plane_width(int width,
>> diff --git a/lib/image-formats.c b/lib/image-formats.c
>> index 9b9a73220c5d..39f1d38ae861 100644
>> --- a/lib/image-formats.c
>> +++ b/lib/image-formats.c
>> @@ -8,6 +8,7 @@
>>  static const struct image_format_info formats[] = {
>>  	{
>>  		.drm_fmt = DRM_FORMAT_C8,
>> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB332,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB565,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
>>  		.depth = 16,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> 
> The V4L2 pixelformats describe the order of the components in memory, and as
> such are independent of the CPU endianness. How is that for the DRM formats?
> 
> Will the order of DRM_FORMAT_RGB888 in memory differ between little and big
> endian systems?
> 
> Mind you, V4L2 drivers are frankly never tested on big endian systems and I
> suspect many if not all will fail miserably on details like this.

Never mind, I now see that there was a long discussion about this same topic.

	Hans

> 
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_BGR888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
>>  		.depth = 32,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV12,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV21,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV16,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV61,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV24,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV42,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUYV,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVYU,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_UYVY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_VYUY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>>  EXPORT_SYMBOL(image_format_drm_lookup);
>>  
>>  /**
>> + * __image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	return __image_format_lookup(v4l2_fmt, v4l2);
>> +}
>> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
>> +
>> +/**
>> + * image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + * Unsupported pixel formats will generate a warning in the kernel log.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	const struct image_format_info *format;
>> +
>> +	format = __image_format_v4l2_lookup(v4l2);
>> +
>> +	WARN_ON(!format);
>> +	return format;
>> +}
>> +EXPORT_SYMBOL(image_format_v4l2_lookup);
>> +
>> +/**
>>   * image_format_plane_cpp - determine the bytes per pixel value
>>   * @format: pointer to the image_format
>>   * @plane: plane index
>>
> 
> Anyway, I think this is a great improvement!
> 
> Regards,
> 
> 	Hans
> 


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
@ 2019-04-11  7:15       ` Hans Verkuil
  0 siblings, 0 replies; 69+ messages in thread
From: Hans Verkuil @ 2019-04-11  7:15 UTC (permalink / raw)
  To: Maxime Ripard, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, linux-kernel, dri-devel, Paul Kocialkowski,
	Hans Verkuil, Laurent Pinchart, Thomas Petazzoni, linux-media

On 4/11/19 9:12 AM, Hans Verkuil wrote:
> Hi Maxime,
> 
> Some comments below...
> 
> On 3/19/19 10:57 PM, Maxime Ripard wrote:
>> V4L2 uses different fourcc's than DRM, and has a different set of formats.
>> For now, let's add the v4l2 fourcc's for the already existing formats.
>>
>> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
>> ---
>>  include/linux/image-formats.h |  9 +++++-
>>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>>  2 files changed, 76 insertions(+)
>>
>> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
>> index 53fd73a71b3d..fbc3a4501ebd 100644
>> --- a/include/linux/image-formats.h
>> +++ b/include/linux/image-formats.h
>> @@ -26,6 +26,13 @@ struct image_format_info {
>>  	};
>>  
>>  	/**
>> +	 * @v4l2_fmt:
>> +	 *
>> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
>> +	 */
>> +	u32 v4l2_fmt;
>> +
>> +	/**
>>  	 * @depth:
>>  	 *
>>  	 * Color depth (number of bits per pixel excluding padding bits),
>> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>>  
>>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>>  const struct image_format_info *image_format_drm_lookup(u32 drm);
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>>  				    int plane);
>>  unsigned int image_format_plane_width(int width,
>> diff --git a/lib/image-formats.c b/lib/image-formats.c
>> index 9b9a73220c5d..39f1d38ae861 100644
>> --- a/lib/image-formats.c
>> +++ b/lib/image-formats.c
>> @@ -8,6 +8,7 @@
>>  static const struct image_format_info formats[] = {
>>  	{
>>  		.drm_fmt = DRM_FORMAT_C8,
>> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB332,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB565,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
>>  		.depth = 16,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> 
> The V4L2 pixelformats describe the order of the components in memory, and as
> such are independent of the CPU endianness. How is that for the DRM formats?
> 
> Will the order of DRM_FORMAT_RGB888 in memory differ between little and big
> endian systems?
> 
> Mind you, V4L2 drivers are frankly never tested on big endian systems and I
> suspect many if not all will fail miserably on details like this.

Never mind, I now see that there was a long discussion about this same topic.

	Hans

> 
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_BGR888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
>>  		.depth = 32,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV12,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV21,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV16,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV61,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV24,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV42,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUYV,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVYU,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_UYVY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_VYUY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>>  EXPORT_SYMBOL(image_format_drm_lookup);
>>  
>>  /**
>> + * __image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	return __image_format_lookup(v4l2_fmt, v4l2);
>> +}
>> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
>> +
>> +/**
>> + * image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + * Unsupported pixel formats will generate a warning in the kernel log.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	const struct image_format_info *format;
>> +
>> +	format = __image_format_v4l2_lookup(v4l2);
>> +
>> +	WARN_ON(!format);
>> +	return format;
>> +}
>> +EXPORT_SYMBOL(image_format_v4l2_lookup);
>> +
>> +/**
>>   * image_format_plane_cpp - determine the bytes per pixel value
>>   * @format: pointer to the image_format
>>   * @plane: plane index
>>
> 
> Anyway, I think this is a great improvement!
> 
> Regards,
> 
> 	Hans
> 

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

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-04-01 14:44     ` Maxime Ripard
@ 2019-04-11  7:24       ` Hans Verkuil
  0 siblings, 0 replies; 69+ messages in thread
From: Hans Verkuil @ 2019-04-11  7:24 UTC (permalink / raw)
  To: Maxime Ripard, Nicolas Dufresne
  Cc: Daniel Vetter, David Airlie, Maarten Lankhorst, Sean Paul,
	Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, Paul Kocialkowski, dri-devel,
	linux-kernel, linux-media

On 4/1/19 4:44 PM, Maxime Ripard wrote:
> Hi Nicolas,
> 
> On Fri, Mar 22, 2019 at 03:55:19PM -0400, Nicolas Dufresne wrote:
>> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
>>> V4L2 uses different fourcc's than DRM, and has a different set of formats.
>>> For now, let's add the v4l2 fourcc's for the already existing formats.
>>
>> Hopefully I get the fixup right this time, see inline.
> 
> Thanks a lot for that extensive review.
> 
> About the single vs multi-planar issue, I'd be inclined with just
> supporting single-planar formats for now, and extend it later to deal
> with multiplanar formats.
> 
> Would that work for everyone?

I'd say that is the right approach.

Regards,

	Hans

> 
> Maxime
> 
> --
> Maxime Ripard, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com
> 


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-03-22 19:55   ` Nicolas Dufresne
  2019-04-01 14:44     ` Maxime Ripard
@ 2019-04-11  7:38     ` Hans Verkuil
  2019-04-11 15:55       ` Maxime Ripard
  1 sibling, 1 reply; 69+ messages in thread
From: Hans Verkuil @ 2019-04-11  7:38 UTC (permalink / raw)
  To: Nicolas Dufresne, Maxime Ripard, Daniel Vetter, David Airlie,
	Maarten Lankhorst, Sean Paul, Mauro Carvalho Chehab
  Cc: Sakari Ailus, Hans Verkuil, Laurent Pinchart, Thomas Petazzoni,
	Paul Kocialkowski, dri-devel, linux-kernel, linux-media

On 3/22/19 8:55 PM, Nicolas Dufresne wrote:
> Le mardi 19 mars 2019 à 22:57 +0100, Maxime Ripard a écrit :
>> V4L2 uses different fourcc's than DRM, and has a different set of formats.
>> For now, let's add the v4l2 fourcc's for the already existing formats.
> 
> Hopefully I get the fixup right this time, see inline.
> 
>>
>> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
>> ---
>>  include/linux/image-formats.h |  9 +++++-
>>  lib/image-formats.c           | 67 ++++++++++++++++++++++++++++++++++++-
>>  2 files changed, 76 insertions(+)
>>
>> diff --git a/include/linux/image-formats.h b/include/linux/image-formats.h
>> index 53fd73a71b3d..fbc3a4501ebd 100644
>> --- a/include/linux/image-formats.h
>> +++ b/include/linux/image-formats.h
>> @@ -26,6 +26,13 @@ struct image_format_info {
>>  	};
>>  
>>  	/**
>> +	 * @v4l2_fmt:
>> +	 *
>> +	 * V4L2 4CC format identifier (V4L2_PIX_FMT_*)
>> +	 */
>> +	u32 v4l2_fmt;
>> +
>> +	/**
>>  	 * @depth:
>>  	 *
>>  	 * Color depth (number of bits per pixel excluding padding bits),
>> @@ -222,6 +229,8 @@ image_format_info_is_yuv_sampling_444(const struct image_format_info *info)
>>  
>>  const struct image_format_info *__image_format_drm_lookup(u32 drm);
>>  const struct image_format_info *image_format_drm_lookup(u32 drm);
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2);
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2);
>>  unsigned int image_format_plane_cpp(const struct image_format_info *format,
>>  				    int plane);
>>  unsigned int image_format_plane_width(int width,
>> diff --git a/lib/image-formats.c b/lib/image-formats.c
>> index 9b9a73220c5d..39f1d38ae861 100644
>> --- a/lib/image-formats.c
>> +++ b/lib/image-formats.c
>> @@ -8,6 +8,7 @@
>>  static const struct image_format_info formats[] = {
>>  	{
>>  		.drm_fmt = DRM_FORMAT_C8,
>> +		.v4l2_fmt = V4L2_PIX_FMT_GREY,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -15,6 +16,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB332,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB332,
>>  		.depth = 8,
>>  		.num_planes = 1,
>>  		.cpp = { 1, 0, 0 },
>> @@ -29,6 +31,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB444,
> 
> Not completely sure, looks like in the V4L2 variant, the padding is on
> the 4 MSB of the second byte, which makes it incompatible. There is no
> other equivalent.
> 
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -57,6 +60,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB4444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB444,
> 
> Similarly.
> 
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -89,6 +93,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB555,
> 
> Same swapping, can't find a match.
> 
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -117,6 +122,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB1555,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB555,
> 
> Same.
> 
>>  		.depth = 15,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB565,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> 
> -> V4L2_PIX_FMT_RGB565X
> 
> Was added later, as what you expect is not compatible.

All these 16-bit V4L2 pixelformats are ancient, but they are (to my knowledge)
correct w.r.t. the documented layout of the bits in memory. I.e., that's what
the hardware will give you.

I think if there is no equivalence between the drm and v4l2 fourcc's, then
you need two entries in this table, one for drm (v4l2_fmt == 0), one for v4l2
(drm_fmt == 0).

> 
>>  		.depth = 16,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -163,6 +170,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_RGB888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_RGB24,
> 
> -> V4L2_PIX_FMT_BGR24
> 
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -170,6 +178,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_BGR888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_BGR24,
> 
> -> V4L2_PIX_FMT_RGB24
> 
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 3, 0, 0 },
>> @@ -177,6 +186,7 @@ static const struct image_format_info formats[] = {
>>  		.vsub = 1,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_XRGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_XRGB32,
> 
> -> V4L2_PIX_FMT_XBGR32
> 
>>  		.depth = 24,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -281,6 +291,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_ARGB8888,
>> +		.v4l2_fmt = V4L2_PIX_FMT_ARGB32,
> 
> -> V4L2_PIX_FMT_ABGR32
> 
>>  		.depth = 32,
>>  		.num_planes = 1,
>>  		.cpp = { 4, 0, 0 },
>> @@ -361,6 +372,7 @@ static const struct image_format_info formats[] = {
>>  		.has_alpha = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -369,6 +381,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU410,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU410,
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -393,6 +406,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV420M,
> 
> There is two valid matches in V4L2 for this format, not sure how this
> will be handled. The M variant is to be used with MPLANE v4l2_buffer
> when num_planes is bigger then 1.

We should use the non-multiplanar variant (without the M). At least for now.

> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -401,6 +415,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU420,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU420M,
> 
> Same.
> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -409,6 +424,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV422M,
> 
> Same.
> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -417,6 +433,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU422,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU422M,
> 
> Same. 
> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -425,6 +442,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUV444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUV444M,
> 
> Same.
> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -433,6 +451,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVU444,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVU444M,
> 
> Same.
> 
>>  		.depth = 0,
>>  		.num_planes = 3,
>>  		.cpp = { 1, 1, 1 },
>> @@ -441,6 +460,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV12,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV12,
> 
> V4L2_PIX_FMT_NV12M is the mplane variant. Depending on how you handle,
> which should be concistant picking one up.
> 
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -449,6 +469,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV21,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV21,
> 
> Same, NV12M for mplane.
> 
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -457,6 +478,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV16,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV16,
> 
> Same, NV16M.
> 
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -465,6 +487,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV61,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV61,
> 
> Same, NV61M.
> 
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV24,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> 
> For extra fun, the M variant has not been added yet.

Note that it has been the practice in V4L2 to avoid adding pixelformats unless
they are in use by a V4L2 driver. So that's why some combinations do not exist.

If we are creating a common library then I think we should change that rule
to: "unless they are in use by a DRM or V4L2 driver". And when new formats are
added, and they exists already for DRM or V4L2, then we should use the same
fourcc for the other subsystem.

I.e. if pixelformat V4L2_PIX_FMT_FOO was already defined, then add a:

#define DRM_FORMAT_FOO V4L2_PIX_FMT_FOO

rather than creating a new fourcc.

We could even start looking at redoing the whole scheme in a unified way, but
that's something for the (far) future.

This is already a big step forward.

Regards,

	Hans

> 
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -481,6 +505,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_NV42,
>> +		.v4l2_fmt = V4L2_PIX_FMT_NV42,
>>  		.depth = 0,
>>  		.num_planes = 2,
>>  		.cpp = { 1, 2, 0 },
>> @@ -489,6 +514,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YUYV,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YUYV,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -497,6 +523,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_YVYU,
>> +		.v4l2_fmt = V4L2_PIX_FMT_YVYU,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -505,6 +532,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_UYVY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_UYVY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -513,6 +541,7 @@ static const struct image_format_info formats[] = {
>>  		.is_yuv = true,
>>  	}, {
>>  		.drm_fmt = DRM_FORMAT_VYUY,
>> +		.v4l2_fmt = V4L2_PIX_FMT_VYUY,
>>  		.depth = 0,
>>  		.num_planes = 1,
>>  		.cpp = { 2, 0, 0 },
>> @@ -632,6 +661,44 @@ const struct image_format_info *image_format_drm_lookup(u32 drm)
>>  EXPORT_SYMBOL(image_format_drm_lookup);
>>  
>>  /**
>> + * __image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *__image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	return __image_format_lookup(v4l2_fmt, v4l2);
>> +}
>> +EXPORT_SYMBOL(__image_format_v4l2_lookup);
>> +
>> +/**
>> + * image_format_v4l2_lookup - query information for a given format
>> + * @v4l2: V4L2 fourcc pixel format (V4L2_PIX_FMT_*)
>> + *
>> + * The caller should only pass a supported pixel format to this function.
>> + * Unsupported pixel formats will generate a warning in the kernel log.
>> + *
>> + * Returns:
>> + * The instance of struct image_format_info that describes the pixel format, or
>> + * NULL if the format is unsupported.
>> + */
>> +const struct image_format_info *image_format_v4l2_lookup(u32 v4l2)
>> +{
>> +	const struct image_format_info *format;
>> +
>> +	format = __image_format_v4l2_lookup(v4l2);
>> +
>> +	WARN_ON(!format);
>> +	return format;
>> +}
>> +EXPORT_SYMBOL(image_format_v4l2_lookup);
>> +
>> +/**
>>   * image_format_plane_cpp - determine the bytes per pixel value
>>   * @format: pointer to the image_format
>>   * @plane: plane index


^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support
  2019-04-11  7:38     ` Hans Verkuil
@ 2019-04-11 15:55       ` Maxime Ripard
  0 siblings, 0 replies; 69+ messages in thread
From: Maxime Ripard @ 2019-04-11 15:55 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Nicolas Dufresne, Daniel Vetter, David Airlie, Maarten Lankhorst,
	Sean Paul, Mauro Carvalho Chehab, Sakari Ailus, Hans Verkuil,
	Laurent Pinchart, Thomas Petazzoni, Paul Kocialkowski, dri-devel,
	linux-kernel, linux-media

[-- Attachment #1: Type: text/plain, Size: 2141 bytes --]

Hi,

On Thu, Apr 11, 2019 at 09:38:06AM +0200, Hans Verkuil wrote:
> >> @@ -149,6 +155,7 @@ static const struct image_format_info formats[] = {
> >>  		.has_alpha = true,
> >>  	}, {
> >>  		.drm_fmt = DRM_FORMAT_RGB565,
> >> +		.v4l2_fmt = V4L2_PIX_FMT_RGB565,
> >
> > -> V4L2_PIX_FMT_RGB565X
> >
> > Was added later, as what you expect is not compatible.
>
> All these 16-bit V4L2 pixelformats are ancient, but they are (to my knowledge)
> correct w.r.t. the documented layout of the bits in memory. I.e., that's what
> the hardware will give you.
>
> I think if there is no equivalence between the drm and v4l2 fourcc's, then
> you need two entries in this table, one for drm (v4l2_fmt == 0), one for v4l2
> (drm_fmt == 0).

Yeah, that was my plan. I'd definitely expect some formats in V4L2
while not supported by DRM, or the other way around.

> >> @@ -473,6 +496,7 @@ static const struct image_format_info formats[] = {
> >>  		.is_yuv = true,
> >>  	}, {
> >>  		.drm_fmt = DRM_FORMAT_NV24,
> >> +		.v4l2_fmt = V4L2_PIX_FMT_NV24,
> >
> > For extra fun, the M variant has not been added yet.
>
> Note that it has been the practice in V4L2 to avoid adding pixelformats unless
> they are in use by a V4L2 driver. So that's why some combinations do not exist.
>
> If we are creating a common library then I think we should change that rule
> to: "unless they are in use by a DRM or V4L2 driver". And when new formats are
> added, and they exists already for DRM or V4L2, then we should use the same
> fourcc for the other subsystem.
>
> I.e. if pixelformat V4L2_PIX_FMT_FOO was already defined, then add a:
>
> #define DRM_FORMAT_FOO V4L2_PIX_FMT_FOO
>
> rather than creating a new fourcc.

That makes sense

> We could even start looking at redoing the whole scheme in a unified way, but
> that's something for the (far) future.

Yeah, my secret plan is to have eventually a single fourcc (or even
#define) for both DRM and v4l2 for any new format. But don't tell
anyone :)

> This is already a big step forward.

Great, I'll respin this then.

Maxime

--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2019-04-11 15:55 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-19 21:57 [RFC PATCH 00/20] drm: Split out the formats API and move it to a common place Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 01/20] drm: Remove users of drm_format_num_planes Maxime Ripard
2019-03-20 14:16   ` Paul Kocialkowski
2019-04-02  9:43   ` Emil Velikov
2019-04-02 14:51     ` Maxime Ripard
2019-04-04 16:24       ` Emil Velikov
2019-03-19 21:57 ` [RFC PATCH 02/20] drm: Remove users of drm_format_(horz|vert)_chroma_subsampling Maxime Ripard
2019-03-20 14:19   ` Paul Kocialkowski
2019-03-20 14:19     ` Paul Kocialkowski
2019-03-19 21:57 ` [RFC PATCH 03/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_cpp Maxime Ripard
2019-03-19 21:57   ` Maxime Ripard
2019-03-20 14:24   ` Paul Kocialkowski
2019-03-21 10:13     ` Maxime Ripard
2019-03-21 10:13       ` Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 04/20] drm/fourcc: Pass the format_info pointer to drm_format_plane_width/height Maxime Ripard
2019-03-20 14:26   ` Paul Kocialkowski
2019-03-19 21:57 ` [RFC PATCH 05/20] drm: Replace instances of drm_format_info by drm_get_format_info Maxime Ripard
2019-03-20 14:27   ` Paul Kocialkowski
2019-03-19 21:57 ` [RFC PATCH 06/20] lib: Add video format information library Maxime Ripard
2019-03-19 21:57   ` Maxime Ripard
2019-03-20 13:39   ` Boris Brezillon
2019-03-21  8:20     ` Maxime Ripard
2019-03-21  8:20       ` Maxime Ripard
2019-03-21  8:40       ` Boris Brezillon
2019-03-19 21:57 ` [RFC PATCH 07/20] drm/fb: Move from drm_format_info to image_format_info Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 08/20] drm/malidp: Convert to generic image format library Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 09/20] drm/client: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 10/20] drm/exynos: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 11/20] drm/i915: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 12/20] drm/ipuv3: " Maxime Ripard
2019-03-19 21:57   ` Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 13/20] drm/msm: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 14/20] drm/omap: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 15/20] drm/rockchip: " Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 16/20] drm/tegra: " Maxime Ripard
2019-03-19 21:57   ` Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 17/20] drm/fourcc: Remove old DRM format API Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 18/20] lib: image-formats: Add v4l2 formats support Maxime Ripard
2019-03-19 23:29   ` Nicolas Dufresne
2019-03-20 14:27     ` Ville Syrjälä
2019-03-20 15:51       ` Nicolas Dufresne
2019-03-20 16:09         ` Ville Syrjälä
2019-03-20 16:30           ` Nicolas Dufresne
2019-03-20 16:41             ` Ville Syrjälä
2019-03-20 18:27               ` Nicolas Dufresne
2019-03-20 18:39                 ` Ville Syrjälä
2019-03-21 16:04                   ` Paul Kocialkowski
2019-03-21 16:04                     ` Paul Kocialkowski
2019-03-21 16:35                     ` Ville Syrjälä
2019-03-21 19:14                       ` Nicolas Dufresne
2019-03-21 21:44                         ` Ville Syrjälä
2019-03-22 18:24                           ` Nicolas Dufresne
2019-03-22 18:44                             ` Ville Syrjälä
2019-03-22 19:25                               ` Nicolas Dufresne
2019-03-22 14:42                         ` Ville Syrjälä
2019-03-22 18:11                           ` Nicolas Dufresne
2019-03-20 18:15     ` Brian Starkey
2019-03-21 15:47       ` Maxime Ripard
2019-03-22 19:55   ` Nicolas Dufresne
2019-04-01 14:44     ` Maxime Ripard
2019-04-11  7:24       ` Hans Verkuil
2019-04-11  7:38     ` Hans Verkuil
2019-04-11 15:55       ` Maxime Ripard
2019-04-11  7:12   ` Hans Verkuil
2019-04-11  7:15     ` Hans Verkuil
2019-04-11  7:15       ` Hans Verkuil
2019-03-19 21:57 ` [RFC PATCH 19/20] lib: image-formats: Add more functions Maxime Ripard
2019-03-19 21:57   ` Maxime Ripard
2019-03-19 21:57 ` [RFC PATCH 20/20] media: sun6i: Convert to the image format API Maxime Ripard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.