vc4: hopefully improve the vblank crash issues

This commit is contained in:
Peter Robinson 2017-06-26 10:25:22 +01:00
parent f812443471
commit bb6904669c
2 changed files with 194 additions and 21 deletions

View File

@ -0,0 +1,165 @@
From e487709ee89a572a3a8068f33e9275479fde9bf4 Mon Sep 17 00:00:00 2001
From: Boris Brezillon <boris.brezillon@free-electrons.com>
Date: Fri, 16 Jun 2017 10:30:33 +0200
Subject: [PATCH 1/2] drm/vc4: Send a VBLANK event when disabling a CRTC
VBLANK events are missed when the CRTC is being disabled because the
driver does not wait till the end of the frame before stopping the
HVS and PV blocks. In this case, we should explicitly issue a VBLANK
event if there's one waiting.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 9fcf05ca492b..66cffc548af2 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -526,6 +526,19 @@ static void vc4_crtc_disable(struct drm_crtc *crtc)
WARN_ON_ONCE((HVS_READ(SCALER_DISPSTATX(chan)) &
(SCALER_DISPSTATX_FULL | SCALER_DISPSTATX_EMPTY)) !=
SCALER_DISPSTATX_EMPTY);
+
+ /*
+ * Make sure we issue a vblank event after disabling the CRTC if
+ * someone was waiting it.
+ */
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ drm_crtc_send_vblank_event(crtc, crtc->state->event);
+ crtc->state->event = NULL;
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ }
}
static void vc4_crtc_enable(struct drm_crtc *crtc)
--
2.13.0
From 6c9d1ad4c10657d7d6f8455088686abee1805102 Mon Sep 17 00:00:00 2001
From: Peter Robinson <pbrobinson@gmail.com>
Date: Mon, 26 Jun 2017 09:03:28 +0100
Subject: [PATCH 2/2] drm/vc4: Fix VBLANK handling in crtc->enable() path
When we are enabling a CRTC, drm_crtc_vblank_get() is called before
drm_crtc_vblank_on(), which is not supposed to happen (hence the
WARN_ON() in the code). To solve the problem, we delay the 'update
display list' operation after the CRTC is actually enabled.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
---
drivers/gpu/drm/vc4/vc4_crtc.c | 66 +++++++++++++++++++++++++++---------------
1 file changed, 43 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 66cffc548af2..47a8ef0a755d 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -541,6 +541,34 @@ static void vc4_crtc_disable(struct drm_crtc *crtc)
}
}
+static void vc4_crtc_update_dlist(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(dev);
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
+
+ if (crtc->state->event) {
+ unsigned long flags;
+
+ crtc->state->event->pipe = drm_crtc_index(crtc);
+
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ vc4_crtc->event = crtc->state->event;
+ crtc->state->event = NULL;
+
+ HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+ vc4_state->mm.start);
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+ } else {
+ HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
+ vc4_state->mm.start);
+ }
+}
+
static void vc4_crtc_enable(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
@@ -551,6 +579,12 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
require_hvs_enabled(dev);
+ /* Enable vblank irq handling before crtc is started otherwise
+ * drm_crtc_get_vblank() fails in vc4_crtc_update_dlist().
+ */
+ drm_crtc_vblank_on(crtc);
+ vc4_crtc_update_dlist(crtc);
+
/* Turn on the scaler, which will wait for vstart to start
* compositing.
*/
@@ -562,9 +596,6 @@ static void vc4_crtc_enable(struct drm_crtc *crtc)
/* Turn on the pixel valve, which will emit the vstart signal. */
CRTC_WRITE(PV_V_CONTROL,
CRTC_READ(PV_V_CONTROL) | PV_VCONTROL_VIDEN);
-
- /* Enable vblank irq handling after crtc is started. */
- drm_crtc_vblank_on(crtc);
}
static bool vc4_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -619,7 +650,6 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
- struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state);
struct drm_plane *plane;
bool debug_dump_regs = false;
@@ -641,25 +671,15 @@ static void vc4_crtc_atomic_flush(struct drm_crtc *crtc,
WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size);
- if (crtc->state->event) {
- unsigned long flags;
-
- crtc->state->event->pipe = drm_crtc_index(crtc);
-
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
-
- spin_lock_irqsave(&dev->event_lock, flags);
- vc4_crtc->event = crtc->state->event;
- crtc->state->event = NULL;
-
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
- vc4_state->mm.start);
-
- spin_unlock_irqrestore(&dev->event_lock, flags);
- } else {
- HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel),
- vc4_state->mm.start);
- }
+ /* Only update DISPLIST if the CRTC was already running and is not
+ * being disabled.
+ * vc4_crtc_enable() takes care of updating the dlist just after
+ * re-enabling VBLANK interrupts and before enabling the engine.
+ * If the CRTC is being disabled, there's no point in updating this
+ * information.
+ */
+ if (crtc->state->active && old_state->active)
+ vc4_crtc_update_dlist(crtc);
if (debug_dump_regs) {
DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc));
--
2.13.0

View File

@ -546,36 +546,41 @@ Patch428: ti-bluetooth.patch
Patch429: arm64-hikey-fixes.patch
# http://www.spinics.net/lists/devicetree/msg163238.html
Patch430: bcm2837-initial-support.patch
Patch431: arm-rk3288-tinker.patch
# bcm283x mmc for wifi http://www.spinics.net/lists/arm-kernel/msg567077.html
Patch434: bcm283x-mmc-bcm2835.patch
# Upstream fixes for i2c/serial/ethernet MAC addresses
Patch435: bcm283x-fixes.patch
# https://lists.freedesktop.org/archives/dri-devel/2017-February/133823.html
Patch436: vc4-fix-vblank-cursor-update-issue.patch
Patch437: bcm283x-hdmi-audio.patch
Patch430: arm-rk3288-tinker.patch
# https://www.spinics.net/lists/arm-kernel/msg554183.html
Patch438: arm-imx6-hummingboard2.patch
Patch431: arm-imx6-hummingboard2.patch
# Cavium fixes
Patch439: arm64-cavium-fixes.patch
Patch432: arm64-cavium-fixes.patch
Patch440: arm64-Add-option-of-13-for-FORCE_MAX_ZONEORDER.patch
Patch433: arm64-Add-option-of-13-for-FORCE_MAX_ZONEORDER.patch
Patch441: bcm2835-clk-audio-jitter-issues.patch
# http://www.spinics.net/lists/devicetree/msg163238.html
Patch440: bcm2837-initial-support.patch
# bcm283x mmc for wifi http://www.spinics.net/lists/arm-kernel/msg567077.html
Patch441: bcm283x-mmc-bcm2835.patch
# Upstream fixes for i2c/serial/ethernet MAC addresses
Patch442: bcm283x-fixes.patch
# https://lists.freedesktop.org/archives/dri-devel/2017-February/133823.html
Patch443: vc4-fix-vblank-cursor-update-issue.patch
Patch444: bcm283x-hdmi-audio.patch
Patch445: bcm2835-clk-audio-jitter-issues.patch
# http://www.spinics.net/lists/dri-devel/msg132235.html
Patch443: drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch
Patch446: drm-vc4-Fix-OOPSes-from-trying-to-cache-a-partially-constructed-BO..patch
# https://lists.freedesktop.org/archives/dri-devel/2017-June/143688.html
Patch444: vc4-tformat-fixes.patch
Patch447: vc4-tformat-fixes.patch
# https://patchwork.freedesktop.org/patch/163300/
# https://patchwork.freedesktop.org/patch/161978/
Patch448: bcm283x-vc4-fix-vblank.patch
Patch460: lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch
@ -2235,6 +2240,9 @@ fi
#
#
%changelog
* Mon Jun 26 2017 Peter Robinson <pbrobinson@fedoraproject.org>
- vc4: hopefully improve the vblank crash issues
* Tue Jun 20 2017 Laura Abbott <labbott@fedoraproject.org>
- Add fix for iptables (rhbz 1459676)