Blob Blame History Raw
From: Thierry Reding <treding@nvidia.com>
Date: Thu, 15 Mar 2018 16:44:04 +0100
Subject: drm/tegra: plane: Support format modifiers
Git-commit: e90124cb46bdb6b8dd642e0066207ace0fc3f972
Patch-mainline: v4.17-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Pass the list of valid format modifiers to planes upon initialization
and implement the ->format_mod_supported() callback so that userspace
can query for the valid combinations of formats and modifiers.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/tegra/dc.c    |   26 +++++++++++++++++++++++++-
 drivers/gpu/drm/tegra/dc.h    |    1 +
 drivers/gpu/drm/tegra/hub.c   |   15 ++++++++++++++-
 drivers/gpu/drm/tegra/plane.c |   16 ++++++++++++++++
 4 files changed, 56 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -383,6 +383,12 @@ static const u32 tegra20_primary_formats
 	DRM_FORMAT_XRGB8888,
 };
 
+static const u64 tegra20_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED,
+	DRM_FORMAT_MOD_INVALID
+};
+
 static const u32 tegra114_primary_formats[] = {
 	DRM_FORMAT_ARGB4444,
 	DRM_FORMAT_ARGB1555,
@@ -430,6 +436,17 @@ static const u32 tegra124_primary_format
 	DRM_FORMAT_BGRX8888,
 };
 
+static const u64 tegra124_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
+	DRM_FORMAT_MOD_INVALID
+};
+
 static int tegra_plane_atomic_check(struct drm_plane *plane,
 				    struct drm_plane_state *state)
 {
@@ -596,6 +613,7 @@ static struct drm_plane *tegra_primary_p
 	enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY;
 	struct tegra_plane *plane;
 	unsigned int num_formats;
+	const u64 *modifiers;
 	const u32 *formats;
 	int err;
 
@@ -610,10 +628,11 @@ static struct drm_plane *tegra_primary_p
 
 	num_formats = dc->soc->num_primary_formats;
 	formats = dc->soc->primary_formats;
+	modifiers = dc->soc->modifiers;
 
 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
-				       num_formats, NULL, type, NULL);
+				       num_formats, modifiers, type, NULL);
 	if (err < 0) {
 		kfree(plane);
 		return ERR_PTR(err);
@@ -1984,6 +2003,7 @@ static const struct tegra_dc_soc_info te
 	.primary_formats = tegra20_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
 	.overlay_formats = tegra20_overlay_formats,
+	.modifiers = tegra20_modifiers,
 };
 
 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -2000,6 +2020,7 @@ static const struct tegra_dc_soc_info te
 	.primary_formats = tegra20_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra20_overlay_formats),
 	.overlay_formats = tegra20_overlay_formats,
+	.modifiers = tegra20_modifiers,
 };
 
 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -2016,6 +2037,7 @@ static const struct tegra_dc_soc_info te
 	.primary_formats = tegra114_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
 	.overlay_formats = tegra114_overlay_formats,
+	.modifiers = tegra20_modifiers,
 };
 
 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -2032,6 +2054,7 @@ static const struct tegra_dc_soc_info te
 	.primary_formats = tegra124_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra124_overlay_formats),
 	.overlay_formats = tegra124_overlay_formats,
+	.modifiers = tegra124_modifiers,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2048,6 +2071,7 @@ static const struct tegra_dc_soc_info te
 	.primary_formats = tegra114_primary_formats,
 	.num_overlay_formats = ARRAY_SIZE(tegra114_overlay_formats),
 	.overlay_formats = tegra114_overlay_formats,
+	.modifiers = tegra124_modifiers,
 };
 
 static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -66,6 +66,7 @@ struct tegra_dc_soc_info {
 	unsigned int num_primary_formats;
 	const u32 *overlay_formats;
 	unsigned int num_overlay_formats;
+	const u64 *modifiers;
 };
 
 struct tegra_dc {
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -49,6 +49,17 @@ static const u32 tegra_shared_plane_form
 	DRM_FORMAT_YUV422,
 };
 
+static const u64 tegra_shared_plane_modifiers[] = {
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4),
+	DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5),
+	DRM_FORMAT_MOD_INVALID
+};
+
 static inline unsigned int tegra_plane_offset(struct tegra_plane *plane,
 					      unsigned int offset)
 {
@@ -527,6 +538,7 @@ struct drm_plane *tegra_shared_plane_cre
 	unsigned int possible_crtcs = 0x7;
 	struct tegra_shared_plane *plane;
 	unsigned int num_formats;
+	const u64 *modifiers;
 	struct drm_plane *p;
 	const u32 *formats;
 	int err;
@@ -545,10 +557,11 @@ struct drm_plane *tegra_shared_plane_cre
 
 	num_formats = ARRAY_SIZE(tegra_shared_plane_formats);
 	formats = tegra_shared_plane_formats;
+	modifiers = tegra_shared_plane_modifiers;
 
 	err = drm_universal_plane_init(drm, p, possible_crtcs,
 				       &tegra_plane_funcs, formats,
-				       num_formats, NULL, type, NULL);
+				       num_formats, modifiers, type, NULL);
 	if (err < 0) {
 		kfree(plane);
 		return ERR_PTR(err);
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -68,6 +68,21 @@ static void tegra_plane_atomic_destroy_s
 	kfree(state);
 }
 
+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);
+
+	if (modifier == DRM_FORMAT_MOD_LINEAR)
+		return true;
+
+	if (info->num_planes == 1)
+		return true;
+
+	return false;
+}
+
 const struct drm_plane_funcs tegra_plane_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
@@ -75,6 +90,7 @@ const struct drm_plane_funcs tegra_plane
 	.reset = tegra_plane_reset,
 	.atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
 	.atomic_destroy_state = tegra_plane_atomic_destroy_state,
+	.format_mod_supported = tegra_plane_format_mod_supported,
 };
 
 int tegra_plane_state_add(struct tegra_plane *plane,