aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2019-08-09 19:50:30 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2019-08-27 11:10:01 +0200
commit2340c646e6a5da658e114be2f721ff90853588d4 (patch)
treedf9744d2344e71e8c5d1b75c3e1528bc474313fe /target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
parent81d0da118694feb874f992093063a2852285d194 (diff)
downloadupstream-2340c646e6a5da658e114be2f721ff90853588d4.tar.gz
upstream-2340c646e6a5da658e114be2f721ff90853588d4.tar.bz2
upstream-2340c646e6a5da658e114be2f721ff90853588d4.zip
brcm2708: update to latest patches from RPi foundation
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch')
-rw-r--r--target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch85
1 files changed, 85 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch b/target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
new file mode 100644
index 0000000000..523c3823a4
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.19/950-0657-drm-vc4-Add-status-of-which-display-is-updated-throu.patch
@@ -0,0 +1,85 @@
+From 1b8faaeb3d705b1babc5de8cbd1f32653d1c5d64 Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.org>
+Date: Tue, 4 Jun 2019 12:14:30 +0100
+Subject: [PATCH 657/773] drm: vc4: Add status of which display is updated
+ through vblank
+
+Previously multiple displays were slaved off the same SMI
+interrupt, triggered by HVS channel 1 (HDMI0).
+This doesn't work if you only have a DPI or DSI screen (HVS channel
+0), and gives slightly erroneous results with dual HDMI as the
+events for HDMI1 are incorrect.
+
+Use SMIDSW0 and SMIDSW1 registers to denote which display has
+triggered the vblank.
+Handling should be backwards compatible with older firmware.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
+---
+ drivers/gpu/drm/vc4/vc4_firmware_kms.c | 41 ++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 5 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
++++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
+@@ -230,8 +230,13 @@ static const struct vc_image_format *vc4
+ * hardware, which has only this one register.
+ */
+ #define SMICS 0x0
++#define SMIDSW0 0x14
++#define SMIDSW1 0x1C
+ #define SMICS_INTERRUPTS (BIT(9) | BIT(10) | BIT(11))
+
++/* Flag to denote that the firmware is giving multiple display callbacks */
++#define SMI_NEW 0xabcd0000
++
+ #define vc4_crtc vc4_kms_crtc
+ #define to_vc4_crtc to_vc4_kms_crtc
+ struct vc4_crtc {
+@@ -884,16 +889,42 @@ static irqreturn_t vc4_crtc_irq_handler(
+ int i;
+ u32 stat = readl(crtc_list[0]->regs + SMICS);
+ irqreturn_t ret = IRQ_NONE;
++ u32 chan;
+
+ if (stat & SMICS_INTERRUPTS) {
+ writel(0, crtc_list[0]->regs + SMICS);
+
+- for (i = 0; crtc_list[i]; i++) {
+- if (crtc_list[i]->vblank_enabled)
+- drm_crtc_handle_vblank(&crtc_list[i]->base);
+- vc4_crtc_handle_page_flip(crtc_list[i]);
+- ret = IRQ_HANDLED;
++ chan = readl(crtc_list[0]->regs + SMIDSW0);
++
++ if ((chan & 0xFFFF0000) != SMI_NEW) {
++ /* Older firmware. Treat the one interrupt as vblank/
++ * complete for all crtcs.
++ */
++ for (i = 0; crtc_list[i]; i++) {
++ if (crtc_list[i]->vblank_enabled)
++ drm_crtc_handle_vblank(&crtc_list[i]->base);
++ vc4_crtc_handle_page_flip(crtc_list[i]);
++ }
++ } else {
++ if (chan & 1) {
++ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW0);
++ if (crtc_list[0]->vblank_enabled)
++ drm_crtc_handle_vblank(&crtc_list[0]->base);
++ vc4_crtc_handle_page_flip(crtc_list[0]);
++ }
++
++ /* Check for the secondary display too */
++ chan = readl(crtc_list[0]->regs + SMIDSW1);
++
++ if (chan & 1) {
++ writel(SMI_NEW, crtc_list[0]->regs + SMIDSW1);
++ if (crtc_list[1]->vblank_enabled)
++ drm_crtc_handle_vblank(&crtc_list[1]->base);
++ vc4_crtc_handle_page_flip(crtc_list[1]);
++ }
+ }
++
++ ret = IRQ_HANDLED;
+ }
+
+ return ret;