drm/vc4: Correct interrupt masking bit assignment for HVS5
authorDave Stevenson <dave.stevenson@raspberrypi.com>
Thu, 11 Aug 2022 14:52:28 +0000 (15:52 +0100)
committerPhil Elwell <8911409+pelwell@users.noreply.github.com>
Thu, 1 Sep 2022 16:58:41 +0000 (17:58 +0100)
HVS5 has moved the interrupt enable bits around within the
DISPCTRL register, therefore the configuration has to be updated
to account for this.

Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_regs.h

index 5667855..e0d4c86 100644 (file)
@@ -817,7 +817,8 @@ void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel)
 {
        u32 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);
 }
@@ -826,7 +827,8 @@ void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel)
 {
        u32 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));
@@ -850,14 +852,17 @@ static irqreturn_t vc4_hvs_irq_handler(int irq, void *data)
        int channel;
        u32 control;
        u32 status;
+       u32 dspeislur;
 
        status = HVS_READ(SCALER_DISPSTAT);
        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);
 
@@ -989,19 +994,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 eeeeb30..b65abdf 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..