Blob Blame History Raw
From: Linus Walleij <linus.walleij@linaro.org>
Date: Tue, 6 Feb 2018 10:35:39 +0100
Subject: drm/pl111: Support variants with broken VBLANK
Git-commit: 08e3211251e36a506ff6b0c31620e362b5800f47
Patch-mainline: v4.17-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

The early Integrator CLCD synthesized in the Integrator CP and
IM-PD1 FPGAs are broken: their vertical and next base interrupts
are not functional. Support these variants by simply disabling
the use of the vblank interrupt on these variants.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20180206093540.8147-4-linus.walleij@linaro.org

Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/pl111/pl111_display.c   |    6 ++++--
 drivers/gpu/drm/pl111/pl111_drm.h       |    2 ++
 drivers/gpu/drm/pl111/pl111_drv.c       |   19 +++++++++++--------
 drivers/gpu/drm/pl111/pl111_versatile.c |    1 +
 4 files changed, 18 insertions(+), 10 deletions(-)

--- a/drivers/gpu/drm/pl111/pl111_display.c
+++ b/drivers/gpu/drm/pl111/pl111_display.c
@@ -256,7 +256,8 @@ static void pl111_display_enable(struct
 	cntl |= CNTL_LCDPWR;
 	writel(cntl, priv->regs + priv->ctrl);
 
-	drm_crtc_vblank_on(crtc);
+	if (!priv->variant->broken_vblank)
+		drm_crtc_vblank_on(crtc);
 }
 
 void pl111_display_disable(struct drm_simple_display_pipe *pipe)
@@ -266,7 +267,8 @@ void pl111_display_disable(struct drm_si
 	struct pl111_drm_dev_private *priv = drm->dev_private;
 	u32 cntl;
 
-	drm_crtc_vblank_off(crtc);
+	if (!priv->variant->broken_vblank)
+		drm_crtc_vblank_off(crtc);
 
 	/* Power Down */
 	cntl = readl(priv->regs + priv->ctrl);
--- a/drivers/gpu/drm/pl111/pl111_drm.h
+++ b/drivers/gpu/drm/pl111/pl111_drm.h
@@ -40,6 +40,7 @@ struct drm_minor;
  *	BGR/RGB routing
  * @broken_clockdivider: the clock divider is broken and we need to
  *	use the supplied clock directly
+ * @broken_vblank: the vblank IRQ is broken on this variant
  * @formats: array of supported pixel formats on this variant
  * @nformats: the length of the array of supported pixel formats
  */
@@ -48,6 +49,7 @@ struct pl111_variant_data {
 	bool is_pl110;
 	bool external_bgr;
 	bool broken_clockdivider;
+	bool broken_vblank;
 	const u32 *formats;
 	unsigned int nformats;
 };
--- a/drivers/gpu/drm/pl111/pl111_drv.c
+++ b/drivers/gpu/drm/pl111/pl111_drv.c
@@ -132,10 +132,12 @@ static int pl111_modeset_init(struct drm
 	if (ret)
 		return ret;
 
-	ret = drm_vblank_init(dev, 1);
-	if (ret != 0) {
-		dev_err(dev->dev, "Failed to init vblank\n");
-		goto out_bridge;
+	if (!priv->variant->broken_vblank) {
+		ret = drm_vblank_init(dev, 1);
+		if (ret != 0) {
+			dev_err(dev->dev, "Failed to init vblank\n");
+			goto out_bridge;
+		}
 	}
 
 	drm_mode_config_reset(dev);
@@ -172,10 +174,6 @@ static struct drm_driver pl111_drm_drive
 	.dumb_create = drm_gem_cma_dumb_create,
 	.gem_free_object_unlocked = drm_gem_cma_free_object,
 	.gem_vm_ops = &drm_gem_cma_vm_ops,
-
-	.enable_vblank = pl111_enable_vblank,
-	.disable_vblank = pl111_disable_vblank,
-
 	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
 	.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
 	.gem_prime_import = drm_gem_prime_import,
@@ -201,6 +199,11 @@ static int pl111_amba_probe(struct amba_
 	if (!priv)
 		return -ENOMEM;
 
+	if (!variant->broken_vblank) {
+		pl111_drm_driver.enable_vblank = pl111_enable_vblank;
+		pl111_drm_driver.disable_vblank = pl111_disable_vblank;
+	}
+
 	drm = drm_dev_alloc(&pl111_drm_driver, dev);
 	if (IS_ERR(drm))
 		return PTR_ERR(drm);
--- a/drivers/gpu/drm/pl111/pl111_versatile.c
+++ b/drivers/gpu/drm/pl111/pl111_versatile.c
@@ -238,6 +238,7 @@ static const struct pl111_variant_data p
 	.name = "PL110 Integrator",
 	.is_pl110 = true,
 	.broken_clockdivider = true,
+	.broken_vblank = true,
 	.formats = pl110_integrator_pixel_formats,
 	.nformats = ARRAY_SIZE(pl110_integrator_pixel_formats),
 };