drm/i915: Move framestart_delay to crtc_state
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 21 Feb 2022 11:03:53 +0000 (13:03 +0200)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 4 Mar 2022 16:24:18 +0000 (18:24 +0200)
We need to make framestart_delay dynamic for DRRS on PCH
ports. To that end move it into the crtc state. As a bonus
we get state check+dump for it. Will also allow us to get
rid of the somewhat questionable framestart_delay sanitation
code.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220221110356.5532-1-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_pch_display.c
drivers/gpu/drm/i915/display/intel_vrr.c
drivers/gpu/drm/i915/i915_drv.h

index 10d483ce04a7578711f80ddd2f48f7b4cfaffb7b..7b0a8775985202db920851c3a7e3acf93b7c1911 100644 (file)
@@ -1866,7 +1866,7 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 
        val = intel_de_read(dev_priv, reg);
        val &= ~HSW_FRAME_START_DELAY_MASK;
-       val |= HSW_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+       val |= HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
        intel_de_write(dev_priv, reg, val);
 }
 
@@ -3244,7 +3244,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
 
        pipeconf |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
 
-       pipeconf |= PIPECONF_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+       pipeconf |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
 
        intel_de_write(dev_priv, PIPECONF(crtc->pipe), pipeconf);
        intel_de_posting_read(dev_priv, PIPECONF(crtc->pipe));
@@ -3434,6 +3434,8 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 
        pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_I9XX, tmp);
 
+       pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1;
+
        if (IS_CHERRYVIEW(dev_priv))
                pipe_config->cgm_mode = intel_de_read(dev_priv,
                                                      CGM_PIPE_MODE(crtc->pipe));
@@ -3559,7 +3561,7 @@ static void ilk_set_pipeconf(const struct intel_crtc_state *crtc_state)
 
        val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
 
-       val |= PIPECONF_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+       val |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
 
        intel_de_write(dev_priv, PIPECONF(pipe), val);
        intel_de_posting_read(dev_priv, PIPECONF(pipe));
@@ -3846,6 +3848,8 @@ static bool ilk_get_pipe_config(struct intel_crtc *crtc,
 
        pipe_config->gamma_mode = REG_FIELD_GET(PIPECONF_GAMMA_MODE_MASK_ILK, tmp);
 
+       pipe_config->framestart_delay = REG_FIELD_GET(PIPECONF_FRAME_START_DELAY_MASK, tmp) + 1;
+
        pipe_config->csc_mode = intel_de_read(dev_priv,
                                              PIPE_CSC_MODE(crtc->pipe));
 
@@ -4281,6 +4285,15 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
                pipe_config->pixel_multiplier = 1;
        }
 
+       if (!transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+               tmp = intel_de_read(dev_priv, CHICKEN_TRANS(pipe_config->cpu_transcoder));
+
+               pipe_config->framestart_delay = REG_FIELD_GET(HSW_FRAME_START_DELAY_MASK, tmp) + 1;
+       } else {
+               /* no idea if this is correct */
+               pipe_config->framestart_delay = 1;
+       }
+
 out:
        intel_display_power_put_all_in_set(dev_priv, &power_domain_set);
 
@@ -5318,6 +5331,9 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
                                      &pipe_config->dp_m2_n2);
        }
 
+       drm_dbg_kms(&dev_priv->drm, "framestart delay: %d\n",
+                   pipe_config->framestart_delay);
+
        drm_dbg_kms(&dev_priv->drm,
                    "audio: %i, infoframes: %i, infoframes enabled: 0x%x\n",
                    pipe_config->has_audio, pipe_config->has_infoframe,
@@ -5666,6 +5682,8 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
        pipe_config->cpu_transcoder =
                (enum transcoder) to_intel_crtc(crtc)->pipe;
 
+       pipe_config->framestart_delay = 1;
+
        /*
         * Sanitize sync polarity flags based on requested ones. If neither
         * positive or negative polarity is requested, treat this as meaning
@@ -6203,6 +6221,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
        PIPE_CONF_CHECK_X(output_types);
 
+       PIPE_CONF_CHECK_I(framestart_delay);
+
        PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
        PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
        PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hblank_start);
@@ -9612,8 +9632,6 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
        i915->flip_wq = alloc_workqueue("i915_flip", WQ_HIGHPRI |
                                        WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
 
-       i915->framestart_delay = 1; /* 1-4 */
-
        i915->window2_delay = 0; /* No DSB so no window2 delay */
 
        intel_mode_config_init(i915);
@@ -9917,12 +9935,14 @@ static bool has_pch_trancoder(struct drm_i915_private *dev_priv,
                (HAS_PCH_LPT_H(dev_priv) && pch_transcoder == PIPE_A);
 }
 
-static void intel_sanitize_frame_start_delay(const struct intel_crtc_state *crtc_state)
+static void intel_sanitize_frame_start_delay(struct intel_crtc_state *crtc_state)
 {
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
+       crtc_state->framestart_delay = 1;
+
        if (DISPLAY_VER(dev_priv) >= 9 ||
            IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) {
                i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
@@ -9933,7 +9953,7 @@ static void intel_sanitize_frame_start_delay(const struct intel_crtc_state *crtc
 
                val = intel_de_read(dev_priv, reg);
                val &= ~HSW_FRAME_START_DELAY_MASK;
-               val |= HSW_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
                intel_de_write(dev_priv, reg, val);
        } else {
                i915_reg_t reg = PIPECONF(cpu_transcoder);
@@ -9941,7 +9961,7 @@ static void intel_sanitize_frame_start_delay(const struct intel_crtc_state *crtc
 
                val = intel_de_read(dev_priv, reg);
                val &= ~PIPECONF_FRAME_START_DELAY_MASK;
-               val |= PIPECONF_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= PIPECONF_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
                intel_de_write(dev_priv, reg, val);
        }
 
@@ -9954,7 +9974,7 @@ static void intel_sanitize_frame_start_delay(const struct intel_crtc_state *crtc
 
                val = intel_de_read(dev_priv, reg);
                val &= ~TRANS_FRAME_START_DELAY_MASK;
-               val |= TRANS_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= TRANS_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
                intel_de_write(dev_priv, reg, val);
        } else {
                enum pipe pch_transcoder = intel_crtc_pch_transcoder(crtc);
@@ -9963,7 +9983,7 @@ static void intel_sanitize_frame_start_delay(const struct intel_crtc_state *crtc
 
                val = intel_de_read(dev_priv, reg);
                val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
-               val |= TRANS_CHICKEN2_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
                intel_de_write(dev_priv, reg, val);
        }
 }
index 776b3e6662f23ee4c54820bd6e4433db2d137f9c..593aa7444a491c6008b124f4814d06b36183eb94 100644 (file)
@@ -1154,6 +1154,8 @@ struct intel_crtc_state {
        /* bitmask of planes that will be updated during the commit */
        u8 update_planes;
 
+       u8 framestart_delay; /* 1-4 */
+
        struct {
                u32 enable;
                u32 gcp;
index 9192769e3337482a6df18112b90334331e327b14..00232dab217d895696c58d2dc617eb55463ec308 100644 (file)
@@ -181,7 +181,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
                val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
                /* Configure frame start delay to match the CPU */
                val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
-               val |= TRANS_CHICKEN2_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
                intel_de_write(dev_priv, reg, val);
        }
 
@@ -192,7 +192,7 @@ static void ilk_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
        if (HAS_PCH_IBX(dev_priv)) {
                /* Configure frame start delay to match the CPU */
                val &= ~TRANS_FRAME_START_DELAY_MASK;
-               val |= TRANS_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+               val |= TRANS_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
 
                /*
                 * Make the BPC in transcoder be consistent with
@@ -466,9 +466,11 @@ void ilk_pch_get_config(struct intel_crtc_state *crtc_state)
        ilk_pch_clock_get(crtc_state);
 }
 
-static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
-                                     enum transcoder cpu_transcoder)
+static void lpt_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
 {
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        u32 val, pipeconf_val;
 
        /* FDI must be feeding us bits for PCH ports */
@@ -480,7 +482,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
        val |= TRANS_CHICKEN2_TIMING_OVERRIDE;
        /* Configure frame start delay to match the CPU */
        val &= ~TRANS_CHICKEN2_FRAME_START_DELAY_MASK;
-       val |= TRANS_CHICKEN2_FRAME_START_DELAY(dev_priv->framestart_delay - 1);
+       val |= TRANS_CHICKEN2_FRAME_START_DELAY(crtc_state->framestart_delay - 1);
        intel_de_write(dev_priv, TRANS_CHICKEN2(PIPE_A), val);
 
        val = TRANS_ENABLE;
@@ -521,7 +523,6 @@ void lpt_pch_enable(struct intel_atomic_state *state,
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        const struct intel_crtc_state *crtc_state =
                intel_atomic_get_new_crtc_state(state, crtc);
-       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
        assert_pch_transcoder_disabled(dev_priv, PIPE_A);
 
@@ -530,7 +531,7 @@ void lpt_pch_enable(struct intel_atomic_state *state,
        /* Set transcoder timing. */
        ilk_pch_transcoder_set_timings(crtc_state, PIPE_A);
 
-       lpt_enable_pch_transcoder(dev_priv, cpu_transcoder);
+       lpt_enable_pch_transcoder(crtc_state);
 }
 
 void lpt_pch_disable(struct intel_atomic_state *state,
index 139e8936edc580a2374cdefb948217cdc1242ee7..396f2f994fa071aba2dc80219c6df02bd74fda8c 100644 (file)
@@ -69,9 +69,9 @@ static int intel_vrr_vblank_exit_length(const struct intel_crtc_state *crtc_stat
 
        /* The hw imposes the extra scanline before frame start */
        if (DISPLAY_VER(i915) >= 13)
-               return crtc_state->vrr.guardband + i915->framestart_delay + 1;
+               return crtc_state->vrr.guardband + crtc_state->framestart_delay + 1;
        else
-               return crtc_state->vrr.pipeline_full + i915->framestart_delay + 1;
+               return crtc_state->vrr.pipeline_full + crtc_state->framestart_delay + 1;
 }
 
 int intel_vrr_vmin_vblank_start(const struct intel_crtc_state *crtc_state)
index b9f9168280e80a6ae5424e5f5ea60d43e4825e3c..29cc6f7bebf255f80cada86b09d748834506c484 100644 (file)
@@ -814,8 +814,6 @@ struct drm_i915_private {
                struct file *mmap_singleton;
        } gem;
 
-       u8 framestart_delay;
-
        /* Window2 specifies time required to program DSB (Window2) in number of scan lines */
        u8 window2_delay;