Blob Blame History Raw
From: Thierry Reding <treding@nvidia.com>
Date: Mon, 8 Jan 2018 16:11:00 +0100
Subject: drm/tegra: dc: Fix possible_crtcs mask for planes
Git-commit: 89f6501825b5bae3d4aaa2447636f9d3a4287a75
Patch-mainline: v4.16-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Cursor and overlay planes use a possible_crtcs mask based on the DC pipe
number. However, DRM requires each bit in the mask to correspond to the
index of the CRTC, which will be different from the DC pipe number for a
configuration where the first display controller is disabled, or where a
deferred probe leads to the first display controller being probed after
the first.

Suggested-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/tegra/dc.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -572,8 +572,7 @@ static const struct drm_plane_helper_fun
 	.atomic_update = tegra_plane_atomic_update,
 };
 
-static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
-						    struct tegra_dc *dc)
+static unsigned long tegra_plane_get_possible_crtcs(struct drm_device *drm)
 {
 	/*
 	 * Ideally this would use drm_crtc_mask(), but that would require the
@@ -587,7 +586,13 @@ static struct drm_plane *tegra_primary_p
 	 * of CRTCs that have been registered, and should therefore always be
 	 * the same as drm_crtc_index() after registration.
 	 */
-	unsigned long possible_crtcs = 1 << drm->mode_config.num_crtc;
+	return 1 << drm->mode_config.num_crtc;
+}
+
+static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
+						    struct tegra_dc *dc)
+{
+	unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
 	enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY;
 	struct tegra_plane *plane;
 	unsigned int num_formats;
@@ -744,6 +749,7 @@ static const struct drm_plane_helper_fun
 static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
 						      struct tegra_dc *dc)
 {
+	unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
 	struct tegra_plane *plane;
 	unsigned int num_formats;
 	const u32 *formats;
@@ -766,7 +772,7 @@ static struct drm_plane *tegra_dc_cursor
 	num_formats = ARRAY_SIZE(tegra_cursor_plane_formats);
 	formats = tegra_cursor_plane_formats;
 
-	err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
+	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, NULL,
 				       DRM_PLANE_TYPE_CURSOR, NULL);
@@ -860,6 +866,7 @@ static struct drm_plane *tegra_dc_overla
 						       struct tegra_dc *dc,
 						       unsigned int index)
 {
+	unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
 	struct tegra_plane *plane;
 	unsigned int num_formats;
 	const u32 *formats;
@@ -876,7 +883,7 @@ static struct drm_plane *tegra_dc_overla
 	num_formats = dc->soc->num_overlay_formats;
 	formats = dc->soc->overlay_formats;
 
-	err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
+	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, NULL,
 				       DRM_PLANE_TYPE_OVERLAY, NULL);