drm/vc4: kms: Fix to split vc4 and vc5 hvs pv muxing commit 40/245640/1
authorHoegeun Kwon <hoegeun.kwon@samsung.com>
Mon, 12 Oct 2020 12:10:58 +0000 (21:10 +0900)
committerHoegeun Kwon <hoegeun.kwon@samsung.com>
Tue, 13 Oct 2020 09:01:42 +0000 (18:01 +0900)
In order to use dual HDMI normally, vc4 and vc5 should be separated.
Split vc4 hvs pv muxing commit and vc5 referring to patch[1].

[1] drm/vc4: crtc: Assign output to channel automatically
    https://cgit.freedesktop.org/drm/drm-misc/commit/?id=87ebcd42fb7b8d1d3269007a621e41ae96a0077e

Change-Id: I5427cfd885c4643f764f8f84bed0f017c5d2a562
Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
drivers/gpu/drm/vc4/vc4_kms.c

index 5beb875..367cead 100644 (file)
@@ -157,6 +157,45 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
 {
        struct drm_crtc_state *crtc_state;
        struct drm_crtc *crtc;
+       unsigned int i;
+
+       for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+               struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
+               u32 dispctrl;
+               u32 dsp3_mux;
+
+               if (!crtc_state->active)
+                       continue;
+
+               if (vc4_state->assigned_channel != 2)
+                       continue;
+
+               /*
+                * SCALER_DISPCTRL_DSP3 = X, where X < 2 means 'connect DSP3 to
+                * FIFO X'.
+                * SCALER_DISPCTRL_DSP3 = 3 means 'disable DSP 3'.
+                *
+                * DSP3 is connected to FIFO2 unless the transposer is
+                * enabled. In this case, FIFO 2 is directly accessed by the
+                * TXP IP, and we need to disable the FIFO2 -> pixelvalve1
+                * route.
+                */
+               if (vc4_state->feed_txp)
+                       dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX);
+               else
+                       dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX);
+
+               dispctrl = HVS_READ(SCALER_DISPCTRL) &
+                          ~SCALER_DISPCTRL_DSP3_MUX_MASK;
+               HVS_WRITE(SCALER_DISPCTRL, dispctrl | dsp3_mux);
+       }
+}
+
+static void vc5_hvs_pv_muxing_commit(struct vc4_dev *vc4,
+                                    struct drm_atomic_state *state)
+{
+       struct drm_crtc_state *crtc_state;
+       struct drm_crtc *crtc;
        unsigned char dsp2_mux = 0;
        unsigned char dsp3_mux = 3;
        unsigned char dsp4_mux = 3;
@@ -173,7 +212,7 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
 
                switch (vc4_crtc->data->hvs_output) {
                case 2:
-                       dsp2_mux = (vc4_state->assigned_channel == 2) ? 1 : 0;
+                       dsp2_mux = (vc4_state->assigned_channel == 2) ? 0 : 1;
                        break;
 
                case 3:
@@ -194,30 +233,27 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4,
        }
 
        reg = HVS_READ(SCALER_DISPECTRL);
-       if (FIELD_GET(SCALER_DISPECTRL_DSP2_MUX_MASK, reg) != dsp2_mux)
-               HVS_WRITE(SCALER_DISPECTRL,
-                         (reg & ~SCALER_DISPECTRL_DSP2_MUX_MASK) |
-                         VC4_SET_FIELD(dsp2_mux, SCALER_DISPECTRL_DSP2_MUX));
+       HVS_WRITE(SCALER_DISPECTRL,
+                 (reg & ~SCALER_DISPECTRL_DSP2_MUX_MASK) |
+                 VC4_SET_FIELD(dsp2_mux, SCALER_DISPECTRL_DSP2_MUX));
 
        reg = HVS_READ(SCALER_DISPCTRL);
-       if (FIELD_GET(SCALER_DISPCTRL_DSP3_MUX_MASK, reg) != dsp3_mux)
-               HVS_WRITE(SCALER_DISPCTRL,
-                         (reg & ~SCALER_DISPCTRL_DSP3_MUX_MASK) |
-                         VC4_SET_FIELD(dsp3_mux, SCALER_DISPCTRL_DSP3_MUX));
+       HVS_WRITE(SCALER_DISPCTRL,
+                 (reg & ~SCALER_DISPCTRL_DSP3_MUX_MASK) |
+                 VC4_SET_FIELD(dsp3_mux, SCALER_DISPCTRL_DSP3_MUX));
 
        reg = HVS_READ(SCALER_DISPEOLN);
-       if (FIELD_GET(SCALER_DISPEOLN_DSP4_MUX_MASK, reg) != dsp4_mux)
-               HVS_WRITE(SCALER_DISPEOLN,
-                         (reg & ~SCALER_DISPEOLN_DSP4_MUX_MASK) |
-                         VC4_SET_FIELD(dsp4_mux, SCALER_DISPEOLN_DSP4_MUX));
+       HVS_WRITE(SCALER_DISPEOLN,
+                 (reg & ~SCALER_DISPEOLN_DSP4_MUX_MASK) |
+                 VC4_SET_FIELD(dsp4_mux, SCALER_DISPEOLN_DSP4_MUX));
 
        reg = HVS_READ(SCALER_DISPDITHER);
-       if (FIELD_GET(SCALER_DISPDITHER_DSP5_MUX_MASK, reg) != dsp5_mux)
-               HVS_WRITE(SCALER_DISPDITHER,
-                         (reg & ~SCALER_DISPDITHER_DSP5_MUX_MASK) |
-                         VC4_SET_FIELD(dsp5_mux, SCALER_DISPDITHER_DSP5_MUX));
+       HVS_WRITE(SCALER_DISPDITHER,
+                 (reg & ~SCALER_DISPDITHER_DSP5_MUX_MASK) |
+                 VC4_SET_FIELD(dsp5_mux, SCALER_DISPDITHER_DSP5_MUX));
 }
 
+
 static void
 vc4_atomic_complete_commit(struct drm_atomic_state *state)
 {
@@ -248,10 +284,12 @@ vc4_atomic_complete_commit(struct drm_atomic_state *state)
 
        drm_atomic_helper_commit_modeset_disables(dev, state);
 
-       if (!vc4->firmware_kms) {
-               vc4_ctm_commit(vc4, state);
+       vc4_ctm_commit(vc4, state);
+
+       if (vc4->hvs->hvs5)
+               vc5_hvs_pv_muxing_commit(vc4, state);
+       else
                vc4_hvs_pv_muxing_commit(vc4, state);
-       }
 
        drm_atomic_helper_commit_planes(dev, state, 0);