summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/Makefile1
-rw-r--r--drivers/gpu/drm/i915/display/i9xx_plane.c24
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c23
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_display.c236
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_debugfs.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.c519
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power.h37
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.c113
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_power_well.h153
-rw-r--r--drivers/gpu/drm/i915/display/intel_dmc.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_fb.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_fbc.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_hdcp.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_plane_initial.c1
-rw-r--r--drivers/gpu/drm/i915/display/intel_snps_phy.c8
-rw-r--r--drivers/gpu/drm/i915/display/intel_sprite.c45
-rw-r--r--drivers/gpu/drm/i915/display/intel_vdsc.c16
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c219
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h13
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c1
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/intel_device_info.h1
-rw-r--r--drivers/gpu/drm/i915/intel_pch.c2
-rw-r--r--drivers/gpu/drm/i915/intel_pch.h2
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c5
27 files changed, 759 insertions, 690 deletions
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 9d588d936e3d..1a771ee5b1d0 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -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 \
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c
index a87b65cd41fd..af190bacdd97 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -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
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 2ade8fdd9bdd..57ef9403f4e9 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -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:
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index e4260806c2a4..1cd394b0585e 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -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;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 80b19c304c43..b8d511360f9f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -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,
diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index ffe6822d7414..78752ce46639 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -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"
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c
index 9ebae7ac3235..e8e8ce13aa96 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -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"
@@ -26,101 +27,6 @@
#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;
@@ -749,18 +603,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]);
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h
index f6d0e6e73c6d..ced384b0a165 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.h
+++ b/drivers/gpu/drm/i915/display/intel_display_power.h
@@ -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
index 000000000000..2a0fb9d9c60f
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -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
index 000000000000..9a3756fdcf7f
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.h
@@ -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
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index 7616a3906b9e..133476be6d28 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -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;
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c
index 23cfe2e5ce2a..94c57facbb46 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -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:
diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h
index ba9df8986c1e..12386f13a4e0 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.h
+++ b/drivers/gpu/drm/i915/display/intel_fb.h
@@ -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);
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 87f4af3fd523..f7dca327c294 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -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:
diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c
index e1ecf38db0ef..4de4c174a987 100644
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -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"
diff --git a/drivers/gpu/drm/i915/display/intel_plane_initial.c b/drivers/gpu/drm/i915/display/intel_plane_initial.c
index d7b1de4cc205..e207d12286b5 100644
--- a/drivers/gpu/drm/i915/display/intel_plane_initial.c
+++ b/drivers/gpu/drm/i915/display/intel_plane_initial.c
@@ -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,
diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 7e6245b97fed..0dd4775e8195 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -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);
}
}
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 2d71294aaceb..f6875a49b8cb 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -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
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 545eff5bf158..e7120900bc45 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -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;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 1223075595ff..fdade206f056 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -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);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f600d1cb01b3..5cfe69b30841 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -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)
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 8246cbe9b01d..a95ae08b071c 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -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,
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2b8a3086ed35..5f6c307f476a 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4844,6 +4844,7 @@
#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+ */
diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h
index 27dcfe6f2429..8026e805ff12 100644
--- a/drivers/gpu/drm/i915/intel_device_info.h
+++ b/drivers/gpu/drm/i915/intel_device_info.h
@@ -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); \
diff --git a/drivers/gpu/drm/i915/intel_pch.c b/drivers/gpu/drm/i915/intel_pch.c
index 4f7a61d5502e..4cce044efde2 100644
--- a/drivers/gpu/drm/i915/intel_pch.c
+++ b/drivers/gpu/drm/i915/intel_pch.c
@@ -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;
diff --git a/drivers/gpu/drm/i915/intel_pch.h b/drivers/gpu/drm/i915/intel_pch.h
index 6fd20408f7bf..b7a8cf409d48 100644
--- a/drivers/gpu/drm/i915/intel_pch.h
+++ b/drivers/gpu/drm/i915/intel_pch.h
@@ -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
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5af16ca4dabd..b9d711246f1e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -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);
}