drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Wed, 7 Dec 2022 11:53:15 +0000 (12:53 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 08:33:11 +0000 (09:33 +0100)
[ Upstream commit 87551ec650bb87d35f1b29bba6a2430896e08da0 ]

HVS5 has moved the interrupt enable bits around within the
DISPCTRL register, therefore the configuration has to be updated
to account for this.

Fixes: c54619b0bfb3 ("drm/vc4: Add support for the BCM2711 HVS5")
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://lore.kernel.org/r/20221207-rpi-hvs-crtc-misc-v1-4-1f8e0770798b@cerno.tech
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_regs.h

index 413ebb6f56a2340c5301b9dd26a2c25af33b4883..47990ecbfc4df6042c3007e710a8019c45328436 100644 (file)
@@ -658,7 +658,8 @@ void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel)
                return;
 
        dispctrl = HVS_READ(SCALER_DISPCTRL);
-       dispctrl &= ~SCALER_DISPCTRL_DSPEISLUR(channel);
+       dispctrl &= ~(hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
+                                        SCALER_DISPCTRL_DSPEISLUR(channel));
 
        HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 
@@ -675,7 +676,8 @@ void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel)
                return;
 
        dispctrl = HVS_READ(SCALER_DISPCTRL);
-       dispctrl |= SCALER_DISPCTRL_DSPEISLUR(channel);
+       dispctrl |= (hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
+                                       SCALER_DISPCTRL_DSPEISLUR(channel));
 
        HVS_WRITE(SCALER_DISPSTAT,
                  SCALER_DISPSTAT_EUFLOW(channel));
@@ -701,6 +703,7 @@ static irqreturn_t vc4_hvs_irq_handler(int irq, void *data)
        int channel;
        u32 control;
        u32 status;
+       u32 dspeislur;
 
        /*
         * NOTE: We don't need to protect the register access using
@@ -717,9 +720,11 @@ static irqreturn_t vc4_hvs_irq_handler(int irq, void *data)
        control = HVS_READ(SCALER_DISPCTRL);
 
        for (channel = 0; channel < SCALER_CHANNELS_COUNT; channel++) {
+               dspeislur = vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
+                                         SCALER_DISPCTRL_DSPEISLUR(channel);
                /* Interrupt masking is not always honored, so check it here. */
                if (status & SCALER_DISPSTAT_EUFLOW(channel) &&
-                   control & SCALER_DISPCTRL_DSPEISLUR(channel)) {
+                   control & dspeislur) {
                        vc4_hvs_mask_underrun(hvs, channel);
                        vc4_hvs_report_underrun(dev);
 
@@ -872,19 +877,34 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
                    SCALER_DISPCTRL_DISPEIRQ(1) |
                    SCALER_DISPCTRL_DISPEIRQ(2);
 
-       dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ |
-                     SCALER_DISPCTRL_SLVWREIRQ |
-                     SCALER_DISPCTRL_SLVRDEIRQ |
-                     SCALER_DISPCTRL_DSPEIEOF(0) |
-                     SCALER_DISPCTRL_DSPEIEOF(1) |
-                     SCALER_DISPCTRL_DSPEIEOF(2) |
-                     SCALER_DISPCTRL_DSPEIEOLN(0) |
-                     SCALER_DISPCTRL_DSPEIEOLN(1) |
-                     SCALER_DISPCTRL_DSPEIEOLN(2) |
-                     SCALER_DISPCTRL_DSPEISLUR(0) |
-                     SCALER_DISPCTRL_DSPEISLUR(1) |
-                     SCALER_DISPCTRL_DSPEISLUR(2) |
-                     SCALER_DISPCTRL_SCLEIRQ);
+       if (!vc4->is_vc5)
+               dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ |
+                             SCALER_DISPCTRL_SLVWREIRQ |
+                             SCALER_DISPCTRL_SLVRDEIRQ |
+                             SCALER_DISPCTRL_DSPEIEOF(0) |
+                             SCALER_DISPCTRL_DSPEIEOF(1) |
+                             SCALER_DISPCTRL_DSPEIEOF(2) |
+                             SCALER_DISPCTRL_DSPEIEOLN(0) |
+                             SCALER_DISPCTRL_DSPEIEOLN(1) |
+                             SCALER_DISPCTRL_DSPEIEOLN(2) |
+                             SCALER_DISPCTRL_DSPEISLUR(0) |
+                             SCALER_DISPCTRL_DSPEISLUR(1) |
+                             SCALER_DISPCTRL_DSPEISLUR(2) |
+                             SCALER_DISPCTRL_SCLEIRQ);
+       else
+               dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ |
+                             SCALER5_DISPCTRL_SLVEIRQ |
+                             SCALER5_DISPCTRL_DSPEIEOF(0) |
+                             SCALER5_DISPCTRL_DSPEIEOF(1) |
+                             SCALER5_DISPCTRL_DSPEIEOF(2) |
+                             SCALER5_DISPCTRL_DSPEIEOLN(0) |
+                             SCALER5_DISPCTRL_DSPEIEOLN(1) |
+                             SCALER5_DISPCTRL_DSPEIEOLN(2) |
+                             SCALER5_DISPCTRL_DSPEISLUR(0) |
+                             SCALER5_DISPCTRL_DSPEISLUR(1) |
+                             SCALER5_DISPCTRL_DSPEISLUR(2) |
+                             SCALER_DISPCTRL_SCLEIRQ);
+
 
        /* Set AXI panic mode.
         * VC4 panics when < 2 lines in FIFO.
index 95deacdc31e77adf4b1f2ceedae232fa7f233b98..1256f0877ff668f7c014509402fcc2283012e2fd 100644 (file)
  * always enabled.
  */
 # define SCALER_DISPCTRL_DSPEISLUR(x)          BIT(13 + (x))
+# define SCALER5_DISPCTRL_DSPEISLUR(x)         BIT(9 + ((x) * 4))
 /* Enables Display 0 end-of-line-N contribution to
  * SCALER_DISPSTAT_IRQDISP0
  */
 # define SCALER_DISPCTRL_DSPEIEOLN(x)          BIT(8 + ((x) * 2))
+# define SCALER5_DISPCTRL_DSPEIEOLN(x)         BIT(8 + ((x) * 4))
 /* Enables Display 0 EOF contribution to SCALER_DISPSTAT_IRQDISP0 */
 # define SCALER_DISPCTRL_DSPEIEOF(x)           BIT(7 + ((x) * 2))
+# define SCALER5_DISPCTRL_DSPEIEOF(x)          BIT(7 + ((x) * 4))
 
-# define SCALER_DISPCTRL_SLVRDEIRQ             BIT(6)
-# define SCALER_DISPCTRL_SLVWREIRQ             BIT(5)
+# define SCALER5_DISPCTRL_DSPEIVST(x)          BIT(6 + ((x) * 4))
+
+# define SCALER_DISPCTRL_SLVRDEIRQ             BIT(6)  /* HVS4 only */
+# define SCALER_DISPCTRL_SLVWREIRQ             BIT(5)  /* HVS4 only */
+# define SCALER5_DISPCTRL_SLVEIRQ              BIT(5)
 # define SCALER_DISPCTRL_DMAEIRQ               BIT(4)
 /* Enables interrupt generation on the enabled EOF/EOLN/EISLUR
  * bits and short frames..