]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/vc4: hvs: Reset muxes at probe time
authorMaxime Ripard <maxime@cerno.tech>
Mon, 28 Mar 2022 15:36:54 +0000 (17:36 +0200)
committerMaxime Ripard <maxime@cerno.tech>
Fri, 8 Apr 2022 11:38:06 +0000 (13:38 +0200)
By default, the HVS driver will force the HVS output 3 to be muxed to
the HVS channel 2. However, the Transposer can only be assigned to the
HVS channel 2, so whenever we try to use the writeback connector, we'll
mux its associated output (Output 2) to the channel 2.

This leads to both the output 2 and 3 feeding from the same channel,
which is explicitly discouraged in the documentation.

In order to avoid this, let's reset all the output muxes to their reset
value.

Fixes: 51c4f5a96dda ("drm/vc4: crtc: Assign output to channel automatically")
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://lore.kernel.org/r/20220328153659.2382206-2-maxime@cerno.tech
drivers/gpu/drm/vc4/vc4_hvs.c

index 9194cb52e7062d13d220a06d4bcf4b62ce09095b..2a58fc421cf601fa14e76b230d81aba4365fd559 100644 (file)
@@ -611,6 +611,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
        struct vc4_hvs *hvs = NULL;
        int ret;
        u32 dispctrl;
+       u32 reg;
 
        hvs = devm_kzalloc(&pdev->dev, sizeof(*hvs), GFP_KERNEL);
        if (!hvs)
@@ -682,6 +683,26 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
 
        vc4->hvs = hvs;
 
+       reg = HVS_READ(SCALER_DISPECTRL);
+       reg &= ~SCALER_DISPECTRL_DSP2_MUX_MASK;
+       HVS_WRITE(SCALER_DISPECTRL,
+                 reg | VC4_SET_FIELD(0, SCALER_DISPECTRL_DSP2_MUX));
+
+       reg = HVS_READ(SCALER_DISPCTRL);
+       reg &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
+       HVS_WRITE(SCALER_DISPCTRL,
+                 reg | VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX));
+
+       reg = HVS_READ(SCALER_DISPEOLN);
+       reg &= ~SCALER_DISPEOLN_DSP4_MUX_MASK;
+       HVS_WRITE(SCALER_DISPEOLN,
+                 reg | VC4_SET_FIELD(3, SCALER_DISPEOLN_DSP4_MUX));
+
+       reg = HVS_READ(SCALER_DISPDITHER);
+       reg &= ~SCALER_DISPDITHER_DSP5_MUX_MASK;
+       HVS_WRITE(SCALER_DISPDITHER,
+                 reg | VC4_SET_FIELD(3, SCALER_DISPDITHER_DSP5_MUX));
+
        dispctrl = HVS_READ(SCALER_DISPCTRL);
 
        dispctrl |= SCALER_DISPCTRL_ENABLE;
@@ -689,10 +710,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
                    SCALER_DISPCTRL_DISPEIRQ(1) |
                    SCALER_DISPCTRL_DISPEIRQ(2);
 
-       /* Set DSP3 (PV1) to use HVS channel 2, which would otherwise
-        * be unused.
-        */
-       dispctrl &= ~SCALER_DISPCTRL_DSP3_MUX_MASK;
        dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ |
                      SCALER_DISPCTRL_SLVWREIRQ |
                      SCALER_DISPCTRL_SLVRDEIRQ |
@@ -706,7 +723,6 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data)
                      SCALER_DISPCTRL_DSPEISLUR(1) |
                      SCALER_DISPCTRL_DSPEISLUR(2) |
                      SCALER_DISPCTRL_SCLEIRQ);
-       dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
 
        HVS_WRITE(SCALER_DISPCTRL, dispctrl);