Merge drm/drm-next into drm-intel-next
authorRodrigo Vivi <rodrigo.vivi@intel.com>
Wed, 2 Mar 2022 16:28:33 +0000 (11:28 -0500)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Wed, 2 Mar 2022 16:28:33 +0000 (11:28 -0500)
To catch up with recent rounds of pull requests
and get some drm-misc dependencies so we can merge
linux/string_helpers related changes.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
28 files changed:
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/display/i9xx_plane.c
drivers/gpu/drm/i915/display/intel_cursor.c
drivers/gpu/drm/i915/display/intel_ddi.c
drivers/gpu/drm/i915/display/intel_display.c
drivers/gpu/drm/i915/display/intel_display_debugfs.c
drivers/gpu/drm/i915/display/intel_display_power.c
drivers/gpu/drm/i915/display/intel_display_power.h
drivers/gpu/drm/i915/display/intel_display_power_well.c [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_display_power_well.h [new file with mode: 0644]
drivers/gpu/drm/i915/display/intel_dmc.c
drivers/gpu/drm/i915/display/intel_fb.c
drivers/gpu/drm/i915/display/intel_fb.h
drivers/gpu/drm/i915/display/intel_fbc.c
drivers/gpu/drm/i915/display/intel_hdcp.c
drivers/gpu/drm/i915/display/intel_plane_initial.c
drivers/gpu/drm/i915/display/intel_snps_phy.c
drivers/gpu/drm/i915/display/intel_sprite.c
drivers/gpu/drm/i915/display/intel_vdsc.c
drivers/gpu/drm/i915/display/skl_universal_plane.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_device_info.h
drivers/gpu/drm/i915/intel_pch.c
drivers/gpu/drm/i915/intel_pch.h
drivers/gpu/drm/i915/intel_pm.c
include/uapi/drm/drm_fourcc.h

index 9d588d936e3dc3994cee0064ceb1777449fe431e..1a771ee5b1d0171c4069dd736dd2a03542a90f46 100644 (file)
@@ -212,6 +212,7 @@ i915-y += \
        display/intel_cursor.o \
        display/intel_display.o \
        display/intel_display_power.o \
+       display/intel_display_power_well.o \
        display/intel_dmc.o \
        display/intel_dpio_phy.o \
        display/intel_dpll.o \
index a87b65cd41fd741f9d3344730e0dfba79c004398..af190bacdd97cf82f99587063f5d572f30698f75 100644 (file)
@@ -418,9 +418,6 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
                          plane_state->view.color_plane[0].mapping_stride);
@@ -441,8 +438,6 @@ static void i9xx_plane_update_noarm(struct intel_plane *plane,
                intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
                                  DISP_HEIGHT(crtc_h - 1) | DISP_WIDTH(crtc_w - 1));
        }
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void i9xx_plane_update_arm(struct intel_plane *plane,
@@ -465,8 +460,6 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
        else
                dspaddr_offset = linear_offset;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
                int crtc_x = plane_state->uapi.dst.x1;
                int crtc_y = plane_state->uapi.dst.y1;
@@ -496,13 +489,15 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
         * the control register just before the surface register.
         */
        intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+
+       /* lock to protect against rmw in fbc nuke */
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        if (DISPLAY_VER(dev_priv) >= 4)
                intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
                                  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
        else
                intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
                                  intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
-
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -540,14 +535,14 @@ static void i9xx_plane_disable_arm(struct intel_plane *plane,
         */
        dspcntr = i9xx_plane_ctl_crtc(crtc_state);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+
+       /* lock to protect against rmw in fbc nuke */
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        if (DISPLAY_VER(dev_priv) >= 4)
                intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
        else
                intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
-
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
@@ -566,8 +561,10 @@ g4x_primary_async_flip(struct intel_plane *plane,
        if (async_flip)
                dspcntr |= DISP_ASYNC_FLIP;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
+
+       /* lock to protect against rmw in fbc nuke */
+       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
                          intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
        spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
@@ -582,12 +579,9 @@ vlv_primary_async_flip(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        u32 dspaddr_offset = plane_state->view.color_plane[0].offset;
        enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
-       unsigned long irqflags;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
        intel_de_write_fw(dev_priv, DSPADDR_VLV(i9xx_plane),
                          intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
index 2ade8fdd9bdd4e240987cdfba2499fab574a0e61..57ef9403f4e9ed56af31002342be20e836803724 100644 (file)
@@ -152,6 +152,9 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
        /* Use the unclipped src/dst rectangles, which we program to hw */
        plane_state->uapi.src = src;
        plane_state->uapi.dst = dst;
+       if (intel_crtc_is_bigjoiner_slave(crtc_state))
+               drm_rect_translate(&plane_state->uapi.dst,
+                                  -crtc_state->pipe_src_w, 0);
 
        ret = intel_cursor_check_surface(plane_state);
        if (ret)
@@ -255,7 +258,6 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        u32 cntl = 0, base = 0, pos = 0, size = 0;
-       unsigned long irqflags;
 
        if (plane_state && plane_state->uapi.visible) {
                unsigned int width = drm_rect_width(&plane_state->uapi.dst);
@@ -270,8 +272,6 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
                pos = intel_cursor_position(plane_state);
        }
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        /* On these chipsets we can only modify the base/size/stride
         * whilst the cursor is disabled.
         */
@@ -290,8 +290,6 @@ static void i845_cursor_update_arm(struct intel_plane *plane,
        } else {
                intel_de_write_fw(dev_priv, CURPOS(PIPE_A), pos);
        }
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void i845_cursor_disable_arm(struct intel_plane *plane,
@@ -492,7 +490,6 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum pipe pipe = plane->pipe;
        u32 cntl = 0, base = 0, pos = 0, fbc_ctl = 0;
-       unsigned long irqflags;
 
        if (plane_state && plane_state->uapi.visible) {
                int width = drm_rect_width(&plane_state->uapi.dst);
@@ -508,8 +505,6 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
                pos = intel_cursor_position(plane_state);
        }
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        /*
         * On some platforms writing CURCNTR first will also
         * cause CURPOS to be armed by the CURBASE write.
@@ -555,8 +550,6 @@ static void i9xx_cursor_update_arm(struct intel_plane *plane,
                intel_de_write_fw(dev_priv, CURPOS(pipe), pos);
                intel_de_write_fw(dev_priv, CURBASE(pipe), base);
        }
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void i9xx_cursor_disable_arm(struct intel_plane *plane,
@@ -715,6 +708,14 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
         */
        crtc_state->active_planes = new_crtc_state->active_planes;
 
+       /*
+        * Technically we should do a vblank evasion here to make
+        * sure all the cursor registers update on the same frame.
+        * For now just make sure the register writes happen as
+        * quickly as possible to minimize the race window.
+        */
+       local_irq_disable();
+
        if (new_plane_state->uapi.visible) {
                intel_plane_update_noarm(plane, crtc_state, new_plane_state);
                intel_plane_update_arm(plane, crtc_state, new_plane_state);
@@ -722,6 +723,8 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
                intel_plane_disable_arm(plane, crtc_state);
        }
 
+       local_irq_enable();
+
        intel_plane_unpin_fb(old_plane_state);
 
 out_free:
index e4260806c2a40b336abe98b66a0ba2011a3bc4bd..1cd394b0585e271786e638f99da389724da93f6b 100644 (file)
@@ -4308,6 +4308,14 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
                return;
        }
 
+       if (intel_phy_is_snps(dev_priv, phy) &&
+           dev_priv->snps_phy_failed_calibration & BIT(phy)) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "SNPS PHY %c failed to calibrate; output will not be used.\n",
+                           phy_name(phy));
+               return;
+       }
+
        dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL);
        if (!dig_port)
                return;
index 80b19c304c4325179e55b5f8c96bf13a3b2459be..b8d511360f9fee527b0bbf25305961e67c5821d6 100644 (file)
@@ -346,7 +346,10 @@ static enum pipe bigjoiner_master_pipe(const struct intel_crtc_state *crtc_state
 
 u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state)
 {
-       return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
+       if (crtc_state->bigjoiner_pipes)
+               return crtc_state->bigjoiner_pipes & ~BIT(bigjoiner_master_pipe(crtc_state));
+       else
+               return 0;
 }
 
 bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state)
@@ -2725,58 +2728,78 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
                        ilk_pipe_pixel_rate(crtc_state);
 }
 
+static void intel_bigjoiner_adjust_timings(const struct intel_crtc_state *crtc_state,
+                                          struct drm_display_mode *mode)
+{
+       if (!crtc_state->bigjoiner)
+               return;
+
+       mode->crtc_clock /= 2;
+       mode->crtc_hdisplay /= 2;
+       mode->crtc_hblank_start /= 2;
+       mode->crtc_hblank_end /= 2;
+       mode->crtc_hsync_start /= 2;
+       mode->crtc_hsync_end /= 2;
+       mode->crtc_htotal /= 2;
+}
+
+static void intel_splitter_adjust_timings(const struct intel_crtc_state *crtc_state,
+                                         struct drm_display_mode *mode)
+{
+       int overlap = crtc_state->splitter.pixel_overlap;
+       int n = crtc_state->splitter.link_count;
+
+       if (!crtc_state->splitter.enable)
+               return;
+
+       /*
+        * eDP MSO uses segment timings from EDID for transcoder
+        * timings, but full mode for everything else.
+        *
+        * h_full = (h_segment - pixel_overlap) * link_count
+        */
+       mode->crtc_hdisplay = (mode->crtc_hdisplay - overlap) * n;
+       mode->crtc_hblank_start = (mode->crtc_hblank_start - overlap) * n;
+       mode->crtc_hblank_end = (mode->crtc_hblank_end - overlap) * n;
+       mode->crtc_hsync_start = (mode->crtc_hsync_start - overlap) * n;
+       mode->crtc_hsync_end = (mode->crtc_hsync_end - overlap) * n;
+       mode->crtc_htotal = (mode->crtc_htotal - overlap) * n;
+       mode->crtc_clock *= n;
+}
+
 static void intel_crtc_readout_derived_state(struct intel_crtc_state *crtc_state)
 {
        struct drm_display_mode *mode = &crtc_state->hw.mode;
        struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
        struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 
+       /*
+        * Start with the adjusted_mode crtc timings, which
+        * have been filled with the transcoder timings.
+        */
        drm_mode_copy(pipe_mode, adjusted_mode);
 
-       if (crtc_state->bigjoiner) {
-               /*
-                * transcoder is programmed to the full mode,
-                * but pipe timings are half of the transcoder mode
-                */
-               pipe_mode->crtc_hdisplay /= 2;
-               pipe_mode->crtc_hblank_start /= 2;
-               pipe_mode->crtc_hblank_end /= 2;
-               pipe_mode->crtc_hsync_start /= 2;
-               pipe_mode->crtc_hsync_end /= 2;
-               pipe_mode->crtc_htotal /= 2;
-               pipe_mode->crtc_clock /= 2;
-       }
-
-       if (crtc_state->splitter.enable) {
-               int n = crtc_state->splitter.link_count;
-               int overlap = crtc_state->splitter.pixel_overlap;
-
-               /*
-                * eDP MSO uses segment timings from EDID for transcoder
-                * timings, but full mode for everything else.
-                *
-                * h_full = (h_segment - pixel_overlap) * link_count
-                */
-               pipe_mode->crtc_hdisplay = (pipe_mode->crtc_hdisplay - overlap) * n;
-               pipe_mode->crtc_hblank_start = (pipe_mode->crtc_hblank_start - overlap) * n;
-               pipe_mode->crtc_hblank_end = (pipe_mode->crtc_hblank_end - overlap) * n;
-               pipe_mode->crtc_hsync_start = (pipe_mode->crtc_hsync_start - overlap) * n;
-               pipe_mode->crtc_hsync_end = (pipe_mode->crtc_hsync_end - overlap) * n;
-               pipe_mode->crtc_htotal = (pipe_mode->crtc_htotal - overlap) * n;
-               pipe_mode->crtc_clock *= n;
-
-               intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
-               intel_mode_from_crtc_timings(adjusted_mode, pipe_mode);
-       } else {
-               intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
-               intel_mode_from_crtc_timings(adjusted_mode, adjusted_mode);
-       }
+       /* Expand MSO per-segment transcoder timings to full */
+       intel_splitter_adjust_timings(crtc_state, pipe_mode);
 
-       intel_crtc_compute_pixel_rate(crtc_state);
+       /*
+        * We want the full numbers in adjusted_mode normal timings,
+        * adjusted_mode crtc timings are left with the raw transcoder
+        * timings.
+        */
+       intel_mode_from_crtc_timings(adjusted_mode, pipe_mode);
 
-       drm_mode_copy(mode, adjusted_mode);
+       /* Populate the "user" mode with full numbers */
+       drm_mode_copy(mode, pipe_mode);
+       intel_mode_from_crtc_timings(mode, mode);
        mode->hdisplay = crtc_state->pipe_src_w << crtc_state->bigjoiner;
        mode->vdisplay = crtc_state->pipe_src_h;
+
+       /* Derive per-pipe timings in case bigjoiner is used */
+       intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
+       intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
+
+       intel_crtc_compute_pixel_rate(crtc_state);
 }
 
 static void intel_encoder_get_config(struct intel_encoder *encoder,
@@ -2787,44 +2810,63 @@ static void intel_encoder_get_config(struct intel_encoder *encoder,
        intel_crtc_readout_derived_state(crtc_state);
 }
 
-static int intel_crtc_compute_config(struct intel_crtc *crtc,
-                                    struct intel_crtc_state *pipe_config)
+static int intel_crtc_compute_pipe_src(struct intel_crtc_state *crtc_state)
 {
-       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-       struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
-       int clock_limit = dev_priv->max_dotclk_freq;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 
-       drm_mode_copy(pipe_mode, &pipe_config->hw.adjusted_mode);
+       if (crtc_state->bigjoiner)
+               crtc_state->pipe_src_w /= 2;
+
+       /*
+        * Pipe horizontal size must be even in:
+        * - DVO ganged mode
+        * - LVDS dual channel mode
+        * - Double wide pipe
+        */
+       if (crtc_state->pipe_src_w & 1) {
+               if (crtc_state->double_wide) {
+                       drm_dbg_kms(&i915->drm,
+                                   "[CRTC:%d:%s] Odd pipe source width not supported with double wide pipe\n",
+                                   crtc->base.base.id, crtc->base.name);
+                       return -EINVAL;
+               }
 
-       /* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
-       if (pipe_config->bigjoiner) {
-               pipe_mode->crtc_clock /= 2;
-               pipe_mode->crtc_hdisplay /= 2;
-               pipe_mode->crtc_hblank_start /= 2;
-               pipe_mode->crtc_hblank_end /= 2;
-               pipe_mode->crtc_hsync_start /= 2;
-               pipe_mode->crtc_hsync_end /= 2;
-               pipe_mode->crtc_htotal /= 2;
-               pipe_config->pipe_src_w /= 2;
+               if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+                   intel_is_dual_link_lvds(i915)) {
+                       drm_dbg_kms(&i915->drm,
+                                   "[CRTC:%d:%s] Odd pipe source width not supported with dual link LVDS\n",
+                                   crtc->base.base.id, crtc->base.name);
+                       return -EINVAL;
+               }
        }
 
-       if (pipe_config->splitter.enable) {
-               int n = pipe_config->splitter.link_count;
-               int overlap = pipe_config->splitter.pixel_overlap;
+       return 0;
+}
 
-               pipe_mode->crtc_hdisplay = (pipe_mode->crtc_hdisplay - overlap) * n;
-               pipe_mode->crtc_hblank_start = (pipe_mode->crtc_hblank_start - overlap) * n;
-               pipe_mode->crtc_hblank_end = (pipe_mode->crtc_hblank_end - overlap) * n;
-               pipe_mode->crtc_hsync_start = (pipe_mode->crtc_hsync_start - overlap) * n;
-               pipe_mode->crtc_hsync_end = (pipe_mode->crtc_hsync_end - overlap) * n;
-               pipe_mode->crtc_htotal = (pipe_mode->crtc_htotal - overlap) * n;
-               pipe_mode->crtc_clock *= n;
-       }
+static int intel_crtc_compute_pipe_mode(struct intel_crtc_state *crtc_state)
+{
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+       struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+       struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+       struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
+       int clock_limit = i915->max_dotclk_freq;
 
+       /*
+        * Start with the adjusted_mode crtc timings, which
+        * have been filled with the transcoder timings.
+        */
+       drm_mode_copy(pipe_mode, adjusted_mode);
+
+       /* Expand MSO per-segment transcoder timings to full */
+       intel_splitter_adjust_timings(crtc_state, pipe_mode);
+
+       /* Derive per-pipe timings in case bigjoiner is used */
+       intel_bigjoiner_adjust_timings(crtc_state, pipe_mode);
        intel_mode_from_crtc_timings(pipe_mode, pipe_mode);
 
-       if (DISPLAY_VER(dev_priv) < 4) {
-               clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
+       if (DISPLAY_VER(i915) < 4) {
+               clock_limit = i915->max_cdclk_freq * 9 / 10;
 
                /*
                 * Enable double wide mode when the dot clock
@@ -2832,44 +2874,40 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
                 */
                if (intel_crtc_supports_double_wide(crtc) &&
                    pipe_mode->crtc_clock > clock_limit) {
-                       clock_limit = dev_priv->max_dotclk_freq;
-                       pipe_config->double_wide = true;
+                       clock_limit = i915->max_dotclk_freq;
+                       crtc_state->double_wide = true;
                }
        }
 
        if (pipe_mode->crtc_clock > clock_limit) {
-               drm_dbg_kms(&dev_priv->drm,
-                           "requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
+               drm_dbg_kms(&i915->drm,
+                           "[CRTC:%d:%s] requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
+                           crtc->base.base.id, crtc->base.name,
                            pipe_mode->crtc_clock, clock_limit,
-                           yesno(pipe_config->double_wide));
+                           yesno(crtc_state->double_wide));
                return -EINVAL;
        }
 
-       /*
-        * Pipe horizontal size must be even in:
-        * - DVO ganged mode
-        * - LVDS dual channel mode
-        * - Double wide pipe
-        */
-       if (pipe_config->pipe_src_w & 1) {
-               if (pipe_config->double_wide) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "Odd pipe source width not supported with double wide pipe\n");
-                       return -EINVAL;
-               }
+       return 0;
+}
 
-               if (intel_crtc_has_type(pipe_config, INTEL_OUTPUT_LVDS) &&
-                   intel_is_dual_link_lvds(dev_priv)) {
-                       drm_dbg_kms(&dev_priv->drm,
-                                   "Odd pipe source width not supported with dual link LVDS\n");
-                       return -EINVAL;
-               }
-       }
+static int intel_crtc_compute_config(struct intel_crtc *crtc,
+                                    struct intel_crtc_state *crtc_state)
+{
+       int ret;
+
+       ret = intel_crtc_compute_pipe_src(crtc_state);
+       if (ret)
+               return ret;
+
+       ret = intel_crtc_compute_pipe_mode(crtc_state);
+       if (ret)
+               return ret;
 
-       intel_crtc_compute_pixel_rate(pipe_config);
+       intel_crtc_compute_pixel_rate(crtc_state);
 
-       if (pipe_config->has_pch_encoder)
-               return ilk_fdi_compute_config(crtc, pipe_config);
+       if (crtc_state->has_pch_encoder)
+               return ilk_fdi_compute_config(crtc, crtc_state);
 
        return 0;
 }
@@ -5590,12 +5628,9 @@ copy_bigjoiner_crtc_state_modeset(struct intel_atomic_state *state,
 
        copy_bigjoiner_crtc_state_nomodeset(state, slave_crtc);
 
-       /* Some fixups */
        slave_crtc_state->uapi.mode_changed = master_crtc_state->uapi.mode_changed;
        slave_crtc_state->uapi.connectors_changed = master_crtc_state->uapi.connectors_changed;
        slave_crtc_state->uapi.active_changed = master_crtc_state->uapi.active_changed;
-       slave_crtc_state->cpu_transcoder = master_crtc_state->cpu_transcoder;
-       slave_crtc_state->has_audio = master_crtc_state->has_audio;
 
        return 0;
 }
@@ -7458,6 +7493,7 @@ static int intel_atomic_check_async(struct intel_atomic_state *state, struct int
                case I915_FORMAT_MOD_X_TILED:
                case I915_FORMAT_MOD_Y_TILED:
                case I915_FORMAT_MOD_Yf_TILED:
+               case I915_FORMAT_MOD_4_TILED:
                        break;
                default:
                        drm_dbg_kms(&i915->drm,
index ffe6822d7414a454a10f0e8f0a66a0b51aa988ee..78752ce46639b295c5eb872f70a3b3b3ae856073 100644 (file)
@@ -10,6 +10,7 @@
 #include "intel_de.h"
 #include "intel_display_debugfs.h"
 #include "intel_display_power.h"
+#include "intel_display_power_well.h"
 #include "intel_display_types.h"
 #include "intel_dmc.h"
 #include "intel_dp.h"
index 9ebae7ac32356e925830bc06fdf06684b49ed324..e8e8ce13aa96075cd9121f99c28f7439ae989080 100644 (file)
@@ -11,6 +11,7 @@
 #include "intel_crt.h"
 #include "intel_de.h"
 #include "intel_display_power.h"
+#include "intel_display_power_well.h"
 #include "intel_display_types.h"
 #include "intel_dmc.h"
 #include "intel_dpio_phy.h"
 #include "intel_vga.h"
 #include "vlv_sideband.h"
 
-struct i915_power_well_ops {
-       /*
-        * Synchronize the well's hw state to match the current sw state, for
-        * example enable/disable it based on the current refcount. Called
-        * during driver init and resume time, possibly after first calling
-        * the enable/disable handlers.
-        */
-       void (*sync_hw)(struct drm_i915_private *dev_priv,
-                       struct i915_power_well *power_well);
-       /*
-        * Enable the well and resources that depend on it (for example
-        * interrupts located on the well). Called after the 0->1 refcount
-        * transition.
-        */
-       void (*enable)(struct drm_i915_private *dev_priv,
-                      struct i915_power_well *power_well);
-       /*
-        * Disable the well and resources that depend on it. Called after
-        * the 1->0 refcount transition.
-        */
-       void (*disable)(struct drm_i915_private *dev_priv,
-                       struct i915_power_well *power_well);
-       /* Returns the hw enabled state. */
-       bool (*is_enabled)(struct drm_i915_private *dev_priv,
-                          struct i915_power_well *power_well);
-};
-
-struct i915_power_well_regs {
-       i915_reg_t bios;
-       i915_reg_t driver;
-       i915_reg_t kvmr;
-       i915_reg_t debug;
-};
-
-/* Power well structure for haswell */
-struct i915_power_well_desc {
-       const char *name;
-       bool always_on;
-       u64 domains;
-       /* unique identifier for this power well */
-       enum i915_power_well_id id;
-       /*
-        * Arbitraty data associated with this power well. Platform and power
-        * well specific.
-        */
-       union {
-               struct {
-                       /*
-                        * request/status flag index in the PUNIT power well
-                        * control/status registers.
-                        */
-                       u8 idx;
-               } vlv;
-               struct {
-                       enum dpio_phy phy;
-               } bxt;
-               struct {
-                       const struct i915_power_well_regs *regs;
-                       /*
-                        * request/status flag index in the power well
-                        * constrol/status registers.
-                        */
-                       u8 idx;
-                       /* Mask of pipes whose IRQ logic is backed by the pw */
-                       u8 irq_pipe_mask;
-                       /*
-                        * Instead of waiting for the status bit to ack enables,
-                        * just wait a specific amount of time and then consider
-                        * the well enabled.
-                        */
-                       u16 fixed_enable_delay;
-                       /* The pw is backing the VGA functionality */
-                       bool has_vga:1;
-                       bool has_fuses:1;
-                       /*
-                        * The pw is for an ICL+ TypeC PHY port in
-                        * Thunderbolt mode.
-                        */
-                       bool is_tc_tbt:1;
-               } hsw;
-       };
-       const struct i915_power_well_ops *ops;
-};
-
-struct i915_power_well {
-       const struct i915_power_well_desc *desc;
-       /* power well enable/disable usage count */
-       int count;
-       /* cached hw enabled state */
-       bool hw_enabled;
-};
-
-bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
-                                        enum i915_power_well_id power_well_id);
-
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain)
 {
@@ -153,12 +59,12 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
                return "TRANSCODER_D";
        case POWER_DOMAIN_TRANSCODER_EDP:
                return "TRANSCODER_EDP";
-       case POWER_DOMAIN_TRANSCODER_VDSC_PW2:
-               return "TRANSCODER_VDSC_PW2";
        case POWER_DOMAIN_TRANSCODER_DSI_A:
                return "TRANSCODER_DSI_A";
        case POWER_DOMAIN_TRANSCODER_DSI_C:
                return "TRANSCODER_DSI_C";
+       case POWER_DOMAIN_TRANSCODER_VDSC_PW2:
+               return "TRANSCODER_VDSC_PW2";
        case POWER_DOMAIN_PORT_DDI_A_LANES:
                return "PORT_DDI_A_LANES";
        case POWER_DOMAIN_PORT_DDI_B_LANES:
@@ -259,40 +165,6 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
        }
 }
 
-static void intel_power_well_enable(struct drm_i915_private *dev_priv,
-                                   struct i915_power_well *power_well)
-{
-       drm_dbg_kms(&dev_priv->drm, "enabling %s\n", power_well->desc->name);
-       power_well->desc->ops->enable(dev_priv, power_well);
-       power_well->hw_enabled = true;
-}
-
-static void intel_power_well_disable(struct drm_i915_private *dev_priv,
-                                    struct i915_power_well *power_well)
-{
-       drm_dbg_kms(&dev_priv->drm, "disabling %s\n", power_well->desc->name);
-       power_well->hw_enabled = false;
-       power_well->desc->ops->disable(dev_priv, power_well);
-}
-
-static void intel_power_well_get(struct drm_i915_private *dev_priv,
-                                struct i915_power_well *power_well)
-{
-       if (!power_well->count++)
-               intel_power_well_enable(dev_priv, power_well);
-}
-
-static void intel_power_well_put(struct drm_i915_private *dev_priv,
-                                struct i915_power_well *power_well)
-{
-       drm_WARN(&dev_priv->drm, !power_well->count,
-                "Use count on power well %s is already zero",
-                power_well->desc->name);
-
-       if (!--power_well->count)
-               intel_power_well_disable(dev_priv, power_well);
-}
-
 /**
  * __intel_display_power_is_enabled - unlocked check for a power domain
  * @dev_priv: i915 device instance
@@ -317,10 +189,10 @@ bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
        is_enabled = true;
 
        for_each_power_domain_well_reverse(dev_priv, power_well, BIT_ULL(domain)) {
-               if (power_well->desc->always_on)
+               if (intel_power_well_is_always_on(power_well))
                        continue;
 
-               if (!power_well->hw_enabled) {
+               if (!intel_power_well_is_enabled_cached(power_well)) {
                        is_enabled = false;
                        break;
                }
@@ -438,7 +310,7 @@ static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
                                           struct i915_power_well *power_well,
                                           bool timeout_expected)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        int enable_delay = power_well->desc->hsw.fixed_enable_delay;
 
@@ -456,7 +328,7 @@ static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
        if (intel_de_wait_for_set(dev_priv, regs->driver,
                                  HSW_PWR_WELL_CTL_STATE(pw_idx), 1)) {
                drm_dbg_kms(&dev_priv->drm, "%s power well enable timeout\n",
-                           power_well->desc->name);
+                           intel_power_well_name(power_well));
 
                drm_WARN_ON(&dev_priv->drm, !timeout_expected);
 
@@ -482,7 +354,7 @@ static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv,
 static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
                                            struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        bool disabled;
        u32 reqs;
@@ -504,7 +376,7 @@ static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
 
        drm_dbg_kms(&dev_priv->drm,
                    "%s forced on (bios:%d driver:%d kvmr:%d debug:%d)\n",
-                   power_well->desc->name,
+                   intel_power_well_name(power_well),
                    !!(reqs & 1), !!(reqs & 2), !!(reqs & 4), !!(reqs & 8));
 }
 
@@ -520,7 +392,7 @@ static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv,
 static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
                                  struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        u32 val;
 
@@ -567,7 +439,7 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
 static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        u32 val;
 
@@ -584,7 +456,7 @@ static void
 icl_combo_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
                                    struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        enum phy phy = icl_aux_pw_to_phy(dev_priv, power_well);
        u32 val;
@@ -616,7 +488,7 @@ static void
 icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
                                     struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        enum phy phy = icl_aux_pw_to_phy(dev_priv, power_well);
        u32 val;
@@ -636,28 +508,10 @@ icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)
 
-static u64 async_put_domains_mask(struct i915_power_domains *power_domains);
-
-static int power_well_async_ref_count(struct drm_i915_private *dev_priv,
-                                     struct i915_power_well *power_well)
-{
-       int refs = hweight64(power_well->desc->domains &
-                            async_put_domains_mask(&dev_priv->power_domains));
-
-       drm_WARN_ON(&dev_priv->drm, refs > power_well->count);
-
-       return refs;
-}
-
 static void icl_tc_port_assert_ref_held(struct drm_i915_private *dev_priv,
                                        struct i915_power_well *power_well,
                                        struct intel_digital_port *dig_port)
 {
-       /* Bypass the check if all references are released asynchronously */
-       if (power_well_async_ref_count(dev_priv, power_well) ==
-           power_well->count)
-               return;
-
        if (drm_WARN_ON(&dev_priv->drm, !dig_port))
                return;
 
@@ -706,7 +560,7 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
 {
        enum aux_ch aux_ch = icl_aux_pw_to_ch(power_well);
        struct intel_digital_port *dig_port = aux_ch_to_digital_port(dev_priv, aux_ch);
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        bool is_tbt = power_well->desc->hsw.is_tc_tbt;
        bool timeout_expected;
        u32 val;
@@ -748,18 +602,6 @@ icl_tc_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
        }
 }
 
-static void
-icl_tc_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
-                                 struct i915_power_well *power_well)
-{
-       enum aux_ch aux_ch = icl_aux_pw_to_ch(power_well);
-       struct intel_digital_port *dig_port = aux_ch_to_digital_port(dev_priv, aux_ch);
-
-       icl_tc_port_assert_ref_held(dev_priv, power_well, dig_port);
-
-       hsw_power_well_disable(dev_priv, power_well);
-}
-
 static void
 icl_aux_power_well_enable(struct drm_i915_private *dev_priv,
                          struct i915_power_well *power_well)
@@ -782,7 +624,7 @@ icl_aux_power_well_disable(struct drm_i915_private *dev_priv,
        enum phy phy = icl_aux_pw_to_phy(dev_priv, power_well);
 
        if (intel_phy_is_tc(dev_priv, phy))
-               return icl_tc_phy_aux_power_well_disable(dev_priv, power_well);
+               return hsw_power_well_disable(dev_priv, power_well);
        else if (IS_ICELAKE(dev_priv))
                return icl_combo_phy_aux_power_well_disable(dev_priv,
                                                            power_well);
@@ -798,7 +640,7 @@ icl_aux_power_well_disable(struct drm_i915_private *dev_priv,
 static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        enum i915_power_well_id id = power_well->desc->id;
        int pw_idx = power_well->desc->hsw.idx;
        u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx) |
@@ -1073,29 +915,6 @@ static void assert_dmc_loaded(struct drm_i915_private *dev_priv)
                      "DMC HTP Not fine\n");
 }
 
-static struct i915_power_well *
-lookup_power_well(struct drm_i915_private *dev_priv,
-                 enum i915_power_well_id power_well_id)
-{
-       struct i915_power_well *power_well;
-
-       for_each_power_well(dev_priv, power_well)
-               if (power_well->desc->id == power_well_id)
-                       return power_well;
-
-       /*
-        * It's not feasible to add error checking code to the callers since
-        * this condition really shouldn't happen and it doesn't even make sense
-        * to abort things like display initialization sequences. Just return
-        * the first power well and hope the WARN gets reported so we can fix
-        * our driver.
-        */
-       drm_WARN(&dev_priv->drm, 1,
-                "Power well %d not defined for this platform\n",
-                power_well_id);
-       return &dev_priv->power_domains.power_wells[0];
-}
-
 /**
  * intel_display_power_set_target_dc_state - Set target dc state.
  * @dev_priv: i915 device
@@ -1123,19 +942,18 @@ void intel_display_power_set_target_dc_state(struct drm_i915_private *dev_priv,
        if (state == dev_priv->dmc.target_dc_state)
                goto unlock;
 
-       dc_off_enabled = power_well->desc->ops->is_enabled(dev_priv,
-                                                          power_well);
+       dc_off_enabled = intel_power_well_is_enabled(dev_priv, power_well);
        /*
         * If DC off power well is disabled, need to enable and disable the
         * DC off power well to effect target DC state.
         */
        if (!dc_off_enabled)
-               power_well->desc->ops->enable(dev_priv, power_well);
+               intel_power_well_enable(dev_priv, power_well);
 
        dev_priv->dmc.target_dc_state = state;
 
        if (!dc_off_enabled)
-               power_well->desc->ops->disable(dev_priv, power_well);
+               intel_power_well_disable(dev_priv, power_well);
 
 unlock:
        mutex_unlock(&power_domains->lock);
@@ -1208,7 +1026,7 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv)
 static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       const struct i915_power_well_regs *regs = power_well->desc->ops->regs;
        int pw_idx = power_well->desc->hsw.idx;
        u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx);
        u32 bios_req = intel_de_read(dev_priv, regs->bios);
@@ -1246,17 +1064,17 @@ static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
        struct i915_power_well *power_well;
 
        power_well = lookup_power_well(dev_priv, BXT_DISP_PW_DPIO_CMN_A);
-       if (power_well->count > 0)
+       if (intel_power_well_refcount(power_well) > 0)
                bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy);
 
        power_well = lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC);
-       if (power_well->count > 0)
+       if (intel_power_well_refcount(power_well) > 0)
                bxt_ddi_phy_verify_state(dev_priv, power_well->desc->bxt.phy);
 
        if (IS_GEMINILAKE(dev_priv)) {
                power_well = lookup_power_well(dev_priv,
                                               GLK_DISP_PW_DPIO_CMN_C);
-               if (power_well->count > 0)
+               if (intel_power_well_refcount(power_well) > 0)
                        bxt_ddi_phy_verify_state(dev_priv,
                                                 power_well->desc->bxt.phy);
        }
@@ -1382,7 +1200,7 @@ static bool i830_pipes_power_well_enabled(struct drm_i915_private *dev_priv,
 static void i830_pipes_power_well_sync_hw(struct drm_i915_private *dev_priv,
                                          struct i915_power_well *power_well)
 {
-       if (power_well->count > 0)
+       if (intel_power_well_refcount(power_well) > 0)
                i830_pipes_power_well_enable(dev_priv, power_well);
        else
                i830_pipes_power_well_disable(dev_priv, power_well);
@@ -1655,7 +1473,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
                                     PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 0) |
                                     PHY_STATUS_SPLINE_LDO(DPIO_PHY1, DPIO_CH0, 1));
 
-       if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) {
+       if (intel_power_well_is_enabled(dev_priv, cmn_bc)) {
                phy_status |= PHY_POWERGOOD(DPIO_PHY0);
 
                /* this assumes override is only used to enable lanes */
@@ -1696,7 +1514,7 @@ static void assert_chv_phy_status(struct drm_i915_private *dev_priv)
                        phy_status |= PHY_STATUS_SPLINE_LDO(DPIO_PHY0, DPIO_CH1, 1);
        }
 
-       if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) {
+       if (intel_power_well_is_enabled(dev_priv, cmn_d)) {
                phy_status |= PHY_POWERGOOD(DPIO_PHY1);
 
                /* this assumes override is only used to enable lanes */
@@ -3280,7 +3098,15 @@ static const struct i915_power_well_desc i830_power_wells[] = {
        },
 };
 
+static const struct i915_power_well_regs hsw_power_well_regs = {
+       .bios   = HSW_PWR_WELL_CTL1,
+       .driver = HSW_PWR_WELL_CTL2,
+       .kvmr   = HSW_PWR_WELL_CTL3,
+       .debug  = HSW_PWR_WELL_CTL4,
+};
+
 static const struct i915_power_well_ops hsw_power_well_ops = {
+       .regs = &hsw_power_well_regs,
        .sync_hw = hsw_power_well_sync_hw,
        .enable = hsw_power_well_enable,
        .disable = hsw_power_well_disable,
@@ -3301,13 +3127,6 @@ static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = {
        .is_enabled = bxt_dpio_cmn_power_well_enabled,
 };
 
-static const struct i915_power_well_regs hsw_power_well_regs = {
-       .bios   = HSW_PWR_WELL_CTL1,
-       .driver = HSW_PWR_WELL_CTL2,
-       .kvmr   = HSW_PWR_WELL_CTL3,
-       .debug  = HSW_PWR_WELL_CTL4,
-};
-
 static const struct i915_power_well_desc hsw_power_wells[] = {
        {
                .name = "always-on",
@@ -3322,7 +3141,6 @@ static const struct i915_power_well_desc hsw_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = HSW_DISP_PW_GLOBAL,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
                        .hsw.has_vga = true,
                },
@@ -3343,7 +3161,6 @@ static const struct i915_power_well_desc bdw_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = HSW_DISP_PW_GLOBAL,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
@@ -3487,18 +3304,6 @@ static const struct i915_power_well_desc chv_power_wells[] = {
        },
 };
 
-bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
-                                        enum i915_power_well_id power_well_id)
-{
-       struct i915_power_well *power_well;
-       bool ret;
-
-       power_well = lookup_power_well(dev_priv, power_well_id);
-       ret = power_well->desc->ops->is_enabled(dev_priv, power_well);
-
-       return ret;
-}
-
 static const struct i915_power_well_desc skl_power_wells[] = {
        {
                .name = "always-on",
@@ -3515,7 +3320,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -3528,7 +3332,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_MISC_IO,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_MISC_IO,
                },
        },
@@ -3544,7 +3347,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
@@ -3557,7 +3359,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_A_E,
                },
        },
@@ -3567,7 +3368,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
                },
        },
@@ -3577,7 +3377,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
                },
        },
@@ -3587,7 +3386,6 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_D,
                },
        },
@@ -3609,7 +3407,6 @@ static const struct i915_power_well_desc bxt_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -3626,7 +3423,6 @@ static const struct i915_power_well_desc bxt_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
@@ -3669,7 +3465,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -3686,7 +3481,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
@@ -3726,7 +3520,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = GLK_PW_CTL_IDX_AUX_A,
                },
        },
@@ -3736,7 +3529,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = GLK_PW_CTL_IDX_AUX_B,
                },
        },
@@ -3746,7 +3538,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = GLK_PW_CTL_IDX_AUX_C,
                },
        },
@@ -3756,7 +3547,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = GLK_PW_CTL_IDX_DDI_A,
                },
        },
@@ -3766,7 +3556,6 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
                },
        },
@@ -3776,31 +3565,39 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
                },
        },
 };
 
+static const struct i915_power_well_regs icl_aux_power_well_regs = {
+       .bios   = ICL_PWR_WELL_CTL_AUX1,
+       .driver = ICL_PWR_WELL_CTL_AUX2,
+       .debug  = ICL_PWR_WELL_CTL_AUX4,
+};
+
 static const struct i915_power_well_ops icl_aux_power_well_ops = {
+       .regs = &icl_aux_power_well_regs,
        .sync_hw = hsw_power_well_sync_hw,
        .enable = icl_aux_power_well_enable,
        .disable = icl_aux_power_well_disable,
        .is_enabled = hsw_power_well_enabled,
 };
 
-static const struct i915_power_well_regs icl_aux_power_well_regs = {
-       .bios   = ICL_PWR_WELL_CTL_AUX1,
-       .driver = ICL_PWR_WELL_CTL_AUX2,
-       .debug  = ICL_PWR_WELL_CTL_AUX4,
-};
-
 static const struct i915_power_well_regs icl_ddi_power_well_regs = {
        .bios   = ICL_PWR_WELL_CTL_DDI1,
        .driver = ICL_PWR_WELL_CTL_DDI2,
        .debug  = ICL_PWR_WELL_CTL_DDI4,
 };
 
+static const struct i915_power_well_ops icl_ddi_power_well_ops = {
+       .regs = &icl_ddi_power_well_regs,
+       .sync_hw = hsw_power_well_sync_hw,
+       .enable = hsw_power_well_enable,
+       .disable = hsw_power_well_disable,
+       .is_enabled = hsw_power_well_enabled,
+};
+
 static const struct i915_power_well_desc icl_power_wells[] = {
        {
                .name = "always-on",
@@ -3817,7 +3614,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -3834,7 +3630,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_2,
                        .hsw.has_fuses = true,
                },
@@ -3845,7 +3640,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_3,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_3,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_vga = true,
@@ -3855,60 +3649,54 @@ static const struct i915_power_well_desc icl_power_wells[] = {
        {
                .name = "DDI A IO",
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
                },
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
                },
        },
        {
                .name = "DDI C IO",
                .domains = ICL_DDI_IO_C_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_C,
                },
        },
        {
                .name = "DDI D IO",
                .domains = ICL_DDI_IO_D_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_D,
                },
        },
        {
                .name = "DDI E IO",
                .domains = ICL_DDI_IO_E_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_E,
                },
        },
        {
                .name = "DDI F IO",
                .domains = ICL_DDI_IO_F_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_F,
                },
        },
@@ -3918,7 +3706,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
                },
        },
@@ -3928,7 +3715,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
                },
        },
@@ -3938,7 +3724,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_C,
                        .hsw.is_tc_tbt = false,
                },
@@ -3949,7 +3734,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_D,
                        .hsw.is_tc_tbt = false,
                },
@@ -3960,7 +3744,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_E,
                        .hsw.is_tc_tbt = false,
                },
@@ -3971,7 +3754,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_F,
                        .hsw.is_tc_tbt = false,
                },
@@ -3982,7 +3764,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT1,
                        .hsw.is_tc_tbt = true,
                },
@@ -3993,7 +3774,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT2,
                        .hsw.is_tc_tbt = true,
                },
@@ -4004,7 +3784,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT3,
                        .hsw.is_tc_tbt = true,
                },
@@ -4015,7 +3794,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT4,
                        .hsw.is_tc_tbt = true,
                },
@@ -4026,7 +3804,6 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_4,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
@@ -4094,7 +3871,7 @@ static void
 tgl_tc_cold_off_power_well_sync_hw(struct drm_i915_private *i915,
                                   struct i915_power_well *power_well)
 {
-       if (power_well->count > 0)
+       if (intel_power_well_refcount(power_well) > 0)
                tgl_tc_cold_off_power_well_enable(i915, power_well);
        else
                tgl_tc_cold_off_power_well_disable(i915, power_well);
@@ -4108,7 +3885,7 @@ tgl_tc_cold_off_power_well_is_enabled(struct drm_i915_private *dev_priv,
         * Not the correctly implementation but there is no way to just read it
         * from PCODE, so returning count to avoid state mismatch errors
         */
-       return power_well->count;
+       return intel_power_well_refcount(power_well);
 }
 
 static const struct i915_power_well_ops tgl_tc_cold_off_ops = {
@@ -4134,7 +3911,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -4151,7 +3927,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_2,
                        .hsw.has_fuses = true,
                },
@@ -4162,7 +3937,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_3,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_3,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_vga = true,
@@ -4172,90 +3946,81 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
        {
                .name = "DDI A IO",
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
                }
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
                }
        },
        {
                .name = "DDI C IO",
                .domains = ICL_DDI_IO_C_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_C,
                }
        },
        {
                .name = "DDI IO TC1",
                .domains = TGL_DDI_IO_TC1_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
                },
        },
        {
                .name = "DDI IO TC2",
                .domains = TGL_DDI_IO_TC2_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
                },
        },
        {
                .name = "DDI IO TC3",
                .domains = TGL_DDI_IO_TC3_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC3,
                },
        },
        {
                .name = "DDI IO TC4",
                .domains = TGL_DDI_IO_TC4_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC4,
                },
        },
        {
                .name = "DDI IO TC5",
                .domains = TGL_DDI_IO_TC5_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC5,
                },
        },
        {
                .name = "DDI IO TC6",
                .domains = TGL_DDI_IO_TC6_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC6,
                },
        },
@@ -4271,7 +4036,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
                },
        },
@@ -4281,7 +4045,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
                },
        },
@@ -4291,7 +4054,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_C,
                },
        },
@@ -4301,7 +4063,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
                        .hsw.is_tc_tbt = false,
                },
@@ -4312,7 +4073,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
                        .hsw.is_tc_tbt = false,
                },
@@ -4323,7 +4083,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC3,
                        .hsw.is_tc_tbt = false,
                },
@@ -4334,7 +4093,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC4,
                        .hsw.is_tc_tbt = false,
                },
@@ -4345,7 +4103,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC5,
                        .hsw.is_tc_tbt = false,
                },
@@ -4356,7 +4113,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC6,
                        .hsw.is_tc_tbt = false,
                },
@@ -4367,7 +4123,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT1,
                        .hsw.is_tc_tbt = true,
                },
@@ -4378,7 +4133,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT2,
                        .hsw.is_tc_tbt = true,
                },
@@ -4389,7 +4143,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT3,
                        .hsw.is_tc_tbt = true,
                },
@@ -4400,7 +4153,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT4,
                        .hsw.is_tc_tbt = true,
                },
@@ -4411,7 +4163,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT5,
                        .hsw.is_tc_tbt = true,
                },
@@ -4422,7 +4173,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT6,
                        .hsw.is_tc_tbt = true,
                },
@@ -4433,7 +4183,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_4,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
@@ -4445,7 +4194,6 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_PW_5,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_D),
@@ -4469,7 +4217,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -4486,7 +4233,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_3,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_3,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_vga = true,
@@ -4499,7 +4245,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_4,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
@@ -4508,40 +4253,36 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
        {
                .name = "DDI A IO",
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
                }
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
                }
        },
        {
                .name = "DDI IO TC1",
                .domains = TGL_DDI_IO_TC1_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
                },
        },
        {
                .name = "DDI IO TC2",
                .domains = TGL_DDI_IO_TC2_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
                },
        },
@@ -4551,7 +4292,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
                },
        },
@@ -4561,7 +4301,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
                },
        },
@@ -4571,7 +4310,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
                },
        },
@@ -4581,7 +4319,6 @@ static const struct i915_power_well_desc rkl_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
                },
        },
@@ -4603,7 +4340,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -4620,7 +4356,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_2,
                        .hsw.has_fuses = true,
                },
@@ -4631,7 +4366,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_3,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_3,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_vga = true,
@@ -4641,40 +4375,36 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
        {
                .name = "DDI A IO",
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
                }
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
                }
        },
        {
                .name = "DDI IO TC1",
                .domains = TGL_DDI_IO_TC1_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
                },
        },
        {
                .name = "DDI IO TC2",
                .domains = TGL_DDI_IO_TC2_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
                },
        },
@@ -4684,7 +4414,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
                },
        },
@@ -4694,7 +4423,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
                },
        },
@@ -4704,7 +4432,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
                        .hsw.is_tc_tbt = false,
                },
@@ -4715,7 +4442,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
                        .hsw.is_tc_tbt = false,
                },
@@ -4726,7 +4452,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_4,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
@@ -4738,7 +4463,6 @@ static const struct i915_power_well_desc dg1_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_PW_5,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_D),
@@ -4762,7 +4486,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
@@ -4779,7 +4502,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_PW_2,
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -4791,7 +4513,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_PW_A,
                        .hsw.irq_pipe_mask = BIT(PIPE_A),
                        .hsw.has_fuses = true,
@@ -4803,7 +4524,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_PW_B,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_fuses = true,
@@ -4815,7 +4535,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_PW_C,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
                        .hsw.has_fuses = true,
@@ -4827,7 +4546,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &hsw_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_PW_D,
                        .hsw.irq_pipe_mask = BIT(PIPE_D),
                        .hsw.has_fuses = true,
@@ -4836,90 +4554,81 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
        {
                .name = "DDI A IO",
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
                }
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
                }
        },
        {
                .name = "DDI C IO",
                .domains = ICL_DDI_IO_C_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_DDI_C,
                }
        },
        {
                .name = "DDI IO D_XELPD",
                .domains = XELPD_DDI_IO_D_XELPD_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_DDI_D,
                }
        },
        {
                .name = "DDI IO E_XELPD",
                .domains = XELPD_DDI_IO_E_XELPD_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_DDI_E,
                }
        },
        {
                .name = "DDI IO TC1",
                .domains = XELPD_DDI_IO_TC1_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC1,
                }
        },
        {
                .name = "DDI IO TC2",
                .domains = XELPD_DDI_IO_TC2_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC2,
                }
        },
        {
                .name = "DDI IO TC3",
                .domains = XELPD_DDI_IO_TC3_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC3,
                }
        },
        {
                .name = "DDI IO TC4",
                .domains = XELPD_DDI_IO_TC4_POWER_DOMAINS,
-               .ops = &hsw_power_well_ops,
+               .ops = &icl_ddi_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_ddi_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_DDI_TC4,
                }
        },
@@ -4929,7 +4638,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
                        .hsw.fixed_enable_delay = 600,
                },
@@ -4940,7 +4648,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
                        .hsw.fixed_enable_delay = 600,
                },
@@ -4951,7 +4658,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = ICL_PW_CTL_IDX_AUX_C,
                        .hsw.fixed_enable_delay = 600,
                },
@@ -4962,7 +4668,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_AUX_D,
                        .hsw.fixed_enable_delay = 600,
                },
@@ -4973,7 +4678,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = XELPD_PW_CTL_IDX_AUX_E,
                },
        },
@@ -4983,7 +4687,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC1,
                        .hsw.fixed_enable_delay = 600,
                },
@@ -4994,7 +4697,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC2,
                },
        },
@@ -5004,7 +4706,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC3,
                },
        },
@@ -5014,7 +4715,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TC4,
                },
        },
@@ -5024,7 +4724,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT1,
                        .hsw.is_tc_tbt = true,
                },
@@ -5035,7 +4734,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT2,
                        .hsw.is_tc_tbt = true,
                },
@@ -5046,7 +4744,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT3,
                        .hsw.is_tc_tbt = true,
                },
@@ -5057,7 +4754,6 @@ static const struct i915_power_well_desc xelpd_power_wells[] = {
                .ops = &icl_aux_power_well_ops,
                .id = DISP_PW_ID_NONE,
                {
-                       .hsw.regs = &icl_aux_power_well_regs,
                        .hsw.idx = TGL_PW_CTL_IDX_AUX_TBT4,
                        .hsw.is_tc_tbt = true,
                },
@@ -5281,11 +4977,8 @@ static void intel_power_domains_sync_hw(struct drm_i915_private *dev_priv)
        struct i915_power_well *power_well;
 
        mutex_lock(&power_domains->lock);
-       for_each_power_well(dev_priv, power_well) {
-               power_well->desc->ops->sync_hw(dev_priv, power_well);
-               power_well->hw_enabled =
-                       power_well->desc->ops->is_enabled(dev_priv, power_well);
-       }
+       for_each_power_well(dev_priv, power_well)
+               intel_power_well_sync_hw(dev_priv, power_well);
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5998,7 +5691,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
         * override and set the lane powerdown bits accding to the
         * current lane status.
         */
-       if (cmn_bc->desc->ops->is_enabled(dev_priv, cmn_bc)) {
+       if (intel_power_well_is_enabled(dev_priv, cmn_bc)) {
                u32 status = intel_de_read(dev_priv, DPLL(PIPE_A));
                unsigned int mask;
 
@@ -6029,7 +5722,7 @@ static void chv_phy_control_init(struct drm_i915_private *dev_priv)
                dev_priv->chv_phy_assert[DPIO_PHY0] = true;
        }
 
-       if (cmn_d->desc->ops->is_enabled(dev_priv, cmn_d)) {
+       if (intel_power_well_is_enabled(dev_priv, cmn_d)) {
                u32 status = intel_de_read(dev_priv, DPIO_PHY_STATUS);
                unsigned int mask;
 
@@ -6065,15 +5758,15 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
                lookup_power_well(dev_priv, VLV_DISP_PW_DISP2D);
 
        /* If the display might be already active skip this */
-       if (cmn->desc->ops->is_enabled(dev_priv, cmn) &&
-           disp2d->desc->ops->is_enabled(dev_priv, disp2d) &&
+       if (intel_power_well_is_enabled(dev_priv, cmn) &&
+           intel_power_well_is_enabled(dev_priv, disp2d) &&
            intel_de_read(dev_priv, DPIO_CTL) & DPIO_CMNRST)
                return;
 
        drm_dbg_kms(&dev_priv->drm, "toggling display PHY side reset\n");
 
        /* cmnlane needs DPLL registers */
-       disp2d->desc->ops->enable(dev_priv, disp2d);
+       intel_power_well_enable(dev_priv, disp2d);
 
        /*
         * From VLV2A0_DP_eDP_HDMI_DPIO_driver_vbios_notes_11.docx:
@@ -6082,7 +5775,7 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
         * Simply ungating isn't enough to reset the PHY enough to get
         * ports and lanes running.
         */
-       cmn->desc->ops->disable(dev_priv, cmn);
+       intel_power_well_disable(dev_priv, cmn);
 }
 
 static bool vlv_punit_is_power_gated(struct drm_i915_private *dev_priv, u32 reg0)
@@ -6233,12 +5926,12 @@ void intel_power_domains_sanitize_state(struct drm_i915_private *i915)
 
        for_each_power_well_reverse(i915, power_well) {
                if (power_well->desc->always_on || power_well->count ||
-                   !power_well->desc->ops->is_enabled(i915, power_well))
+                   !intel_power_well_is_enabled(i915, power_well))
                        continue;
 
                drm_dbg_kms(&i915->drm,
                            "BIOS left unused %s power well enabled, disabling it\n",
-                           power_well->desc->name);
+                           intel_power_well_name(power_well));
                intel_power_well_disable(i915, power_well);
        }
 
@@ -6377,9 +6070,9 @@ static void intel_power_domains_dump_info(struct drm_i915_private *i915)
                enum intel_display_power_domain domain;
 
                drm_dbg(&i915->drm, "%-25s %d\n",
-                       power_well->desc->name, power_well->count);
+                       intel_power_well_name(power_well), intel_power_well_refcount(power_well));
 
-               for_each_power_domain(domain, power_well->desc->domains)
+               for_each_power_domain(domain, intel_power_well_domains(power_well))
                        drm_dbg(&i915->drm, "  %-23s %d\n",
                                intel_display_power_domain_str(domain),
                                power_domains->domain_use_count[domain]);
@@ -6412,23 +6105,25 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915)
                int domains_count;
                bool enabled;
 
-               enabled = power_well->desc->ops->is_enabled(i915, power_well);
-               if ((power_well->count || power_well->desc->always_on) !=
+               enabled = intel_power_well_is_enabled(i915, power_well);
+               if ((intel_power_well_refcount(power_well) ||
+                    intel_power_well_is_always_on(power_well)) !=
                    enabled)
                        drm_err(&i915->drm,
                                "power well %s state mismatch (refcount %d/enabled %d)",
-                               power_well->desc->name,
-                               power_well->count, enabled);
+                               intel_power_well_name(power_well),
+                               intel_power_well_refcount(power_well), enabled);
 
                domains_count = 0;
-               for_each_power_domain(domain, power_well->desc->domains)
+               for_each_power_domain(domain, intel_power_well_domains(power_well))
                        domains_count += power_domains->domain_use_count[domain];
 
-               if (power_well->count != domains_count) {
+               if (intel_power_well_refcount(power_well) != domains_count) {
                        drm_err(&i915->drm,
                                "power well %s refcount/domain refcount mismatch "
                                "(refcount %d/domains refcount %d)\n",
-                               power_well->desc->name, power_well->count,
+                               intel_power_well_name(power_well),
+                               intel_power_well_refcount(power_well),
                                domains_count);
                        dump_domain_info = true;
                }
@@ -6533,10 +6228,10 @@ void intel_display_power_debug(struct drm_i915_private *i915, struct seq_file *m
                enum intel_display_power_domain power_domain;
 
                power_well = &power_domains->power_wells[i];
-               seq_printf(m, "%-25s %d\n", power_well->desc->name,
-                          power_well->count);
+               seq_printf(m, "%-25s %d\n", intel_power_well_name(power_well),
+                          intel_power_well_refcount(power_well));
 
-               for_each_power_domain(power_domain, power_well->desc->domains)
+               for_each_power_domain(power_domain, intel_power_well_domains(power_well))
                        seq_printf(m, "  %-23s %d\n",
                                   intel_display_power_domain_str(power_domain),
                                   power_domains->domain_use_count[power_domain]);
index f6d0e6e73c6d93be489addb21c05b025f3d68fa8..ced384b0a1658250c404f1d6aa905d95a76d2270 100644 (file)
@@ -14,6 +14,11 @@ struct drm_i915_private;
 struct i915_power_well;
 struct intel_encoder;
 
+/*
+ * Keep the pipe, transcoder, port (DDI_LANES,DDI_IO,AUX) domain instances
+ * consecutive, so that the pipe,transcoder,port -> power domain macros
+ * work correctly.
+ */
 enum intel_display_power_domain {
        POWER_DOMAIN_DISPLAY_CORE,
        POWER_DOMAIN_PIPE_A,
@@ -29,10 +34,12 @@ enum intel_display_power_domain {
        POWER_DOMAIN_TRANSCODER_C,
        POWER_DOMAIN_TRANSCODER_D,
        POWER_DOMAIN_TRANSCODER_EDP,
-       /* VDSC/joining for eDP/DSI transcoder (ICL) or pipe A (TGL) */
-       POWER_DOMAIN_TRANSCODER_VDSC_PW2,
        POWER_DOMAIN_TRANSCODER_DSI_A,
        POWER_DOMAIN_TRANSCODER_DSI_C,
+
+       /* VDSC/joining for eDP/DSI transcoder (ICL) or pipe A (TGL) */
+       POWER_DOMAIN_TRANSCODER_VDSC_PW2,
+
        POWER_DOMAIN_PORT_DDI_A_LANES,
        POWER_DOMAIN_PORT_DDI_B_LANES,
        POWER_DOMAIN_PORT_DDI_C_LANES,
@@ -125,30 +132,6 @@ enum intel_display_power_domain {
        POWER_DOMAIN_NUM,
 };
 
-/*
- * i915_power_well_id:
- *
- * IDs used to look up power wells. Power wells accessed directly bypassing
- * the power domains framework must be assigned a unique ID. The rest of power
- * wells must be assigned DISP_PW_ID_NONE.
- */
-enum i915_power_well_id {
-       DISP_PW_ID_NONE,
-
-       VLV_DISP_PW_DISP2D,
-       BXT_DISP_PW_DPIO_CMN_A,
-       VLV_DISP_PW_DPIO_CMN_BC,
-       GLK_DISP_PW_DPIO_CMN_C,
-       CHV_DISP_PW_DPIO_CMN_D,
-       HSW_DISP_PW_GLOBAL,
-       SKL_DISP_PW_MISC_IO,
-       SKL_DISP_PW_1,
-       SKL_DISP_PW_2,
-       ICL_DISP_PW_3,
-       SKL_DISP_DC_OFF,
-       TGL_DISP_PW_TC_COLD_OFF,
-};
-
 #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
 #define POWER_DOMAIN_PIPE_PANEL_FITTER(pipe) \
                ((pipe) + POWER_DOMAIN_PIPE_A_PANEL_FITTER)
@@ -232,8 +215,6 @@ intel_display_power_domain_str(enum intel_display_power_domain domain);
 
 bool intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
                                    enum intel_display_power_domain domain);
-bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
-                                        enum i915_power_well_id power_well_id);
 bool __intel_display_power_is_enabled(struct drm_i915_private *dev_priv,
                                      enum intel_display_power_domain domain);
 intel_wakeref_t intel_display_power_get(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c
new file mode 100644 (file)
index 0000000..2a0fb9d
--- /dev/null
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright Â© 2022 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_display_power_well.h"
+
+struct i915_power_well *
+lookup_power_well(struct drm_i915_private *i915,
+                 enum i915_power_well_id power_well_id)
+{
+       struct i915_power_well *power_well;
+
+       for_each_power_well(i915, power_well)
+               if (power_well->desc->id == power_well_id)
+                       return power_well;
+
+       /*
+        * It's not feasible to add error checking code to the callers since
+        * this condition really shouldn't happen and it doesn't even make sense
+        * to abort things like display initialization sequences. Just return
+        * the first power well and hope the WARN gets reported so we can fix
+        * our driver.
+        */
+       drm_WARN(&i915->drm, 1,
+                "Power well %d not defined for this platform\n",
+                power_well_id);
+       return &i915->power_domains.power_wells[0];
+}
+
+void intel_power_well_enable(struct drm_i915_private *i915,
+                            struct i915_power_well *power_well)
+{
+       drm_dbg_kms(&i915->drm, "enabling %s\n", power_well->desc->name);
+       power_well->desc->ops->enable(i915, power_well);
+       power_well->hw_enabled = true;
+}
+
+void intel_power_well_disable(struct drm_i915_private *i915,
+                             struct i915_power_well *power_well)
+{
+       drm_dbg_kms(&i915->drm, "disabling %s\n", power_well->desc->name);
+       power_well->hw_enabled = false;
+       power_well->desc->ops->disable(i915, power_well);
+}
+
+void intel_power_well_sync_hw(struct drm_i915_private *i915,
+                             struct i915_power_well *power_well)
+{
+       power_well->desc->ops->sync_hw(i915, power_well);
+       power_well->hw_enabled =
+               power_well->desc->ops->is_enabled(i915, power_well);
+}
+
+void intel_power_well_get(struct drm_i915_private *i915,
+                         struct i915_power_well *power_well)
+{
+       if (!power_well->count++)
+               intel_power_well_enable(i915, power_well);
+}
+
+void intel_power_well_put(struct drm_i915_private *i915,
+                         struct i915_power_well *power_well)
+{
+       drm_WARN(&i915->drm, !power_well->count,
+                "Use count on power well %s is already zero",
+                power_well->desc->name);
+
+       if (!--power_well->count)
+               intel_power_well_disable(i915, power_well);
+}
+
+bool intel_power_well_is_enabled(struct drm_i915_private *i915,
+                                struct i915_power_well *power_well)
+{
+       return power_well->desc->ops->is_enabled(i915, power_well);
+}
+
+bool intel_power_well_is_enabled_cached(struct i915_power_well *power_well)
+{
+       return power_well->hw_enabled;
+}
+
+bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
+                                        enum i915_power_well_id power_well_id)
+{
+       struct i915_power_well *power_well;
+
+       power_well = lookup_power_well(dev_priv, power_well_id);
+
+       return intel_power_well_is_enabled(dev_priv, power_well);
+}
+
+bool intel_power_well_is_always_on(struct i915_power_well *power_well)
+{
+       return power_well->desc->always_on;
+}
+
+const char *intel_power_well_name(struct i915_power_well *power_well)
+{
+       return power_well->desc->name;
+}
+
+u64 intel_power_well_domains(struct i915_power_well *power_well)
+{
+       return power_well->desc->domains;
+}
+
+int intel_power_well_refcount(struct i915_power_well *power_well)
+{
+       return power_well->count;
+}
diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.h b/drivers/gpu/drm/i915/display/intel_display_power_well.h
new file mode 100644 (file)
index 0000000..9a3756f
--- /dev/null
@@ -0,0 +1,153 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright Â© 2022 Intel Corporation
+ */
+#ifndef __INTEL_DISPLAY_POWER_WELL_H__
+#define __INTEL_DISPLAY_POWER_WELL_H__
+
+#include <linux/types.h>
+
+#include "intel_display.h"
+
+struct drm_i915_private;
+struct i915_power_well;
+
+/*
+ * i915_power_well_id:
+ *
+ * IDs used to look up power wells. Power wells accessed directly bypassing
+ * the power domains framework must be assigned a unique ID. The rest of power
+ * wells must be assigned DISP_PW_ID_NONE.
+ */
+enum i915_power_well_id {
+       DISP_PW_ID_NONE,
+
+       VLV_DISP_PW_DISP2D,
+       BXT_DISP_PW_DPIO_CMN_A,
+       VLV_DISP_PW_DPIO_CMN_BC,
+       GLK_DISP_PW_DPIO_CMN_C,
+       CHV_DISP_PW_DPIO_CMN_D,
+       HSW_DISP_PW_GLOBAL,
+       SKL_DISP_PW_MISC_IO,
+       SKL_DISP_PW_1,
+       SKL_DISP_PW_2,
+       ICL_DISP_PW_3,
+       SKL_DISP_DC_OFF,
+       TGL_DISP_PW_TC_COLD_OFF,
+};
+
+struct i915_power_well_regs {
+       i915_reg_t bios;
+       i915_reg_t driver;
+       i915_reg_t kvmr;
+       i915_reg_t debug;
+};
+
+struct i915_power_well_ops {
+       const struct i915_power_well_regs *regs;
+       /*
+        * Synchronize the well's hw state to match the current sw state, for
+        * example enable/disable it based on the current refcount. Called
+        * during driver init and resume time, possibly after first calling
+        * the enable/disable handlers.
+        */
+       void (*sync_hw)(struct drm_i915_private *i915,
+                       struct i915_power_well *power_well);
+       /*
+        * Enable the well and resources that depend on it (for example
+        * interrupts located on the well). Called after the 0->1 refcount
+        * transition.
+        */
+       void (*enable)(struct drm_i915_private *i915,
+                      struct i915_power_well *power_well);
+       /*
+        * Disable the well and resources that depend on it. Called after
+        * the 1->0 refcount transition.
+        */
+       void (*disable)(struct drm_i915_private *i915,
+                       struct i915_power_well *power_well);
+       /* Returns the hw enabled state. */
+       bool (*is_enabled)(struct drm_i915_private *i915,
+                          struct i915_power_well *power_well);
+};
+
+struct i915_power_well_desc {
+       const char *name;
+       bool always_on;
+       u64 domains;
+       /* unique identifier for this power well */
+       enum i915_power_well_id id;
+       /*
+        * Arbitraty data associated with this power well. Platform and power
+        * well specific.
+        */
+       union {
+               struct {
+                       /*
+                        * request/status flag index in the PUNIT power well
+                        * control/status registers.
+                        */
+                       u8 idx;
+               } vlv;
+               struct {
+                       enum dpio_phy phy;
+               } bxt;
+               struct {
+                       /*
+                        * request/status flag index in the power well
+                        * constrol/status registers.
+                        */
+                       u8 idx;
+                       /* Mask of pipes whose IRQ logic is backed by the pw */
+                       u8 irq_pipe_mask;
+                       /*
+                        * Instead of waiting for the status bit to ack enables,
+                        * just wait a specific amount of time and then consider
+                        * the well enabled.
+                        */
+                       u16 fixed_enable_delay;
+                       /* The pw is backing the VGA functionality */
+                       bool has_vga:1;
+                       bool has_fuses:1;
+                       /*
+                        * The pw is for an ICL+ TypeC PHY port in
+                        * Thunderbolt mode.
+                        */
+                       bool is_tc_tbt:1;
+               } hsw;
+       };
+       const struct i915_power_well_ops *ops;
+};
+
+struct i915_power_well {
+       const struct i915_power_well_desc *desc;
+       /* power well enable/disable usage count */
+       int count;
+       /* cached hw enabled state */
+       bool hw_enabled;
+};
+
+struct i915_power_well *lookup_power_well(struct drm_i915_private *i915,
+                                         enum i915_power_well_id id);
+
+void intel_power_well_enable(struct drm_i915_private *i915,
+                            struct i915_power_well *power_well);
+void intel_power_well_disable(struct drm_i915_private *i915,
+                             struct i915_power_well *power_well);
+void intel_power_well_sync_hw(struct drm_i915_private *i915,
+                             struct i915_power_well *power_well);
+void intel_power_well_get(struct drm_i915_private *i915,
+                         struct i915_power_well *power_well);
+void intel_power_well_put(struct drm_i915_private *i915,
+                         struct i915_power_well *power_well);
+bool intel_power_well_is_enabled(struct drm_i915_private *i915,
+                                struct i915_power_well *power_well);
+bool intel_power_well_is_enabled_cached(struct i915_power_well *power_well);
+bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
+                                        enum i915_power_well_id power_well_id);
+bool intel_power_well_is_always_on(struct i915_power_well *power_well);
+const char *intel_power_well_name(struct i915_power_well *power_well);
+u64 intel_power_well_domains(struct i915_power_well *power_well);
+int intel_power_well_refcount(struct i915_power_well *power_well);
+
+#endif
index 7616a3906b9ec440b0bf648dc10a79ebf2da246d..133476be6d289ba23e55345144c55914c041497d 100644 (file)
@@ -697,7 +697,7 @@ void intel_dmc_ucode_init(struct drm_i915_private *dev_priv)
                dmc->fw_path = RKL_DMC_PATH;
                dmc->required_version = RKL_DMC_VERSION_REQUIRED;
                dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
-       } else if (DISPLAY_VER(dev_priv) >= 12) {
+       } else if (IS_TIGERLAKE(dev_priv)) {
                dmc->fw_path = TGL_DMC_PATH;
                dmc->required_version = TGL_DMC_VERSION_REQUIRED;
                dmc->max_fw_size = DISPLAY_VER12_DMC_MAX_FW_SIZE;
index 23cfe2e5ce2a4ff2ee4694c9c1ee13ee52569b6d..94c57facbb463b8e6cc2863a9f5a2e965d909f3e 100644 (file)
@@ -135,11 +135,16 @@ struct intel_modifier_desc {
                                         INTEL_PLANE_CAP_CCS_MC)
 #define INTEL_PLANE_CAP_TILING_MASK    (INTEL_PLANE_CAP_TILING_X | \
                                         INTEL_PLANE_CAP_TILING_Y | \
-                                        INTEL_PLANE_CAP_TILING_Yf)
+                                        INTEL_PLANE_CAP_TILING_Yf | \
+                                        INTEL_PLANE_CAP_TILING_4)
 #define INTEL_PLANE_CAP_TILING_NONE    0
 
 static const struct intel_modifier_desc intel_modifiers[] = {
        {
+               .modifier = I915_FORMAT_MOD_4_TILED,
+               .display_ver = { 13, 13 },
+               .plane_caps = INTEL_PLANE_CAP_TILING_4,
+       }, {
                .modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
                .display_ver = { 12, 13 },
                .plane_caps = INTEL_PLANE_CAP_TILING_Y | INTEL_PLANE_CAP_CCS_MC,
@@ -545,6 +550,12 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
                        return 128;
                else
                        return 512;
+       case I915_FORMAT_MOD_4_TILED:
+               /*
+                * Each 4K tile consists of 64B(8*8) subtiles, with
+                * same shape as Y Tile(i.e 4*16B OWords)
+                */
+               return 128;
        case I915_FORMAT_MOD_Y_TILED_CCS:
                if (intel_fb_is_ccs_aux_plane(fb, color_plane))
                        return 128;
@@ -650,6 +661,7 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
                return I915_TILING_Y;
        case INTEL_PLANE_CAP_TILING_X:
                return I915_TILING_X;
+       case INTEL_PLANE_CAP_TILING_4:
        case INTEL_PLANE_CAP_TILING_Yf:
        case INTEL_PLANE_CAP_TILING_NONE:
                return I915_TILING_NONE;
@@ -737,6 +749,7 @@ unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
        case I915_FORMAT_MOD_Y_TILED_CCS:
        case I915_FORMAT_MOD_Yf_TILED_CCS:
        case I915_FORMAT_MOD_Y_TILED:
+       case I915_FORMAT_MOD_4_TILED:
        case I915_FORMAT_MOD_Yf_TILED:
                return 1 * 1024 * 1024;
        default:
index ba9df8986c1ee7237674f24b551041f1744582e7..12386f13a4e0f4f382ab160f0ffc9e8cbb6cf56e 100644 (file)
@@ -27,6 +27,7 @@ struct intel_plane_state;
 #define INTEL_PLANE_CAP_TILING_X       BIT(3)
 #define INTEL_PLANE_CAP_TILING_Y       BIT(4)
 #define INTEL_PLANE_CAP_TILING_Yf      BIT(5)
+#define INTEL_PLANE_CAP_TILING_4       BIT(6)
 
 bool intel_fb_is_ccs_modifier(u64 modifier);
 bool intel_fb_is_rc_ccs_cc_modifier(u64 modifier);
index 87f4af3fd523ec0d1a9a2191aeec6bbd422c43db..f7dca327c29492be03bed02ccfd50f31ee277389 100644 (file)
@@ -946,6 +946,7 @@ static bool tiling_is_valid(const struct intel_plane_state *plane_state)
        case I915_FORMAT_MOD_Y_TILED:
        case I915_FORMAT_MOD_Yf_TILED:
                return DISPLAY_VER(i915) >= 9;
+       case I915_FORMAT_MOD_4_TILED:
        case I915_FORMAT_MOD_X_TILED:
                return true;
        default:
index e1ecf38db0ef8d298281fd855846e068d574a55b..4de4c174a987d711402a9d69b33c82f517c2a2d5 100644 (file)
@@ -20,6 +20,7 @@
 #include "intel_connector.h"
 #include "intel_de.h"
 #include "intel_display_power.h"
+#include "intel_display_power_well.h"
 #include "intel_display_types.h"
 #include "intel_hdcp.h"
 #include "intel_pcode.h"
index d7b1de4cc205ef3407d89004b25a61c732dbefad..e207d12286b5ab3391b222d6b7de955441407348 100644 (file)
@@ -127,6 +127,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc,
        case DRM_FORMAT_MOD_LINEAR:
        case I915_FORMAT_MOD_X_TILED:
        case I915_FORMAT_MOD_Y_TILED:
+       case I915_FORMAT_MOD_4_TILED:
                break;
        default:
                drm_dbg(&dev_priv->drm,
index 7e6245b97fedab38898fa795a35d44411decfb83..0dd4775e8195eed62ed3e2eba732991811f5be3d 100644 (file)
@@ -32,10 +32,14 @@ void intel_snps_phy_wait_for_calibration(struct drm_i915_private *i915)
                if (!intel_phy_is_snps(i915, phy))
                        continue;
 
+               /*
+                * If calibration does not complete successfully, we'll remember
+                * which phy was affected and skip setup of the corresponding
+                * output later.
+                */
                if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
                                            DG2_PHY_DP_TX_ACK_MASK, 25))
-                       drm_err(&i915->drm, "SNPS PHY %c failed to calibrate after 25ms.\n",
-                               phy_name(phy));
+                       i915->snps_phy_failed_calibration |= BIT(phy);
        }
 }
 
index 2d71294aaceb1f81846037d989da9fb03dceeace..f6875a49b8cb4b2e7475b0efcb81c53a278b1929 100644 (file)
@@ -430,9 +430,6 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
        int crtc_y = plane_state->uapi.dst.y1;
        u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
        u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
                          plane_state->view.color_plane[0].mapping_stride);
@@ -440,8 +437,6 @@ vlv_sprite_update_noarm(struct intel_plane *plane,
                          SP_POS_Y(crtc_y) | SP_POS_X(crtc_x));
        intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
                          SP_HEIGHT(crtc_h - 1) | SP_WIDTH(crtc_w - 1));
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -457,14 +452,11 @@ vlv_sprite_update_arm(struct intel_plane *plane,
        u32 x = plane_state->view.color_plane[0].x;
        u32 y = plane_state->view.color_plane[0].y;
        u32 sprctl, linear_offset;
-       unsigned long irqflags;
 
        sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
 
        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
                chv_sprite_update_csc(plane_state);
 
@@ -494,8 +486,6 @@ vlv_sprite_update_arm(struct intel_plane *plane,
 
        vlv_sprite_update_clrc(plane_state);
        vlv_sprite_update_gamma(plane_state);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -505,14 +495,9 @@ vlv_sprite_disable_arm(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum pipe pipe = plane->pipe;
        enum plane_id plane_id = plane->id;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0);
        intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static bool
@@ -862,15 +847,12 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
        u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
        u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
        u32 sprscale = 0;
-       unsigned long irqflags;
 
        if (crtc_w != src_w || crtc_h != src_h)
                sprscale = SPRITE_SCALE_ENABLE |
                        SPRITE_SRC_WIDTH(src_w - 1) |
                        SPRITE_SRC_HEIGHT(src_h - 1);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
                          plane_state->view.color_plane[0].mapping_stride);
        intel_de_write_fw(dev_priv, SPRPOS(pipe),
@@ -879,8 +861,6 @@ ivb_sprite_update_noarm(struct intel_plane *plane,
                          SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1));
        if (IS_IVYBRIDGE(dev_priv))
                intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -895,14 +875,11 @@ ivb_sprite_update_arm(struct intel_plane *plane,
        u32 x = plane_state->view.color_plane[0].x;
        u32 y = plane_state->view.color_plane[0].y;
        u32 sprctl, linear_offset;
-       unsigned long irqflags;
 
        sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
 
        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        if (key->flags) {
                intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value);
                intel_de_write_fw(dev_priv, SPRKEYMSK(pipe),
@@ -931,8 +908,6 @@ ivb_sprite_update_arm(struct intel_plane *plane,
                          intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
 
        ivb_sprite_update_gamma(plane_state);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -941,17 +916,12 @@ ivb_sprite_disable_arm(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum pipe pipe = plane->pipe;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, SPRCTL(pipe), 0);
        /* Disable the scaler */
        if (IS_IVYBRIDGE(dev_priv))
                intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0);
        intel_de_write_fw(dev_priv, SPRSURF(pipe), 0);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static bool
@@ -1204,15 +1174,12 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
        u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
        u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
        u32 dvsscale = 0;
-       unsigned long irqflags;
 
        if (crtc_w != src_w || crtc_h != src_h)
                dvsscale = DVS_SCALE_ENABLE |
                        DVS_SRC_WIDTH(src_w - 1) |
                        DVS_SRC_HEIGHT(src_h - 1);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
                          plane_state->view.color_plane[0].mapping_stride);
        intel_de_write_fw(dev_priv, DVSPOS(pipe),
@@ -1220,8 +1187,6 @@ g4x_sprite_update_noarm(struct intel_plane *plane,
        intel_de_write_fw(dev_priv, DVSSIZE(pipe),
                          DVS_HEIGHT(crtc_h - 1) | DVS_WIDTH(crtc_w - 1));
        intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -1236,14 +1201,11 @@ g4x_sprite_update_arm(struct intel_plane *plane,
        u32 x = plane_state->view.color_plane[0].x;
        u32 y = plane_state->view.color_plane[0].y;
        u32 dvscntr, linear_offset;
-       unsigned long irqflags;
 
        dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
 
        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        if (key->flags) {
                intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
                intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
@@ -1267,8 +1229,6 @@ g4x_sprite_update_arm(struct intel_plane *plane,
                g4x_sprite_update_gamma(plane_state);
        else
                ilk_sprite_update_gamma(plane_state);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -1277,16 +1237,11 @@ g4x_sprite_disable_arm(struct intel_plane *plane,
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum pipe pipe = plane->pipe;
-       unsigned long irqflags;
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
 
        intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0);
        /* Disable the scaler */
        intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0);
        intel_de_write_fw(dev_priv, DVSSURF(pipe), 0);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static bool
index 545eff5bf158c37e8d0a92eac2b358b4571effa3..e7120900bc45e8445e92438520128f65e4f7c83d 100644 (file)
@@ -378,10 +378,18 @@ calculate_rc_params(struct rc_parameters *rc,
 {
        int bpc = vdsc_cfg->bits_per_component;
        int bpp = vdsc_cfg->bits_per_pixel >> 4;
-       int ofs_und6[] = { 0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 };
-       int ofs_und8[] = { 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12 };
-       int ofs_und12[] = { 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12 };
-       int ofs_und15[] = { 10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12 };
+       static const s8 ofs_und6[] = {
+               0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
+       };
+       static const s8 ofs_und8[] = {
+               2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
+       };
+       static const s8 ofs_und12[] = {
+               2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
+       };
+       static const s8 ofs_und15[] = {
+               10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
+       };
        int qp_bpc_modifier = (bpc - 8) * 2;
        u32 res, buf_i, bpp_i;
 
index 1223075595ff0bc782e2ae75e1941c9ad66b90ba..fdade206f056f2aa461a6b36b4e6af24755ba634 100644 (file)
@@ -615,9 +615,20 @@ skl_plane_disable_arm(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
-       unsigned long irqflags;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+       skl_write_plane_wm(plane, crtc_state);
+
+       intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
+       intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
+}
+
+static void
+icl_plane_disable_arm(struct intel_plane *plane,
+                     const struct intel_crtc_state *crtc_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+       enum plane_id plane_id = plane->id;
+       enum pipe pipe = plane->pipe;
 
        if (icl_is_hdr_plane(dev_priv, plane_id))
                intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
@@ -627,8 +638,6 @@ skl_plane_disable_arm(struct intel_plane *plane,
        intel_psr2_disable_plane_sel_fetch(plane, crtc_state);
        intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
        intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static bool
@@ -762,6 +771,8 @@ static u32 skl_plane_ctl_tiling(u64 fb_modifier)
                return PLANE_CTL_TILED_X;
        case I915_FORMAT_MOD_Y_TILED:
                return PLANE_CTL_TILED_Y;
+       case I915_FORMAT_MOD_4_TILED:
+               return PLANE_CTL_TILED_4;
        case I915_FORMAT_MOD_Y_TILED_CCS:
        case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
                return PLANE_CTL_TILED_Y | PLANE_CTL_RENDER_DECOMPRESSION_ENABLE;
@@ -1065,7 +1076,7 @@ static void icl_plane_csc_load_black(struct intel_plane *plane)
        intel_de_write_fw(i915, PLANE_CSC_POSTOFF(pipe, plane_id, 2), 0);
 }
 
-static int skl_plane_color_plane(const struct intel_plane_state *plane_state)
+static int icl_plane_color_plane(const struct intel_plane_state *plane_state)
 {
        /* Program the UV plane on planar master */
        if (plane_state->planar_linked_plane && !plane_state->planar_slave)
@@ -1082,14 +1093,11 @@ skl_plane_update_noarm(struct intel_plane *plane,
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
-       int color_plane = skl_plane_color_plane(plane_state);
-       u32 stride = skl_plane_stride(plane_state, color_plane);
-       const struct drm_framebuffer *fb = plane_state->hw.fb;
+       u32 stride = skl_plane_stride(plane_state, 0);
        int crtc_x = plane_state->uapi.dst.x1;
        int crtc_y = plane_state->uapi.dst.y1;
        u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
        u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
-       unsigned long irqflags;
 
        /* The scaler will handle the output position */
        if (plane_state->scaler_id >= 0) {
@@ -1097,14 +1105,99 @@ skl_plane_update_noarm(struct intel_plane *plane,
                crtc_y = 0;
        }
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
+       intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
+                         PLANE_STRIDE_(stride));
+       intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
+                         PLANE_POS_Y(crtc_y) | PLANE_POS_X(crtc_x));
+       intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
+                         PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
+
+       skl_write_plane_wm(plane, crtc_state);
+}
+
+static void
+skl_plane_update_arm(struct intel_plane *plane,
+                    const struct intel_crtc_state *crtc_state,
+                    const struct intel_plane_state *plane_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+       enum plane_id plane_id = plane->id;
+       enum pipe pipe = plane->pipe;
+       u32 x = plane_state->view.color_plane[0].x;
+       u32 y = plane_state->view.color_plane[0].y;
+       u32 plane_ctl, plane_color_ctl = 0;
+
+       plane_ctl = plane_state->ctl |
+               skl_plane_ctl_crtc(crtc_state);
+
+       if (DISPLAY_VER(dev_priv) >= 10)
+               plane_color_ctl = plane_state->color_ctl |
+                       glk_plane_color_ctl_crtc(crtc_state);
+
+       intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
+       intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
+       intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
+
+       intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
+                         PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
+
+       intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
+                         skl_plane_aux_dist(plane_state, 0));
+
+       intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
+                         PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
+                         PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
+
+       if (DISPLAY_VER(dev_priv) >= 10)
+               intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
 
        /*
-        * FIXME: pxp session invalidation can hit any time even at time of commit
-        * or after the commit, display content will be garbage.
+        * Enable the scaler before the plane so that we don't
+        * get a catastrophic underrun even if the two operations
+        * end up happening in two different frames.
+        *
+        * TODO: split into noarm+arm pair
         */
-       if (plane_state->force_black)
-               icl_plane_csc_load_black(plane);
+       if (plane_state->scaler_id >= 0)
+               skl_program_plane_scaler(plane, crtc_state, plane_state);
+
+       /*
+        * The control register self-arms if the plane was previously
+        * disabled. Try to make the plane enable atomic by writing
+        * the control register just before the surface register.
+        */
+       intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
+       intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
+                         skl_plane_surf(plane_state, 0));
+}
+
+static void
+icl_plane_update_noarm(struct intel_plane *plane,
+                      const struct intel_crtc_state *crtc_state,
+                      const struct intel_plane_state *plane_state)
+{
+       struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+       enum plane_id plane_id = plane->id;
+       enum pipe pipe = plane->pipe;
+       int color_plane = icl_plane_color_plane(plane_state);
+       u32 stride = skl_plane_stride(plane_state, color_plane);
+       const struct drm_framebuffer *fb = plane_state->hw.fb;
+       int crtc_x = plane_state->uapi.dst.x1;
+       int crtc_y = plane_state->uapi.dst.y1;
+       int x = plane_state->view.color_plane[color_plane].x;
+       int y = plane_state->view.color_plane[color_plane].y;
+       int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
+       int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
+       u32 plane_color_ctl;
+
+       plane_color_ctl = plane_state->color_ctl |
+               glk_plane_color_ctl_crtc(crtc_state);
+
+       /* The scaler will handle the output position */
+       if (plane_state->scaler_id >= 0) {
+               crtc_x = 0;
+               crtc_y = 0;
+       }
 
        intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id),
                          PLANE_STRIDE_(stride));
@@ -1113,6 +1206,13 @@ skl_plane_update_noarm(struct intel_plane *plane,
        intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
                          PLANE_HEIGHT(src_h - 1) | PLANE_WIDTH(src_w - 1));
 
+       intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
+       intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
+       intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
+
+       intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
+                         PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
+
        if (intel_fb_is_rc_ccs_cc_modifier(fb->modifier)) {
                intel_de_write_fw(dev_priv, PLANE_CC_VAL(pipe, plane_id, 0),
                                  lower_32_bits(plane_state->ccval));
@@ -1120,60 +1220,43 @@ skl_plane_update_noarm(struct intel_plane *plane,
                                  upper_32_bits(plane_state->ccval));
        }
 
+       intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
+                         skl_plane_aux_dist(plane_state, color_plane));
+
        if (icl_is_hdr_plane(dev_priv, plane_id))
                intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
                                  plane_state->cus_ctl);
 
+       intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
+
        if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
                icl_program_input_csc(plane, crtc_state, plane_state);
 
        skl_write_plane_wm(plane, crtc_state);
 
-       intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
+       /*
+        * FIXME: pxp session invalidation can hit any time even at time of commit
+        * or after the commit, display content will be garbage.
+        */
+       if (plane_state->force_black)
+               icl_plane_csc_load_black(plane);
 
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
+       intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane);
 }
 
 static void
-skl_plane_update_arm(struct intel_plane *plane,
+icl_plane_update_arm(struct intel_plane *plane,
                     const struct intel_crtc_state *crtc_state,
                     const struct intel_plane_state *plane_state)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
-       int color_plane = skl_plane_color_plane(plane_state);
-       u32 x = plane_state->view.color_plane[color_plane].x;
-       u32 y = plane_state->view.color_plane[color_plane].y;
-       u32 plane_color_ctl = 0;
-       u32 plane_ctl = plane_state->ctl;
-       unsigned long irqflags;
-
-       plane_ctl |= skl_plane_ctl_crtc(crtc_state);
-
-       if (DISPLAY_VER(dev_priv) >= 10)
-               plane_color_ctl = plane_state->color_ctl |
-                       glk_plane_color_ctl_crtc(crtc_state);
-
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
-       intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id), skl_plane_keyval(plane_state));
-       intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), skl_plane_keymsk(plane_state));
-       intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), skl_plane_keymax(plane_state));
-
-       intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
-                         PLANE_OFFSET_Y(y) | PLANE_OFFSET_X(x));
-
-       intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id),
-                         skl_plane_aux_dist(plane_state, color_plane));
+       int color_plane = icl_plane_color_plane(plane_state);
+       u32 plane_ctl;
 
-       if (DISPLAY_VER(dev_priv) < 11)
-               intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
-                                 PLANE_OFFSET_Y(plane_state->view.color_plane[1].y) |
-                                 PLANE_OFFSET_X(plane_state->view.color_plane[1].x));
-
-       if (DISPLAY_VER(dev_priv) >= 10)
-               intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
+       plane_ctl = plane_state->ctl |
+               skl_plane_ctl_crtc(crtc_state);
 
        /*
         * Enable the scaler before the plane so that we don't
@@ -1193,8 +1276,6 @@ skl_plane_update_arm(struct intel_plane *plane,
        intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
        intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
                          skl_plane_surf(plane_state, color_plane));
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static void
@@ -1204,7 +1285,6 @@ skl_plane_async_flip(struct intel_plane *plane,
                     bool async_flip)
 {
        struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-       unsigned long irqflags;
        enum plane_id plane_id = plane->id;
        enum pipe pipe = plane->pipe;
        u32 plane_ctl = plane_state->ctl;
@@ -1214,13 +1294,9 @@ skl_plane_async_flip(struct intel_plane *plane,
        if (async_flip)
                plane_ctl |= PLANE_CTL_ASYNC_FLIP;
 
-       spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
-
        intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
        intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
                          skl_plane_surf(plane_state, 0));
-
-       spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
 static bool intel_format_is_p01x(u32 format)
@@ -2011,9 +2087,7 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
        case DRM_FORMAT_Y216:
        case DRM_FORMAT_XVYU12_16161616:
        case DRM_FORMAT_XVYU16161616:
-               if (modifier == DRM_FORMAT_MOD_LINEAR ||
-                   modifier == I915_FORMAT_MOD_X_TILED ||
-                   modifier == I915_FORMAT_MOD_Y_TILED)
+               if (!intel_fb_is_ccs_modifier(modifier))
                        return true;
                fallthrough;
        default:
@@ -2106,6 +2180,8 @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915,
                caps |= INTEL_PLANE_CAP_TILING_Y;
        if (DISPLAY_VER(i915) < 12)
                caps |= INTEL_PLANE_CAP_TILING_Yf;
+       if (HAS_4TILE(i915))
+               caps |= INTEL_PLANE_CAP_TILING_4;
 
        if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) {
                caps |= INTEL_PLANE_CAP_CCS_RC;
@@ -2162,9 +2238,15 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
        }
 
        plane->max_stride = skl_plane_max_stride;
-       plane->update_noarm = skl_plane_update_noarm;
-       plane->update_arm = skl_plane_update_arm;
-       plane->disable_arm = skl_plane_disable_arm;
+       if (DISPLAY_VER(dev_priv) >= 11) {
+               plane->update_noarm = icl_plane_update_noarm;
+               plane->update_arm = icl_plane_update_arm;
+               plane->disable_arm = icl_plane_disable_arm;
+       } else {
+               plane->update_noarm = skl_plane_update_noarm;
+               plane->update_arm = skl_plane_update_arm;
+               plane->disable_arm = skl_plane_disable_arm;
+       }
        plane->get_hw_state = skl_plane_get_hw_state;
        plane->check_plane = skl_plane_check;
 
@@ -2278,6 +2360,7 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
        unsigned int aligned_height;
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
+       static_assert(PLANE_CTL_TILED_YF == PLANE_CTL_TILED_4);
 
        if (!plane->get_hw_state(plane, &pipe))
                return;
@@ -2340,11 +2423,15 @@ skl_get_initial_plane_config(struct intel_crtc *crtc,
                else
                        fb->modifier = I915_FORMAT_MOD_Y_TILED;
                break;
-       case PLANE_CTL_TILED_YF:
-               if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
-                       fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
-               else
-                       fb->modifier = I915_FORMAT_MOD_Yf_TILED;
+       case PLANE_CTL_TILED_YF: /* aka PLANE_CTL_TILED_4 on XE_LPD+ */
+               if (HAS_4TILE(dev_priv)) {
+                       fb->modifier = I915_FORMAT_MOD_4_TILED;
+               } else {
+                       if (val & PLANE_CTL_RENDER_DECOMPRESSION_ENABLE)
+                               fb->modifier = I915_FORMAT_MOD_Yf_TILED_CCS;
+                       else
+                               fb->modifier = I915_FORMAT_MOD_Yf_TILED;
+               }
                break;
        default:
                MISSING_CASE(tiling);
index f600d1cb01b34b598f9d0b6b8df80c1ad10902a5..5cfe69b308416ba7c3fa42699a8946993067085b 100644 (file)
@@ -837,8 +837,16 @@ struct drm_i915_private {
 
        bool irq_enabled;
 
-       /* perform PHY state sanity checks? */
-       bool chv_phy_assert[2];
+       union {
+               /* perform PHY state sanity checks? */
+               bool chv_phy_assert[2];
+
+               /*
+                * DG2: Mask of PHYs that were not calibrated by the firmware
+                * and should not be used.
+                */
+               u8 snps_phy_failed_calibration;
+       };
 
        bool ipc_enabled;
 
@@ -1252,6 +1260,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define CMDPARSER_USES_GGTT(dev_priv) (GRAPHICS_VER(dev_priv) == 7)
 
 #define HAS_LLC(dev_priv)      (INTEL_INFO(dev_priv)->has_llc)
+#define HAS_4TILE(dev_priv)    (INTEL_INFO(dev_priv)->has_4tile)
 #define HAS_SNOOP(dev_priv)    (INTEL_INFO(dev_priv)->has_snoop)
 #define HAS_EDRAM(dev_priv)    ((dev_priv)->edram_size_mb)
 #define HAS_SECURE_BATCHES(dev_priv) (GRAPHICS_VER(dev_priv) < 6)
index 8246cbe9b01db92ada9cae93ca3128270d32f018..a95ae08b071c50f138033b1c930ebf752be07657 100644 (file)
@@ -1046,6 +1046,7 @@ static const struct intel_device_info dg2_info = {
        DGFX_FEATURES,
        .graphics.rel = 55,
        .media.rel = 55,
+       .has_4tile = 1,
        PLATFORM(INTEL_DG2),
        .has_guc_deprivilege = 1,
        .has_64k_pages = 1,
index 2b8a3086ed35aad70999a213e48eceb23228a503..5f6c307f476a33db8280c26d6200fd069f01eb22 100644 (file)
 #define   PLANE_CTL_TILED_X                    REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 1)
 #define   PLANE_CTL_TILED_Y                    REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 4)
 #define   PLANE_CTL_TILED_YF                   REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
+#define   PLANE_CTL_TILED_4                     REG_FIELD_PREP(PLANE_CTL_TILED_MASK, 5)
 #define   PLANE_CTL_ASYNC_FLIP                 REG_BIT(9)
 #define   PLANE_CTL_FLIP_HORIZONTAL            REG_BIT(8)
 #define   PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE REG_BIT(4) /* TGL+ */
index 27dcfe6f24290f9faefdf2daa2092abf041698db..8026e805ff12b6369f8894b4468190991a74151f 100644 (file)
@@ -133,6 +133,7 @@ enum intel_ppgtt_type {
        func(has_64k_pages); \
        func(gpu_reset_clobbers_display); \
        func(has_reset_engine); \
+       func(has_4tile); \
        func(has_global_mocs); \
        func(has_gt_uc); \
        func(has_guc_deprivilege); \
index 4f7a61d5502e40511dec0881bff25f92b08e35d0..4cce044efde2de3b7cb91ce569ad0d9073eb49c1 100644 (file)
@@ -108,6 +108,7 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
                /* Comet Lake V PCH is based on KBP, which is SPT compatible */
                return PCH_SPT;
        case INTEL_PCH_ICP_DEVICE_ID_TYPE:
+       case INTEL_PCH_ICP2_DEVICE_ID_TYPE:
                drm_dbg_kms(&dev_priv->drm, "Found Ice Lake PCH\n");
                drm_WARN_ON(&dev_priv->drm, !IS_ICELAKE(dev_priv));
                return PCH_ICP;
@@ -123,7 +124,6 @@ intel_pch_type(const struct drm_i915_private *dev_priv, unsigned short id)
                            !IS_GEN9_BC(dev_priv));
                return PCH_TGP;
        case INTEL_PCH_JSP_DEVICE_ID_TYPE:
-       case INTEL_PCH_JSP2_DEVICE_ID_TYPE:
                drm_dbg_kms(&dev_priv->drm, "Found Jasper Lake PCH\n");
                drm_WARN_ON(&dev_priv->drm, !IS_JSL_EHL(dev_priv));
                return PCH_JSP;
index 6fd20408f7bfe49036aef73ac81378f04ec321a4..b7a8cf409d48345d205e90d88cd118b782feb09a 100644 (file)
@@ -50,11 +50,11 @@ enum intel_pch {
 #define INTEL_PCH_CMP2_DEVICE_ID_TYPE          0x0680
 #define INTEL_PCH_CMP_V_DEVICE_ID_TYPE         0xA380
 #define INTEL_PCH_ICP_DEVICE_ID_TYPE           0x3480
+#define INTEL_PCH_ICP2_DEVICE_ID_TYPE          0x3880
 #define INTEL_PCH_MCC_DEVICE_ID_TYPE           0x4B00
 #define INTEL_PCH_TGP_DEVICE_ID_TYPE           0xA080
 #define INTEL_PCH_TGP2_DEVICE_ID_TYPE          0x4380
 #define INTEL_PCH_JSP_DEVICE_ID_TYPE           0x4D80
-#define INTEL_PCH_JSP2_DEVICE_ID_TYPE          0x3880
 #define INTEL_PCH_ADP_DEVICE_ID_TYPE           0x7A80
 #define INTEL_PCH_ADP2_DEVICE_ID_TYPE          0x5180
 #define INTEL_PCH_ADP3_DEVICE_ID_TYPE          0x7A00
index 5af16ca4dabd6e8ebd77e41e44745e8862548f40..b9d711246f1e3e6f25baa28f03c298f314b44d21 100644 (file)
@@ -5415,6 +5415,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
        }
 
        wp->y_tiled = modifier == I915_FORMAT_MOD_Y_TILED ||
+                     modifier == I915_FORMAT_MOD_4_TILED ||
                      modifier == I915_FORMAT_MOD_Yf_TILED ||
                      modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
                      modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
@@ -5930,7 +5931,7 @@ static void skl_write_wm_level(struct drm_i915_private *dev_priv,
                val |= PLANE_WM_EN;
        if (level->ignore_lines)
                val |= PLANE_WM_IGNORE_LINES;
-       val |= level->blocks;
+       val |= REG_FIELD_PREP(PLANE_WM_BLOCKS_MASK, level->blocks);
        val |= REG_FIELD_PREP(PLANE_WM_LINES_MASK, level->lines);
 
        intel_de_write_fw(dev_priv, reg, val);
@@ -6578,7 +6579,7 @@ static void skl_wm_level_from_reg_val(u32 val, struct skl_wm_level *level)
 {
        level->enable = val & PLANE_WM_EN;
        level->ignore_lines = val & PLANE_WM_IGNORE_LINES;
-       level->blocks = val & PLANE_WM_BLOCKS_MASK;
+       level->blocks = REG_FIELD_GET(PLANE_WM_BLOCKS_MASK, val);
        level->lines = REG_FIELD_GET(PLANE_WM_LINES_MASK, val);
 }
 
index fc0c1454d2757d5d61783739a2ce272e3a739dcd..b73fe6797fc3712edaace7bcd29187d26e5e94b2 100644 (file)
@@ -572,6 +572,17 @@ extern "C" {
  */
 #define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC fourcc_mod_code(INTEL, 8)
 
+/*
+ * Intel Tile 4 layout
+ *
+ * This is a tiled layout using 4KB tiles in a row-major layout. It has the same
+ * shape as Tile Y at two granularities: 4KB (128B x 32) and 64B (16B x 4). It
+ * only differs from Tile Y at the 256B granularity in between. At this
+ * granularity, Tile Y has a shape of 16B x 32 rows, but this tiling has a shape
+ * of 64B x 8 rows.
+ */
+#define I915_FORMAT_MOD_4_TILED         fourcc_mod_code(INTEL, 9)
+
 /*
  * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
  *