Merge tag 'drm-intel-next-2023-03-23' of git://anongit.freedesktop.org/drm/drm-intel...
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_display.c
index edbcb12..5a386c7 100644 (file)
 #include "intel_quirks.h"
 #include "intel_sdvo.h"
 #include "intel_snps_phy.h"
-#include "intel_sprite.h"
 #include "intel_tc.h"
 #include "intel_tv.h"
 #include "intel_vblank.h"
 static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
 static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
 static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
-static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state);
+static void bdw_set_pipe_misc(const struct intel_crtc_state *crtc_state);
 static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
 
 /* returns HPLL frequency in kHz */
@@ -1116,6 +1115,9 @@ static void intel_post_plane_update(struct intel_atomic_state *state,
        if (needs_cursorclk_wa(old_crtc_state) &&
            !needs_cursorclk_wa(new_crtc_state))
                icl_wa_cursorclkgating(dev_priv, pipe, false);
+
+       if (intel_crtc_needs_color_update(new_crtc_state))
+               intel_color_post_update(new_crtc_state);
 }
 
 static void intel_crtc_enable_flip_done(struct intel_atomic_state *state,
@@ -1793,7 +1795,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 
        intel_set_pipe_src_size(new_crtc_state);
        if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-               bdw_set_pipemisc(new_crtc_state);
+               bdw_set_pipe_misc(new_crtc_state);
 
        if (!intel_crtc_is_bigjoiner_slave(new_crtc_state) &&
            !transcoder_is_dsi(cpu_transcoder))
@@ -2139,6 +2141,8 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
 
        intel_set_pipe_src_size(new_crtc_state);
 
+       intel_de_write(dev_priv, VLV_PIPE_MSA_MISC(pipe), 0);
+
        if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
                intel_de_write(dev_priv, CHV_BLEND(pipe), CHV_BLEND_LEGACY);
                intel_de_write(dev_priv, CHV_CANVAS(pipe), 0);
@@ -3074,20 +3078,20 @@ static void chv_crtc_clock_get(struct intel_crtc *crtc,
 }
 
 static enum intel_output_format
-bdw_get_pipemisc_output_format(struct intel_crtc *crtc)
+bdw_get_pipe_misc_output_format(struct intel_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 tmp;
 
-       tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
+       tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe));
 
-       if (tmp & PIPEMISC_YUV420_ENABLE) {
+       if (tmp & PIPE_MISC_YUV420_ENABLE) {
                /* We support 4:2:0 in full blend mode only */
                drm_WARN_ON(&dev_priv->drm,
-                           (tmp & PIPEMISC_YUV420_MODE_FULL_BLEND) == 0);
+                           (tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0);
 
                return INTEL_OUTPUT_FORMAT_YCBCR420;
-       } else if (tmp & PIPEMISC_OUTPUT_COLORSPACE_YUV) {
+       } else if (tmp & PIPE_MISC_OUTPUT_COLORSPACE_YUV) {
                return INTEL_OUTPUT_FORMAT_YCBCR444;
        } else {
                return INTEL_OUTPUT_FORMAT_RGB;
@@ -3330,7 +3334,7 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
        intel_de_posting_read(dev_priv, TRANSCONF(cpu_transcoder));
 }
 
-static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
+static void bdw_set_pipe_misc(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);
@@ -3338,18 +3342,18 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
 
        switch (crtc_state->pipe_bpp) {
        case 18:
-               val |= PIPEMISC_BPC_6;
+               val |= PIPE_MISC_BPC_6;
                break;
        case 24:
-               val |= PIPEMISC_BPC_8;
+               val |= PIPE_MISC_BPC_8;
                break;
        case 30:
-               val |= PIPEMISC_BPC_10;
+               val |= PIPE_MISC_BPC_10;
                break;
        case 36:
                /* Port output 12BPC defined for ADLP+ */
                if (DISPLAY_VER(dev_priv) > 12)
-                       val |= PIPEMISC_BPC_12_ADLP;
+                       val |= PIPE_MISC_BPC_12_ADLP;
                break;
        default:
                MISSING_CASE(crtc_state->pipe_bpp);
@@ -3357,38 +3361,38 @@ static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
        }
 
        if (crtc_state->dither)
-               val |= PIPEMISC_DITHER_ENABLE | PIPEMISC_DITHER_TYPE_SP;
+               val |= PIPE_MISC_DITHER_ENABLE | PIPE_MISC_DITHER_TYPE_SP;
 
        if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
            crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444)
-               val |= PIPEMISC_OUTPUT_COLORSPACE_YUV;
+               val |= PIPE_MISC_OUTPUT_COLORSPACE_YUV;
 
        if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
-               val |= PIPEMISC_YUV420_ENABLE |
-                       PIPEMISC_YUV420_MODE_FULL_BLEND;
+               val |= PIPE_MISC_YUV420_ENABLE |
+                       PIPE_MISC_YUV420_MODE_FULL_BLEND;
 
        if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state))
-               val |= PIPEMISC_HDR_MODE_PRECISION;
+               val |= PIPE_MISC_HDR_MODE_PRECISION;
 
        if (DISPLAY_VER(dev_priv) >= 12)
-               val |= PIPEMISC_PIXEL_ROUNDING_TRUNC;
+               val |= PIPE_MISC_PIXEL_ROUNDING_TRUNC;
 
-       intel_de_write(dev_priv, PIPEMISC(crtc->pipe), val);
+       intel_de_write(dev_priv, PIPE_MISC(crtc->pipe), val);
 }
 
-int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
+int bdw_get_pipe_misc_bpp(struct intel_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        u32 tmp;
 
-       tmp = intel_de_read(dev_priv, PIPEMISC(crtc->pipe));
+       tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe));
 
-       switch (tmp & PIPEMISC_BPC_MASK) {
-       case PIPEMISC_BPC_6:
+       switch (tmp & PIPE_MISC_BPC_MASK) {
+       case PIPE_MISC_BPC_6:
                return 18;
-       case PIPEMISC_BPC_8:
+       case PIPE_MISC_BPC_8:
                return 24;
-       case PIPEMISC_BPC_10:
+       case PIPE_MISC_BPC_10:
                return 30;
        /*
         * PORT OUTPUT 12 BPC defined for ADLP+.
@@ -3400,7 +3404,7 @@ int bdw_get_pipemisc_bpp(struct intel_crtc *crtc)
         * on older platforms, need to find a workaround for 12 BPC
         * MIPI DSI HW readout.
         */
-       case PIPEMISC_BPC_12_ADLP:
+       case PIPE_MISC_BPC_12_ADLP:
                if (DISPLAY_VER(dev_priv) > 12)
                        return 36;
                fallthrough;
@@ -3981,7 +3985,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
                        pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
        } else {
                pipe_config->output_format =
-                       bdw_get_pipemisc_output_format(crtc);
+                       bdw_get_pipe_misc_output_format(crtc);
        }
 
        pipe_config->gamma_mode = intel_de_read(dev_priv,
@@ -5079,6 +5083,7 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
         * only fields that are know to not cause problems are preserved. */
 
        saved_state->uapi = crtc_state->uapi;
+       saved_state->inherited = crtc_state->inherited;
        saved_state->scaler_state = crtc_state->scaler_state;
        saved_state->shared_dpll = crtc_state->shared_dpll;
        saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
@@ -5904,68 +5909,6 @@ int intel_modeset_all_pipes(struct intel_atomic_state *state,
        return 0;
 }
 
-void intel_crtc_update_active_timings(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);
-       struct drm_display_mode adjusted_mode;
-
-       drm_mode_init(&adjusted_mode, &crtc_state->hw.adjusted_mode);
-
-       if (crtc_state->vrr.enable) {
-               adjusted_mode.crtc_vtotal = crtc_state->vrr.vmax;
-               adjusted_mode.crtc_vblank_end = crtc_state->vrr.vmax;
-               adjusted_mode.crtc_vblank_start = intel_vrr_vmin_vblank_start(crtc_state);
-               crtc->vmax_vblank_start = intel_vrr_vmax_vblank_start(crtc_state);
-       }
-
-       drm_calc_timestamping_constants(&crtc->base, &adjusted_mode);
-
-       crtc->mode_flags = crtc_state->mode_flags;
-
-       /*
-        * The scanline counter increments at the leading edge of hsync.
-        *
-        * On most platforms it starts counting from vtotal-1 on the
-        * first active line. That means the scanline counter value is
-        * always one less than what we would expect. Ie. just after
-        * start of vblank, which also occurs at start of hsync (on the
-        * last active line), the scanline counter will read vblank_start-1.
-        *
-        * On gen2 the scanline counter starts counting from 1 instead
-        * of vtotal-1, so we have to subtract one (or rather add vtotal-1
-        * to keep the value positive), instead of adding one.
-        *
-        * On HSW+ the behaviour of the scanline counter depends on the output
-        * type. For DP ports it behaves like most other platforms, but on HDMI
-        * there's an extra 1 line difference. So we need to add two instead of
-        * one to the value.
-        *
-        * On VLV/CHV DSI the scanline counter would appear to increment
-        * approx. 1/3 of a scanline before start of vblank. Unfortunately
-        * that means we can't tell whether we're in vblank or not while
-        * we're on that particular line. We must still set scanline_offset
-        * to 1 so that the vblank timestamps come out correct when we query
-        * the scanline counter from within the vblank interrupt handler.
-        * However if queried just before the start of vblank we'll get an
-        * answer that's slightly in the future.
-        */
-       if (DISPLAY_VER(dev_priv) == 2) {
-               int vtotal;
-
-               vtotal = adjusted_mode.crtc_vtotal;
-               if (adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
-                       vtotal /= 2;
-
-               crtc->scanline_offset = vtotal - 1;
-       } else if (HAS_DDI(dev_priv) &&
-                  intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
-               crtc->scanline_offset = 2;
-       } else {
-               crtc->scanline_offset = 1;
-       }
-}
-
 /*
  * This implements the workaround described in the "notes" section of the mode
  * set sequence documentation. When going from no pipes or single pipe to
@@ -6970,7 +6913,7 @@ static void commit_pipe_pre_planes(struct intel_atomic_state *state,
                        intel_color_commit_arm(new_crtc_state);
 
                if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-                       bdw_set_pipemisc(new_crtc_state);
+                       bdw_set_pipe_misc(new_crtc_state);
 
                if (intel_crtc_needs_fastset(new_crtc_state))
                        intel_pipe_fastset(old_crtc_state, new_crtc_state);
@@ -7046,6 +6989,8 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 
        intel_fbc_update(state, crtc);
 
+       drm_WARN_ON(&i915->drm, !intel_display_power_is_enabled(i915, POWER_DOMAIN_DC_OFF));
+
        if (!modeset &&
            intel_crtc_needs_color_update(new_crtc_state))
                intel_color_commit_noarm(new_crtc_state);
@@ -7413,8 +7358,28 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
        drm_atomic_helper_wait_for_dependencies(&state->base);
        drm_dp_mst_atomic_wait_for_dependencies(&state->base);
 
-       if (state->modeset)
-               wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_MODESET);
+       /*
+        * During full modesets we write a lot of registers, wait
+        * for PLLs, etc. Doing that while DC states are enabled
+        * is not a good idea.
+        *
+        * During fastsets and other updates we also need to
+        * disable DC states due to the following scenario:
+        * 1. DC5 exit and PSR exit happen
+        * 2. Some or all _noarm() registers are written
+        * 3. Due to some long delay PSR is re-entered
+        * 4. DC5 entry -> DMC saves the already written new
+        *    _noarm() registers and the old not yet written
+        *    _arm() registers
+        * 5. DC5 exit -> DMC restores a mixture of old and
+        *    new register values and arms the update
+        * 6. PSR exit -> hardware latches a mixture of old and
+        *    new register values -> corrupted frame, or worse
+        * 7. New _arm() registers are finally written
+        * 8. Hardware finally latches a complete set of new
+        *    register values, and subsequent frames will be OK again
+        */
+       wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_DC_OFF);
 
        intel_atomic_prepare_plane_clear_colors(state);
 
@@ -7563,8 +7528,8 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
                 * the culprit.
                 */
                intel_uncore_arm_unclaimed_mmio_detection(&dev_priv->uncore);
-               intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET, wakeref);
        }
+       intel_display_power_put(dev_priv, POWER_DOMAIN_DC_OFF, wakeref);
        intel_runtime_pm_put(&dev_priv->runtime_pm, state->wakeref);
 
        /*
@@ -8886,14 +8851,14 @@ void intel_display_driver_register(struct drm_i915_private *i915)
        if (!HAS_DISPLAY(i915))
                return;
 
-       intel_display_debugfs_register(i915);
-
        /* Must be done after probing outputs */
        intel_opregion_register(i915);
        intel_acpi_video_register(i915);
 
        intel_audio_init(i915);
 
+       intel_display_debugfs_register(i915);
+
        /*
         * Some ports require correctly set-up hpd registers for
         * detection to work properly (leading to ghost connected