All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
@ 2019-09-20 11:42 Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now Maarten Lankhorst
                   ` (28 more replies)
  0 siblings, 29 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx; +Cc: Maarten Lankhorst, stable, Manasi Navare

There was a integer wraparound when mode_clock became too high,
and we didn't correct for the FEC overhead factor when dividing,
with the calculations breaking at HBR3.

As a result our calculated bpp was way too high, and the link width
limitation never came into effect.

Print out the resulting bpp calcululations as a sanity check, just
in case we ever have to debug it later on again.

We also used the wrong factor for FEC. While bspec mentions 2.4%,
all the calculations use 1/0.972261, and the same ratio should be
applied to data M/N as well, so use it there when FEC is enabled.

Make sure we don't break hw readout, and read out FEC enable state
and correct the DDI clock readout for the new values.

Together with the next commit, this causes FEC to work correctly
with big joiner, while also having the correct refresh rate
reported in kms_setmode.basic.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
Cc: <stable@vger.kernel.org> # v5.0+
Cc: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  19 +-
 drivers/gpu/drm/i915/display/intel_display.c |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c      | 195 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
 4 files changed, 128 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3e6394139964..1b59b852874b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
 	if (pipe_config->pixel_multiplier)
 		dotclock /= pipe_config->pixel_multiplier;
 
+	/* fec adds overhead to the data M/N values, correct for it */
+	if (pipe_config->fec_enable)
+		dotclock = intel_dp_fec_to_mode_clock(dotclock);
+
 	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
 }
 
@@ -4031,7 +4035,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	case TRANS_DDI_MODE_SELECT_FDI:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
 		break;
-	case TRANS_DDI_MODE_SELECT_DP_SST:
+	case TRANS_DDI_MODE_SELECT_DP_SST: {
+		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+
 		if (encoder->type == INTEL_OUTPUT_EDP)
 			pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
 		else
@@ -4039,7 +4045,18 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		pipe_config->lane_count =
 			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
 		intel_dp_get_m_n(intel_crtc, pipe_config);
+
+		if (INTEL_GEN(dev_priv) >= 11) {
+			pipe_config->fec_enable =
+				I915_READ(intel_dp->regs.dp_tp_ctl) &
+					  DP_TP_CTL_FEC_ENABLE;
+			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
+				      encoder->base.base.id, encoder->base.name,
+				      pipe_config->fec_enable);
+		}
+
 		break;
+	}
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
 		pipe_config->lane_count =
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e0033d99f6e3..7996864e6f7c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -12773,6 +12773,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
 	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
 	PIPE_CONF_CHECK_BOOL(has_infoframe);
+	PIPE_CONF_CHECK_BOOL(fec_enable);
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index ccaf9f00b747..4dfb78dc7fa2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -76,8 +76,8 @@
 #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
 #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
 
-/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
-#define DP_DSC_FEC_OVERHEAD_FACTOR		976
+/* DP DSC FEC Overhead factor = 1/(0.972261) */
+#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
 
 /* Compliance test status bits  */
 #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
@@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	return 0;
 }
 
+static inline u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
+{
+	return div_u64(mul_u32_u32(mode_clock, 1000000U),
+		       DP_DSC_FEC_OVERHEAD_FACTOR);
+}
+
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
+{
+	return div_u64(mul_u32_u32(fec_clock,
+				   DP_DSC_FEC_OVERHEAD_FACTOR),
+		       1000000U);
+}
+
+static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
+				       u32 mode_clock, u32 mode_hdisplay)
+{
+	u32 bits_per_pixel, max_bpp_small_joiner_ram;
+	int i;
+
+	/*
+	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
+	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
+	 * for SST -> TimeSlotsPerMTP is 1,
+	 * for MST -> TimeSlotsPerMTP has to be calculated
+	 */
+	bits_per_pixel = (link_clock * lane_count * 8) /
+			 intel_dp_mode_to_fec_clock(mode_clock);
+	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
+
+	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
+
+	/*
+	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
+	 * check, output bpp from small joiner RAM check)
+	 */
+	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+
+	/* Error out if the max bpp is less than smallest allowed valid bpp */
+	if (bits_per_pixel < valid_dsc_bpp[0]) {
+		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
+			      bits_per_pixel, valid_dsc_bpp[0]);
+		return 0;
+	}
+
+	/* Find the nearest match in the array of known BPPs from VESA */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
+		if (bits_per_pixel < valid_dsc_bpp[i + 1])
+			break;
+	}
+	bits_per_pixel = valid_dsc_bpp[i];
+
+	/*
+	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
+	 * fractional part is 0
+	 */
+	return bits_per_pixel << 4;
+}
+
+static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+				       int mode_clock, int mode_hdisplay)
+{
+	u8 min_slice_count, i;
+	int max_slice_width;
+
+	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_0);
+	else
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_1);
+
+	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
+	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
+		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
+			      max_slice_width);
+		return 0;
+	}
+	/* Also take into account max slice width */
+	min_slice_count = min_t(u8, min_slice_count,
+				DIV_ROUND_UP(mode_hdisplay,
+					     max_slice_width));
+
+	/* Find the closest match to the valid slice count values */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
+		if (valid_dsc_slicecount[i] >
+		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+						    false))
+			break;
+		if (min_slice_count  <= valid_dsc_slicecount[i])
+			return valid_dsc_slicecount[i];
+	}
+
+	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+	return 0;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -2182,6 +2280,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
 					   DP_DPCD_QUIRK_CONSTANT_N);
 	int ret = 0, output_bpp;
+	u32 data_clock;
 
 	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
 		pipe_config->has_pch_encoder = true;
@@ -2244,9 +2343,14 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 	else
 		output_bpp = intel_dp_output_bpp(pipe_config, pipe_config->pipe_bpp);
 
+	if (pipe_config->fec_enable)
+		data_clock = intel_dp_mode_to_fec_clock(adjusted_mode->crtc_clock);
+	else
+		data_clock = adjusted_mode->crtc_clock;
+
 	intel_link_compute_m_n(output_bpp,
 			       pipe_config->lane_count,
-			       adjusted_mode->crtc_clock,
+			       data_clock,
 			       pipe_config->port_clock,
 			       &pipe_config->dp_m_n,
 			       constant_n);
@@ -4363,91 +4467,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 		DP_DPRX_ESI_LEN;
 }
 
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay)
-{
-	u16 bits_per_pixel, max_bpp_small_joiner_ram;
-	int i;
-
-	/*
-	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
-	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
-	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
-	 * for MST -> TimeSlotsPerMTP has to be calculated
-	 */
-	bits_per_pixel = (link_clock * lane_count * 8 *
-			  DP_DSC_FEC_OVERHEAD_FACTOR) /
-		mode_clock;
-
-	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
-		mode_hdisplay;
-
-	/*
-	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
-	 * check, output bpp from small joiner RAM check)
-	 */
-	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-	/* Error out if the max bpp is less than smallest allowed valid bpp */
-	if (bits_per_pixel < valid_dsc_bpp[0]) {
-		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
-		return 0;
-	}
-
-	/* Find the nearest match in the array of known BPPs from VESA */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
-		if (bits_per_pixel < valid_dsc_bpp[i + 1])
-			break;
-	}
-	bits_per_pixel = valid_dsc_bpp[i];
-
-	/*
-	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-	 * fractional part is 0
-	 */
-	return bits_per_pixel << 4;
-}
-
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-				int mode_clock,
-				int mode_hdisplay)
-{
-	u8 min_slice_count, i;
-	int max_slice_width;
-
-	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_0);
-	else
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_1);
-
-	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
-	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
-		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-			      max_slice_width);
-		return 0;
-	}
-	/* Also take into account max slice width */
-	min_slice_count = min_t(u8, min_slice_count,
-				DIV_ROUND_UP(mode_hdisplay,
-					     max_slice_width));
-
-	/* Find the closest match to the valid slice count values */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-		if (valid_dsc_slicecount[i] >
-		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-						    false))
-			break;
-		if (min_slice_count  <= valid_dsc_slicecount[i])
-			return valid_dsc_slicecount[i];
-	}
-
-	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
-	return 0;
-}
-
 static void
 intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
 			       const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e01d1f89409d..e9f11e698697 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay);
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
-				int mode_hdisplay);
 
 bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
@@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
+
 #endif /* __INTEL_DP_H__ */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-23 13:08   ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state Maarten Lankhorst
                   ` (27 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

I get a permanent FIFO underrun when enabling FEC with big joiner,
so for now disable it.

It seems that even at 1024x768 resolution without bigjoiner we don't
get a working configuration. Flag is set but vblank timing shows that
vblanks are delivered slightly faster, so the extra overhead we
calculated for data M/N goes unused.

Not-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 4dfb78dc7fa2..02242a16640b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1877,7 +1877,8 @@ static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *pipe_config)
 {
-	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
+	/* HACK: Disable FEC until we solved FIFO underruns */
+	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
 		return false;
 
 	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
@@ -2024,8 +2025,9 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 	int pipe_bpp;
 	int ret;
 
+	/* HACK: Disable FEC until we solved FIFO underruns */
 	pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
-		intel_dp_supports_fec(intel_dp, pipe_config);
+		intel_dp_supports_fec(intel_dp, pipe_config) && 0;
 
 	if (!intel_dp_supports_dsc(intel_dp, pipe_config))
 		return -EINVAL;
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-24 23:40   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split Maarten Lankhorst
                   ` (26 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

We want to split drm_crtc_state into the user visible state
and actual hardware state. To prepare for this, we need some
ground rules what should be in each state:

In uapi we use:
- crtc, *_changed flags, event, commit, state, mode_blob, (plane/connector/encoder)_mask.

In hw state we use what's displayed in hardware:
- enable, active, (adjusted) mode, color property blobs.

clear_intel_crtc_state and hw readout need to be updated for these rules,
which will allow us to enable 2 joined pipes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c        |  18 +-
 drivers/gpu/drm/i915/display/intel_atomic.c   |  14 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c |   6 +-
 drivers/gpu/drm/i915/display/intel_audio.c    |  12 +-
 drivers/gpu/drm/i915/display/intel_bw.c       |   4 +-
 drivers/gpu/drm/i915/display/intel_cdclk.c    |  16 +-
 drivers/gpu/drm/i915/display/intel_color.c    | 180 +++---
 drivers/gpu/drm/i915/display/intel_crt.c      |  24 +-
 drivers/gpu/drm/i915/display/intel_ddi.c      |  34 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 540 +++++++++---------
 .../drm/i915/display/intel_display_types.h    |  28 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |  42 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   6 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  14 +-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |  20 +-
 drivers/gpu/drm/i915/display/intel_dvo.c      |  14 +-
 drivers/gpu/drm/i915/display/intel_fbc.c      |   2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |  62 +-
 drivers/gpu/drm/i915/display/intel_lspcon.c   |   4 +-
 drivers/gpu/drm/i915/display/intel_lvds.c     |  12 +-
 drivers/gpu/drm/i915/display/intel_panel.c    |  14 +-
 drivers/gpu/drm/i915/display/intel_pipe_crc.c |   6 +-
 drivers/gpu/drm/i915/display/intel_psr.c      |  10 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c     |  22 +-
 drivers/gpu/drm/i915/display/intel_sprite.c   |  25 +-
 drivers/gpu/drm/i915/display/intel_tv.c       |   8 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     |  12 +-
 drivers/gpu/drm/i915/display/vlv_dsi.c        |  20 +-
 drivers/gpu/drm/i915/i915_debugfs.c           |  14 +-
 drivers/gpu/drm/i915/intel_pm.c               | 180 +++---
 30 files changed, 699 insertions(+), 664 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 6e398c33a524..0e24b8e257e5 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -276,7 +276,7 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
 
 	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
 		const struct drm_display_mode *adjusted_mode =
-					&pipe_config->base.adjusted_mode;
+					&pipe_config->hw.adjusted_mode;
 		u32 dss_ctl2;
 		u16 hactive = adjusted_mode->crtc_hdisplay;
 		u16 dl_buffer_depth;
@@ -625,7 +625,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	enum pipe pipe = intel_crtc->pipe;
 	u32 tmp;
 	enum port port;
@@ -768,7 +768,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	const struct drm_display_mode *adjusted_mode =
-					&pipe_config->base.adjusted_mode;
+					&pipe_config->hw.adjusted_mode;
 	enum port port;
 	enum transcoder dsi_trans;
 	/* horizontal timings */
@@ -1216,7 +1216,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	struct drm_display_mode *adjusted_mode =
-					&pipe_config->base.adjusted_mode;
+					&pipe_config->hw.adjusted_mode;
 
 	if (intel_dsi->dual_link) {
 		adjusted_mode->crtc_hdisplay *= 2;
@@ -1242,16 +1242,16 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 				 struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 
 	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
 	pipe_config->port_clock =
 		cnl_calc_wrpll_link(dev_priv, &pipe_config->dpll_hw_state);
 
-	pipe_config->base.adjusted_mode.crtc_clock = intel_dsi->pclk;
+	pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
 	if (intel_dsi->dual_link)
-		pipe_config->base.adjusted_mode.crtc_clock *= 2;
+		pipe_config->hw.adjusted_mode.crtc_clock *= 2;
 
 	gen11_dsi_get_timings(encoder, pipe_config);
 	pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
@@ -1265,11 +1265,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
 	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
 						   base);
 	struct intel_connector *intel_connector = intel_dsi->attached_connector;
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	const struct drm_display_mode *fixed_mode =
 					intel_connector->panel.fixed_mode;
 	struct drm_display_mode *adjusted_mode =
-					&pipe_config->base.adjusted_mode;
+					&pipe_config->hw.adjusted_mode;
 
 	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
 	intel_fixed_panel_mode(fixed_mode, adjusted_mode);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 698802da07b7..f4440ede95c5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -186,13 +186,14 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector)
 struct drm_crtc_state *
 intel_crtc_duplicate_state(struct drm_crtc *crtc)
 {
+	const struct intel_crtc_state *old_crtc_state = to_intel_crtc_state(crtc->state);
 	struct intel_crtc_state *crtc_state;
 
-	crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
+	crtc_state = kmemdup(old_crtc_state, sizeof(*crtc_state), GFP_KERNEL);
 	if (!crtc_state)
 		return NULL;
 
-	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
 
 	crtc_state->update_pipe = false;
 	crtc_state->disable_lp_wm = false;
@@ -205,7 +206,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	crtc_state->fb_bits = 0;
 	crtc_state->update_planes = 0;
 
-	return &crtc_state->base;
+	return &crtc_state->uapi;
 }
 
 /**
@@ -220,7 +221,10 @@ void
 intel_crtc_destroy_state(struct drm_crtc *crtc,
 			 struct drm_crtc_state *state)
 {
-	drm_atomic_helper_crtc_destroy_state(crtc, state);
+	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
+
+	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
+	kfree(crtc_state);
 }
 
 static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state,
@@ -316,7 +320,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
 	struct intel_plane_state *plane_state = NULL;
 	struct intel_crtc_scaler_state *scaler_state =
 		&crtc_state->scaler_state;
-	struct drm_atomic_state *drm_state = crtc_state->base.state;
+	struct drm_atomic_state *drm_state = crtc_state->uapi.state;
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
 	int num_scalers_need;
 	int i;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 476ef0906ba0..1f50b15ec704 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -271,7 +271,7 @@ void intel_update_plane(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
 			const struct intel_plane_state *plane_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	trace_intel_update_plane(&plane->base, crtc);
 	plane->update_plane(plane, crtc_state, plane_state);
@@ -281,7 +281,7 @@ void intel_update_slave(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
 			const struct intel_plane_state *plane_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	trace_intel_update_plane(&plane->base, crtc);
 	plane->update_slave(plane, crtc_state, plane_state);
@@ -290,7 +290,7 @@ void intel_update_slave(struct intel_plane *plane,
 void intel_disable_plane(struct intel_plane *plane,
 			 const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	trace_intel_disable_plane(&plane->base, crtc);
 	plane->disable_plane(plane, crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
index aac089c79ceb..2ecf1df0eeda 100644
--- a/drivers/gpu/drm/i915/display/intel_audio.c
+++ b/drivers/gpu/drm/i915/display/intel_audio.c
@@ -233,7 +233,7 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
 static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
 {
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
@@ -554,7 +554,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder,
 				    const struct drm_connector_state *old_conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 	enum port port = encoder->port;
 	u32 tmp, eldv;
@@ -601,7 +601,7 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
 				   const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_connector *connector = conn_state->connector;
 	enum pipe pipe = crtc->pipe;
 	enum port port = encoder->port;
@@ -691,10 +691,10 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct i915_audio_component *acomp = dev_priv->audio_component;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_connector *connector = conn_state->connector;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	enum port port = encoder->port;
 	enum pipe pipe = crtc->pipe;
 
@@ -752,7 +752,7 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct i915_audio_component *acomp = dev_priv->audio_component;
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	enum port port = encoder->port;
 	enum pipe pipe = crtc->pipe;
 
diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
index 688858ebe4d0..a83a297be9a4 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -264,7 +264,7 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat
 
 static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	unsigned int data_rate = 0;
 	enum plane_id plane_id;
 
@@ -285,7 +285,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_
 void intel_bw_crtc_update(struct intel_bw_state *bw_state,
 			  const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	bw_state->data_rate[crtc->pipe] =
 		intel_bw_crtc_data_rate(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 43564295b864..17ffe7fbaa21 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1917,10 +1917,10 @@ static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv,
 int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->base.crtc->dev);
+		to_i915(crtc_state->uapi.crtc->dev);
 	int min_cdclk;
 
-	if (!crtc_state->base.enable)
+	if (!crtc_state->hw.enable)
 		return 0;
 
 	min_cdclk = intel_pixel_rate_to_cdclk(dev_priv, crtc_state->pixel_rate);
@@ -2043,7 +2043,7 @@ static u8 bxt_compute_min_voltage_level(struct intel_atomic_state *state)
 	       sizeof(state->min_voltage_level));
 
 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		if (crtc_state->base.enable)
+		if (crtc_state->hw.enable)
 			state->min_voltage_level[i] =
 				crtc_state->min_voltage_level;
 		else
@@ -2129,7 +2129,7 @@ static int skl_dpll0_vco(struct intel_atomic_state *state)
 		vco = dev_priv->skl_preferred_vco_freq;
 
 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!crtc_state->base.enable)
+		if (!crtc_state->hw.enable)
 			continue;
 
 		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
@@ -2255,11 +2255,11 @@ static int intel_modeset_all_pipes(struct intel_atomic_state *state)
 		if (IS_ERR(crtc_state))
 			return PTR_ERR(crtc_state);
 
-		if (!crtc_state->base.active ||
-		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
+		if (!crtc_state->hw.active ||
+		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
 			continue;
 
-		crtc_state->base.mode_changed = true;
+		crtc_state->uapi.mode_changed = true;
 
 		ret = drm_atomic_add_affected_connectors(&state->base,
 							 &crtc->base);
@@ -2310,7 +2310,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
 		crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
 		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 		if (crtc_state &&
-		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
+		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
 			pipe = INVALID_PIPE;
 	} else {
 		pipe = INVALID_PIPE;
diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index 318308dc136c..9b058907ef4e 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -101,10 +101,10 @@ static bool lut_is_legacy(const struct drm_property_blob *lut)
 
 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
 {
-	return !crtc_state->base.degamma_lut &&
-		!crtc_state->base.ctm &&
-		crtc_state->base.gamma_lut &&
-		lut_is_legacy(crtc_state->base.gamma_lut);
+	return !crtc_state->hw.degamma_lut &&
+		!crtc_state->hw.ctm &&
+		crtc_state->hw.gamma_lut &&
+		lut_is_legacy(crtc_state->hw.gamma_lut);
 }
 
 /*
@@ -189,7 +189,7 @@ static void icl_update_output_csc(struct intel_crtc *crtc,
 
 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	/*
 	 * FIXME if there's a gamma LUT after the CSC, we should
@@ -203,7 +203,7 @@ static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
 				u16 coeffs[9])
 {
-	const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
+	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
 	const u64 *input;
 	u64 temp[9];
 	int i;
@@ -254,11 +254,11 @@ static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
 
 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
 
-	if (crtc_state->base.ctm) {
+	if (crtc_state->hw.ctm) {
 		u16 coeff[9];
 
 		ilk_csc_convert_ctm(crtc_state, coeff);
@@ -293,10 +293,10 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 
 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
-	if (crtc_state->base.ctm) {
+	if (crtc_state->hw.ctm) {
 		u16 coeff[9];
 
 		ilk_csc_convert_ctm(crtc_state, coeff);
@@ -322,12 +322,12 @@ static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
  */
 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
-	if (crtc_state->base.ctm) {
-		const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
+	if (crtc_state->hw.ctm) {
+		const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
 		u16 coeffs[9] = {};
 		int i;
 
@@ -388,7 +388,7 @@ static u32 ilk_lut_10(const struct drm_color_lut *color)
 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
 				    const struct drm_property_blob *blob)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	int i;
@@ -419,12 +419,12 @@ static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
 
 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
+	i9xx_load_luts_internal(crtc_state, crtc_state->hw.gamma_lut);
 }
 
 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	u32 val;
@@ -437,7 +437,7 @@ static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
 
 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	u32 val;
@@ -452,7 +452,7 @@ static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
 
 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
@@ -462,7 +462,7 @@ static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
 
 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	u32 val = 0;
@@ -508,8 +508,8 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
 
 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
 
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
 		i9xx_load_luts(crtc_state);
@@ -531,8 +531,8 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
 
 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
 
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
 		i9xx_load_luts(crtc_state);
@@ -632,9 +632,9 @@ static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
 
 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
 
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
 		i9xx_load_luts(crtc_state);
@@ -655,9 +655,9 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
 
 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
 
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
 		i9xx_load_luts(crtc_state);
@@ -678,11 +678,11 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
 
 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
-	const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
+	const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
 	u32 i;
 
 	/*
@@ -717,7 +717,7 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
 
 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
@@ -744,8 +744,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat
 
 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	/*
 	 * On GLK+ both pipe CSC and degamma LUT are controlled
@@ -755,7 +755,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 	 * the degama LUT so that we don't have to reload
 	 * it every time the pipe CSC is being enabled.
 	 */
-	if (crtc_state->base.degamma_lut)
+	if (crtc_state->hw.degamma_lut)
 		glk_load_degamma_lut(crtc_state);
 	else
 		glk_load_degamma_lut_linear(crtc_state);
@@ -786,7 +786,7 @@ static void
 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
 	       const struct drm_color_lut *color)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -799,9 +799,9 @@ icl_load_gcmax(const struct intel_crtc_state *crtc_state,
 static void
 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
+	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
 	const struct drm_color_lut *lut = blob->data;
 	enum pipe pipe = crtc->pipe;
 	u32 i;
@@ -828,9 +828,9 @@ icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
 static void
 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
+	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
 	const struct drm_color_lut *lut = blob->data;
 	const struct drm_color_lut *entry;
 	enum pipe pipe = crtc->pipe;
@@ -880,10 +880,10 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
 
 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
-	if (crtc_state->base.degamma_lut)
+	if (crtc_state->hw.degamma_lut)
 		glk_load_degamma_lut(crtc_state);
 
 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
@@ -958,9 +958,9 @@ static void chv_load_cgm_gamma(struct intel_crtc *crtc,
 
 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
 
 	cherryview_load_csc_matrix(crtc_state);
 
@@ -978,28 +978,28 @@ static void chv_load_luts(const struct intel_crtc_state *crtc_state)
 
 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	dev_priv->display.load_luts(crtc_state);
 }
 
 void intel_color_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	dev_priv->display.color_commit(crtc_state);
 }
 
 int intel_color_check(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	return dev_priv->display.color_check(crtc_state);
 }
 
 void intel_color_get_config(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	if (dev_priv->display.read_luts)
 		dev_priv->display.read_luts(crtc_state);
@@ -1023,16 +1023,16 @@ static bool need_plane_update(struct intel_plane *plane,
 static int
 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(new_crtc_state->base.state);
+		to_intel_atomic_state(new_crtc_state->uapi.state);
 	const struct intel_crtc_state *old_crtc_state =
 		intel_atomic_get_old_crtc_state(state, crtc);
 	struct intel_plane *plane;
 
-	if (!new_crtc_state->base.active ||
-	    drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
+	if (!new_crtc_state->hw.active ||
+	    drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
 		return 0;
 
 	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
@@ -1074,9 +1074,9 @@ static int check_lut_size(const struct drm_property_blob *lut, int expected)
 
 static int check_luts(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
-	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
+	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
 	int gamma_length, degamma_length;
 	u32 gamma_tests, degamma_tests;
 
@@ -1124,7 +1124,7 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
 		return ret;
 
 	crtc_state->gamma_enable =
-		crtc_state->base.gamma_lut &&
+		crtc_state->hw.gamma_lut &&
 		!crtc_state->c8_planes;
 
 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
@@ -1143,11 +1143,11 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
 	if (crtc_state_is_legacy_gamma(crtc_state))
 		return 0;
 
-	if (crtc_state->base.degamma_lut)
+	if (crtc_state->hw.degamma_lut)
 		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
-	if (crtc_state->base.ctm)
+	if (crtc_state->hw.ctm)
 		cgm_mode |= CGM_PIPE_MODE_CSC;
-	if (crtc_state->base.gamma_lut)
+	if (crtc_state->hw.gamma_lut)
 		cgm_mode |= CGM_PIPE_MODE_GAMMA;
 
 	return cgm_mode;
@@ -1206,7 +1206,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
 		return ret;
 
 	crtc_state->gamma_enable =
-		crtc_state->base.gamma_lut &&
+		crtc_state->hw.gamma_lut &&
 		!crtc_state->c8_planes;
 
 	/*
@@ -1232,8 +1232,8 @@ static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
 	if (!crtc_state->gamma_enable ||
 	    crtc_state_is_legacy_gamma(crtc_state))
 		return GAMMA_MODE_MODE_8BIT;
-	else if (crtc_state->base.gamma_lut &&
-		 crtc_state->base.degamma_lut)
+	else if (crtc_state->hw.gamma_lut &&
+		 crtc_state->hw.degamma_lut)
 		return GAMMA_MODE_MODE_SPLIT;
 	else
 		return GAMMA_MODE_MODE_10BIT;
@@ -1247,7 +1247,7 @@ static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
 	 * CSC comes after the LUT in degamma, RGB->YCbCr,
 	 * and RGB full->limited range mode.
 	 */
-	if (crtc_state->base.degamma_lut ||
+	if (crtc_state->hw.degamma_lut ||
 	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
 	    limited_color_range)
 		return 0;
@@ -1265,13 +1265,13 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
 		return ret;
 
 	crtc_state->gamma_enable =
-		(crtc_state->base.gamma_lut ||
-		 crtc_state->base.degamma_lut) &&
+		(crtc_state->hw.gamma_lut ||
+		 crtc_state->hw.degamma_lut) &&
 		!crtc_state->c8_planes;
 
 	crtc_state->csc_enable =
 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
-		crtc_state->base.ctm || limited_color_range;
+		crtc_state->hw.ctm || limited_color_range;
 
 	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
 
@@ -1302,14 +1302,14 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
 		return ret;
 
 	crtc_state->gamma_enable =
-		crtc_state->base.gamma_lut &&
+		crtc_state->hw.gamma_lut &&
 		!crtc_state->c8_planes;
 
 	/* On GLK+ degamma LUT is controlled by csc_enable */
 	crtc_state->csc_enable =
-		crtc_state->base.degamma_lut ||
+		crtc_state->hw.degamma_lut ||
 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
-		crtc_state->base.ctm || crtc_state->limited_color_range;
+		crtc_state->hw.ctm || crtc_state->limited_color_range;
 
 	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
 
@@ -1326,14 +1326,14 @@ static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
 {
 	u32 gamma_mode = 0;
 
-	if (crtc_state->base.degamma_lut)
+	if (crtc_state->hw.degamma_lut)
 		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
 
-	if (crtc_state->base.gamma_lut &&
+	if (crtc_state->hw.gamma_lut &&
 	    !crtc_state->c8_planes)
 		gamma_mode |= POST_CSC_GAMMA_ENABLE;
 
-	if (!crtc_state->base.gamma_lut ||
+	if (!crtc_state->hw.gamma_lut ||
 	    crtc_state_is_legacy_gamma(crtc_state))
 		gamma_mode |= GAMMA_MODE_MODE_8BIT;
 	else
@@ -1346,7 +1346,7 @@ static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
 {
 	u32 csc_mode = 0;
 
-	if (crtc_state->base.ctm)
+	if (crtc_state->hw.ctm)
 		csc_mode |= ICL_CSC_ENABLE;
 
 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
@@ -1423,7 +1423,7 @@ static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
 
 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!crtc_state->gamma_enable)
@@ -1532,7 +1532,7 @@ static u32 intel_color_lut_pack(u32 val, u32 bit_precision)
 static struct drm_property_blob *
 i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	struct drm_property_blob *blob;
@@ -1566,13 +1566,13 @@ i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
 
 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
 {
-	crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
+	crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
 }
 
 static struct drm_property_blob *
 i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
 	enum pipe pipe = crtc->pipe;
@@ -1613,15 +1613,15 @@ i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
 static void i965_read_luts(struct intel_crtc_state *crtc_state)
 {
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
+		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
 	else
-		crtc_state->base.gamma_lut = i965_read_lut_10p6(crtc_state);
+		crtc_state->uapi.gamma_lut = i965_read_lut_10p6(crtc_state);
 }
 
 static struct drm_property_blob *
 chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
 	enum pipe pipe = crtc->pipe;
@@ -1655,15 +1655,15 @@ chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
 static void chv_read_luts(struct intel_crtc_state *crtc_state)
 {
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
+		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
 	else
-		crtc_state->base.gamma_lut = chv_read_cgm_lut(crtc_state);
+		crtc_state->uapi.gamma_lut = chv_read_cgm_lut(crtc_state);
 }
 
 static struct drm_property_blob *
 ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
 	enum pipe pipe = crtc->pipe;
@@ -1696,15 +1696,15 @@ ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
 {
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
+		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
 	else
-		crtc_state->base.gamma_lut = ilk_read_lut_10(crtc_state);
+		crtc_state->uapi.gamma_lut = ilk_read_lut_10(crtc_state);
 }
 
 static struct drm_property_blob *
 glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	int hw_lut_size = ivb_lut_10_size(prec_index);
 	enum pipe pipe = crtc->pipe;
@@ -1742,9 +1742,9 @@ glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
 static void glk_read_luts(struct intel_crtc_state *crtc_state)
 {
 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
-		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
+		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
 	else
-		crtc_state->base.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
+		crtc_state->uapi.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
 }
 
 void intel_color_init(struct intel_crtc *crtc)
diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
index e6e8d4a82044..35a25172b269 100644
--- a/drivers/gpu/drm/i915/display/intel_crt.c
+++ b/drivers/gpu/drm/i915/display/intel_crt.c
@@ -132,9 +132,9 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
 {
 	pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
 
-	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
+	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
 
-	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
 static void hsw_crt_get_config(struct intel_encoder *encoder,
@@ -144,13 +144,13 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
 
 	intel_ddi_get_config(encoder, pipe_config);
 
-	pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
+	pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
 					      DRM_MODE_FLAG_NHSYNC |
 					      DRM_MODE_FLAG_PVSYNC |
 					      DRM_MODE_FLAG_NVSYNC);
-	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
+	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
 
-	pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
+	pipe_config->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
 }
 
 /* Note: The caller is required to filter out dpms modes not supported by the
@@ -161,8 +161,8 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_crt *crt = intel_encoder_to_crt(encoder);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	u32 adpa;
 
 	if (INTEL_GEN(dev_priv) >= 5)
@@ -271,7 +271,7 @@ static void hsw_pre_enable_crt(struct intel_encoder *encoder,
 			       const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 
 	WARN_ON(!crtc_state->has_pch_encoder);
@@ -288,7 +288,7 @@ static void hsw_enable_crt(struct intel_encoder *encoder,
 			   const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 
 	WARN_ON(!crtc_state->has_pch_encoder);
@@ -358,7 +358,7 @@ static int intel_crt_compute_config(struct intel_encoder *encoder,
 				    struct drm_connector_state *conn_state)
 {
 	struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return -EINVAL;
@@ -373,7 +373,7 @@ static int pch_crt_compute_config(struct intel_encoder *encoder,
 				  struct drm_connector_state *conn_state)
 {
 	struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return -EINVAL;
@@ -390,7 +390,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return -EINVAL;
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 1b59b852874b..c775fd205915 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1483,7 +1483,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
 	if (pipe_config->fec_enable)
 		dotclock = intel_dp_fec_to_mode_clock(dotclock);
 
-	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
 }
 
 static void icl_ddi_clock_get(struct intel_encoder *encoder,
@@ -1698,7 +1698,7 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
 
 void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 temp;
@@ -1752,7 +1752,7 @@ void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
 void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 				    bool state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 temp;
@@ -1774,7 +1774,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 static u32
 intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
@@ -1806,9 +1806,9 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 		BUG();
 	}
 
-	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
 		temp |= TRANS_DDI_PVSYNC;
-	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
 		temp |= TRANS_DDI_PHSYNC;
 
 	if (cpu_transcoder == TRANSCODER_EDP) {
@@ -1861,7 +1861,7 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
 
 void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 temp;
@@ -1877,7 +1877,7 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
 static void
 intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 temp;
@@ -1889,7 +1889,7 @@ intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
 
 void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
@@ -2187,7 +2187,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 
 void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
 	enum port port = encoder->port;
@@ -2205,7 +2205,7 @@ void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
 
 void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
 	if (cpu_transcoder != TRANSCODER_EDP) {
@@ -3421,7 +3421,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
 				 const struct intel_crtc_state *crtc_state,
 				 const struct drm_connector_state *conn_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -3846,7 +3846,7 @@ intel_ddi_update_prepare(struct intel_atomic_state *state,
 	WARN_ON(crtc && crtc->active);
 
 	intel_tc_port_get_link(enc_to_dig_port(&encoder->base), required_lanes);
-	if (crtc_state && crtc_state->base.active)
+	if (crtc_state && crtc_state->hw.active)
 		intel_update_active_dpll(state, crtc, encoder);
 }
 
@@ -3976,7 +3976,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 			  struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	u32 temp, flags = 0;
 
@@ -3994,7 +3994,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	else
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
 	switch (temp & TRANS_DDI_BPC_MASK) {
 	case TRANS_DDI_BPC_6:
@@ -4136,7 +4136,7 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder,
 				    struct intel_crtc_state *pipe_config,
 				    struct drm_connector_state *conn_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum port port = encoder->port;
 	int ret;
@@ -4267,7 +4267,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
 
 	WARN_ON(!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI));
 
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return 0;
 
 	if (!crtc_state->hdmi_high_tmds_clock_ratio &&
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 7996864e6f7c..6818cbd00ac2 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -518,7 +518,7 @@ icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
 static bool
 needs_modeset(const struct intel_crtc_state *state)
 {
-	return drm_atomic_crtc_needs_modeset(&state->base);
+	return drm_atomic_crtc_needs_modeset(&state->uapi);
 }
 
 /*
@@ -632,7 +632,7 @@ i9xx_select_p2_div(const struct intel_limit *limit,
 		   const struct intel_crtc_state *crtc_state,
 		   int target)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
 		/*
@@ -668,7 +668,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit,
 		    int target, int refclk, struct dpll *match_clock,
 		    struct dpll *best_clock)
 {
-	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_device *dev = crtc_state->uapi.crtc->dev;
 	struct dpll clock;
 	int err = target;
 
@@ -726,7 +726,7 @@ pnv_find_best_dpll(const struct intel_limit *limit,
 		   int target, int refclk, struct dpll *match_clock,
 		   struct dpll *best_clock)
 {
-	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_device *dev = crtc_state->uapi.crtc->dev;
 	struct dpll clock;
 	int err = target;
 
@@ -782,7 +782,7 @@ g4x_find_best_dpll(const struct intel_limit *limit,
 		   int target, int refclk, struct dpll *match_clock,
 		   struct dpll *best_clock)
 {
-	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_device *dev = crtc_state->uapi.crtc->dev;
 	struct dpll clock;
 	int max_n;
 	bool found = false;
@@ -876,7 +876,7 @@ vlv_find_best_dpll(const struct intel_limit *limit,
 		   int target, int refclk, struct dpll *match_clock,
 		   struct dpll *best_clock)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct dpll clock;
 	unsigned int bestppm = 1000000;
@@ -936,7 +936,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
 		   int target, int refclk, struct dpll *match_clock,
 		   struct dpll *best_clock)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	unsigned int best_error_ppm;
 	struct dpll clock;
@@ -1015,7 +1015,7 @@ bool intel_crtc_active(struct intel_crtc *crtc)
 	 * for atomic.
 	 */
 	return crtc->active && crtc->base.primary->state->fb &&
-		crtc->config->base.adjusted_mode.crtc_clock;
+		crtc->config->hw.adjusted_mode.crtc_clock;
 }
 
 enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
@@ -1069,7 +1069,7 @@ static void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
 static void
 intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (INTEL_GEN(dev_priv) >= 4) {
@@ -1528,7 +1528,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc,
 
 static void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -1619,7 +1619,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
 
 static void ironlake_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	i915_reg_t reg;
@@ -1763,7 +1763,7 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
 
 static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	/*
 	 * On i965gm the hardware frame counter reads
@@ -1783,7 +1783,7 @@ static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state
 
 static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	drm_crtc_set_max_vblank_count(&crtc->base,
 				      intel_crtc_max_vblank_count(crtc_state));
@@ -1792,7 +1792,7 @@ static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
 
 static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
@@ -1850,7 +1850,7 @@ static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
 
 static void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
@@ -3116,14 +3116,14 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state,
 	plane_state->base.visible = visible;
 
 	if (visible)
-		crtc_state->base.plane_mask |= drm_plane_mask(&plane->base);
+		crtc_state->uapi.plane_mask |= drm_plane_mask(&plane->base);
 	else
-		crtc_state->base.plane_mask &= ~drm_plane_mask(&plane->base);
+		crtc_state->uapi.plane_mask &= ~drm_plane_mask(&plane->base);
 }
 
 static void fixup_active_planes(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	struct drm_plane *plane;
 
 	/*
@@ -3134,7 +3134,7 @@ static void fixup_active_planes(struct intel_crtc_state *crtc_state)
 	crtc_state->active_planes = 0;
 
 	drm_for_each_plane_mask(plane, &dev_priv->drm,
-				crtc_state->base.plane_mask)
+				crtc_state->uapi.plane_mask)
 		crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
 }
 
@@ -3608,7 +3608,7 @@ i9xx_plane_max_stride(struct intel_plane *plane,
 
 static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 dspcntr = 0;
 
@@ -3762,7 +3762,7 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
 		return ret;
 
 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->base,
+						  &crtc_state->uapi,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  i9xx_plane_has_windowing(plane),
@@ -3938,7 +3938,7 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
  */
 static void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	const struct intel_crtc_scaler_state *scaler_state =
 		&crtc_state->scaler_state;
 	int i;
@@ -4133,7 +4133,7 @@ static u32 cnl_plane_ctl_flip(unsigned int reflect)
 
 u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	u32 plane_ctl = 0;
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
@@ -4189,7 +4189,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
 
 u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	u32 plane_color_ctl = 0;
 
 	if (INTEL_GEN(dev_priv) >= 11)
@@ -4411,11 +4411,11 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
 static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state,
 				     const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
-	crtc->base.mode = new_crtc_state->base.mode;
+	crtc->base.mode = new_crtc_state->uapi.mode;
 
 	/*
 	 * Update pipe size and adjust fitter if needed: the reason for this is
@@ -4844,7 +4844,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
 
 static void ironlake_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	enum pipe pipe = intel_crtc->pipe;
 	i915_reg_t reg;
@@ -5005,9 +5005,9 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
 /* Program iCLKIP clock to the desired frequency */
 static void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	int clock = crtc_state->base.adjusted_mode.crtc_clock;
+	int clock = crtc_state->hw.adjusted_mode.crtc_clock;
 	u32 divsel, phaseinc, auxdiv, phasedir = 0;
 	u32 temp;
 
@@ -5121,7 +5121,7 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
 static void ironlake_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state,
 						enum pipe pch_transcoder)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
@@ -5164,7 +5164,7 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool e
 
 static void ivybridge_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	switch (crtc->pipe) {
@@ -5194,7 +5194,7 @@ static struct intel_encoder *
 intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
 			   const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	const struct drm_connector_state *connector_state;
 	const struct drm_connector *connector;
 	struct intel_encoder *encoder = NULL;
@@ -5226,7 +5226,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
 static void ironlake_pch_enable(const struct intel_atomic_state *state,
 				const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	enum pipe pipe = crtc->pipe;
@@ -5280,7 +5280,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
 	if (HAS_PCH_CPT(dev_priv) &&
 	    intel_crtc_has_dp_encoder(crtc_state)) {
 		const struct drm_display_mode *adjusted_mode =
-			&crtc_state->base.adjusted_mode;
+			&crtc_state->hw.adjusted_mode;
 		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
 		i915_reg_t reg = TRANS_DP_CTL(pipe);
 		enum port port;
@@ -5310,7 +5310,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
 static void lpt_pch_enable(const struct intel_atomic_state *state,
 			   const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
@@ -5427,10 +5427,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 	struct intel_crtc_scaler_state *scaler_state =
 		&crtc_state->scaler_state;
 	struct intel_crtc *intel_crtc =
-		to_intel_crtc(crtc_state->base.crtc);
+		to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 
 	/*
 	 * Src coordinates are already rotated by 270 degrees for
@@ -5446,7 +5446,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 	 * Once NV12 is enabled, handle it here while allocating scaler
 	 * for NV12.
 	 */
-	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
+	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->hw.enable &&
 	    need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
 		DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
 		return -EINVAL;
@@ -5518,13 +5518,13 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
  */
 int skl_update_scaler_crtc(struct intel_crtc_state *state)
 {
-	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &state->hw.adjusted_mode;
 	bool need_scaler = false;
 
 	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
 		need_scaler = true;
 
-	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
+	return skl_update_scaler(state, !state->hw.active, SKL_CRTC_INDEX,
 				 &state->scaler_state.scaler_id,
 				 state->pipe_src_w, state->pipe_src_h,
 				 adjusted_mode->crtc_hdisplay,
@@ -5624,7 +5624,7 @@ static void skylake_scaler_disable(struct intel_crtc *crtc)
 
 static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	const struct intel_crtc_scaler_state *scaler_state =
@@ -5661,7 +5661,7 @@ static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
 
 static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -5682,7 +5682,7 @@ static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
 
 void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
@@ -5718,7 +5718,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
 
 void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 
@@ -5828,7 +5828,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
 static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
 				       const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!old_crtc_state->ips_enabled)
@@ -5844,7 +5844,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
 	 * Disable IPS before we program the LUT.
 	 */
 	if (IS_HASWELL(dev_priv) &&
-	    (new_crtc_state->base.color_mgmt_changed ||
+	    (new_crtc_state->uapi.color_mgmt_changed ||
 	     new_crtc_state->update_pipe) &&
 	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
 		return true;
@@ -5855,7 +5855,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
 static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
 				       const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!new_crtc_state->ips_enabled)
@@ -5871,7 +5871,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
 	 * Re-enable IPS after the LUT has been programmed.
 	 */
 	if (IS_HASWELL(dev_priv) &&
-	    (new_crtc_state->base.color_mgmt_changed ||
+	    (new_crtc_state->uapi.color_mgmt_changed ||
 	     new_crtc_state->update_pipe) &&
 	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
 		return true;
@@ -5881,7 +5881,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
 	 * forcibly enable IPS on the first fastset.
 	 */
 	if (new_crtc_state->update_pipe &&
-	    old_crtc_state->base.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
 		return true;
 
 	return !old_crtc_state->ips_enabled;
@@ -5912,10 +5912,10 @@ static bool needs_scalerclk_wa(struct drm_i915_private *dev_priv,
 
 static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_atomic_state *state = old_crtc_state->base.state;
+	struct drm_atomic_state *state = old_crtc_state->uapi.state;
 	struct intel_crtc_state *pipe_config =
 		intel_atomic_get_new_crtc_state(to_intel_atomic_state(state),
 						crtc);
@@ -5925,7 +5925,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 
 	intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
 
-	if (pipe_config->update_wm_post && pipe_config->base.active)
+	if (pipe_config->update_wm_post && pipe_config->hw.active)
 		intel_update_watermarks(crtc);
 
 	if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
@@ -5955,10 +5955,10 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
 static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
 				   struct intel_crtc_state *pipe_config)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_atomic_state *state = old_crtc_state->base.state;
+	struct drm_atomic_state *state = old_crtc_state->uapi.state;
 	struct drm_plane *primary = crtc->base.primary;
 	struct drm_plane_state *old_primary_state =
 		drm_atomic_get_old_plane_state(state, primary);
@@ -6003,7 +6003,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
 	 * event which is after the vblank start event, so we need to have a
 	 * wait-for-vblank between disabling the plane and the pipe.
 	 */
-	if (HAS_GMCH(dev_priv) && old_crtc_state->base.active &&
+	if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&
 	    pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
 		intel_wait_for_vblank(dev_priv, crtc->pipe);
 
@@ -6015,7 +6015,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
 	 * WaCxSRDisabledForSpriteScaling:ivb
 	 */
 	if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev) &&
-	    old_crtc_state->base.active)
+	    old_crtc_state->hw.active)
 		intel_wait_for_vblank(dev_priv, crtc->pipe);
 
 	/*
@@ -6310,7 +6310,7 @@ static void intel_encoders_update_pipe(struct intel_crtc *crtc,
 
 static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
 
 	plane->disable_plane(plane, crtc_state);
@@ -6319,7 +6319,7 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat
 static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
 				 struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -6453,7 +6453,7 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
 static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 				struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum pipe pipe = intel_crtc->pipe, hsw_workaround_pipe;
@@ -6562,7 +6562,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 
 static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -6578,7 +6578,7 @@ static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
 static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
 				  struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = old_crtc_state->base.crtc;
+	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -6637,7 +6637,7 @@ static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
 static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 				 struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = old_crtc_state->base.crtc;
+	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
@@ -6671,7 +6671,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!crtc_state->gmch_pfit.control)
@@ -6801,14 +6801,14 @@ intel_aux_power_domain(struct intel_digital_port *dig_port)
 
 static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct drm_encoder *encoder;
 	enum pipe pipe = crtc->pipe;
 	u64 mask;
 	enum transcoder transcoder = crtc_state->cpu_transcoder;
 
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return 0;
 
 	mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
@@ -6818,7 +6818,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
 		mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
 
 	drm_for_each_encoder_mask(encoder, &dev_priv->drm,
-				  crtc_state->base.encoder_mask) {
+				  crtc_state->uapi.encoder_mask) {
 		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
 
 		mask |= BIT_ULL(intel_encoder->power_domain);
@@ -6836,7 +6836,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
 static u64
 modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum intel_display_power_domain domain;
 	u64 domains, new_domains, old_domains;
@@ -6865,7 +6865,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
 static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 				   struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -6921,7 +6921,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 
 static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	I915_WRITE(FP0(crtc->pipe), crtc_state->dpll_hw_state.fp0);
@@ -6931,7 +6931,7 @@ static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
 static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 			     struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -6981,7 +6981,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 
 static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!old_crtc_state->gmch_pfit.control)
@@ -6997,7 +6997,7 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
 static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
 			      struct intel_atomic_state *state)
 {
-	struct drm_crtc *crtc = old_crtc_state->base.crtc;
+	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -7165,8 +7165,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
 		if (!crtc_state)
 			return;
 
-		I915_STATE_WARN(!crtc_state->base.active,
-		      "connector is active, but attached crtc isn't\n");
+		I915_STATE_WARN(!crtc_state->hw.active,
+				"connector is active, but attached crtc isn't\n");
 
 		if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
 			return;
@@ -7177,8 +7177,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
 		I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
 			"attached encoder crtc differs from connector crtc\n");
 	} else {
-		I915_STATE_WARN(crtc_state && crtc_state->base.active,
-			"attached crtc is active, but connector isn't\n");
+		I915_STATE_WARN(crtc_state && crtc_state->hw.active,
+				"attached crtc is active, but connector isn't\n");
 		I915_STATE_WARN(!crtc_state && conn_state->best_encoder,
 			"best encoder set without crtc!\n");
 	}
@@ -7186,7 +7186,7 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
 
 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
 {
-	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
+	if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
 		return crtc_state->fdi_lanes;
 
 	return 0;
@@ -7196,7 +7196,7 @@ static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
 				     struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct drm_atomic_state *state = pipe_config->base.state;
+	struct drm_atomic_state *state = pipe_config->uapi.state;
 	struct intel_crtc *other_crtc;
 	struct intel_crtc_state *other_crtc_state;
 
@@ -7269,7 +7269,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 				       struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = intel_crtc->base.dev;
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int lane, link_bw, fdi_dotclock, ret;
 	bool needs_recompute = false;
 
@@ -7315,7 +7315,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 
 bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	/* IPS only exists on ULT machines and is tied to pipe A. */
@@ -7345,9 +7345,9 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
 static bool hsw_compute_ips_config(struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->base.crtc->dev);
+		to_i915(crtc_state->uapi.crtc->dev);
 	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 
 	if (!hsw_crtc_state_ips_capable(crtc_state))
 		return false;
@@ -7386,7 +7386,7 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
 	u32 pixel_rate;
 
-	pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
+	pixel_rate = pipe_config->hw.adjusted_mode.crtc_clock;
 
 	/*
 	 * We only use IF-ID interlacing. If we ever use
@@ -7419,12 +7419,12 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 
 static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	if (HAS_GMCH(dev_priv))
 		/* FIXME calculate proper pipe pixel rate for GMCH pfit */
 		crtc_state->pixel_rate =
-			crtc_state->base.adjusted_mode.crtc_clock;
+			crtc_state->hw.adjusted_mode.crtc_clock;
 	else
 		crtc_state->pixel_rate =
 			ilk_pipe_pixel_rate(crtc_state);
@@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 				     struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
 	if (INTEL_GEN(dev_priv) < 4) {
@@ -7460,7 +7460,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 
 	if ((pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
 	     pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) &&
-	     pipe_config->base.ctm) {
+	     pipe_config->hw.ctm) {
 		/*
 		 * There is only one pipe CSC unit per pipe, and we need that
 		 * for output conversion from RGB->YCBCR. So if CTM is already
@@ -7629,7 +7629,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
 static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
 					 const struct intel_link_m_n *m_n)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -7656,7 +7656,7 @@ static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_sta
 					 const struct intel_link_m_n *m_n,
 					 const struct intel_link_m_n *m2_n2)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	enum transcoder transcoder = crtc_state->cpu_transcoder;
@@ -7969,7 +7969,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
 	if (!pipe_config)
 		return -ENOMEM;
 
-	pipe_config->base.crtc = &crtc->base;
+	pipe_config->uapi.crtc = &crtc->base;
 	pipe_config->pixel_multiplier = 1;
 	pipe_config->dpll = *dpll;
 
@@ -8129,11 +8129,11 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc,
 
 static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	u32 crtc_vtotal, crtc_vblank_end;
 	int vsyncshift = 0;
 
@@ -8191,7 +8191,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
 
 static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 
@@ -8212,39 +8212,39 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
 	u32 tmp;
 
 	tmp = I915_READ(HTOTAL(cpu_transcoder));
-	pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
-	pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
 
 	if (!transcoder_is_dsi(cpu_transcoder)) {
 		tmp = I915_READ(HBLANK(cpu_transcoder));
-		pipe_config->base.adjusted_mode.crtc_hblank_start =
+		pipe_config->hw.adjusted_mode.crtc_hblank_start =
 							(tmp & 0xffff) + 1;
-		pipe_config->base.adjusted_mode.crtc_hblank_end =
+		pipe_config->hw.adjusted_mode.crtc_hblank_end =
 						((tmp >> 16) & 0xffff) + 1;
 	}
 	tmp = I915_READ(HSYNC(cpu_transcoder));
-	pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
-	pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
 
 	tmp = I915_READ(VTOTAL(cpu_transcoder));
-	pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
-	pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
 
 	if (!transcoder_is_dsi(cpu_transcoder)) {
 		tmp = I915_READ(VBLANK(cpu_transcoder));
-		pipe_config->base.adjusted_mode.crtc_vblank_start =
+		pipe_config->hw.adjusted_mode.crtc_vblank_start =
 							(tmp & 0xffff) + 1;
-		pipe_config->base.adjusted_mode.crtc_vblank_end =
+		pipe_config->hw.adjusted_mode.crtc_vblank_end =
 						((tmp >> 16) & 0xffff) + 1;
 	}
 	tmp = I915_READ(VSYNC(cpu_transcoder));
-	pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
-	pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
+	pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
 
 	if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
-		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
-		pipe_config->base.adjusted_mode.crtc_vtotal += 1;
-		pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
+		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
+		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
+		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
 	}
 }
 
@@ -8259,27 +8259,27 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
 	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
 	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
 
-	pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
-	pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
+	pipe_config->hw.mode.vdisplay = pipe_config->pipe_src_h;
+	pipe_config->hw.mode.hdisplay = pipe_config->pipe_src_w;
 }
 
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 				 struct intel_crtc_state *pipe_config)
 {
-	mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
-	mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
-	mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
-	mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
+	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
+	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
+	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
+	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
 
-	mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
-	mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
-	mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
-	mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
+	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
+	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
+	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
+	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
 
-	mode->flags = pipe_config->base.adjusted_mode.flags;
+	mode->flags = pipe_config->hw.adjusted_mode.flags;
 	mode->type = DRM_MODE_TYPE_DRIVER;
 
-	mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
+	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
 
 	mode->hsync = drm_mode_hsync(mode);
 	mode->vrefresh = drm_mode_vrefresh(mode);
@@ -8288,7 +8288,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 
 static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 pipeconf;
 
@@ -8325,7 +8325,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
 		}
 	}
 
-	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
 		if (INTEL_GEN(dev_priv) < 4 ||
 		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
 			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
@@ -8757,7 +8757,7 @@ static void intel_get_crtc_ycbcr_config(struct intel_crtc *crtc,
 
 static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
@@ -8880,7 +8880,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 	 * but in case the pipe is enabled w/o any ports we need a sane
 	 * default.
 	 */
-	pipe_config->base.adjusted_mode.crtc_clock =
+	pipe_config->hw.adjusted_mode.crtc_clock =
 		pipe_config->port_clock / pipe_config->pixel_multiplier;
 
 	ret = true;
@@ -9395,7 +9395,7 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
 
 static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	u32 val;
@@ -9423,7 +9423,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
 	if (crtc_state->dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
@@ -9439,7 +9439,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
 
 static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	u32 val = 0;
@@ -9447,7 +9447,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
 	if (IS_HASWELL(dev_priv) && crtc_state->dither)
 		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
 
-	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		val |= PIPECONF_INTERLACED_ILK;
 	else
 		val |= PIPECONF_PROGRESSIVE;
@@ -9458,7 +9458,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
 
 static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 val = 0;
 
@@ -9644,7 +9644,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 	const struct intel_limit *limit;
 	int refclk = 120000;
 
@@ -10060,7 +10060,7 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 
 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
 	    INTEL_GEN(dev_priv) >= 11) {
@@ -10608,7 +10608,7 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 	}
 
 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->base,
+						  &crtc_state->uapi,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  true, true);
@@ -10791,7 +10791,7 @@ i9xx_cursor_max_stride(struct intel_plane *plane,
 
 static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 cntl = 0;
 
@@ -11198,12 +11198,12 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
 		goto fail;
 	}
 
-	crtc_state->base.active = crtc_state->base.enable = true;
+	crtc_state->uapi.active = crtc_state->uapi.enable = true;
 
 	if (!mode)
 		mode = &load_detect_mode;
 
-	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
+	ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi, mode);
 	if (ret)
 		goto fail;
 
@@ -11411,7 +11411,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
 	 * we may need some idea for the dotclock anyway.
 	 * Calculate one based on the FDI configuration.
 	 */
-	pipe_config->base.adjusted_mode.crtc_clock =
+	pipe_config->hw.adjusted_mode.crtc_clock =
 		intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
 					 &pipe_config->fdi_m_n);
 }
@@ -11441,7 +11441,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
 		return NULL;
 	}
 
-	crtc_state->base.crtc = &crtc->base;
+	crtc_state->uapi.crtc = &crtc->base;
 
 	if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) {
 		kfree(crtc_state);
@@ -11512,12 +11512,12 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 				    const struct intel_plane_state *old_plane_state,
 				    struct intel_plane_state *plane_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	bool mode_changed = needs_modeset(crtc_state);
-	bool was_crtc_enabled = old_crtc_state->base.active;
-	bool is_crtc_enabled = crtc_state->base.active;
+	bool was_crtc_enabled = old_crtc_state->hw.active;
+	bool is_crtc_enabled = crtc_state->hw.active;
 	bool turn_off, turn_on, visible, was_visible;
 	struct drm_framebuffer *fb = plane_state->base.fb;
 	int ret;
@@ -11692,9 +11692,9 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
 
 static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
+	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
 	struct intel_plane *plane, *linked;
 	struct intel_plane_state *plane_state;
 	int i;
@@ -11764,9 +11764,9 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 
 static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(new_crtc_state->base.state);
+		to_intel_atomic_state(new_crtc_state->uapi.state);
 	const struct intel_crtc_state *old_crtc_state =
 		intel_atomic_get_old_crtc_state(state, crtc);
 
@@ -11784,10 +11784,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 	bool mode_changed = needs_modeset(crtc_state);
 
 	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
-	    mode_changed && !crtc_state->base.active)
+	    mode_changed && !crtc_state->hw.active)
 		crtc_state->update_wm_post = true;
 
-	if (mode_changed && crtc_state->base.enable &&
+	if (mode_changed && crtc_state->hw.enable &&
 	    dev_priv->display.crtc_compute_clock &&
 	    !WARN_ON(crtc_state->shared_dpll)) {
 		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
@@ -11800,10 +11800,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 	 * when C8 planes are getting enabled/disabled.
 	 */
 	if (c8_planes_changed(crtc_state))
-		crtc_state->base.color_mgmt_changed = true;
+		crtc_state->uapi.color_mgmt_changed = true;
 
 	if (mode_changed || crtc_state->update_pipe ||
-	    crtc_state->base.color_mgmt_changed) {
+	    crtc_state->uapi.color_mgmt_changed) {
 		ret = intel_color_check(crtc_state);
 		if (ret)
 			return ret;
@@ -11925,7 +11925,7 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
 			  struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct drm_atomic_state *state = pipe_config->base.state;
+	struct drm_atomic_state *state = pipe_config->uapi.state;
 	struct drm_connector *connector;
 	struct drm_connector_state *connector_state;
 	int bpp, i;
@@ -12078,7 +12078,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 				   struct intel_atomic_state *state,
 				   const char *context)
 {
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	const struct intel_plane_state *plane_state;
 	struct intel_plane *plane;
@@ -12087,14 +12087,14 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s] enable: %s %s\n",
 		      crtc->base.base.id, crtc->base.name,
-		      yesno(pipe_config->base.enable), context);
+		      yesno(pipe_config->hw.enable), context);
 
-	if (!pipe_config->base.enable)
+	if (!pipe_config->hw.enable)
 		goto dump_planes;
 
 	snprintf_output_types(buf, sizeof(buf), pipe_config->output_types);
 	DRM_DEBUG_KMS("active: %s, output_types: %s (0x%x), output format: %s\n",
-		      yesno(pipe_config->base.active),
+		      yesno(pipe_config->hw.active),
 		      buf, pipe_config->output_types,
 		      output_formats(pipe_config->output_format));
 
@@ -12134,10 +12134,10 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 		intel_dump_infoframe(dev_priv, &pipe_config->infoframes.hdmi);
 
 	DRM_DEBUG_KMS("requested mode:\n");
-	drm_mode_debug_printmodeline(&pipe_config->base.mode);
+	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
 	DRM_DEBUG_KMS("adjusted mode:\n");
-	drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
-	intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
+	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
+	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
 	DRM_DEBUG_KMS("port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
 		      pipe_config->port_clock,
 		      pipe_config->pipe_src_w, pipe_config->pipe_src_h,
@@ -12255,7 +12255,7 @@ static int
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->base.crtc->dev);
+		to_i915(crtc_state->uapi.crtc->dev);
 	struct intel_crtc_state *saved_state;
 
 	saved_state = kzalloc(sizeof(*saved_state), GFP_KERNEL);
@@ -12278,9 +12278,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 		saved_state->wm = crtc_state->wm;
 
 	/* Keep base drm_crtc_state intact, only clear our extended struct */
-	BUILD_BUG_ON(offsetof(struct intel_crtc_state, base));
-	memcpy(&crtc_state->base + 1, &saved_state->base + 1,
-	       sizeof(*crtc_state) - sizeof(crtc_state->base));
+	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
+	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
+	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
+	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
 
 	kfree(saved_state);
 	return 0;
@@ -12289,8 +12290,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 static int
 intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 {
-	struct drm_crtc *crtc = pipe_config->base.crtc;
-	struct drm_atomic_state *state = pipe_config->base.state;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
+	struct drm_atomic_state *state = pipe_config->uapi.state;
 	struct intel_encoder *encoder;
 	struct drm_connector *connector;
 	struct drm_connector_state *connector_state;
@@ -12310,13 +12311,13 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * positive or negative polarity is requested, treat this as meaning
 	 * negative polarity.
 	 */
-	if (!(pipe_config->base.adjusted_mode.flags &
+	if (!(pipe_config->hw.adjusted_mode.flags &
 	      (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
-		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
+		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
 
-	if (!(pipe_config->base.adjusted_mode.flags &
+	if (!(pipe_config->hw.adjusted_mode.flags &
 	      (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
-		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
+		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
 
 	ret = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
 					pipe_config);
@@ -12333,7 +12334,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * computation to clearly distinguish it from the adjusted mode, which
 	 * can be changed by the connectors in the below retry loop.
 	 */
-	drm_mode_get_hv_timing(&pipe_config->base.mode,
+	drm_mode_get_hv_timing(&pipe_config->hw.mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -12366,7 +12367,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	pipe_config->pixel_multiplier = 1;
 
 	/* Fill in default crtc timings, allow encoders to overwrite them. */
-	drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
+	drm_mode_set_crtcinfo(&pipe_config->hw.adjusted_mode,
 			      CRTC_STEREO_DOUBLE);
 
 	/* Pass our mode to the connectors and the CRTC to give them a chance to
@@ -12391,7 +12392,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	/* Set default port clock if not overwritten by the encoder. Needs to be
 	 * done afterwards in case the encoder adjusts the mode. */
 	if (!pipe_config->port_clock)
-		pipe_config->port_clock = pipe_config->base.adjusted_mode.crtc_clock
+		pipe_config->port_clock = pipe_config->hw.adjusted_mode.crtc_clock
 			* pipe_config->pixel_multiplier;
 
 	ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
@@ -12555,12 +12556,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 			  const struct intel_crtc_state *pipe_config,
 			  bool fastset)
 {
-	struct drm_i915_private *dev_priv = to_i915(current_config->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
 	bool ret = true;
 	u32 bp_gamma = 0;
 	bool fixup_inherited = fastset &&
-		(current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
-		!(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED);
+		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
+		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
 
 	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
 		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
@@ -12749,19 +12750,19 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_X(output_types);
 
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
 
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
-	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
+	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
 
 	PIPE_CONF_CHECK_I(pixel_multiplier);
 	PIPE_CONF_CHECK_I(output_format);
@@ -12777,17 +12778,17 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
-	PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
 			      DRM_MODE_FLAG_INTERLACE);
 
 	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
-		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
 				      DRM_MODE_FLAG_PHSYNC);
-		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
 				      DRM_MODE_FLAG_NHSYNC);
-		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
 				      DRM_MODE_FLAG_PVSYNC);
-		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
+		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
 				      DRM_MODE_FLAG_NVSYNC);
 	}
 
@@ -12826,7 +12827,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 		bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
 		if (bp_gamma)
-			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, base.gamma_lut, bp_gamma);
+			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, uapi.gamma_lut, bp_gamma);
 
 	}
 
@@ -12871,7 +12872,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
 		PIPE_CONF_CHECK_I(pipe_bpp);
 
-	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
+	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
 	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
 
 	PIPE_CONF_CHECK_I(min_voltage_level);
@@ -12902,7 +12903,7 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
 	if (pipe_config->has_pch_encoder) {
 		int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
 							    &pipe_config->fdi_m_n);
-		int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
+		int dotclock = pipe_config->hw.adjusted_mode.crtc_clock;
 
 		/*
 		 * FDI already provided one idea for the dotclock.
@@ -12930,7 +12931,7 @@ static void verify_wm_state(struct intel_crtc *crtc,
 	const enum pipe pipe = crtc->pipe;
 	int plane, level, max_level = ilk_wm_max_level(dev_priv);
 
-	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->base.active)
+	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->hw.active)
 		return;
 
 	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
@@ -13139,12 +13140,12 @@ verify_crtc_state(struct intel_crtc *crtc,
 	struct drm_atomic_state *state;
 	bool active;
 
-	state = old_crtc_state->base.state;
-	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->base);
+	state = old_crtc_state->uapi.state;
+	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
 	pipe_config = old_crtc_state;
 	memset(pipe_config, 0, sizeof(*pipe_config));
-	pipe_config->base.crtc = &crtc->base;
-	pipe_config->base.state = state;
+	pipe_config->uapi.crtc = &crtc->base;
+	pipe_config->uapi.state = state;
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.base.id, crtc->base.name);
 
@@ -13152,23 +13153,26 @@ verify_crtc_state(struct intel_crtc *crtc,
 
 	/* we keep both pipes enabled on 830 */
 	if (IS_I830(dev_priv))
-		active = new_crtc_state->base.active;
+		active = new_crtc_state->hw.active;
 
-	I915_STATE_WARN(new_crtc_state->base.active != active,
-	     "crtc active state doesn't match with hw state "
-	     "(expected %i, found %i)\n", new_crtc_state->base.active, active);
+	I915_STATE_WARN(new_crtc_state->hw.active != active,
+			"crtc active state doesn't match with hw state "
+			"(expected %i, found %i)\n",
+			new_crtc_state->hw.active, active);
 
-	I915_STATE_WARN(crtc->active != new_crtc_state->base.active,
-	     "transitional active state does not match atomic hw state "
-	     "(expected %i, found %i)\n", new_crtc_state->base.active, crtc->active);
+	I915_STATE_WARN(crtc->active != new_crtc_state->hw.active,
+			"transitional active state does not match atomic hw state "
+			"(expected %i, found %i)\n",
+			new_crtc_state->hw.active, crtc->active);
 
 	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
 		enum pipe pipe;
 
 		active = encoder->get_hw_state(encoder, &pipe);
-		I915_STATE_WARN(active != new_crtc_state->base.active,
-			"[ENCODER:%i] active %i with crtc active %i\n",
-			encoder->base.base.id, active, new_crtc_state->base.active);
+		I915_STATE_WARN(active != new_crtc_state->hw.active,
+				"[ENCODER:%i] active %i with crtc active %i\n",
+				encoder->base.base.id, active,
+				new_crtc_state->hw.active);
 
 		I915_STATE_WARN(active && crtc->pipe != pipe,
 				"Encoder connected to wrong pipe %c\n",
@@ -13180,7 +13184,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 
 	intel_crtc_compute_pixel_rate(pipe_config);
 
-	if (!new_crtc_state->base.active)
+	if (!new_crtc_state->hw.active)
 		return;
 
 	intel_pipe_config_sanity_check(dev_priv, pipe_config);
@@ -13242,7 +13246,7 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
 
 	crtc_mask = drm_crtc_mask(&crtc->base);
 
-	if (new_crtc_state->base.active)
+	if (new_crtc_state->hw.active)
 		I915_STATE_WARN(!(pll->active_mask & crtc_mask),
 				"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
 				pipe_name(drm_crtc_index(&crtc->base)), pll->active_mask);
@@ -13320,7 +13324,7 @@ intel_modeset_verify_disabled(struct drm_i915_private *dev_priv,
 
 static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	/*
@@ -13351,7 +13355,7 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
 	 * answer that's slightly in the future.
 	 */
 	if (IS_GEN(dev_priv, 2)) {
-		const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
+		const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 		int vtotal;
 
 		vtotal = adjusted_mode->crtc_vtotal;
@@ -13401,7 +13405,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
 
 	/* look at all crtc's that are going to be enabled in during modeset */
 	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
-		if (!crtc_state->base.active ||
+		if (!crtc_state->hw.active ||
 		    !needs_modeset(crtc_state))
 			continue;
 
@@ -13426,7 +13430,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
 
 		crtc_state->hsw_workaround_pipe = INVALID_PIPE;
 
-		if (!crtc_state->base.active ||
+		if (!crtc_state->hw.active ||
 		    needs_modeset(crtc_state))
 			continue;
 
@@ -13469,12 +13473,12 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
-		if (new_crtc_state->base.active)
+		if (new_crtc_state->hw.active)
 			state->active_pipes |= BIT(crtc->pipe);
 		else
 			state->active_pipes &= ~BIT(crtc->pipe);
 
-		if (old_crtc_state->base.active != new_crtc_state->base.active)
+		if (old_crtc_state->hw.active != new_crtc_state->hw.active)
 			state->active_pipe_changes |= BIT(crtc->pipe);
 	}
 
@@ -13513,7 +13517,7 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
 	if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
 		return;
 
-	new_crtc_state->base.mode_changed = false;
+	new_crtc_state->uapi.mode_changed = false;
 	new_crtc_state->update_pipe = true;
 
 	/*
@@ -13548,9 +13552,9 @@ static int intel_atomic_check(struct drm_device *dev,
 	/* Catch I915_MODE_FLAG_INHERITED */
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
-		if (new_crtc_state->base.mode.private_flags !=
-		    old_crtc_state->base.mode.private_flags)
-			new_crtc_state->base.mode_changed = true;
+		if (new_crtc_state->hw.mode.private_flags !=
+		    old_crtc_state->hw.mode.private_flags)
+			new_crtc_state->uapi.mode_changed = true;
 	}
 
 	ret = drm_atomic_helper_check_modeset(dev, &state->base);
@@ -13562,7 +13566,7 @@ static int intel_atomic_check(struct drm_device *dev,
 		if (!needs_modeset(new_crtc_state))
 			continue;
 
-		if (!new_crtc_state->base.enable) {
+		if (!new_crtc_state->uapi.enable) {
 			any_ms = true;
 			continue;
 		}
@@ -13719,11 +13723,10 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 	intel_check_pch_fifo_underruns(dev_priv);
 
 	/* FIXME unify this for all platforms */
-	if (!new_crtc_state->base.active &&
+	if (!new_crtc_state->hw.active &&
 	    !HAS_GMCH(dev_priv) &&
 	    dev_priv->display.initial_watermarks)
-		dev_priv->display.initial_watermarks(state,
-						     new_crtc_state);
+		dev_priv->display.initial_watermarks(state, new_crtc_state);
 }
 
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
@@ -13746,7 +13749,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
 
-		if (old_crtc_state->base.active)
+		if (old_crtc_state->hw.active)
 			intel_old_crtc_state_disables(state,
 						      old_crtc_state,
 						      new_crtc_state,
@@ -13761,7 +13764,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
 	int i;
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
-		if (!new_crtc_state->base.active)
+		if (!new_crtc_state->hw.active)
 			continue;
 
 		intel_update_crtc(crtc, state, old_crtc_state,
@@ -13784,7 +13787,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
 		/* ignore allocations for crtc's that have been turned off. */
-		if (new_crtc_state->base.active)
+		if (new_crtc_state->hw.active)
 			entries[i] = old_crtc_state->wm.skl.ddb;
 
 	/* If 2nd DBuf slice required, enable it here */
@@ -13806,7 +13809,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 
 			pipe = crtc->pipe;
 
-			if (updated & cmask || !new_crtc_state->base.active)
+			if (updated & cmask || !new_crtc_state->hw.active)
 				continue;
 
 			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
@@ -13825,7 +13828,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			 */
 			if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
 						 &old_crtc_state->wm.skl.ddb) &&
-			    !new_crtc_state->base.active_changed &&
+			    !new_crtc_state->uapi.active_changed &&
 			    state->wm_results.dirty_pipes != updated)
 				vbl_wait = true;
 
@@ -13958,12 +13961,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		bool modeset = needs_modeset(new_crtc_state);
 
 		/* Complete events for now disable pipes here. */
-		if (modeset && !new_crtc_state->base.active && new_crtc_state->base.event) {
+		if (modeset && !new_crtc_state->hw.active && new_crtc_state->uapi.event) {
 			spin_lock_irq(&dev->event_lock);
-			drm_crtc_send_vblank_event(&crtc->base, new_crtc_state->base.event);
+			drm_crtc_send_vblank_event(&crtc->base,
+						   new_crtc_state->uapi.event);
 			spin_unlock_irq(&dev->event_lock);
 
-			new_crtc_state->base.event = NULL;
+			new_crtc_state->uapi.event = NULL;
 		}
 	}
 
@@ -13994,9 +13998,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	drm_atomic_helper_wait_for_flip_done(dev, &state->base);
 
 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
-		if (new_crtc_state->base.active &&
+		if (new_crtc_state->hw.active &&
 		    !needs_modeset(new_crtc_state) &&
-		    (new_crtc_state->base.color_mgmt_changed ||
+		    (new_crtc_state->uapi.color_mgmt_changed ||
 		     new_crtc_state->update_pipe))
 			intel_color_load_luts(new_crtc_state);
 	}
@@ -14451,16 +14455,16 @@ int
 skl_max_scale(const struct intel_crtc_state *crtc_state,
 	      const struct drm_format_info *format)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	int max_scale;
 	int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
 
-	if (!crtc_state->base.enable)
+	if (!crtc_state->hw.enable)
 		return DRM_PLANE_HELPER_NO_SCALING;
 
-	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
-	max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
+	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
+	max_dotclk = to_intel_atomic_state(crtc_state->uapi.state)->cdclk.logical.cdclk;
 
 	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
 		max_dotclk *= 2;
@@ -14501,7 +14505,7 @@ static void intel_begin_crtc_commit(struct intel_atomic_state *state,
 	if (modeset)
 		goto out;
 
-	if (new_crtc_state->base.color_mgmt_changed ||
+	if (new_crtc_state->uapi.color_mgmt_changed ||
 	    new_crtc_state->update_pipe)
 		intel_color_commit(new_crtc_state);
 
@@ -14547,7 +14551,7 @@ static void intel_finish_crtc_commit(struct intel_atomic_state *state,
 
 	if (new_crtc_state->update_pipe &&
 	    !needs_modeset(new_crtc_state) &&
-	    old_crtc_state->base.mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
@@ -14659,7 +14663,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 	 * When crtc is inactive or there is a modeset pending,
 	 * wait for it to complete in the slowpath
 	 */
-	if (!crtc_state->base.active || needs_modeset(crtc_state) ||
+	if (!crtc_state->hw.active || needs_modeset(crtc_state) ||
 	    crtc_state->update_pipe)
 		goto slow;
 
@@ -14753,7 +14757,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 out_free:
 	if (new_crtc_state)
-		intel_crtc_destroy_state(crtc, &new_crtc_state->base);
+		intel_crtc_destroy_state(crtc, &new_crtc_state->uapi);
 	if (ret)
 		intel_plane_destroy_state(plane, new_plane_state);
 	else
@@ -15079,7 +15083,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
 		ret = -ENOMEM;
 		goto fail;
 	}
-	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->base);
+	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->uapi);
 	intel_crtc->config = crtc_state;
 
 	primary = intel_primary_plane_create(dev_priv, pipe);
@@ -16455,7 +16459,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
 			   I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
 	}
 
-	if (crtc_state->base.active) {
+	if (crtc_state->hw.active) {
 		struct intel_plane *plane;
 
 		/* Disable everything but the primary plane */
@@ -16480,10 +16484,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
 
 	/* Adjust the state of the output pipe according to whether we
 	 * have active connectors/encoders. */
-	if (crtc_state->base.active && !intel_crtc_has_encoders(crtc))
+	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc))
 		intel_crtc_disable_noatomic(&crtc->base, ctx);
 
-	if (crtc_state->base.active || HAS_GMCH(dev_priv)) {
+	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
 		/*
 		 * We start out with underrun reporting disabled to avoid races.
 		 * For correct bookkeeping mark this on active crtcs.
@@ -16514,7 +16518,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
 
 static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	/*
 	 * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram
@@ -16527,7 +16531,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
 	 * road.
 	 */
 	return IS_GEN(dev_priv, 6) &&
-		crtc_state->base.active &&
+		crtc_state->hw.active &&
 		crtc_state->shared_dpll &&
 		crtc_state->port_clock == 0;
 }
@@ -16544,7 +16548,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
 	 * encoder is active and trying to read from a pipe) and the
 	 * pipe itself being active. */
 	bool has_active_crtc = crtc_state &&
-		crtc_state->base.active;
+		crtc_state->hw.active;
 
 	if (crtc_state && has_bogus_dpll_config(crtc_state)) {
 		DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n",
@@ -16681,22 +16685,22 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		struct intel_crtc_state *crtc_state =
 			to_intel_crtc_state(crtc->base.state);
 
-		__drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
+		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
 		memset(crtc_state, 0, sizeof(*crtc_state));
-		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->base);
+		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
 
-		crtc_state->base.active = crtc_state->base.enable =
+		crtc_state->hw.active = crtc_state->hw.enable =
 			dev_priv->display.get_pipe_config(crtc, crtc_state);
 
-		crtc->base.enabled = crtc_state->base.enable;
-		crtc->active = crtc_state->base.active;
+		crtc->base.enabled = crtc_state->hw.enable;
+		crtc->active = crtc_state->hw.active;
 
-		if (crtc_state->base.active)
+		if (crtc_state->hw.active)
 			dev_priv->active_pipes |= BIT(crtc->pipe);
 
 		DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
 			      crtc->base.base.id, crtc->base.name,
-			      enableddisabled(crtc_state->base.active));
+			      enableddisabled(crtc_state->hw.active));
 	}
 
 	readout_plane_state(dev_priv);
@@ -16718,7 +16722,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			struct intel_crtc_state *crtc_state =
 				to_intel_crtc_state(crtc->base.state);
 
-			if (crtc_state->base.active &&
+			if (crtc_state->hw.active &&
 			    crtc_state->shared_dpll == pll)
 				pll->state.crtc_mask |= 1 << crtc->pipe;
 		}
@@ -16752,21 +16756,24 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 	drm_connector_list_iter_begin(dev, &conn_iter);
 	for_each_intel_connector_iter(connector, &conn_iter) {
 		if (connector->get_hw_state(connector)) {
-			connector->base.dpms = DRM_MODE_DPMS_ON;
+			struct intel_crtc_state *crtc_state = NULL;
 
+			connector->base.dpms = DRM_MODE_DPMS_ON;
 			encoder = connector->encoder;
 			connector->base.encoder = &encoder->base;
 
-			if (encoder->base.crtc &&
-			    encoder->base.crtc->state->active) {
+			if (encoder->base.crtc)
+				crtc_state = to_intel_crtc_state(encoder->base.crtc->state);
+
+			if (crtc_state && crtc_state->hw.active) {
 				/*
 				 * This has to be done during hardware readout
 				 * because anything calling .crtc_disable may
 				 * rely on the connector_mask being accurate.
 				 */
-				encoder->base.crtc->state->connector_mask |=
+				crtc_state->uapi.connector_mask |=
 					drm_connector_mask(&connector->base);
-				encoder->base.crtc->state->encoder_mask |=
+				crtc_state->uapi.encoder_mask |=
 					drm_encoder_mask(&encoder->base);
 			}
 
@@ -16789,11 +16796,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		int min_cdclk = 0;
 
 		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
-		if (crtc_state->base.active) {
+		if (crtc_state->hw.active) {
 			intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
 			crtc->base.mode.hdisplay = crtc_state->pipe_src_w;
 			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
-			intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state);
+			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
+						    crtc_state);
 			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 
 			/*
@@ -16805,7 +16813,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			 * set a flag to indicate that a full recalculation is
 			 * needed on the next commit.
 			 */
-			crtc_state->base.mode.private_flags = I915_MODE_FLAG_INHERITED;
+			crtc_state->hw.mode.private_flags = I915_MODE_FLAG_INHERITED;
 
 			intel_crtc_compute_pixel_rate(crtc_state);
 
@@ -16816,7 +16824,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			}
 
 			drm_calc_timestamping_constants(&crtc->base,
-							&crtc_state->base.adjusted_mode);
+							&crtc_state->hw.adjusted_mode);
 			update_scanline_offset(crtc_state);
 		}
 
@@ -16987,7 +16995,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
 
 		drm_crtc_vblank_reset(&crtc->base);
 
-		if (crtc_state->base.active)
+		if (crtc_state->hw.active)
 			intel_crtc_vblank_on(crtc_state);
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index d5cc4b810d9e..2c3567081e16 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -749,7 +749,31 @@ enum intel_output_format {
 };
 
 struct intel_crtc_state {
-	struct drm_crtc_state base;
+	union {
+	/*
+	 * uapi (drm) state. This is the software state shown to userspace.
+	 * In particular, the following members are used for bookkeeping:
+	 * - crtc
+	 * - state
+	 * - *_changed
+	 * - event
+	 * - commit
+	 * - mode_blob
+	 */
+	struct drm_crtc_state uapi;
+
+	/*
+	 * actual hardware state, the state we program to the hardware.
+	 * The following members are used to verify the hardware state:
+	 * - enable
+	 * - active
+	 * - mode / adjusted_mode
+	 * - color property blobs.
+	 *
+	 * During initial hw readout, they need to be copied to uapi.
+	 */
+	struct drm_crtc_state hw;
+	};
 
 	/**
 	 * quirks - bitfield with hw state readout quirks
@@ -1091,7 +1115,7 @@ struct cxsr_latency {
 
 #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
 #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
-#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
+#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, uapi)
 #define to_intel_connector(x) container_of(x, struct intel_connector, base)
 #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
 #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 02242a16640b..2fceb71f7f70 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1966,7 +1966,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
 				  struct intel_crtc_state *pipe_config,
 				  const struct link_config_limits *limits)
 {
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int bpp, clock, lane_count;
 	int mode_rate, link_clock, link_avail;
 
@@ -2020,7 +2020,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	u8 dsc_max_bpc;
 	int pipe_bpp;
 	int ret;
@@ -2131,7 +2131,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
 			     struct intel_crtc_state *pipe_config,
 			     struct drm_connector_state *conn_state)
 {
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct link_config_limits limits;
 	int common_len;
@@ -2219,8 +2219,8 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
 {
 	const struct drm_display_info *info = &connector->display_info;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+		&crtc_state->hw.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	int ret;
 
 	if (!drm_mode_is_420_only(info, adjusted_mode) ||
@@ -2248,7 +2248,7 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
 	const struct intel_digital_connector_state *intel_conn_state =
 		to_intel_digital_connector_state(conn_state);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 
 	if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
 		/*
@@ -2271,11 +2271,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 			struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base);
 	enum port port = encoder->port;
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_connector *intel_connector = intel_dp->attached_connector;
 	struct intel_digital_connector_state *intel_conn_state =
 		to_intel_digital_connector_state(conn_state);
@@ -2395,8 +2395,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	enum port port = encoder->port;
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 
 	intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
 				 pipe_config->lane_count,
@@ -2993,7 +2993,7 @@ static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
 static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
 				const struct intel_crtc_state *pipe_config)
 {
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	assert_pipe_disabled(dev_priv, crtc->pipe);
@@ -3033,7 +3033,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
 static void ironlake_edp_pll_off(struct intel_dp *intel_dp,
 				 const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	assert_pipe_disabled(dev_priv, crtc->pipe);
@@ -3193,7 +3193,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	u32 tmp, flags = 0;
 	enum port port = encoder->port;
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
@@ -3228,7 +3228,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 			flags |= DRM_MODE_FLAG_NVSYNC;
 	}
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
 	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
 		pipe_config->limited_color_range = true;
@@ -3245,7 +3245,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
 			pipe_config->port_clock = 270000;
 	}
 
-	pipe_config->base.adjusted_mode.crtc_clock =
+	pipe_config->hw.adjusted_mode.crtc_clock =
 		intel_dotclock_calculate(pipe_config->port_clock,
 					 &pipe_config->dp_m_n);
 
@@ -3460,7 +3460,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	u32 dp_reg = I915_READ(intel_dp->output_reg);
 	enum pipe pipe = crtc->pipe;
 	intel_wakeref_t wakeref;
@@ -3593,7 +3593,7 @@ static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	lockdep_assert_held(&dev_priv->pps_mutex);
 
@@ -4115,7 +4115,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	enum port port = encoder->port;
 	u32 DP = intel_dp->DP;
 
@@ -4876,7 +4876,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
 
 	WARN_ON(!intel_crtc_has_dp_encoder(crtc_state));
 
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return 0;
 
 	if (conn_state->commit &&
@@ -6695,7 +6695,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
 				    int refresh_rate)
 {
 	struct intel_dp *intel_dp = dev_priv->drrs.dp;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
 
 	if (refresh_rate <= 0) {
@@ -6728,7 +6728,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
 		return;
 	}
 
-	if (!crtc_state->base.active) {
+	if (!crtc_state->hw.active) {
 		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index eeeb3f933aa4..76f066b1dfe5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -42,13 +42,13 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 					    struct drm_connector_state *conn_state,
 					    struct link_config_limits *limits)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
 	struct intel_dp *intel_dp = &intel_mst->primary->dp;
 	struct intel_connector *connector =
 		to_intel_connector(conn_state->connector);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	void *port = connector->port;
 	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
 					   DP_DPCD_QUIRK_CONSTANT_N);
@@ -99,7 +99,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
 	struct intel_digital_connector_state *intel_conn_state =
 		to_intel_digital_connector_state(conn_state);
 	const struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 	void *port = connector->port;
 	struct link_config_limits limits;
 	int ret;
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 556d1b30f06a..704f38681c4b 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -739,7 +739,7 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 	u32 val;
 
@@ -783,7 +783,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 	unsigned int lane_mask =
@@ -864,7 +864,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel ch = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 	int data, i, stagger;
@@ -953,7 +953,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
 			      const struct intel_crtc_state *old_crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
 	u32 val;
 
 	vlv_dpio_get(dev_priv);
@@ -1016,7 +1016,7 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 
@@ -1046,7 +1046,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 	u32 val;
@@ -1075,7 +1075,7 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
 {
 	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	enum dpio_channel port = vlv_dport_to_channel(dport);
 	enum pipe pipe = crtc->pipe;
 
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 98288edf88f0..43c12bcfe3b2 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -136,7 +136,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
  */
 void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
 
@@ -163,7 +163,7 @@ void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
  */
 void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
 	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
@@ -208,7 +208,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
  */
 void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
 	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
@@ -825,7 +825,7 @@ hsw_ddi_hdmi_get_dpll(struct intel_atomic_state *state,
 static struct intel_shared_dpll *
 hsw_ddi_dp_get_dpll(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	struct intel_shared_dpll *pll;
 	enum intel_dpll_id pll_id;
 	int clock = crtc_state->port_clock;
@@ -1734,7 +1734,7 @@ static bool
 bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
 			  struct bxt_clk_div *clk_div)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct dpll best_clock;
 
 	/* Calculate HDMI div */
@@ -2257,7 +2257,7 @@ static bool
 cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
 			struct skl_wrpll_params *wrpll_params)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	u32 afe_clock = crtc_state->port_clock * 5;
 	u32 ref_clock;
 	u32 dco_min = 7998000;
@@ -2523,7 +2523,7 @@ static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = {
 static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
 				  struct skl_wrpll_params *pll_params)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	const struct icl_combo_pll_params *params =
 		dev_priv->cdclk.hw.ref == 24000 ?
 		icl_dp_combo_pll_24MHz_values :
@@ -2545,7 +2545,7 @@ static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
 static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
 			     struct skl_wrpll_params *pll_params)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	*pll_params = dev_priv->cdclk.hw.ref == 24000 ?
 			icl_tbt_pll_24MHz_values : icl_tbt_pll_19_2MHz_values;
@@ -2556,7 +2556,7 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
 				struct intel_encoder *encoder,
 				struct intel_dpll_hw_state *pll_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	u32 cfgcr0, cfgcr1;
 	struct skl_wrpll_params pll_params = { 0 };
 	bool ret;
@@ -2682,7 +2682,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
 static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
 				  struct intel_dpll_hw_state *pll_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int refclk_khz = dev_priv->cdclk.hw.ref;
 	int clock = crtc_state->port_clock;
 	u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index 34193d04597a..af0149e32bf4 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -178,9 +178,9 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
 	else
 		flags |= DRM_MODE_FLAG_NVSYNC;
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
-	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
 static void intel_disable_dvo(struct intel_encoder *encoder,
@@ -207,8 +207,8 @@ static void intel_enable_dvo(struct intel_encoder *encoder,
 	u32 temp = I915_READ(dvo_reg);
 
 	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
-					 &pipe_config->base.mode,
-					 &pipe_config->base.adjusted_mode);
+					 &pipe_config->hw.mode,
+					 &pipe_config->hw.adjusted_mode);
 
 	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
 	I915_READ(dvo_reg);
@@ -253,7 +253,7 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder,
 	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
 	const struct drm_display_mode *fixed_mode =
 		intel_dvo->attached_connector->panel.fixed_mode;
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 
 	/*
 	 * If we have timings from the BIOS for the panel, put them in
@@ -277,8 +277,8 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder,
 				 const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
 	enum pipe pipe = crtc->pipe;
 	u32 dvo_val;
diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 3111ecaeabd0..c6cc3775f3b8 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -667,7 +667,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
 	cache->vma = NULL;
 	cache->flags = 0;
 
-	cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
+	cache->crtc.mode_flags = crtc_state->hw.adjusted_mode.flags;
 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
 		cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate;
 
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 14e350f5ecc8..e1dbf641be79 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -279,7 +279,7 @@ static void ibx_write_infoframe(struct intel_encoder *encoder,
 {
 	const u32 *data = frame;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
 	u32 val = I915_READ(reg);
 	int i;
@@ -315,7 +315,7 @@ static void ibx_read_infoframe(struct intel_encoder *encoder,
 			       void *frame, ssize_t len)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	u32 val, *data = frame;
 	int i;
 
@@ -334,7 +334,7 @@ static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
 	i915_reg_t reg = TVIDEO_DIP_CTL(pipe);
 	u32 val = I915_READ(reg);
 
@@ -356,7 +356,7 @@ static void cpt_write_infoframe(struct intel_encoder *encoder,
 {
 	const u32 *data = frame;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
 	u32 val = I915_READ(reg);
 	int i;
@@ -395,7 +395,7 @@ static void cpt_read_infoframe(struct intel_encoder *encoder,
 			       void *frame, ssize_t len)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	u32 val, *data = frame;
 	int i;
 
@@ -414,7 +414,7 @@ static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
 	u32 val = I915_READ(TVIDEO_DIP_CTL(pipe));
 
 	if ((val & VIDEO_DIP_ENABLE) == 0)
@@ -432,7 +432,7 @@ static void vlv_write_infoframe(struct intel_encoder *encoder,
 {
 	const u32 *data = frame;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
 	u32 val = I915_READ(reg);
 	int i;
@@ -468,7 +468,7 @@ static void vlv_read_infoframe(struct intel_encoder *encoder,
 			       void *frame, ssize_t len)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	u32 val, *data = frame;
 	int i;
 
@@ -487,7 +487,7 @@ static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
 	u32 val = I915_READ(VLV_TVIDEO_DIP_CTL(pipe));
 
 	if ((val & VIDEO_DIP_ENABLE) == 0)
@@ -700,7 +700,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
 {
 	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	struct drm_connector *connector = conn_state->connector;
 	int ret;
 
@@ -787,7 +787,7 @@ intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
 
 	ret = drm_hdmi_vendor_infoframe_from_display_mode(frame,
 							  conn_state->connector,
-							  &crtc_state->base.adjusted_mode);
+							  &crtc_state->hw.adjusted_mode);
 	if (WARN_ON(ret))
 		return false;
 
@@ -948,7 +948,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
 					 const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	i915_reg_t reg;
 
 	if ((crtc_state->infoframes.enable &
@@ -973,7 +973,7 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
 				   struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	i915_reg_t reg;
 
 	if ((crtc_state->infoframes.enable &
@@ -1010,7 +1010,7 @@ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
 
 	/* Enable default_phase whenever the display mode is suitably aligned */
 	if (gcp_default_phase_possible(crtc_state->pipe_bpp,
-				       &crtc_state->base.adjusted_mode))
+				       &crtc_state->hw.adjusted_mode))
 		crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE;
 }
 
@@ -1020,7 +1020,7 @@ static void ibx_set_infoframes(struct intel_encoder *encoder,
 			       const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
 	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
 	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
@@ -1079,7 +1079,7 @@ static void cpt_set_infoframes(struct intel_encoder *encoder,
 			       const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
 	u32 val = I915_READ(reg);
@@ -1128,7 +1128,7 @@ static void vlv_set_infoframes(struct intel_encoder *encoder,
 			       const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
 	u32 val = I915_READ(reg);
@@ -1724,9 +1724,9 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	u32 hdmi_val;
 
 	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
@@ -1817,7 +1817,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
 	    tmp & HDMI_COLOR_RANGE_16_235)
 		pipe_config->limited_color_range = true;
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
 	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
 		dotclock = pipe_config->port_clock * 2 / 3;
@@ -1827,7 +1827,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
 	if (pipe_config->pixel_multiplier)
 		dotclock /= pipe_config->pixel_multiplier;
 
-	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
 
 	pipe_config->lane_count = 4;
 
@@ -1848,7 +1848,7 @@ static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
 				    const struct intel_crtc_state *pipe_config,
 				    const struct drm_connector_state *conn_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 
 	WARN_ON(!pipe_config->has_hdmi_sink);
 	DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
@@ -1934,7 +1934,7 @@ static void cpt_enable_hdmi(struct intel_encoder *encoder,
 {
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	enum pipe pipe = crtc->pipe;
 	u32 temp;
@@ -1998,7 +1998,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	struct intel_digital_port *intel_dig_port =
 		hdmi_to_dig_port(intel_hdmi);
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	u32 temp;
 
 	temp = I915_READ(intel_hdmi->hdmi_reg);
@@ -2198,12 +2198,12 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 				     int bpc)
 {
 	struct drm_i915_private *dev_priv =
-		to_i915(crtc_state->base.crtc->dev);
-	struct drm_atomic_state *state = crtc_state->base.state;
+		to_i915(crtc_state->uapi.crtc->dev);
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_connector_state *connector_state;
 	struct drm_connector *connector;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	int i;
 
 	if (HAS_GMCH(dev_priv))
@@ -2228,7 +2228,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
 	for_each_new_connector_in_state(state, connector, connector_state, i) {
 		const struct drm_display_info *info = &connector->display_info;
 
-		if (connector_state->crtc != crtc_state->base.crtc)
+		if (connector_state->crtc != crtc_state->uapi.crtc)
 			continue;
 
 		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
@@ -2269,7 +2269,7 @@ static bool
 intel_hdmi_ycbcr420_config(struct drm_connector *connector,
 			   struct intel_crtc_state *config)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(config->uapi.crtc);
 
 	if (!connector->ycbcr_420_allowed) {
 		DRM_ERROR("Platform doesn't support YCBCR420 output\n");
@@ -2324,7 +2324,7 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
 {
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	int bpc, clock = adjusted_mode->crtc_clock;
 
 	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
@@ -2366,7 +2366,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
 {
 	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	struct drm_connector *connector = conn_state->connector;
 	struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
 	struct intel_digital_connector_state *intel_conn_state =
diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
index f8f1308643a9..5145ff8b962b 100644
--- a/drivers/gpu/drm/i915/display/intel_lspcon.c
+++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
@@ -189,7 +189,7 @@ void lspcon_ycbcr420_config(struct drm_connector *connector,
 {
 	const struct drm_display_info *info = &connector->display_info;
 	const struct drm_display_mode *adjusted_mode =
-					&crtc_state->base.adjusted_mode;
+					&crtc_state->hw.adjusted_mode;
 
 	if (drm_mode_is_420_only(info, adjusted_mode) &&
 	    connector->ycbcr_420_allowed) {
@@ -475,7 +475,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
 	struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
 	struct intel_lspcon *lspcon = &dig_port->lspcon;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 
 	if (!lspcon->active) {
 		DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
index c786abdc3336..0f77e5a8b7ff 100644
--- a/drivers/gpu/drm/i915/display/intel_lvds.c
+++ b/drivers/gpu/drm/i915/display/intel_lvds.c
@@ -135,7 +135,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
 	else
 		flags |= DRM_MODE_FLAG_PVSYNC;
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
 	if (INTEL_GEN(dev_priv) < 5)
 		pipe_config->gmch_pfit.lvds_border_bits =
@@ -148,7 +148,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
 		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
 	}
 
-	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
+	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
 }
 
 static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
@@ -230,8 +230,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
 {
 	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	enum pipe pipe = crtc->pipe;
 	u32 temp;
 
@@ -392,8 +392,8 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
 		to_lvds_encoder(&intel_encoder->base);
 	struct intel_connector *intel_connector =
 		lvds_encoder->attached_connector;
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	unsigned int lvds_bpp;
 
 	/* Should never happen!! */
diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
index bc14e9c0285a..6f3eaae3761f 100644
--- a/drivers/gpu/drm/i915/display/intel_panel.c
+++ b/drivers/gpu/drm/i915/display/intel_panel.c
@@ -178,7 +178,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
 			struct intel_crtc_state *pipe_config,
 			int fitting_mode)
 {
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int x = 0, y = 0, width = 0, height = 0;
 
 	/* Native modes don't need fitting */
@@ -300,7 +300,7 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
 static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
 			      u32 *pfit_control)
 {
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	u32 scaled_width = adjusted_mode->crtc_hdisplay *
 		pipe_config->pipe_src_h;
 	u32 scaled_height = pipe_config->pipe_src_w *
@@ -321,7 +321,7 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
 			      u32 *pfit_control, u32 *pfit_pgm_ratios,
 			      u32 *border)
 {
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	u32 scaled_width = adjusted_mode->crtc_hdisplay *
 		pipe_config->pipe_src_h;
 	u32 scaled_height = pipe_config->pipe_src_w *
@@ -380,7 +380,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
 {
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 
 	/* Native modes don't need fitting */
 	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
@@ -1047,7 +1047,7 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
 	u32 ctl, ctl2;
 
 	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
@@ -1077,7 +1077,7 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
 	u32 pwm_ctl, val;
 
 	/* Controller 1 uses the utility pin. */
@@ -1189,7 +1189,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_panel *panel = &connector->panel;
-	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
 
 	if (!panel->backlight.present)
 		return;
diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
index 6260a2082719..2746512f4466 100644
--- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
@@ -309,13 +309,13 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
 		goto put_state;
 	}
 
-	pipe_config->base.mode_changed = pipe_config->has_psr;
+	pipe_config->uapi.mode_changed = pipe_config->has_psr;
 	pipe_config->crc_enabled = enable;
 
 	if (IS_HASWELL(dev_priv) &&
-	    pipe_config->base.active && crtc->pipe == PIPE_A &&
+	    pipe_config->hw.active && crtc->pipe == PIPE_A &&
 	    pipe_config->cpu_transcoder == TRANSCODER_EDP)
-		pipe_config->base.mode_changed = true;
+		pipe_config->uapi.mode_changed = true;
 
 	ret = drm_atomic_commit(state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index b3c7eef53bf3..8988dbe8c19e 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -538,8 +538,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
 				    struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	int crtc_hdisplay = crtc_state->base.adjusted_mode.crtc_hdisplay;
-	int crtc_vdisplay = crtc_state->base.adjusted_mode.crtc_vdisplay;
+	int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
+	int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
 	int psr_max_h = 0, psr_max_v = 0;
 
 	if (!dev_priv->psr.sink_psr2_support)
@@ -605,7 +605,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	int psr_setup_time;
 
 	if (!CAN_PSR(dev_priv))
@@ -745,7 +745,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
 
 	dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state);
 	dev_priv->psr.busy_frontbuffer_bits = 0;
-	dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
+	dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
 	dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
 
 	/*
@@ -988,7 +988,7 @@ void intel_psr_update(struct intel_dp *intel_dp,
 int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
 			    u32 *out_value)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
 	if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index adeb1c840976..f74c528d5d68 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1087,7 +1087,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo,
 {
 	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	int ret;
 
 	if (!crtc_state->has_hdmi_sink)
@@ -1276,8 +1276,8 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 		to_intel_sdvo_connector_state(conn_state);
 	struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(conn_state->connector);
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
-	struct drm_display_mode *mode = &pipe_config->base.mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+	struct drm_display_mode *mode = &pipe_config->hw.mode;
 
 	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
 	pipe_config->pipe_bpp = 8*3;
@@ -1429,13 +1429,13 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 				  const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
-	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
 	const struct intel_sdvo_connector_state *sdvo_state =
 		to_intel_sdvo_connector_state(conn_state);
 	const struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(conn_state->connector);
-	const struct drm_display_mode *mode = &crtc_state->base.mode;
+	const struct drm_display_mode *mode = &crtc_state->hw.mode;
 	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
@@ -1629,7 +1629,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 			flags |= DRM_MODE_FLAG_NVSYNC;
 	}
 
-	pipe_config->base.adjusted_mode.flags |= flags;
+	pipe_config->hw.adjusted_mode.flags |= flags;
 
 	/*
 	 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
@@ -1649,7 +1649,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
 	if (pipe_config->pixel_multiplier)
 		dotclock /= pipe_config->pixel_multiplier;
 
-	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
+	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
 
 	/* Cross check the port pixel multiplier with the sdvo encoder state. */
 	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
@@ -1701,7 +1701,7 @@ static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo,
 				    const struct drm_connector_state *conn_state)
 {
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	struct drm_connector *connector = conn_state->connector;
 	u8 *eld = connector->eld;
 
@@ -1723,7 +1723,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	u32 temp;
 
 	if (old_crtc_state->has_audio)
@@ -1785,7 +1785,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder,
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	u32 temp;
 	bool input1, input2;
 	int i;
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 7a7078d0ba23..a602e21c5fd5 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -81,9 +81,9 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
  */
 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
 	long timeout = msecs_to_jiffies_timeout(1);
 	int scanline, min, max, vblank_start;
 	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
@@ -190,7 +190,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
  */
 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
 	int scanline_end = intel_get_crtc_scanline(crtc);
 	u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
@@ -203,14 +203,15 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
 	 * Would be slightly nice to just grab the vblank count and arm the
 	 * event outside of the critical section - the spinlock might spin for a
 	 * while ... */
-	if (new_crtc_state->base.event) {
+	if (new_crtc_state->uapi.event) {
 		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
 
 		spin_lock(&crtc->base.dev->event_lock);
-		drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
+		drm_crtc_arm_vblank_event(&crtc->base,
+				          new_crtc_state->uapi.event);
 		spin_unlock(&crtc->base.dev->event_lock);
 
-		new_crtc_state->base.event = NULL;
+		new_crtc_state->uapi.event = NULL;
 	}
 
 	local_irq_enable();
@@ -1515,7 +1516,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
 	const struct drm_rect *dst = &plane_state->base.dst;
 	int src_x, src_w, src_h, crtc_w, crtc_h;
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	unsigned int cpp = fb->format->cpp[0];
 	unsigned int width_bytes;
 	int min_width, min_height;
@@ -1587,7 +1588,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
 	}
 
 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->base,
+						  &crtc_state->uapi,
 						  min_scale, max_scale,
 						  true, true);
 	if (ret)
@@ -1644,7 +1645,7 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
 		return ret;
 
 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->base,
+						  &crtc_state->uapi,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  DRM_PLANE_HELPER_NO_SCALING,
 						  true, true);
@@ -1728,8 +1729,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
 	}
 
 	/* Y-tiling is not supported in IF-ID Interlace mode */
-	if (crtc_state->base.enable &&
-	    crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
+	if (crtc_state->hw.enable &&
+	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
 	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
@@ -1809,7 +1810,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 	}
 
 	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->base,
+						  &crtc_state->uapi,
 						  min_scale, max_scale,
 						  true, true);
 	if (ret)
diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
index b70221f5112a..96a3d9348471 100644
--- a/drivers/gpu/drm/i915/display/intel_tv.c
+++ b/drivers/gpu/drm/i915/display/intel_tv.c
@@ -924,7 +924,7 @@ intel_enable_tv(struct intel_encoder *encoder,
 
 	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
 	intel_wait_for_vblank(dev_priv,
-			      to_intel_crtc(pipe_config->base.crtc)->pipe);
+			      to_intel_crtc(pipe_config->uapi.crtc)->pipe);
 
 	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
 }
@@ -1086,7 +1086,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 	struct drm_display_mode mode = {};
 	u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
 	struct tv_mode tv_mode = {};
@@ -1189,7 +1189,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
 		to_intel_tv_connector_state(conn_state);
 	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
 	struct drm_display_mode *adjusted_mode =
-		&pipe_config->base.adjusted_mode;
+		&pipe_config->hw.adjusted_mode;
 	int hdisplay = adjusted_mode->crtc_hdisplay;
 	int vdisplay = adjusted_mode->crtc_vdisplay;
 
@@ -1418,7 +1418,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder,
 				const struct drm_connector_state *conn_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_tv *intel_tv = enc_to_tv(encoder);
 	const struct intel_tv_connector_state *tv_conn_state =
 		to_intel_tv_connector_state(conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index d4fb7f16f9f6..38c181499505 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -329,8 +329,8 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
 	int column_index = 0;
 	u8 line_buf_depth = 0;
 
-	vdsc_cfg->pic_width = pipe_config->base.adjusted_mode.crtc_hdisplay;
-	vdsc_cfg->pic_height = pipe_config->base.adjusted_mode.crtc_vdisplay;
+	vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
+	vdsc_cfg->pic_height = pipe_config->hw.adjusted_mode.crtc_vdisplay;
 	vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
 					     pipe_config->dsc_params.slice_count);
 	/*
@@ -459,7 +459,7 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
 enum intel_display_power_domain
 intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *i915 = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
 	/*
@@ -483,7 +483,7 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
 						const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
 	enum pipe pipe = crtc->pipe;
@@ -902,7 +902,7 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
 void intel_dsc_enable(struct intel_encoder *encoder,
 		      const struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	enum pipe pipe = crtc->pipe;
 	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
@@ -938,7 +938,7 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 
 void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
index 50064cde0724..16f93d1e71e5 100644
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -261,9 +261,9 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder,
 	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
 						   base);
 	struct intel_connector *intel_connector = intel_dsi->attached_connector;
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
-	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int ret;
 
 	DRM_DEBUG_KMS("\n");
@@ -624,7 +624,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	enum port port;
 
@@ -746,7 +746,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
 				 const struct drm_connector_state *conn_state)
 {
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
-	struct drm_crtc *crtc = pipe_config->base.crtc;
+	struct drm_crtc *crtc = pipe_config->uapi.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum pipe pipe = intel_crtc->pipe;
@@ -1032,9 +1032,9 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
 	struct drm_device *dev = encoder->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct drm_display_mode *adjusted_mode =
-					&pipe_config->base.adjusted_mode;
+					&pipe_config->hw.adjusted_mode;
 	struct drm_display_mode *adjusted_mode_sw;
-	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
 	unsigned int lane_count = intel_dsi->lane_count;
 	unsigned int bpp, fmt;
@@ -1045,7 +1045,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
 				crtc_hblank_start_sw, crtc_hblank_end_sw;
 
 	/* FIXME: hw readout should not depend on SW state */
-	adjusted_mode_sw = &crtc->config->base.adjusted_mode;
+	adjusted_mode_sw = &crtc->config->hw.adjusted_mode;
 
 	/*
 	 * Atleast one port is active as encoder->get_config called only if
@@ -1204,7 +1204,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
 	}
 
 	if (pclk) {
-		pipe_config->base.adjusted_mode.crtc_clock = pclk;
+		pipe_config->hw.adjusted_mode.crtc_clock = pclk;
 		pipe_config->port_clock = pclk;
 	}
 }
@@ -1315,9 +1315,9 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_device *dev = encoder->dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
-	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	enum port port;
 	unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
 	u32 val, tmp;
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 43db50095257..1c4c3972fd23 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2749,11 +2749,11 @@ static int i915_display_info(struct seq_file *m, void *unused)
 
 		seq_printf(m, "CRTC %d: pipe: %c, active=%s, (size=%dx%d), dither=%s, bpp=%d\n",
 			   crtc->base.base.id, pipe_name(crtc->pipe),
-			   yesno(pipe_config->base.active),
+			   yesno(pipe_config->hw.active),
 			   pipe_config->pipe_src_w, pipe_config->pipe_src_h,
 			   yesno(pipe_config->dither), pipe_config->pipe_bpp);
 
-		if (pipe_config->base.active) {
+		if (pipe_config->hw.active) {
 			struct intel_plane *cursor =
 				to_intel_plane(crtc->base.cursor);
 
@@ -4204,11 +4204,11 @@ static int i915_drrs_ctl_set(void *data, u64 val)
 
 		crtc_state = to_intel_crtc_state(crtc->base.state);
 
-		if (!crtc_state->base.active ||
+		if (!crtc_state->hw.active ||
 		    !crtc_state->has_drrs)
 			goto out;
 
-		commit = crtc_state->base.commit;
+		commit = crtc_state->uapi.commit;
 		if (commit) {
 			ret = wait_for_completion_interruptible(&commit->hw_done);
 			if (ret)
@@ -4220,7 +4220,7 @@ static int i915_drrs_ctl_set(void *data, u64 val)
 			struct intel_encoder *encoder;
 			struct intel_dp *intel_dp;
 
-			if (!(crtc_state->base.connector_mask &
+			if (!(crtc_state->uapi.connector_mask &
 			      drm_connector_mask(connector)))
 				continue;
 
@@ -4279,14 +4279,14 @@ i915_fifo_underrun_reset_write(struct file *filp,
 			return ret;
 
 		crtc_state = to_intel_crtc_state(intel_crtc->base.state);
-		commit = crtc_state->base.commit;
+		commit = crtc_state->uapi.commit;
 		if (commit) {
 			ret = wait_for_completion_interruptible(&commit->hw_done);
 			if (!ret)
 				ret = wait_for_completion_interruptible(&commit->flip_done);
 		}
 
-		if (!ret && crtc_state->base.active) {
+		if (!ret && crtc_state->hw.active) {
 			DRM_DEBUG_KMS("Re-arming FIFO underruns on pipe %c\n",
 				      pipe_name(intel_crtc->pipe));
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6aa40f546226..edabf2cf4440 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -484,7 +484,7 @@ static const int pessimal_latency_ns = 5000;
 
 static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
 	enum pipe pipe = crtc->pipe;
@@ -818,7 +818,7 @@ static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 
 	/* FIXME check the 'enable' instead */
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return false;
 
 	/*
@@ -871,7 +871,7 @@ static void pineview_update_wm(struct intel_crtc *unused_crtc)
 	crtc = single_enabled_crtc(dev_priv);
 	if (crtc) {
 		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->base.adjusted_mode;
+			&crtc->config->hw.adjusted_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp = fb->format->cpp[0];
@@ -1107,7 +1107,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
 	unsigned int clock, htotal, cpp, width, wm;
 
@@ -1167,7 +1167,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
 				 int level, enum plane_id plane_id, u16 value)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	bool dirty = false;
 
 	for (; level < intel_wm_num_levels(dev_priv); level++) {
@@ -1183,7 +1183,7 @@ static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
 static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state,
 			       int level, u16 value)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	bool dirty = false;
 
 	/* NORMAL level doesn't have an FBC watermark */
@@ -1285,7 +1285,7 @@ static bool g4x_raw_plane_wm_is_valid(const struct intel_crtc_state *crtc_state,
 static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
 				     int level)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 
 	if (level > dev_priv->wm.max_level)
 		return false;
@@ -1323,9 +1323,9 @@ static void g4x_invalidate_wms(struct intel_crtc *crtc,
 
 static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 	struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
 	int num_active_planes = hweight8(crtc_state->active_planes &
 					 ~BIT(PLANE_CURSOR));
@@ -1412,17 +1412,17 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 
 static int g4x_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate;
 	const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal;
 	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(new_crtc_state->base.state);
+		to_intel_atomic_state(new_crtc_state->uapi.state);
 	const struct intel_crtc_state *old_crtc_state =
 		intel_atomic_get_old_crtc_state(intel_state, crtc);
 	const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal;
 	enum plane_id plane_id;
 
-	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
+	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
 		*intermediate = *optimal;
 
 		intermediate->cxsr = false;
@@ -1554,8 +1554,8 @@ static void g4x_program_watermarks(struct drm_i915_private *dev_priv)
 static void g4x_initial_watermarks(struct intel_atomic_state *state,
 				   struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 	crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate;
@@ -1566,8 +1566,8 @@ static void g4x_initial_watermarks(struct intel_atomic_state *state,
 static void g4x_optimize_watermarks(struct intel_atomic_state *state,
 				    struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	if (!crtc_state->wm.need_postvbl_update)
 		return;
@@ -1616,7 +1616,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	unsigned int clock, htotal, cpp, width, wm;
 
 	if (dev_priv->wm.pri_latency[level] == 0)
@@ -1654,7 +1654,7 @@ static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes)
 
 static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	const struct g4x_pipe_wm *raw =
 		&crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2];
 	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
@@ -1766,7 +1766,7 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
 static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
 				 int level, enum plane_id plane_id, u16 value)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int num_levels = intel_wm_num_levels(dev_priv);
 	bool dirty = false;
 
@@ -1841,16 +1841,16 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
 
 static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_atomic_state *state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
 	const struct vlv_fifo_state *fifo_state =
 		&crtc_state->wm.vlv.fifo_state;
 	int num_active_planes = hweight8(crtc_state->active_planes &
 					 ~BIT(PLANE_CURSOR));
-	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base);
+	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
 	const struct intel_plane_state *old_plane_state;
 	const struct intel_plane_state *new_plane_state;
 	struct intel_plane *plane;
@@ -1949,7 +1949,7 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
 				   struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_uncore *uncore = &dev_priv->uncore;
 	const struct vlv_fifo_state *fifo_state =
@@ -2045,17 +2045,17 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
 
 static int vlv_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate;
 	const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal;
 	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(new_crtc_state->base.state);
+		to_intel_atomic_state(new_crtc_state->uapi.state);
 	const struct intel_crtc_state *old_crtc_state =
 		intel_atomic_get_old_crtc_state(intel_state, crtc);
 	const struct vlv_wm_state *active = &old_crtc_state->wm.vlv.optimal;
 	int level;
 
-	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
+	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
 		*intermediate = *optimal;
 
 		intermediate->cxsr = false;
@@ -2173,8 +2173,8 @@ static void vlv_program_watermarks(struct drm_i915_private *dev_priv)
 static void vlv_initial_watermarks(struct intel_atomic_state *state,
 				   struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 	crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate;
@@ -2185,8 +2185,8 @@ static void vlv_initial_watermarks(struct intel_atomic_state *state,
 static void vlv_optimize_watermarks(struct intel_atomic_state *state,
 				    struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	if (!crtc_state->wm.need_postvbl_update)
 		return;
@@ -2211,7 +2211,7 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
 		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->base.adjusted_mode;
+			&crtc->config->hw.adjusted_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int clock = adjusted_mode->crtc_clock;
@@ -2292,7 +2292,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
 	if (intel_crtc_active(crtc)) {
 		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->base.adjusted_mode;
+			&crtc->config->hw.adjusted_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2319,7 +2319,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
 	if (intel_crtc_active(crtc)) {
 		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->base.adjusted_mode;
+			&crtc->config->hw.adjusted_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2367,7 +2367,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
 		const struct drm_display_mode *adjusted_mode =
-			&enabled->config->base.adjusted_mode;
+			&enabled->config->hw.adjusted_mode;
 		const struct drm_framebuffer *fb =
 			enabled->base.primary->state->fb;
 		int clock = adjusted_mode->crtc_clock;
@@ -2425,7 +2425,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
 	if (crtc == NULL)
 		return;
 
-	adjusted_mode = &crtc->config->base.adjusted_mode;
+	adjusted_mode = &crtc->config->hw.adjusted_mode;
 	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
 				       &i845_wm_info,
 				       dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
@@ -2515,7 +2515,7 @@ static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state,
 		return method1;
 
 	method2 = ilk_wm_method2(crtc_state->pixel_rate,
-				 crtc_state->base.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->base.dst),
 				 cpp, mem_value);
 
@@ -2543,7 +2543,7 @@ static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state,
 
 	method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value);
 	method2 = ilk_wm_method2(crtc_state->pixel_rate,
-				 crtc_state->base.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.adjusted_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->base.dst),
 				 cpp, mem_value);
 	return min(method1, method2);
@@ -2568,7 +2568,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
 	cpp = plane_state->base.fb->format->cpp[0];
 
 	return ilk_wm_method2(crtc_state->pixel_rate,
-			      crtc_state->base.adjusted_mode.crtc_htotal,
+			      crtc_state->hw.adjusted_mode.crtc_htotal,
 			      plane_state->base.crtc_w, cpp, mem_value);
 }
 
@@ -2789,12 +2789,12 @@ static u32
 hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(crtc_state->base.state);
+		to_intel_atomic_state(crtc_state->uapi.state);
 	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->base.adjusted_mode;
+		&crtc_state->hw.adjusted_mode;
 	u32 linetime, ips_linetime;
 
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return 0;
 	if (WARN_ON(adjusted_mode->crtc_clock == 0))
 		return 0;
@@ -3104,11 +3104,9 @@ static bool ilk_validate_pipe_wm(const struct drm_i915_private *dev_priv,
 /* Compute new watermarks for the pipe */
 static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct intel_pipe_wm *pipe_wm;
-	struct drm_device *dev = state->dev;
-	const struct drm_i915_private *dev_priv = to_i915(dev);
 	struct drm_plane *plane;
 	const struct drm_plane_state *plane_state;
 	const struct intel_plane_state *pristate = NULL;
@@ -3119,7 +3117,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 
 	pipe_wm = &crtc_state->wm.ilk.optimal;
 
-	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->base) {
+	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->uapi) {
 		const struct intel_plane_state *ps = to_intel_plane_state(plane_state);
 
 		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
@@ -3130,7 +3128,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 			curstate = ps;
 	}
 
-	pipe_wm->pipe_enabled = crtc_state->base.active;
+	pipe_wm->pipe_enabled = crtc_state->hw.active;
 	if (sprstate) {
 		pipe_wm->sprites_enabled = sprstate->base.visible;
 		pipe_wm->sprites_scaled = sprstate->base.visible &&
@@ -3187,11 +3185,11 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
  */
 static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
 	struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate;
 	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(newstate->base.state);
+		to_intel_atomic_state(newstate->uapi.state);
 	const struct intel_crtc_state *oldstate =
 		intel_atomic_get_old_crtc_state(intel_state, intel_crtc);
 	const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal;
@@ -3203,7 +3201,7 @@ static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
 	 * and after the vblank.
 	 */
 	*a = newstate->wm.ilk.optimal;
-	if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base) ||
+	if (!newstate->hw.active || drm_atomic_crtc_needs_modeset(&newstate->uapi) ||
 	    intel_state->skip_intermediate_wm)
 		return 0;
 
@@ -3780,7 +3778,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
 	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
 	crtc_state = to_intel_crtc_state(crtc->base.state);
 
-	if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
 	for_each_intel_plane_on_crtc(dev, crtc, plane) {
@@ -3830,7 +3828,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 	if (INTEL_GEN(dev_priv) < 11)
 		return ddb_size - 4; /* 4 blocks for bypass path allocation */
 
-	adjusted_mode = &crtc_state->base.adjusted_mode;
+	adjusted_mode = &crtc_state->hw.adjusted_mode;
 	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
 
 	/*
@@ -3859,16 +3857,16 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 				   struct skl_ddb_entry *alloc, /* out */
 				   int *num_active /* out */)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
-	struct drm_crtc *for_crtc = crtc_state->base.crtc;
+	struct drm_crtc *for_crtc = crtc_state->uapi.crtc;
 	const struct intel_crtc *crtc;
 	u32 pipe_width = 0, total_width = 0, width_before_pipe = 0;
 	enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe;
 	u16 ddb_size;
 	u32 i;
 
-	if (WARN_ON(!state) || !crtc_state->base.active) {
+	if (WARN_ON(!state) || !crtc_state->hw.active) {
 		alloc->start = 0;
 		alloc->end = 0;
 		*num_active = hweight8(dev_priv->active_pipes);
@@ -3907,11 +3905,11 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 	 */
 	for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
 		const struct drm_display_mode *adjusted_mode =
-			&crtc_state->base.adjusted_mode;
+			&crtc_state->hw.adjusted_mode;
 		enum pipe pipe = crtc->pipe;
 		int hdisplay, vdisplay;
 
-		if (!crtc_state->base.enable)
+		if (!crtc_state->hw.enable)
 			continue;
 
 		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
@@ -3942,7 +3940,7 @@ static unsigned int
 skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
 		      int num_active)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
 	struct skl_wm_level wm = {};
 	int ret, min_ddb_alloc = 0;
@@ -4111,7 +4109,7 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
 {
 	uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
 
-	if (!crtc_state->base.enable)
+	if (!crtc_state->hw.enable)
 		return pipe_downscale;
 
 	if (crtc_state->pch_pfit.enabled) {
@@ -4143,7 +4141,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
-	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_plane *plane;
 	const struct drm_plane_state *drm_plane_state;
 	int crtc_clock, dotclk;
@@ -4151,10 +4149,10 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 	uint_fixed_16_16_t pipe_downscale;
 	uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
 
-	if (!crtc_state->base.enable)
+	if (!crtc_state->hw.enable)
 		return 0;
 
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
+	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
 		uint_fixed_16_16_t plane_downscale;
 		uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
 		int bpp;
@@ -4179,7 +4177,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 
 	pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
 
-	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
+	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
 	dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
 
 	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
@@ -4246,7 +4244,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate,
 				 u64 *uv_plane_data_rate)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_plane *plane;
 	const struct drm_plane_state *drm_plane_state;
 	u64 total_data_rate = 0;
@@ -4255,7 +4253,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
+	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
 		enum plane_id plane_id = to_intel_plane(plane)->id;
 		const struct intel_plane_state *plane_state =
 			to_intel_plane_state(drm_plane_state);
@@ -4283,11 +4281,11 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 	const struct drm_plane_state *drm_plane_state;
 	u64 total_data_rate = 0;
 
-	if (WARN_ON(!crtc_state->base.state))
+	if (WARN_ON(!crtc_state->uapi.state))
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
+	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
 		const struct intel_plane_state *plane_state =
 			to_intel_plane_state(drm_plane_state);
 		enum plane_id plane_id = to_intel_plane(plane)->id;
@@ -4329,8 +4327,8 @@ static int
 skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
 		      struct skl_ddb_allocation *ddb /* out */)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
-	struct drm_crtc *crtc = crtc_state->base.crtc;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
+	struct drm_crtc *crtc = crtc_state->uapi.crtc;
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct skl_ddb_entry *alloc = &crtc_state->wm.skl.ddb;
@@ -4352,7 +4350,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
 	if (WARN_ON(!state))
 		return 0;
 
-	if (!crtc_state->base.active) {
+	if (!crtc_state->hw.active) {
 		alloc->start = alloc->end = 0;
 		return 0;
 	}
@@ -4594,7 +4592,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
 	u32 crtc_htotal;
 	uint_fixed_16_16_t linetime_us;
 
-	if (!crtc_state->base.active)
+	if (!crtc_state->hw.active)
 		return u32_to_fixed16(0);
 
 	pixel_rate = crtc_state->pixel_rate;
@@ -4602,7 +4600,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
 	if (WARN_ON(pixel_rate == 0))
 		return u32_to_fixed16(0);
 
-	crtc_htotal = crtc_state->base.adjusted_mode.crtc_htotal;
+	crtc_htotal = crtc_state->hw.adjusted_mode.crtc_htotal;
 	linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
 
 	return linetime_us;
@@ -4637,7 +4635,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 		      u32 plane_pixel_rate, struct skl_wm_params *wp,
 		      int color_plane)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 interm_pbpl;
 
@@ -4763,7 +4761,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 				 const struct skl_wm_level *result_prev,
 				 struct skl_wm_level *result /* out */)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	u32 latency = dev_priv->wm.skl_latency[level];
 	uint_fixed_16_16_t method1, method2;
 	uint_fixed_16_16_t selected_result;
@@ -4789,14 +4787,14 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
 	method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate,
 				 wp->cpp, latency, wp->dbuf_block_size);
 	method2 = skl_wm_method2(wp->plane_pixel_rate,
-				 crtc_state->base.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.adjusted_mode.crtc_htotal,
 				 latency,
 				 wp->plane_blocks_per_line);
 
 	if (wp->y_tiled) {
 		selected_result = max_fixed16(method2, wp->y_tile_minimum);
 	} else {
-		if ((wp->cpp * crtc_state->base.adjusted_mode.crtc_htotal /
+		if ((wp->cpp * crtc_state->hw.adjusted_mode.crtc_htotal /
 		     wp->dbuf_block_size < 1) &&
 		     (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
 			selected_result = method2;
@@ -4887,7 +4885,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 		      const struct skl_wm_params *wm_params,
 		      struct skl_wm_level *levels)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	int level, max_level = ilk_wm_max_level(dev_priv);
 	struct skl_wm_level *result_prev = &levels[0];
 
@@ -4904,7 +4902,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
 static u32
 skl_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 {
-	struct drm_atomic_state *state = crtc_state->base.state;
+	struct drm_atomic_state *state = crtc_state->uapi.state;
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
 	uint_fixed_16_16_t linetime_us;
 	u32 linetime_wm;
@@ -4923,7 +4921,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 				      const struct skl_wm_params *wp,
 				      struct skl_plane_wm *wm)
 {
-	struct drm_device *dev = crtc_state->base.crtc->dev;
+	struct drm_device *dev = crtc_state->uapi.crtc->dev;
 	const struct drm_i915_private *dev_priv = to_i915(dev);
 	u16 trans_min, trans_y_tile_min;
 	const u16 trans_amount = 10; /* This is configurable amount */
@@ -5083,7 +5081,7 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 
 static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
 	struct drm_plane *plane;
 	const struct drm_plane_state *drm_plane_state;
@@ -5096,7 +5094,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
 
 	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state,
-						   &crtc_state->base) {
+						   &crtc_state->uapi) {
 		const struct intel_plane_state *plane_state =
 			to_intel_plane_state(drm_plane_state);
 
@@ -5275,8 +5273,8 @@ static int
 skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
 			    struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
-	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
+	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	struct intel_plane *plane;
 
@@ -5576,7 +5574,7 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
 		 * power well the hardware state will go out of sync
 		 * with the software state.
 		 */
-		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) &&
+		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
 		    skl_plane_wm_equals(dev_priv,
 					&old_crtc_state->wm.skl.optimal.planes[plane_id],
 					&new_crtc_state->wm.skl.optimal.planes[plane_id]))
@@ -5643,7 +5641,7 @@ skl_compute_wm(struct intel_atomic_state *state)
 static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
 				      struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
 	enum pipe pipe = crtc->pipe;
@@ -5657,7 +5655,7 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
 static void skl_initial_wm(struct intel_atomic_state *state,
 			   struct intel_crtc_state *crtc_state)
 {
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = intel_crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct skl_ddb_values *results = &state->wm_results;
@@ -5667,7 +5665,7 @@ static void skl_initial_wm(struct intel_atomic_state *state,
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 
-	if (crtc_state->base.active_changed)
+	if (crtc_state->uapi.active_changed)
 		skl_atomic_update_crtc_wm(state, crtc_state);
 
 	mutex_unlock(&dev_priv->wm.wm_mutex);
@@ -5726,8 +5724,8 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
 static void ilk_initial_watermarks(struct intel_atomic_state *state,
 				   struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	mutex_lock(&dev_priv->wm.wm_mutex);
 	crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate;
@@ -5738,8 +5736,8 @@ static void ilk_initial_watermarks(struct intel_atomic_state *state,
 static void ilk_optimize_watermarks(struct intel_atomic_state *state,
 				    struct intel_crtc_state *crtc_state)
 {
-	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	if (!crtc_state->wm.need_postvbl_update)
 		return;
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-24 23:40   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 05/23] drm/i915: Complete sw/hw split Maarten Lankhorst
                   ` (25 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

We are still looking at drm_crtc_state in a few places, convert those
to use intel_crtc_state instead. Look at uapi/hw where appropriate.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 14 +++++++-------
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  2 +-
 drivers/gpu/drm/i915/display/intel_psr.c     |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 6818cbd00ac2..32bbb5bf48f3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -16081,8 +16081,8 @@ static int intel_initial_commit(struct drm_device *dev)
 {
 	struct drm_atomic_state *state = NULL;
 	struct drm_modeset_acquire_ctx ctx;
-	struct drm_crtc *crtc;
-	struct drm_crtc_state *crtc_state;
+	struct intel_crtc *crtc;
+	struct intel_crtc_state *crtc_state;
 	int ret = 0;
 
 	state = drm_atomic_state_alloc(dev);
@@ -16094,15 +16094,15 @@ static int intel_initial_commit(struct drm_device *dev)
 retry:
 	state->acquire_ctx = &ctx;
 
-	drm_for_each_crtc(crtc, dev) {
-		crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	for_each_intel_crtc(dev, crtc) {
+		crtc_state = intel_atomic_get_crtc_state(state, crtc);
 		if (IS_ERR(crtc_state)) {
 			ret = PTR_ERR(crtc_state);
 			goto out;
 		}
 
-		if (crtc_state->active) {
-			ret = drm_atomic_add_affected_planes(state, crtc);
+		if (crtc_state->hw.active) {
+			ret = drm_atomic_add_affected_planes(state, &crtc->base);
 			if (ret)
 				goto out;
 
@@ -16112,7 +16112,7 @@ static int intel_initial_commit(struct drm_device *dev)
 			 * having a proper LUT loaded. Remove once we
 			 * have readout for pipe gamma enable.
 			 */
-			crtc_state->color_mgmt_changed = true;
+			crtc_state->uapi.color_mgmt_changed = true;
 		}
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 76f066b1dfe5..5127ec037b7b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -187,7 +187,7 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
 
 		if (!crtc_state ||
 		    !drm_atomic_crtc_needs_modeset(crtc_state) ||
-		    crtc_state->enable)
+		    to_intel_crtc_state(crtc_state)->hw.enable)
 			return 0;
 	}
 
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 8988dbe8c19e..979e166f5639 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1068,9 +1068,9 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
 
 		intel_crtc_state = to_intel_crtc_state(crtc_state);
 
-		if (crtc_state->active && intel_crtc_state->has_psr) {
+		if (intel_crtc_state->hw.active && intel_crtc_state->has_psr) {
 			/* Mark mode as changed to trigger a pipe->update() */
-			crtc_state->mode_changed = true;
+			intel_crtc_state->uapi.mode_changed = true;
 			break;
 		}
 	}
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (2 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-24 23:41   ` Matt Roper
  2019-09-25 13:01   ` Ville Syrjälä
  2019-09-20 11:42 ` [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed Maarten Lankhorst
                   ` (24 subsequent siblings)
  28 siblings, 2 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Now that we separated everything into uapi and hw, it's
time to make the split definitive. Remove the union and
make a copy of the hw state on modeset and fastset.

Color blobs are copied in crtc atomic_check(), right
before color management is checked.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
 drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
 .../drm/i915/display/intel_display_types.h    |  8 ++--
 4 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index f4440ede95c5..fb550d3cea7f 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 
 	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
 
+	/* copy color blobs */
+	if (crtc_state->hw.degamma_lut)
+		drm_property_blob_get(crtc_state->hw.degamma_lut);
+	if (crtc_state->hw.ctm)
+		drm_property_blob_get(crtc_state->hw.ctm);
+	if (crtc_state->hw.gamma_lut)
+		drm_property_blob_get(crtc_state->hw.gamma_lut);
+
 	crtc_state->update_pipe = false;
 	crtc_state->disable_lp_wm = false;
 	crtc_state->disable_cxsr = false;
@@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	return &crtc_state->uapi;
 }
 
+static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
+{
+	drm_property_blob_put(crtc_state->hw.degamma_lut);
+	drm_property_blob_put(crtc_state->hw.gamma_lut);
+	drm_property_blob_put(crtc_state->hw.ctm);
+}
+
+void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
+{
+	intel_crtc_put_color_blobs(crtc_state);
+}
+
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
+{
+	intel_crtc_put_color_blobs(crtc_state);
+
+	if (crtc_state->uapi.degamma_lut)
+		crtc_state->hw.degamma_lut =
+			drm_property_blob_get(crtc_state->uapi.degamma_lut);
+	else
+		crtc_state->hw.degamma_lut = NULL;
+
+	if (crtc_state->uapi.gamma_lut)
+		crtc_state->hw.gamma_lut =
+			drm_property_blob_get(crtc_state->uapi.gamma_lut);
+	else
+		crtc_state->hw.gamma_lut = NULL;
+
+	if (crtc_state->uapi.ctm)
+		crtc_state->hw.ctm =
+			drm_property_blob_get(crtc_state->uapi.ctm);
+	else
+		crtc_state->hw.ctm = NULL;
+}
+
 /**
  * intel_crtc_destroy_state - destroy crtc state
  * @crtc: drm crtc
@@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
 	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
 
 	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
+	intel_crtc_free_hw_state(crtc_state);
 	kfree(crtc_state);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 58065d3161a3..42be91e0772a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
 struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
+void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
 struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
 void intel_atomic_state_clear(struct drm_atomic_state *state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 32bbb5bf48f3..e40485a1e503 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
+static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
 static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 				struct intel_crtc_state *pipe_config);
 static void ironlake_pch_clock_get(struct intel_crtc *crtc,
@@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
 	crtc->enabled = false;
 	crtc->state->connector_mask = 0;
 	crtc->state->encoder_mask = 0;
+	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
 
 	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
 		encoder->base.crtc = NULL;
@@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 
 	if (mode_changed || crtc_state->update_pipe ||
 	    crtc_state->uapi.color_mgmt_changed) {
+		/* Copy color blobs to hw state */
+		intel_crtc_copy_color_blobs(crtc_state);
+
 		ret = intel_color_check(crtc_state);
 		if (ret)
 			return ret;
@@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
 	return ret;
 }
 
+static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
+{
+	crtc_state->hw.enable = crtc_state->uapi.enable;
+	crtc_state->hw.active = crtc_state->uapi.active;
+	crtc_state->hw.mode = crtc_state->uapi.mode;
+	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
+}
+
+static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
+{
+	crtc_state->uapi.enable = crtc_state->hw.enable;
+	crtc_state->uapi.active = crtc_state->hw.active;
+	crtc_state->uapi.mode = crtc_state->hw.mode;
+	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
+}
+
 static int
 clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 {
@@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	 * fixed, so that the crtc_state can be safely duplicated. For now,
 	 * only fields that are know to not cause problems are preserved. */
 
+	saved_state->uapi = crtc_state->uapi;
 	saved_state->scaler_state = crtc_state->scaler_state;
 	saved_state->shared_dpll = crtc_state->shared_dpll;
 	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
@@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
 	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
 		saved_state->wm = crtc_state->wm;
 
-	/* Keep base drm_crtc_state intact, only clear our extended struct */
-	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
-	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
-	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
-	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
+	intel_crtc_free_hw_state(crtc_state);
+	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
+	copy_uapi_to_hw_state(crtc_state);
 
 	kfree(saved_state);
 	return 0;
@@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
 		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
+	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
+	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
+
 	return 0;
 }
 
@@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
 
 	state = old_crtc_state->uapi.state;
 	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
+	intel_crtc_free_hw_state(old_crtc_state);
+
 	pipe_config = old_crtc_state;
 	memset(pipe_config, 0, sizeof(*pipe_config));
 	pipe_config->uapi.crtc = &crtc->base;
@@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
 
 		if (!new_crtc_state->uapi.enable) {
 			any_ms = true;
+			clear_intel_crtc_state(new_crtc_state);
 			continue;
 		}
 
@@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			to_intel_crtc_state(crtc->base.state);
 
 		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
+		intel_crtc_free_hw_state(crtc_state);
 		memset(crtc_state, 0, sizeof(*crtc_state));
 		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
 
@@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
 			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
 						    crtc_state);
+			crtc_state->hw.mode = crtc->base.mode;
 			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 
 			/*
@@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 
 		intel_bw_crtc_update(bw_state, crtc_state);
 
+		copy_hw_to_uapi_state(crtc_state);
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
 	}
 }
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 2c3567081e16..e81b785cc8f2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -749,7 +749,6 @@ enum intel_output_format {
 };
 
 struct intel_crtc_state {
-	union {
 	/*
 	 * uapi (drm) state. This is the software state shown to userspace.
 	 * In particular, the following members are used for bookkeeping:
@@ -772,8 +771,11 @@ struct intel_crtc_state {
 	 *
 	 * During initial hw readout, they need to be copied to uapi.
 	 */
-	struct drm_crtc_state hw;
-	};
+	struct {
+		bool active, enable;
+		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
+		struct drm_display_mode mode, adjusted_mode;
+	} hw;
 
 	/**
 	 * quirks - bitfield with hw state readout quirks
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (3 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 05/23] drm/i915: Complete sw/hw split Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-24 23:44   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit Maarten Lankhorst
                   ` (23 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

We had this as an optimization to not do a plane update, but we killed
it off because there are so many reasons we may have to do a plane
update or fastset that it's best to just assume everything changed.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c        |  1 -
 drivers/gpu/drm/i915/display/intel_display.c       | 10 +---------
 drivers/gpu/drm/i915/display/intel_display_types.h |  1 -
 3 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index fb550d3cea7f..4b4eee9c49f5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -208,7 +208,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	crtc_state->disable_cxsr = false;
 	crtc_state->update_wm_pre = false;
 	crtc_state->update_wm_post = false;
-	crtc_state->fb_changed = false;
 	crtc_state->fifo_changed = false;
 	crtc_state->wm.need_postvbl_update = false;
 	crtc_state->fb_bits = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index e40485a1e503..520c66071e67 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -11521,7 +11521,6 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 	bool was_crtc_enabled = old_crtc_state->hw.active;
 	bool is_crtc_enabled = crtc_state->hw.active;
 	bool turn_off, turn_on, visible, was_visible;
-	struct drm_framebuffer *fb = plane_state->base.fb;
 	int ret;
 
 	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
@@ -11555,18 +11554,11 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 	if (!was_visible && !visible)
 		return 0;
 
-	if (fb != old_plane_state->base.fb)
-		crtc_state->fb_changed = true;
-
 	turn_off = was_visible && (!visible || mode_changed);
 	turn_on = visible && (!was_visible || mode_changed);
 
-	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] has [PLANE:%d:%s] with fb %i\n",
+	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
 			 crtc->base.base.id, crtc->base.name,
-			 plane->base.base.id, plane->base.name,
-			 fb ? fb->base.id : -1);
-
-	DRM_DEBUG_ATOMIC("[PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
 			 plane->base.base.id, plane->base.name,
 			 was_visible, visible,
 			 turn_off, turn_on, mode_changed);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index e81b785cc8f2..57dbcfc126df 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -792,7 +792,6 @@ struct intel_crtc_state {
 	bool update_pipe; /* can a fast modeset be performed? */
 	bool disable_cxsr;
 	bool update_wm_pre, update_wm_post; /* watermarks are updated */
-	bool fb_changed; /* fb on any of the planes is changed */
 	bool fifo_changed; /* FIFO split is changed */
 
 	/* Pipe source size (ie. panel fitter input size)
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (4 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-25  4:17   ` Matt Roper
  2019-09-25 22:14   ` Manasi Navare
  2019-09-20 11:42 ` [PATCH 08/23] drm/i915: Rename planar linked plane variables Maarten Lankhorst
                   ` (22 subsequent siblings)
  28 siblings, 2 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

This can all be done from the intel_update_crtc function. Split out the
pipe update into a separate function, just like is done for the planes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 124 ++++++++-----------
 1 file changed, 52 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 520c66071e67..fd8b398733b8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -136,8 +136,6 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
 static void chv_prepare_pll(struct intel_crtc *crtc,
 			    const struct intel_crtc_state *pipe_config);
-static void intel_begin_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
-static void intel_finish_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
 static void intel_crtc_init_scalers(struct intel_crtc *crtc,
 				    struct intel_crtc_state *crtc_state);
 static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state);
@@ -13673,13 +13671,54 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
 	return crtc->base.funcs->get_vblank_counter(&crtc->base);
 }
 
+void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
+				  struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+	if (!IS_GEN(dev_priv, 2))
+		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
+
+	if (crtc_state->has_pch_encoder) {
+		enum pipe pch_transcoder =
+			intel_crtc_pch_transcoder(crtc);
+
+		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
+	}
+}
+
+static void commit_pipe_config(struct intel_atomic_state *state,
+			       struct intel_crtc_state *old_crtc_state,
+			       struct intel_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	bool modeset = needs_modeset(new_crtc_state);
+
+	if (!modeset) {
+		if (new_crtc_state->uapi.color_mgmt_changed ||
+		    new_crtc_state->update_pipe)
+			intel_color_commit(new_crtc_state);
+
+		if (new_crtc_state->update_pipe)
+			intel_update_pipe_config(old_crtc_state, new_crtc_state);
+		else if (INTEL_GEN(dev_priv) >= 9)
+			skl_detach_scalers(new_crtc_state);
+
+		if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+			bdw_set_pipemisc(new_crtc_state);
+	}
+
+	if (dev_priv->display.atomic_update_watermarks)
+		dev_priv->display.atomic_update_watermarks(state,
+							   new_crtc_state);
+}
+
 static void intel_update_crtc(struct intel_crtc *crtc,
 			      struct intel_atomic_state *state,
 			      struct intel_crtc_state *old_crtc_state,
 			      struct intel_crtc_state *new_crtc_state)
 {
-	struct drm_device *dev = state->base.dev;
-	struct drm_i915_private *dev_priv = to_i915(dev);
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	bool modeset = needs_modeset(new_crtc_state);
 	struct intel_plane_state *new_plane_state =
 		intel_atomic_get_new_plane_state(state,
@@ -13703,14 +13742,21 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 	else if (new_plane_state)
 		intel_fbc_enable(crtc, new_crtc_state, new_plane_state);
 
-	intel_begin_crtc_commit(state, crtc);
+	/* Perform vblank evasion around commit operation */
+	intel_pipe_update_start(new_crtc_state);
+
+	commit_pipe_config(state, old_crtc_state, new_crtc_state);
 
 	if (INTEL_GEN(dev_priv) >= 9)
 		skl_update_planes_on_crtc(state, crtc);
 	else
 		i9xx_update_planes_on_crtc(state, crtc);
 
-	intel_finish_crtc_commit(state, crtc);
+	intel_pipe_update_end(new_crtc_state);
+
+	if (new_crtc_state->update_pipe && !modeset &&
+	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
 static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
@@ -14507,72 +14553,6 @@ skl_max_scale(const struct intel_crtc_state *crtc_state,
 	return max_scale;
 }
 
-static void intel_begin_crtc_commit(struct intel_atomic_state *state,
-				    struct intel_crtc *crtc)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_crtc_state *old_crtc_state =
-		intel_atomic_get_old_crtc_state(state, crtc);
-	struct intel_crtc_state *new_crtc_state =
-		intel_atomic_get_new_crtc_state(state, crtc);
-	bool modeset = needs_modeset(new_crtc_state);
-
-	/* Perform vblank evasion around commit operation */
-	intel_pipe_update_start(new_crtc_state);
-
-	if (modeset)
-		goto out;
-
-	if (new_crtc_state->uapi.color_mgmt_changed ||
-	    new_crtc_state->update_pipe)
-		intel_color_commit(new_crtc_state);
-
-	if (new_crtc_state->update_pipe)
-		intel_update_pipe_config(old_crtc_state, new_crtc_state);
-	else if (INTEL_GEN(dev_priv) >= 9)
-		skl_detach_scalers(new_crtc_state);
-
-	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-		bdw_set_pipemisc(new_crtc_state);
-
-out:
-	if (dev_priv->display.atomic_update_watermarks)
-		dev_priv->display.atomic_update_watermarks(state,
-							   new_crtc_state);
-}
-
-void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
-				  struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-
-	if (!IS_GEN(dev_priv, 2))
-		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
-
-	if (crtc_state->has_pch_encoder) {
-		enum pipe pch_transcoder =
-			intel_crtc_pch_transcoder(crtc);
-
-		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
-	}
-}
-
-static void intel_finish_crtc_commit(struct intel_atomic_state *state,
-				     struct intel_crtc *crtc)
-{
-	struct intel_crtc_state *old_crtc_state =
-		intel_atomic_get_old_crtc_state(state, crtc);
-	struct intel_crtc_state *new_crtc_state =
-		intel_atomic_get_new_crtc_state(state, crtc);
-
-	intel_pipe_update_end(new_crtc_state);
-
-	if (new_crtc_state->update_pipe &&
-	    !needs_modeset(new_crtc_state) &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
-		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
-}
-
 /**
  * intel_plane_destroy - destroy a plane
  * @plane: plane to destroy
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 08/23] drm/i915: Rename planar linked plane variables
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (5 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-25  4:30   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+ Maarten Lankhorst
                   ` (21 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Rename linked_plane to planar_linked_plane and slave to planar_slave,
this will make it easier to keep apart bigjoiner linking and planar plane
linking.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |  7 ++++--
 .../gpu/drm/i915/display/intel_atomic_plane.c |  4 ++--
 drivers/gpu/drm/i915/display/intel_display.c  | 22 +++++++++----------
 .../drm/i915/display/intel_display_types.h    |  8 +++----
 drivers/gpu/drm/i915/display/intel_sprite.c   |  4 ++--
 drivers/gpu/drm/i915/intel_pm.c               | 12 +++++-----
 6 files changed, 30 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 4b4eee9c49f5..158594e64bb9 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -311,10 +311,13 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
 			 */
 			mode = PS_SCALER_MODE_NORMAL;
 		} else {
+			struct intel_plane *linked =
+				plane_state->planar_linked_plane;
+
 			mode = PS_SCALER_MODE_PLANAR;
 
-			if (plane_state->linked_plane)
-				mode |= PS_PLANE_Y_SEL(plane_state->linked_plane->id);
+			if (linked)
+				mode |= PS_PLANE_Y_SEL(linked->id);
 		}
 	} else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) {
 		mode = PS_SCALER_MODE_NORMAL;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 1f50b15ec704..a1a34b9981cc 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -321,9 +321,9 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
 
 		if (new_plane_state->base.visible) {
 			intel_update_plane(plane, new_crtc_state, new_plane_state);
-		} else if (new_plane_state->slave) {
+		} else if (new_plane_state->planar_slave) {
 			struct intel_plane *master =
-				new_plane_state->linked_plane;
+				new_plane_state->planar_linked_plane;
 
 			/*
 			 * We update the slave plane from this function because
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index fd8b398733b8..ba52a70840fd 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -11666,7 +11666,7 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
 	int i;
 
 	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
-		linked = plane_state->linked_plane;
+		linked = plane_state->planar_linked_plane;
 
 		if (!linked)
 			continue;
@@ -11675,8 +11675,8 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
 		if (IS_ERR(linked_plane_state))
 			return PTR_ERR(linked_plane_state);
 
-		WARN_ON(linked_plane_state->linked_plane != plane);
-		WARN_ON(linked_plane_state->slave == plane_state->slave);
+		WARN_ON(linked_plane_state->planar_linked_plane != plane);
+		WARN_ON(linked_plane_state->planar_slave == plane_state->planar_slave);
 	}
 
 	return 0;
@@ -11699,16 +11699,16 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 	 * in the crtc_state->active_planes mask.
 	 */
 	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
-		if (plane->pipe != crtc->pipe || !plane_state->linked_plane)
+		if (plane->pipe != crtc->pipe || !plane_state->planar_linked_plane)
 			continue;
 
-		plane_state->linked_plane = NULL;
-		if (plane_state->slave && !plane_state->base.visible) {
+		plane_state->planar_linked_plane = NULL;
+		if (plane_state->planar_slave && !plane_state->base.visible) {
 			crtc_state->active_planes &= ~BIT(plane->id);
 			crtc_state->update_planes |= BIT(plane->id);
 		}
 
-		plane_state->slave = false;
+		plane_state->planar_slave = false;
 	}
 
 	if (!crtc_state->nv12_planes)
@@ -11742,10 +11742,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 			return -EINVAL;
 		}
 
-		plane_state->linked_plane = linked;
+		plane_state->planar_linked_plane = linked;
 
-		linked_state->slave = true;
-		linked_state->linked_plane = plane;
+		linked_state->planar_slave = true;
+		linked_state->planar_linked_plane = plane;
 		crtc_state->active_planes |= BIT(linked->id);
 		crtc_state->update_planes |= BIT(linked->id);
 		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
@@ -13221,7 +13221,7 @@ intel_verify_planes(struct intel_atomic_state *state)
 
 	for_each_new_intel_plane_in_state(state, plane,
 					  plane_state, i)
-		assert_plane(plane, plane_state->slave ||
+		assert_plane(plane, plane_state->planar_slave ||
 			     plane_state->base.visible);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 57dbcfc126df..394f84e5d583 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -559,24 +559,24 @@ struct intel_plane_state {
 	int scaler_id;
 
 	/*
-	 * linked_plane:
+	 * planar_linked_plane:
 	 *
 	 * ICL planar formats require 2 planes that are updated as pairs.
 	 * This member is used to make sure the other plane is also updated
 	 * when required, and for update_slave() to find the correct
 	 * plane_state to pass as argument.
 	 */
-	struct intel_plane *linked_plane;
+	struct intel_plane *planar_linked_plane;
 
 	/*
-	 * slave:
+	 * planar_slave:
 	 * If set don't update use the linked plane's state for updating
 	 * this plane during atomic commit with the update_slave() callback.
 	 *
 	 * It's also used by the watermark code to ignore wm calculations on
 	 * this plane. They're calculated by the linked plane's wm code.
 	 */
-	u32 slave;
+	u32 planar_slave;
 
 	struct drm_intel_sprite_colorkey ckey;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index a602e21c5fd5..f0956fecdea4 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -543,7 +543,7 @@ skl_program_plane(struct intel_plane *plane,
 	u32 y = plane_state->color_plane[color_plane].y;
 	u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
 	u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
-	struct intel_plane *linked = plane_state->linked_plane;
+	struct intel_plane *linked = plane_state->planar_linked_plane;
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	u8 alpha = plane_state->base.alpha >> 8;
 	u32 plane_color_ctl = 0;
@@ -642,7 +642,7 @@ skl_update_plane(struct intel_plane *plane,
 {
 	int color_plane = 0;
 
-	if (plane_state->linked_plane) {
+	if (plane_state->planar_linked_plane) {
 		/* Program the UV plane */
 		color_plane = 1;
 	}
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index edabf2cf4440..acc87b8431f3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4291,7 +4291,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		enum plane_id plane_id = to_intel_plane(plane)->id;
 		u64 rate;
 
-		if (!plane_state->linked_plane) {
+		if (!plane_state->planar_linked_plane) {
 			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
@@ -4305,12 +4305,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 			 * NULL if we try get_new_plane_state(), so we
 			 * always calculate from the master.
 			 */
-			if (plane_state->slave)
+			if (plane_state->planar_slave)
 				continue;
 
 			/* Y plane rate is calculated on the slave */
 			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
-			y_plane_id = plane_state->linked_plane->id;
+			y_plane_id = plane_state->planar_linked_plane->id;
 			plane_data_rate[y_plane_id] = rate;
 			total_data_rate += rate;
 
@@ -5049,12 +5049,12 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 	int ret;
 
 	/* Watermarks calculated in master */
-	if (plane_state->slave)
+	if (plane_state->planar_slave)
 		return 0;
 
-	if (plane_state->linked_plane) {
+	if (plane_state->planar_linked_plane) {
 		const struct drm_framebuffer *fb = plane_state->base.fb;
-		enum plane_id y_plane_id = plane_state->linked_plane->id;
+		enum plane_id y_plane_id = plane_state->planar_linked_plane->id;
 
 		WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state));
 		WARN_ON(!fb->format->is_yuv ||
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (6 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 08/23] drm/i915: Rename planar linked plane variables Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-25  4:55   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid() Maarten Lankhorst
                   ` (20 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

We cannot switch between HQ and normal mode on GLK+, so only
add planes on platforms where it makes sense.

We could probably restrict it even more to only add when scaler
users toggles between 1 and 2, but lets just leave it for now.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 158594e64bb9..c50e0b218bd6 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -421,6 +421,11 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
 			 */
 			if (!plane) {
 				struct drm_plane_state *state;
+
+				/* No need to reprogram, we're not changing scaling mode */
+				if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+					continue;
+
 				plane = drm_plane_from_index(&dev_priv->drm, i);
 				state = drm_atomic_get_plane_state(drm_state, plane);
 				if (IS_ERR(state)) {
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (7 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+ Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-25  5:30   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check Maarten Lankhorst
                   ` (19 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Small changes to intel_dp_mode_valid(), allow listing modes that
can only be supported in the bigjoiner configuration, which is
not supported yet.

Also unexport a few functions only used internally in intel_dp.c

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 98 +++++++++++++++++++------
 1 file changed, 75 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 2fceb71f7f70..046e1662d1e3 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -247,7 +247,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 }
 
 static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
+intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
 {
 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
 	struct intel_encoder *encoder = &intel_dig_port->base;
@@ -257,6 +257,9 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
 
 	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
 
+	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11)
+		max_dotclk *= 2;
+
 	if (type != DP_DS_PORT_TYPE_VGA)
 		return max_dotclk;
 
@@ -505,8 +508,10 @@ u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
 		       1000000U);
 }
 
-static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
-				       u32 mode_clock, u32 mode_hdisplay)
+static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *dev_priv,
+				       u32 link_clock, u32 lane_count,
+				       u32 mode_clock, u32 mode_hdisplay,
+				       bool bigjoiner)
 {
 	u32 bits_per_pixel, max_bpp_small_joiner_ram;
 	int i;
@@ -523,6 +528,10 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
 
 	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
 	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+
+	if (bigjoiner)
+		max_bpp_small_joiner_ram *= 2;
+
 	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
 
 	/*
@@ -531,6 +540,15 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
 	 */
 	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
 
+	if (bigjoiner) {
+		u32 max_bpp_bigjoiner =
+			dev_priv->max_cdclk_freq * 48 /
+			intel_dp_mode_to_fec_clock(mode_clock);
+
+		DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
+		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
+	}
+
 	/* Error out if the max bpp is less than smallest allowed valid bpp */
 	if (bits_per_pixel < valid_dsc_bpp[0]) {
 		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
@@ -553,7 +571,8 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
 }
 
 static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-				       int mode_clock, int mode_hdisplay)
+				       int mode_clock, int mode_hdisplay,
+				       bool bigjoiner)
 {
 	u8 min_slice_count, i;
 	int max_slice_width;
@@ -578,12 +597,20 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
 
 	/* Find the closest match to the valid slice count values */
 	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-		if (valid_dsc_slicecount[i] >
-		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-						    false))
+		u8 test_slice_count = bigjoiner ?
+			2 * valid_dsc_slicecount[i] :
+			valid_dsc_slicecount[i];
+
+		if (test_slice_count >
+		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
 			break;
-		if (min_slice_count  <= valid_dsc_slicecount[i])
-			return valid_dsc_slicecount[i];
+
+		/* big joiner needs small joiner to be enabled */
+		if (bigjoiner && test_slice_count < 4)
+			continue;
+
+		if (min_slice_count <= test_slice_count)
+			return test_slice_count;
 	}
 
 	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
@@ -603,11 +630,15 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	int max_dotclk;
 	u16 dsc_max_output_bpp = 0;
 	u8 dsc_slice_count = 0;
+	bool dsc = false, bigjoiner = false;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
 
-	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_H_ILLEGAL;
+
+	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, false);
 
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
@@ -619,6 +650,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
 		target_clock = fixed_mode->clock;
 	}
 
+	if (mode->clock < 10000)
+		return MODE_CLOCK_LOW;
+
+	if (target_clock > max_dotclk) {
+		max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, true);
+
+		if (target_clock > max_dotclk)
+			return MODE_CLOCK_HIGH;
+
+		bigjoiner = true;
+	}
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -639,26 +682,32 @@ intel_dp_mode_valid(struct drm_connector *connector,
 								true);
 		} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
 			dsc_max_output_bpp =
-				intel_dp_dsc_get_output_bpp(max_link_clock,
+				intel_dp_dsc_get_output_bpp(dev_priv,
+							    max_link_clock,
 							    max_lanes,
 							    target_clock,
-							    mode->hdisplay) >> 4;
+							    mode->hdisplay,
+							    bigjoiner) >> 4;
 			dsc_slice_count =
 				intel_dp_dsc_get_slice_count(intel_dp,
 							     target_clock,
-							     mode->hdisplay);
+							     mode->hdisplay,
+							     bigjoiner);
 		}
+
+		dsc = dsc_max_output_bpp && dsc_slice_count;
 	}
 
-	if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
-	    target_clock > max_dotclk)
+	/* big joiner configuration needs DSC */
+	if (bigjoiner && !dsc) {
+		DRM_DEBUG_KMS("Link clock needs bigjoiner, but DSC or FEC not available\n");
 		return MODE_CLOCK_HIGH;
+	}
 
-	if (mode->clock < 10000)
-		return MODE_CLOCK_LOW;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		return MODE_H_ILLEGAL;
+	if (mode_rate > max_rate && !dsc) {
+		DRM_DEBUG_KMS("Cannot drive without DSC\n");
+		return MODE_CLOCK_HIGH;
+	}
 
 	return intel_mode_valid_max_plane_size(dev_priv, mode);
 }
@@ -2068,14 +2117,17 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 		u8 dsc_dp_slice_count;
 
 		dsc_max_output_bpp =
-			intel_dp_dsc_get_output_bpp(pipe_config->port_clock,
+			intel_dp_dsc_get_output_bpp(dev_priv,
+						    pipe_config->port_clock,
 						    pipe_config->lane_count,
 						    adjusted_mode->crtc_clock,
-						    adjusted_mode->crtc_hdisplay);
+						    adjusted_mode->crtc_hdisplay,
+						    false);
 		dsc_dp_slice_count =
 			intel_dp_dsc_get_slice_count(intel_dp,
 						     adjusted_mode->crtc_clock,
-						     adjusted_mode->crtc_hdisplay);
+						     adjusted_mode->crtc_hdisplay,
+						     false);
 		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
 			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
 			return -EINVAL;
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (8 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid() Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-26  3:48   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences Maarten Lankhorst
                   ` (18 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

When the clock is higher than the dotclock, try with 2 pipes enabled.
If we can enable 2, then we will go into big joiner mode, and steal
the adjacent crtc.

This only links the crtc's in software, no hardware or plane
programming is done yet. Blobs are also copied from the master's
crtc_state, so it doesn't depend at commit time on the other
crtc_state.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |  15 +-
 drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 197 +++++++++++++++++-
 .../drm/i915/display/intel_display_types.h    |  11 +-
 drivers/gpu/drm/i915/display/intel_dp.c       |  25 ++-
 5 files changed, 228 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index c50e0b218bd6..0db04064c86e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -228,25 +228,26 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
 	intel_crtc_put_color_blobs(crtc_state);
 }
 
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
+				 const struct intel_crtc_state *from_crtc_state)
 {
 	intel_crtc_put_color_blobs(crtc_state);
 
-	if (crtc_state->uapi.degamma_lut)
+	if (from_crtc_state->uapi.degamma_lut)
 		crtc_state->hw.degamma_lut =
-			drm_property_blob_get(crtc_state->uapi.degamma_lut);
+			drm_property_blob_get(from_crtc_state->uapi.degamma_lut);
 	else
 		crtc_state->hw.degamma_lut = NULL;
 
-	if (crtc_state->uapi.gamma_lut)
+	if (from_crtc_state->uapi.gamma_lut)
 		crtc_state->hw.gamma_lut =
-			drm_property_blob_get(crtc_state->uapi.gamma_lut);
+			drm_property_blob_get(from_crtc_state->uapi.gamma_lut);
 	else
 		crtc_state->hw.gamma_lut = NULL;
 
-	if (crtc_state->uapi.ctm)
+	if (from_crtc_state->uapi.ctm)
 		crtc_state->hw.ctm =
-			drm_property_blob_get(crtc_state->uapi.ctm);
+			drm_property_blob_get(from_crtc_state->uapi.ctm);
 	else
 		crtc_state->hw.ctm = NULL;
 }
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 42be91e0772a..8da84d64aa04 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -36,7 +36,8 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
 void intel_crtc_destroy_state(struct drm_crtc *crtc,
 			       struct drm_crtc_state *state);
 void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
-void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
+void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
+				 const struct intel_crtc_state *from_crtc_state);
 struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
 void intel_atomic_state_clear(struct drm_atomic_state *state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index ba52a70840fd..143d531c4c81 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 				     struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
+	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
 	if (INTEL_GEN(dev_priv) < 4) {
@@ -7451,6 +7451,25 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 		}
 	}
 
+	/*
+	 * copy hw mode to transcoder mode.
+	 * This matters mostly for big joiner, which splits the mode in half.
+	 */
+	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
+	if (pipe_config->bigjoiner) {
+		/* Make sure the crtc config is halved horizontally */
+		adjusted_mode->crtc_clock /= 2;
+		adjusted_mode->crtc_hdisplay /= 2;
+		adjusted_mode->crtc_hblank_start /= 2;
+		adjusted_mode->crtc_hblank_end /= 2;
+		adjusted_mode->crtc_hsync_start /= 2;
+		adjusted_mode->crtc_hsync_end /= 2;
+		adjusted_mode->crtc_htotal /= 2;
+		adjusted_mode->crtc_hskew /= 2;
+
+		pipe_config->pipe_src_w /= 2;
+	}
+
 	if (adjusted_mode->crtc_clock > clock_limit) {
 		DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
 			      adjusted_mode->crtc_clock, clock_limit,
@@ -8133,7 +8152,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.transcoder_mode;
 	u32 crtc_vtotal, crtc_vblank_end;
 	int vsyncshift = 0;
 
@@ -11774,6 +11793,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 		to_intel_crtc_state(_crtc_state);
 	int ret;
 	bool mode_changed = needs_modeset(crtc_state);
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(crtc_state->uapi.state);
 
 	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
 	    mode_changed && !crtc_state->hw.active)
@@ -11781,6 +11802,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 
 	if (mode_changed && crtc_state->hw.enable &&
 	    dev_priv->display.crtc_compute_clock &&
+	    !crtc_state->bigjoiner_slave &&
 	    !WARN_ON(crtc_state->shared_dpll)) {
 		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
 		if (ret)
@@ -11796,8 +11818,15 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
 
 	if (mode_changed || crtc_state->update_pipe ||
 	    crtc_state->uapi.color_mgmt_changed) {
+		const struct intel_crtc_state *master_crtc_state = crtc_state;
+
+		if (crtc_state->bigjoiner_slave)
+			master_crtc_state =
+				intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);
+
 		/* Copy color blobs to hw state */
-		intel_crtc_copy_color_blobs(crtc_state);
+		intel_crtc_copy_color_blobs(crtc_state, master_crtc_state);
 
 		ret = intel_color_check(crtc_state);
 		if (ret)
@@ -12259,7 +12288,48 @@ static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
 	crtc_state->uapi.enable = crtc_state->hw.enable;
 	crtc_state->uapi.active = crtc_state->hw.active;
 	crtc_state->uapi.mode = crtc_state->hw.mode;
-	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
+	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
+}
+
+static int
+copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
+			  const struct intel_crtc_state *from_crtc_state)
+{
+	struct intel_crtc_state *saved_state;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+	if (!saved_state)
+		return -ENOMEM;
+
+	saved_state->uapi = crtc_state->uapi;
+	saved_state->scaler_state = crtc_state->scaler_state;
+	saved_state->shared_dpll = crtc_state->shared_dpll;
+	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
+	saved_state->crc_enabled = crtc_state->crc_enabled;
+
+	intel_crtc_free_hw_state(crtc_state);
+	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
+	kfree(saved_state);
+
+	/* Re-init hw state */
+	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
+	crtc_state->hw.enable = from_crtc_state->hw.enable;
+	crtc_state->hw.active = from_crtc_state->hw.active;
+	crtc_state->hw.mode = from_crtc_state->hw.mode;
+	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
+
+	/* Some fixups */
+	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
+	crtc_state->uapi.connectors_changed = from_crtc_state->uapi.connectors_changed;
+	crtc_state->uapi.active_changed = from_crtc_state->uapi.active_changed;
+	crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;
+	crtc_state->bigjoiner_linked_crtc = to_intel_crtc(from_crtc_state->uapi.crtc);
+	crtc_state->bigjoiner_slave = true;
+	crtc_state->cpu_transcoder = (enum transcoder)crtc->pipe;
+	crtc_state->has_audio = false;
+
+	return 0;
 }
 
 static int
@@ -12432,7 +12502,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
 	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
-	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
+	pipe_config->uapi.adjusted_mode = pipe_config->hw.transcoder_mode;
 
 	return 0;
 }
@@ -13549,6 +13619,109 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
 	new_crtc_state->has_drrs = old_crtc_state->has_drrs;
 }
 
+static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
+	struct intel_crtc *crtc, *slave, *master;
+	int i, ret = 0;
+
+	if (INTEL_GEN(dev_priv) < 11)
+		return 0;
+
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!old_crtc_state->bigjoiner_slave)
+			continue;
+
+		if (crtc->pipe == PIPE_A) {
+			DRM_ERROR("Bigjoiner slave on pipe A?\n");
+			return -EINVAL;
+		}
+
+		/* crtc staying in slave mode? */
+		if (!new_crtc_state->uapi.enable)
+			continue;
+
+		if (needs_modeset(new_crtc_state) || new_crtc_state->update_pipe) {
+			master = old_crtc_state->bigjoiner_linked_crtc;
+			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
+			if (IS_ERR(master_crtc_state))
+				return PTR_ERR(master_crtc_state);
+
+			/*
+			 * Force modeset on master, to recalculate bigjoiner
+			 * state.
+			 *
+			 * If master_crtc_state was not part of the atomic commit,
+			 * we will fail because the master was not deconfigured,
+			 * but at least fail below to unify the checks.
+			 */
+			master_crtc_state->uapi.mode_changed = true;
+
+			ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
+			if (ret)
+				return ret;
+
+			ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
+			if (ret)
+				return ret;
+		}
+	}
+
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+					    new_crtc_state, i) {
+		if (!new_crtc_state->uapi.enable || !new_crtc_state->bigjoiner) {
+			if (!old_crtc_state->bigjoiner)
+				continue;
+		}
+
+		if (!needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe)
+			continue;
+
+		if (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave) {
+			if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
+				DRM_DEBUG_KMS("Big joiner configuration requires CRTC + 1 to be used, doesn't exist\n");
+				return -EINVAL;
+			}
+
+			slave = new_crtc_state->bigjoiner_linked_crtc =
+				intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
+			slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave);
+			if (IS_ERR(slave_crtc_state))
+				return PTR_ERR(slave_crtc_state);
+
+			if (slave_crtc_state->uapi.enable) {
+				DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires this CRTC to be unconfigured\n",
+					      slave->base.base.id, slave->base.name);
+				return -EINVAL;
+			} else {
+				DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
+					      slave->base.base.id, slave->base.name);
+				ret = copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+			}
+		} else {
+			master = new_crtc_state->bigjoiner_linked_crtc;
+			if (!master)
+				continue;
+
+			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
+			if (IS_ERR(master_crtc_state))
+				return PTR_ERR(master_crtc_state);
+
+			if (!master_crtc_state->uapi.enable && !new_crtc_state->uapi.enable) {
+				DRM_DEBUG_KMS("[CRTC:%d:%s] Disabling slave from big joiner\n",
+					      crtc->base.base.id, crtc->base.name);
+				ret = clear_intel_crtc_state(new_crtc_state);
+			}
+		}
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 /**
  * intel_atomic_check - validate state object
  * @dev: drm device
@@ -13583,7 +13756,10 @@ static int intel_atomic_check(struct drm_device *dev,
 
 		if (!new_crtc_state->uapi.enable) {
 			any_ms = true;
-			clear_intel_crtc_state(new_crtc_state);
+
+			/* big joiner slave is cleared in intel_atomic_check_bigjoiner() */
+			if (!new_crtc_state->bigjoiner_slave)
+				clear_intel_crtc_state(new_crtc_state);
 			continue;
 		}
 
@@ -13597,6 +13773,10 @@ static int intel_atomic_check(struct drm_device *dev,
 			any_ms = true;
 	}
 
+	ret = intel_atomic_check_bigjoiner(state);
+	if (ret)
+		return ret;
+
 	ret = drm_dp_mst_atomic_check(&state->base);
 	if (ret)
 		goto fail;
@@ -13747,7 +13927,9 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	commit_pipe_config(state, old_crtc_state, new_crtc_state);
 
-	if (INTEL_GEN(dev_priv) >= 9)
+	if (new_crtc_state->bigjoiner)
+		{/* Not supported yet */}
+	else if (INTEL_GEN(dev_priv) >= 9)
 		skl_update_planes_on_crtc(state, crtc);
 	else
 		i9xx_update_planes_on_crtc(state, crtc);
@@ -16846,7 +17028,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		}
 
 		intel_bw_crtc_update(bw_state, crtc_state);
-
 		copy_hw_to_uapi_state(crtc_state);
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
 	}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 394f84e5d583..dd0329a4b9ff 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -774,7 +774,7 @@ struct intel_crtc_state {
 	struct {
 		bool active, enable;
 		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
-		struct drm_display_mode mode, adjusted_mode;
+		struct drm_display_mode mode, adjusted_mode, transcoder_mode;
 	} hw;
 
 	/**
@@ -1005,6 +1005,15 @@ struct intel_crtc_state {
 	/* enable pipe csc? */
 	bool csc_enable;
 
+	/* enable pipe big joiner? */
+	bool bigjoiner;
+
+	/* big joiner slave crtc? */
+	bool bigjoiner_slave;
+
+	/* linked crtc for bigjoiner, either slave or master */
+	struct intel_crtc *bigjoiner_linked_crtc;
+
 	/* Display Stream compression state */
 	struct {
 		bool compression_enable;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 046e1662d1e3..3d487ce16151 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2105,6 +2105,19 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 	pipe_config->port_clock = intel_dp->common_rates[limits->max_clock];
 	pipe_config->lane_count = limits->max_lane_count;
 
+	if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, false)) {
+		if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, true)) {
+			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
+			return -EINVAL;
+		}
+		if (intel_dp_is_edp(intel_dp)) {
+			DRM_DEBUG_KMS("Cannot split eDP stream in bigjoiner configuration.\n");
+			return -EINVAL;
+		}
+		pipe_config->bigjoiner = true;
+		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
+	}
+
 	if (intel_dp_is_edp(intel_dp)) {
 		pipe_config->dsc_params.compressed_bpp =
 			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
@@ -2122,12 +2135,12 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 						    pipe_config->lane_count,
 						    adjusted_mode->crtc_clock,
 						    adjusted_mode->crtc_hdisplay,
-						    false);
+						    pipe_config->bigjoiner);
 		dsc_dp_slice_count =
 			intel_dp_dsc_get_slice_count(intel_dp,
 						     adjusted_mode->crtc_clock,
 						     adjusted_mode->crtc_hdisplay,
-						     false);
+						     pipe_config->bigjoiner);
 		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
 			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
 			return -EINVAL;
@@ -2142,13 +2155,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 	 * is greater than the maximum Cdclock and if slice count is even
 	 * then we need to use 2 VDSC instances.
 	 */
-	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) {
-		if (pipe_config->dsc_params.slice_count > 1) {
-			pipe_config->dsc_params.dsc_split = true;
-		} else {
+	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq || pipe_config->bigjoiner) {
+		if (pipe_config->dsc_params.slice_count < 2) {
 			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
 			return -EINVAL;
 		}
+
+		pipe_config->dsc_params.dsc_split = true;
 	}
 
 	ret = intel_dp_compute_dsc_params(intel_dp, pipe_config);
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (9 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-26  5:18   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 13/23] drm/i915: Make hardware readout work on i915 Maarten Lankhorst
                   ` (17 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Make vdsc work when no output is enabled. The big joiner needs VDSC
on the slave, so enable it and set the appropriate bits.
Also update timestamping constants, because slave crtc's are not
updated in drm_atomic_helper_update_legacy_modeset_state().

This should be enough to bring up CRTC's in a big joiner configuration,
without any plane configuration on the second pipe yet.

HOWEVER, we bring up the crtc's in the wrong order. We need to make
sure that the master crtc is brought up after the slave crtc, we
don't do that yet. This is done correctly later in this series.

The next steps are to add atomic commit, and make sure we enable and
update both master and slave in the correct order.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  55 ++-
 drivers/gpu/drm/i915/display/intel_display.c  | 402 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |  17 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  18 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
 6 files changed, 418 insertions(+), 198 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index c775fd205915..a26155f90261 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1694,6 +1694,13 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
 		skl_ddi_clock_get(encoder, pipe_config);
 	else if (INTEL_GEN(dev_priv) <= 8)
 		hsw_ddi_clock_get(encoder, pipe_config);
+
+	if (pipe_config->bigjoiner) {
+		pipe_config->hw.transcoder_mode.crtc_clock =
+			pipe_config->hw.adjusted_mode.crtc_clock;
+
+		pipe_config->hw.adjusted_mode.crtc_clock /= 2;
+	}
 }
 
 void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
@@ -2176,13 +2183,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 	    intel_phy_is_tc(dev_priv, phy))
 		intel_display_power_get(dev_priv,
 					intel_ddi_main_link_aux_domain(dig_port));
-
-	/*
-	 * VDSC power is needed when DSC is enabled
-	 */
-	if (crtc_state->dsc_params.compression_enable)
-		intel_display_power_get(dev_priv,
-					intel_dsc_power_domain(crtc_state));
 }
 
 void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
@@ -3290,7 +3290,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 
 	/* 7.l */
 	intel_ddi_enable_fec(encoder, crtc_state);
-	intel_dsc_enable(encoder, crtc_state);
+	if (!crtc_state->bigjoiner)
+		intel_dsc_enable(encoder, crtc_state);
 }
 
 static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
@@ -3361,7 +3362,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
 	if (!is_mst)
 		intel_ddi_enable_pipe_clock(crtc_state);
 
-	intel_dsc_enable(encoder, crtc_state);
+	if (!crtc_state->bigjoiner)
+		intel_dsc_enable(encoder, crtc_state);
 }
 
 static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
@@ -3972,19 +3974,18 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
 		crtc_state->min_voltage_level = 2;
 }
 
-void intel_ddi_get_config(struct intel_encoder *encoder,
-			  struct intel_crtc_state *pipe_config)
+static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
+				    struct intel_crtc_state *pipe_config)
 {
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	u32 temp, flags = 0;
 
-	/* XXX: DSI transcoder paranoia */
-	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (!(temp & TRANS_DDI_FUNC_ENABLE))
 		return;
 
-	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
 		flags |= DRM_MODE_FLAG_PHSYNC;
 	else
@@ -4066,6 +4067,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	default:
 		break;
 	}
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+
+	/* XXX: DSI transcoder paranoia */
+	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+		return;
+
+	intel_ddi_read_func_ctl(encoder, pipe_config);
+	if (pipe_config->bigjoiner_slave) {
+		/* read out pipe settings from master */
+		enum transcoder save = pipe_config->cpu_transcoder;
+
+		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
+		WARN_ON(pipe_config->output_types);
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
+		intel_ddi_read_func_ctl(encoder, pipe_config);
+		pipe_config->cpu_transcoder = save;
+	}
 
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
@@ -4090,7 +4114,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
 	}
 
-	intel_ddi_clock_get(encoder, pipe_config);
+	if (!pipe_config->bigjoiner_slave)
+		intel_ddi_clock_get(encoder, pipe_config);
 
 	if (IS_GEN9_LP(dev_priv))
 		pipe_config->lane_lat_optim_mask =
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 143d531c4c81..8c08c4914c9b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6449,6 +6449,45 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
 	I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);
 }
 
+static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
+					 struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *master = to_intel_crtc(crtc_state->uapi.crtc);
+	struct intel_crtc_state *master_crtc_state;
+	struct drm_connector_state *conn_state;
+	struct drm_connector *conn;
+	struct intel_encoder *encoder = NULL;
+	int i;
+
+	if (crtc_state->bigjoiner_slave)
+		master = crtc_state->bigjoiner_linked_crtc;
+
+	master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
+
+	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
+		if (conn_state->crtc != &master->base)
+			continue;
+
+		encoder = to_intel_encoder(conn_state->best_encoder);
+		break;
+	}
+
+	if (!crtc_state->bigjoiner_slave) {
+		/* need to enable VDSC, which we skipped in pre-enable */
+		intel_dsc_enable(encoder, crtc_state);
+	} else {
+		/*
+		 * Enable sequence steps 1-7 on bigjoiner master
+		 */
+		intel_encoders_pre_pll_enable(master, master_crtc_state, state);
+		intel_enable_shared_dpll(master_crtc_state);
+		intel_encoders_pre_enable(master, master_crtc_state, state);
+
+		/* and DSC on slave */
+		intel_dsc_enable(NULL, crtc_state);
+	}
+}
+
 static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 				struct intel_atomic_state *state)
 {
@@ -6462,37 +6501,38 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (WARN_ON(intel_crtc->active))
 		return;
 
-	intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
+	if (!pipe_config->bigjoiner) {
+		intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
 
-	if (pipe_config->shared_dpll)
-		intel_enable_shared_dpll(pipe_config);
+		if (pipe_config->shared_dpll)
+			intel_enable_shared_dpll(pipe_config);
 
-	intel_encoders_pre_enable(intel_crtc, pipe_config, state);
+		intel_encoders_pre_enable(intel_crtc, pipe_config, state);
+	} else {
+		icl_ddi_bigjoiner_pre_enable(state, pipe_config);
+	}
 
-	if (intel_crtc_has_dp_encoder(pipe_config))
-		intel_dp_set_m_n(pipe_config, M1_N1);
+	intel_set_pipe_src_size(pipe_config);
+	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+		bdw_set_pipemisc(pipe_config);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_pipe_timings(pipe_config);
+	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
+		if (intel_crtc_has_dp_encoder(pipe_config))
+			intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_src_size(pipe_config);
+		intel_set_pipe_timings(pipe_config);
 
-	if (cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(cpu_transcoder)) {
-		I915_WRITE(PIPE_MULT(cpu_transcoder),
-			   pipe_config->pixel_multiplier - 1);
-	}
+		if (cpu_transcoder != TRANSCODER_EDP)
+			I915_WRITE(PIPE_MULT(cpu_transcoder),
+				  pipe_config->pixel_multiplier - 1);
 
-	if (pipe_config->has_pch_encoder) {
-		intel_cpu_transcoder_set_m_n(pipe_config,
-					     &pipe_config->fdi_m_n, NULL);
-	}
+		if (pipe_config->has_pch_encoder) {
+			intel_cpu_transcoder_set_m_n(pipe_config,
+						    &pipe_config->fdi_m_n, NULL);
+		}
 
-	if (!transcoder_is_dsi(cpu_transcoder))
 		haswell_set_pipeconf(pipe_config);
-
-	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-		bdw_set_pipemisc(pipe_config);
+	}
 
 	intel_crtc->active = true;
 
@@ -6520,9 +6560,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_set_pipe_chicken(intel_crtc);
 
-	intel_ddi_set_pipe_settings(pipe_config);
-	if (!transcoder_is_dsi(cpu_transcoder))
+	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
+		intel_ddi_set_pipe_settings(pipe_config);
+
 		intel_ddi_enable_transcoder_func(pipe_config);
+	}
 
 	if (dev_priv->display.initial_watermarks != NULL)
 		dev_priv->display.initial_watermarks(state, pipe_config);
@@ -6531,8 +6573,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 		icl_pipe_mbus_enable(intel_crtc);
 
 	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
-	if (!transcoder_is_dsi(cpu_transcoder))
+	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
 		intel_enable_pipe(pipe_config);
+	else
+		trace_intel_pipe_enable(intel_crtc);
 
 	if (pipe_config->has_pch_encoder)
 		lpt_pch_enable(state, pipe_config);
@@ -6663,9 +6707,27 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 	else
 		ironlake_pfit_disable(old_crtc_state);
 
-	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
+	if (old_crtc_state->bigjoiner) {
+		struct intel_crtc *master;
+		struct intel_crtc_state *master_crtc_state;
 
-	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
+		/* ports are disabled from the slave, after it deconfigures */
+		if (!old_crtc_state->bigjoiner_slave)
+			return;
+
+		master = old_crtc_state->bigjoiner_linked_crtc;
+		master_crtc_state = intel_atomic_get_old_crtc_state(state, master);
+
+		intel_ddi_disable_pipe_clock(old_crtc_state);
+
+		/* disable ports on the master crtc */
+		intel_encoders_post_disable(master, master_crtc_state, state);
+		intel_encoders_post_pll_disable(master, master_crtc_state, state);
+	} else {
+		intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
+
+		intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
+	}
 }
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -6829,6 +6891,9 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
 	if (crtc_state->shared_dpll)
 		mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE);
 
+	if (crtc_state->dsc_params.compression_enable)
+		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
+
 	return mask;
 }
 
@@ -7417,6 +7482,19 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 	return pixel_rate;
 }
 
+static void intel_encoder_get_config(struct intel_encoder *encoder,
+				     struct intel_crtc_state *crtc_state)
+{
+	encoder->get_config(encoder, crtc_state);
+
+	crtc_state->hw.transcoder_mode.flags = crtc_state->hw.adjusted_mode.flags;
+
+	/* if transcoder clock is not set, assume same as adjusted_mode clock */
+	if (!crtc_state->hw.transcoder_mode.crtc_clock)
+		crtc_state->hw.transcoder_mode.crtc_clock =
+			crtc_state->hw.adjusted_mode.crtc_clock;
+}
+
 static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
@@ -8265,6 +8343,24 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
 		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
 		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
 	}
+
+	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
+	if (pipe_config->bigjoiner) {
+		struct drm_display_mode *adjusted_mode =
+			&pipe_config->hw.adjusted_mode;
+
+		/*
+		  * transcoder is programmed to the full mode,
+		  * but pipje timings are half of the transcoder mode
+		  */
+		adjusted_mode->crtc_hdisplay /= 2;
+		adjusted_mode->crtc_hblank_start /= 2;
+		adjusted_mode->crtc_hblank_end /= 2;
+		adjusted_mode->crtc_hsync_start /= 2;
+		adjusted_mode->crtc_hsync_end /= 2;
+		adjusted_mode->crtc_htotal /= 2;
+		adjusted_mode->crtc_hskew /= 2;
+	}
 }
 
 static void intel_get_pipe_src_size(struct intel_crtc *crtc,
@@ -8285,20 +8381,22 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
 void intel_mode_from_pipe_config(struct drm_display_mode *mode,
 				 struct intel_crtc_state *pipe_config)
 {
-	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
-	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
-	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
-	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
+	struct drm_display_mode *hw_mode = &pipe_config->hw.transcoder_mode;
 
-	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
-	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
-	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
-	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
+	mode->hdisplay = hw_mode->crtc_hdisplay;
+	mode->htotal = hw_mode->crtc_htotal;
+	mode->hsync_start = hw_mode->crtc_hsync_start;
+	mode->hsync_end = hw_mode->crtc_hsync_end;
 
-	mode->flags = pipe_config->hw.adjusted_mode.flags;
+	mode->vdisplay = hw_mode->crtc_vdisplay;
+	mode->vtotal = hw_mode->crtc_vtotal;
+	mode->vsync_start = hw_mode->crtc_vsync_start;
+	mode->vsync_end = hw_mode->crtc_vsync_end;
+
+	mode->flags = hw_mode->flags;
 	mode->type = DRM_MODE_TYPE_DRIVER;
 
-	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
+	mode->clock = hw_mode->crtc_clock;
 
 	mode->hsync = drm_mode_hsync(mode);
 	mode->vrefresh = drm_mode_vrefresh(mode);
@@ -10385,6 +10483,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
 	u32 tmp;
 
 	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
+	if (!(tmp & TRANS_DDI_FUNC_ENABLE))
+		return;
 
 	if (INTEL_GEN(dev_priv) >= 12)
 		port = TGL_TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp);
@@ -10455,11 +10555,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 		WARN_ON(active);
 		active = true;
 	}
+	intel_dsc_get_config(pipe_config);
 
-	if (!active)
-		goto out;
+	if (!active) {
+		/* bigjoiner slave doesn't enable transcoder */
+		if (!pipe_config->bigjoiner_slave)
+			goto out;
+
+		active = true;
+		pipe_config->pixel_multiplier = 1;
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+		/* we cannot read out most state, so don't bother.. */
+		pipe_config->quirks |= PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE;
+	} else if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
 	    INTEL_GEN(dev_priv) >= 11) {
 		haswell_get_ddi_port_state(crtc, pipe_config);
 		intel_get_pipe_timings(crtc, pipe_config);
@@ -10513,7 +10621,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
-	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
+	if (pipe_config->bigjoiner_slave) {
+		/* Cannot be read out as a slave, set to 0. */
+		pipe_config->pixel_multiplier = 0;
+	} else if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
 	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
 		pipe_config->pixel_multiplier =
 			I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
@@ -11468,7 +11579,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
 		return NULL;
 	}
 
-	encoder->get_config(encoder, crtc_state);
+	intel_encoder_get_config(encoder, crtc_state);
 
 	intel_mode_from_pipe_config(mode, crtc_state);
 
@@ -12285,9 +12396,11 @@ static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
 
 static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
 {
-	crtc_state->uapi.enable = crtc_state->hw.enable;
-	crtc_state->uapi.active = crtc_state->hw.active;
-	crtc_state->uapi.mode = crtc_state->hw.mode;
+	if (!crtc_state->bigjoiner_slave) {
+		crtc_state->uapi.enable = crtc_state->hw.enable;
+		crtc_state->uapi.active = crtc_state->hw.active;
+		crtc_state->uapi.mode = crtc_state->hw.mode;
+	}
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
 }
 
@@ -12318,6 +12431,7 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
 	crtc_state->hw.active = from_crtc_state->hw.active;
 	crtc_state->hw.mode = from_crtc_state->hw.mode;
 	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
+	crtc_state->hw.transcoder_mode = from_crtc_state->hw.transcoder_mode;
 
 	/* Some fixups */
 	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
@@ -12833,19 +12947,41 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_X(output_types);
 
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
-
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
-	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
+		/* bigjoiner mode = transcoder mode / 2, for calculations */
+		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
+		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
+		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
+		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
+
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hdisplay);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_htotal);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_start);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_end);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_start);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_end);
+
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vdisplay);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vtotal);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_start);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_end);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_start);
+		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_end);
+
+		PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
+				      DRM_MODE_FLAG_INTERLACE);
+
+		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
+			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
+					      DRM_MODE_FLAG_PHSYNC);
+			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
+					      DRM_MODE_FLAG_NHSYNC);
+			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
+					      DRM_MODE_FLAG_PVSYNC);
+			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
+					      DRM_MODE_FLAG_NVSYNC);
+		}
+	}
 
 	PIPE_CONF_CHECK_I(pixel_multiplier);
 	PIPE_CONF_CHECK_I(output_format);
@@ -12857,24 +12993,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
 	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
 	PIPE_CONF_CHECK_BOOL(has_infoframe);
-	PIPE_CONF_CHECK_BOOL(fec_enable);
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
+		PIPE_CONF_CHECK_BOOL(fec_enable);
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
-	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
-			      DRM_MODE_FLAG_INTERLACE);
-
-	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
-		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
-				      DRM_MODE_FLAG_PHSYNC);
-		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
-				      DRM_MODE_FLAG_NHSYNC);
-		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
-				      DRM_MODE_FLAG_PVSYNC);
-		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
-				      DRM_MODE_FLAG_NVSYNC);
-	}
-
 	PIPE_CONF_CHECK_X(gmch_pfit.control);
 	/* pfit ratios are autocomputed by the hw on gen4+ */
 	if (INTEL_GEN(dev_priv) < 4)
@@ -12898,7 +13021,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 		}
 
 		PIPE_CONF_CHECK_I(scaler_state.scaler_id);
-		PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
+		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
+			PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
 
 		PIPE_CONF_CHECK_X(gamma_mode);
 		if (IS_CHERRYVIEW(dev_priv))
@@ -12917,48 +13041,50 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(double_wide);
 
 	PIPE_CONF_CHECK_P(shared_dpll);
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
-	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
-	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
-	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
-	PIPE_CONF_CHECK_X(dpll_hw_state.spll);
-	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
-	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
-	PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
-	PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
-	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
-	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
-
-	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
-	PIPE_CONF_CHECK_X(dsi_pll.div);
-
-	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
-		PIPE_CONF_CHECK_I(pipe_bpp);
-
-	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
-	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
-
-	PIPE_CONF_CHECK_I(min_voltage_level);
+		PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
+		PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
+		PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
+		PIPE_CONF_CHECK_X(dpll_hw_state.spll);
+		PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
+		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
+		PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
+		PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
+		PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
+		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
+
+		PIPE_CONF_CHECK_X(dsi_pll.ctrl);
+		PIPE_CONF_CHECK_X(dsi_pll.div);
+
+		if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
+			PIPE_CONF_CHECK_I(pipe_bpp);
+
+		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
+		PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
+
+		PIPE_CONF_CHECK_I(min_voltage_level);
+	}
 
 	PIPE_CONF_CHECK_X(infoframes.enable);
 	PIPE_CONF_CHECK_X(infoframes.gcp);
@@ -12967,6 +13093,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_INFOFRAME(hdmi);
 	PIPE_CONF_CHECK_INFOFRAME(drm);
 
+	PIPE_CONF_CHECK_BOOL(bigjoiner);
+	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
+	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
+	PIPE_CONF_CHECK_BOOL(dsc_params.compression_enable);
+	PIPE_CONF_CHECK_BOOL(dsc_params.dsc_split);
+
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
 #undef PIPE_CONF_CHECK_BOOL
@@ -13221,6 +13353,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 	struct intel_encoder *encoder;
 	struct intel_crtc_state *pipe_config;
 	struct drm_atomic_state *state;
+	struct intel_crtc *master = crtc;
 	bool active;
 
 	state = old_crtc_state->uapi.state;
@@ -13250,7 +13383,10 @@ verify_crtc_state(struct intel_crtc *crtc,
 			"(expected %i, found %i)\n",
 			new_crtc_state->hw.active, crtc->active);
 
-	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
+	if (new_crtc_state->bigjoiner_slave)
+		master = new_crtc_state->bigjoiner_linked_crtc;
+
+	for_each_encoder_on_crtc(dev, &master->base, encoder) {
 		enum pipe pipe;
 
 		active = encoder->get_hw_state(encoder, &pipe);
@@ -13259,12 +13395,12 @@ verify_crtc_state(struct intel_crtc *crtc,
 				encoder->base.base.id, active,
 				new_crtc_state->hw.active);
 
-		I915_STATE_WARN(active && crtc->pipe != pipe,
+		I915_STATE_WARN(active && master->pipe != pipe,
 				"Encoder connected to wrong pipe %c\n",
 				pipe_name(pipe));
 
 		if (active)
-			encoder->get_config(encoder, pipe_config);
+			intel_encoder_get_config(encoder, pipe_config);
 	}
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -13906,6 +14042,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	if (modeset) {
 		update_scanline_offset(new_crtc_state);
+		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.transcoder_mode);
 		dev_priv->display.crtc_enable(new_crtc_state, state);
 
 		/* vblanks work again, re-enable pipe CRC. */
@@ -13990,7 +14127,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	 */
 	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
 						    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state))
+		if (!needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner_slave)
 			continue;
 
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
@@ -14000,6 +14137,19 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 						      old_crtc_state,
 						      new_crtc_state,
 						      crtc);
+
+		if (old_crtc_state->bigjoiner) {
+			struct intel_crtc *slave = old_crtc_state->bigjoiner_linked_crtc;
+			struct intel_crtc_state *old_slave_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, slave);
+			struct intel_crtc_state *new_slave_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, slave);
+
+			intel_old_crtc_state_disables(state,
+						      old_slave_crtc_state,
+						      new_slave_crtc_state,
+						      slave);
+		}
 	}
 }
 
@@ -16433,7 +16583,7 @@ int intel_modeset_init(struct drm_device *dev)
 	for_each_intel_crtc(dev, crtc) {
 		struct intel_initial_plane_config plane_config = {};
 
-		if (!crtc->active)
+		if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
 			continue;
 
 		/*
@@ -16923,7 +17073,17 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			crtc_state = to_intel_crtc_state(crtc->base.state);
 
 			encoder->base.crtc = &crtc->base;
-			encoder->get_config(encoder, crtc_state);
+			intel_encoder_get_config(encoder, crtc_state);
+
+			/* read out to slave crtc as well for bigjoiner */
+			if (crtc_state->bigjoiner) {
+				/* encoder should read be linked to bigjoiner master */
+				WARN_ON(crtc_state->bigjoiner_slave);
+
+				crtc = crtc_state->bigjoiner_linked_crtc;
+				crtc_state = to_intel_crtc_state(crtc->base.state);
+				intel_encoder_get_config(encoder, crtc_state);
+			}
 		} else {
 			encoder->base.crtc = NULL;
 		}
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index dd0329a4b9ff..7e06c61447e6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -786,6 +786,7 @@ struct intel_crtc_state {
 	 * accordingly.
 	 */
 #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS	(1<<0) /* unreliable sync mode.flags */
+#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE	(1<<1) /* bigjoiner slave, partial readout */
 	unsigned long quirks;
 
 	unsigned fb_bits; /* framebuffers to flip */
@@ -1572,4 +1573,20 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
 	return i915_ggtt_offset(state->vma);
 }
 
+static inline bool
+intel_crtc_supports_dsc(const struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);
+
+	/* On TGL, DSC is supported on all Pipes */
+	if (INTEL_GEN(dev_priv) >= 12)
+		return true;
+
+	if (INTEL_GEN(dev_priv) >= 10 &&
+	    pipe_config->cpu_transcoder != TRANSCODER_A)
+		return true;
+
+	return false;
+}
+
 #endif /*  __INTEL_DISPLAY_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3d487ce16151..234be1c31958 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1907,22 +1907,6 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
 		drm_dp_sink_supports_fec(intel_dp->fec_capable);
 }
 
-static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
-					 const struct intel_crtc_state *pipe_config)
-{
-	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-
-	/* On TGL, DSC is supported on all Pipes */
-	if (INTEL_GEN(dev_priv) >= 12)
-		return true;
-
-	if (INTEL_GEN(dev_priv) >= 10 &&
-	    pipe_config->cpu_transcoder != TRANSCODER_A)
-		return true;
-
-	return false;
-}
-
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *pipe_config)
 {
@@ -1930,7 +1914,7 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
 		return false;
 
-	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
+	return intel_crtc_supports_dsc(pipe_config) &&
 		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 38c181499505..11d4da9734a0 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -480,11 +480,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
 }
 
-static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
-						const struct intel_crtc_state *crtc_state)
+static void intel_configure_pps_for_dsc_encoder(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
@@ -494,6 +493,9 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
 	u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1;
 	int i = 0;
 
+	if (crtc_state->bigjoiner)
+		num_vdsc_instances *= 2;
+
 	/* Populate PICTURE_PARAMETER_SET_0 registers */
 	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
 		DSC_VER_MIN_SHIFT |
@@ -899,74 +901,104 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
 					sizeof(dp_dsc_pps_sdp));
 }
 
+static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
+{
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+
+	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
+		return DSS_CTL1;
+
+	return ICL_PIPE_DSS_CTL1(pipe);
+}
+
+static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
+{
+	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
+
+	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
+		return DSS_CTL2;
+
+	return ICL_PIPE_DSS_CTL2(pipe);
+}
+
 void intel_dsc_enable(struct intel_encoder *encoder,
 		      const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	enum pipe pipe = crtc->pipe;
-	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 dss_ctl1_val = 0;
 	u32 dss_ctl2_val = 0;
 
 	if (!crtc_state->dsc_params.compression_enable)
 		return;
 
-	/* Enable Power wells for VDSC/joining */
-	intel_display_power_get(dev_priv,
-				intel_dsc_power_domain(crtc_state));
+	intel_configure_pps_for_dsc_encoder(crtc_state);
 
-	intel_configure_pps_for_dsc_encoder(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
 
-	intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
-
-	if (crtc_state->cpu_transcoder == TRANSCODER_EDP) {
-		dss_ctl1_reg = DSS_CTL1;
-		dss_ctl2_reg = DSS_CTL2;
-	} else {
-		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
-		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
-	}
 	dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
 	if (crtc_state->dsc_params.dsc_split) {
 		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
 		dss_ctl1_val |= JOINER_ENABLE;
 	}
-	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
-	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
+	if (crtc_state->bigjoiner) {
+		dss_ctl1_val |= BIG_JOINER_ENABLE;
+		if (!crtc_state->bigjoiner_slave)
+			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
+	}
+	I915_WRITE(dss_ctl1_reg(crtc_state), dss_ctl1_val);
+	I915_WRITE(dss_ctl2_reg(crtc_state), dss_ctl2_val);
 }
 
 void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	enum pipe pipe = crtc->pipe;
-	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
-	u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
 
 	if (!old_crtc_state->dsc_params.compression_enable)
 		return;
 
-	if (old_crtc_state->cpu_transcoder == TRANSCODER_EDP) {
-		dss_ctl1_reg = DSS_CTL1;
-		dss_ctl2_reg = DSS_CTL2;
-	} else {
-		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
-		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
+	I915_WRITE(dss_ctl1_reg(old_crtc_state), 0);
+	I915_WRITE(dss_ctl2_reg(old_crtc_state), 0);
+}
+
+void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	u32 dss_ctl1_val, dss_ctl2_val;
+	intel_wakeref_t wakeref;
+
+	if (!intel_crtc_supports_dsc(crtc_state))
+		return;
+
+	wakeref = intel_display_power_get_if_enabled(dev_priv, intel_dsc_power_domain(crtc_state));
+	if (!wakeref)
+		return;
+
+	dss_ctl1_val = I915_READ(dss_ctl1_reg(crtc_state));
+	dss_ctl2_val = I915_READ(dss_ctl2_reg(crtc_state));
+	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE)
+		crtc_state->dsc_params.compression_enable = true;
+
+	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
+		crtc_state->dsc_params.dsc_split = true;
+
+	if (dss_ctl1_val & BIG_JOINER_ENABLE) {
+		crtc_state->bigjoiner = true;
+
+		if (!(dss_ctl1_val & MASTER_BIG_JOINER_ENABLE)) {
+			crtc_state->bigjoiner_slave = true;
+			if (!WARN_ON(crtc->pipe == PIPE_A))
+				crtc_state->bigjoiner_linked_crtc =
+					intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
+		} else {
+			if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
+				crtc_state->bigjoiner_linked_crtc =
+					intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
+		}
 	}
-	dss_ctl1_val = I915_READ(dss_ctl1_reg);
-	if (dss_ctl1_val & JOINER_ENABLE)
-		dss_ctl1_val &= ~JOINER_ENABLE;
-	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
-
-	dss_ctl2_val = I915_READ(dss_ctl2_reg);
-	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
-	    dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
-		dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
-				  RIGHT_BRANCH_VDSC_ENABLE);
-	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
-
-	/* Disable Power wells for VDSC/joining */
-	intel_display_power_put_unchecked(dev_priv,
-					  intel_dsc_power_domain(old_crtc_state));
+
+	intel_display_power_put(dev_priv, intel_dsc_power_domain(crtc_state), wakeref);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index 90d3f6017fcb..569cf17402ba 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -15,6 +15,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
 int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
 				struct intel_crtc_state *pipe_config);
+void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
+
 enum intel_display_power_domain
 intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
 
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 13/23] drm/i915: Make hardware readout work on i915.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (10 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-27  0:49   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates Maarten Lankhorst
                   ` (16 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Unfortunately I have no way to test this, but it should be correct
if the bios sets up bigjoiner in a sane way.

Skip iterating over bigjoiner slaves, only the master has the state we
care about.

Add the width of the bigjoiner slave to the reconstructed fb.

Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
master.

And last, disable bigjoiner slave from primary if reconstruction fails.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 65 +++++++++++++++++++-
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8c08c4914c9b..0424a378eb51 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3177,6 +3177,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 	struct intel_plane *intel_plane = to_intel_plane(primary);
 	struct intel_plane_state *intel_state =
 		to_intel_plane_state(plane_state);
+	struct intel_crtc_state *crtc_state =
+		to_intel_crtc_state(intel_crtc->base.state);
 	struct drm_framebuffer *fb;
 
 	if (!plane_config->fb)
@@ -3199,7 +3201,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 		if (c == &intel_crtc->base)
 			continue;
 
-		if (!to_intel_crtc(c)->active)
+		if (!to_intel_crtc_state(c->state)->uapi.active)
 			continue;
 
 		state = to_intel_plane_state(c->primary->state);
@@ -3221,6 +3223,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 	 * pretend the BIOS never had it enabled.
 	 */
 	intel_plane_disable_noatomic(intel_crtc, intel_plane);
+	if (crtc_state->bigjoiner) {
+		struct intel_crtc *slave =
+			crtc_state->bigjoiner_linked_crtc;
+
+		intel_plane_disable_noatomic(slave, to_intel_plane(slave->base.primary));
+	}
 
 	return;
 
@@ -9918,6 +9926,7 @@ static void
 skylake_get_initial_plane_config(struct intel_crtc *crtc,
 				 struct intel_initial_plane_config *plane_config)
 {
+	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
@@ -10021,6 +10030,18 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 	fb->height = ((val >> 16) & 0xffff) + 1;
 	fb->width = ((val >> 0) & 0xffff) + 1;
 
+	/* add bigjoiner slave as well, if the fb stretches both */
+	if (crtc_state->bigjoiner) {
+		enum pipe bigjoiner_pipe = crtc_state->bigjoiner_linked_crtc->pipe;
+
+		if (fb->width == crtc_state->pipe_src_w &&
+		    (I915_READ(PLANE_SURF(bigjoiner_pipe, plane_id)) & 0xfffff000) == plane_config->base) {
+			val = I915_READ(PLANE_SIZE(crtc_state->bigjoiner_linked_crtc->pipe, plane_id));
+			fb->height += ((val >> 16) & 0xfff) + 1;
+			fb->width += ((val >> 0) & 0x1fff) + 1;
+		}
+	}
+
 	val = I915_READ(PLANE_STRIDE(pipe, plane_id));
 	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
 	fb->pitches[0] = (val & 0x3ff) * stride_mult;
@@ -16814,7 +16835,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
 
 	/* Adjust the state of the output pipe according to whether we
 	 * have active connectors/encoders. */
-	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc))
+	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc) &&
+	    !crtc_state->bigjoiner_slave)
 		intel_crtc_disable_noatomic(&crtc->base, ctx);
 
 	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
@@ -17136,6 +17158,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		struct intel_plane *plane;
 		int min_cdclk = 0;
 
+		if (crtc_state->bigjoiner_slave)
+			continue;
+
 		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
 		if (crtc_state->hw.active) {
 			intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
@@ -17144,7 +17169,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
 						    crtc_state);
 			crtc_state->hw.mode = crtc->base.mode;
-			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
+			if (!crtc_state->bigjoiner_slave)
+				WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
 
 			/*
 			 * The initial mode needs to be set in order to keep
@@ -17190,6 +17216,39 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		intel_bw_crtc_update(bw_state, crtc_state);
 		copy_hw_to_uapi_state(crtc_state);
 		intel_pipe_config_sanity_check(dev_priv, crtc_state);
+
+		/* discard our incomplete slave state, copy it from master */
+		if (crtc_state->bigjoiner && crtc_state->hw.active) {
+			struct intel_crtc *slave = crtc_state->bigjoiner_linked_crtc;
+			struct intel_crtc_state *slave_crtc_state =
+				to_intel_crtc_state(slave->base.state);
+
+			copy_bigjoiner_crtc_state(slave_crtc_state, crtc_state);
+			slave->base.mode = crtc->base.mode;
+
+			dev_priv->min_cdclk[slave->pipe] = min_cdclk;
+			dev_priv->min_voltage_level[slave->pipe] =
+				crtc_state->min_voltage_level;
+
+			for_each_intel_plane_on_crtc(&dev_priv->drm, slave, plane) {
+				const struct intel_plane_state *plane_state =
+					to_intel_plane_state(plane->base.state);
+
+				/*
+				* FIXME don't have the fb yet, so can't
+				* use intel_plane_data_rate() :(
+				*/
+				if (plane_state->base.visible)
+					crtc_state->data_rate[plane->id] =
+						4 * crtc_state->pixel_rate;
+				else
+					crtc_state->data_rate[plane->id] = 0;
+			}
+
+			intel_bw_crtc_update(bw_state, slave_crtc_state);
+			drm_calc_timestamping_constants(&slave->base,
+							&slave_crtc_state->hw.adjusted_mode);
+		}
 	}
 }
 
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (11 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 13/23] drm/i915: Make hardware readout work on i915 Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-27  3:18   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration Maarten Lankhorst
                   ` (15 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

We want to program slave planes with the master plane_state for
properties such as FB, rotation, coordinates, etc, but the
slave plane_state for all programming parameters.

Instead of special casing NV12 Y-planes, we make the code more
generic, Y planes are programmed with separate state from the UV
plane.

This will allow us to program planes on a bigjoiner slave crtc in
a similar way.

This also requires the VMA to be copied to the slave, which is
done in prepare_plane_fb().

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 21 +++---
 .../gpu/drm/i915/display/intel_atomic_plane.h |  3 -
 drivers/gpu/drm/i915/display/intel_display.c  | 56 ++++++++++++--
 drivers/gpu/drm/i915/display/intel_display.h  |  3 +-
 .../drm/i915/display/intel_display_types.h    |  6 +-
 drivers/gpu/drm/i915/display/intel_sprite.c   | 75 ++++++++++---------
 6 files changed, 106 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index a1a34b9981cc..964db7774d10 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -277,14 +277,15 @@ void intel_update_plane(struct intel_plane *plane,
 	plane->update_plane(plane, crtc_state, plane_state);
 }
 
-void intel_update_slave(struct intel_plane *plane,
-			const struct intel_crtc_state *crtc_state,
-			const struct intel_plane_state *plane_state)
+static void intel_update_slave(struct intel_plane *plane,
+			       const struct intel_crtc_state *crtc_state,
+			       const struct intel_plane_state *master_plane_state,
+			       const struct intel_plane_state *slave_plane_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 
 	trace_intel_update_plane(&plane->base, crtc);
-	plane->update_slave(plane, crtc_state, plane_state);
+	plane->update_slave(plane, crtc_state, master_plane_state, slave_plane_state);
 }
 
 void intel_disable_plane(struct intel_plane *plane,
@@ -324,6 +325,8 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
 		} else if (new_plane_state->planar_slave) {
 			struct intel_plane *master =
 				new_plane_state->planar_linked_plane;
+			struct intel_plane_state *master_plane_state =
+				intel_atomic_get_new_plane_state(state, master);
 
 			/*
 			 * We update the slave plane from this function because
@@ -331,13 +334,11 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
 			 * callback runs into issues when the Y plane is
 			 * reassigned, disabled or used by a different plane.
 			 *
-			 * The slave plane is updated with the master plane's
-			 * plane_state.
+			 * The slave plane is updated with the master's
+			 * plane_state as extra argument.
 			 */
-			new_plane_state =
-				intel_atomic_get_new_plane_state(state, master);
-
-			intel_update_slave(plane, new_crtc_state, new_plane_state);
+			intel_update_slave(plane, new_crtc_state,
+					   master_plane_state, new_plane_state);
 		} else {
 			intel_disable_plane(plane, new_crtc_state);
 		}
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index cb7ef4f9eafd..33fb85cd3909 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -23,9 +23,6 @@ unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
 void intel_update_plane(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
 			const struct intel_plane_state *plane_state);
-void intel_update_slave(struct intel_plane *plane,
-			const struct intel_crtc_state *crtc_state,
-			const struct intel_plane_state *plane_state);
 void intel_disable_plane(struct intel_plane *plane,
 			 const struct intel_crtc_state *crtc_state);
 struct intel_plane *intel_plane_alloc(void);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 0424a378eb51..df588bf47559 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3972,11 +3972,12 @@ static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
 		return intel_tile_width_bytes(fb, color_plane);
 }
 
-u32 skl_plane_stride(const struct intel_plane_state *plane_state,
+u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
+		     const struct intel_plane_state *plane_state,
 		     int color_plane)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	u32 stride = plane_state->color_plane[color_plane].stride;
 
 	if (color_plane >= fb->format->num_planes)
@@ -11900,6 +11901,23 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 		crtc_state->active_planes |= BIT(linked->id);
 		crtc_state->update_planes |= BIT(linked->id);
 		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
+
+		/* Copy parameters to slave plane */
+		linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE;
+		linked_state->color_ctl = plane_state->color_ctl;
+		linked_state->color_plane[0] = plane_state->color_plane[0];
+
+		linked_state->base.src = plane_state->base.src;
+		linked_state->base.dst = plane_state->base.dst;
+
+		if (icl_is_hdr_plane(dev_priv, plane->id)) {
+			if (linked->id == PLANE_SPRITE5)
+				plane_state->cus_ctl |= PLANE_CUS_PLANE_7;
+			else if (linked->id == PLANE_SPRITE4)
+				plane_state->cus_ctl |= PLANE_CUS_PLANE_6;
+			else
+				MISSING_CASE(linked->id);
+		}
 	}
 
 	return 0;
@@ -14782,6 +14800,23 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 			return ret;
 	}
 
+	if (to_intel_plane_state(new_state)->planar_slave) {
+		struct intel_plane_state *new_plane_state = to_intel_plane_state(new_state);
+		const struct intel_plane_state *linked_plane_state =
+			intel_atomic_get_new_plane_state(intel_state, new_plane_state->planar_linked_plane);
+
+		/*
+		 * We are a planar slave, VMA is on our planar master,
+		 * but may not be the same as the bigjoiner master plane.
+		 *
+		 * Copy the vma from our planar master and return.
+		 */
+		if (linked_plane_state->vma)
+			new_plane_state->vma =
+				i915_vma_get(linked_plane_state->vma);
+		return 0;
+	}
+
 	if (!obj)
 		return 0;
 
@@ -14851,10 +14886,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
  */
 void
 intel_cleanup_plane_fb(struct drm_plane *plane,
-		       struct drm_plane_state *old_state)
+		       struct drm_plane_state *_old_state)
 {
+	struct intel_plane_state *old_state = to_intel_plane_state(_old_state);
 	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(old_state->state);
+		to_intel_atomic_state(old_state->base.state);
 	struct drm_i915_private *dev_priv = to_i915(plane->dev);
 
 	if (intel_state->rps_interactive) {
@@ -14862,9 +14898,17 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 		intel_state->rps_interactive = false;
 	}
 
+	/* pin is handled in master plane_state for planar formats */
+	if (old_state->planar_slave) {
+		if (old_state->vma)
+			i915_vma_put(old_state->vma);
+		old_state->vma = NULL;
+		return;
+	}
+
 	/* Should only be called after a successful intel_prepare_plane_fb()! */
 	mutex_lock(&dev_priv->drm.struct_mutex);
-	intel_plane_unpin_fb(to_intel_plane_state(old_state));
+	intel_plane_unpin_fb(old_state);
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index b1ae0e59c715..764d05d13b9e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -560,7 +560,8 @@ u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state);
 u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
 		  const struct intel_plane_state *plane_state);
 u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
-u32 skl_plane_stride(const struct intel_plane_state *plane_state,
+u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
+		     const struct intel_plane_state *plane_state,
 		     int plane);
 int skl_check_plane_surface(struct intel_plane_state *plane_state);
 int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7e06c61447e6..ace372a76330 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -538,6 +538,9 @@ struct intel_plane_state {
 	/* plane color control register */
 	u32 color_ctl;
 
+	/* chroma upsampler control register */
+	u32 cus_ctl;
+
 	/*
 	 * scaler_id
 	 *    = -1 : not using a scaler
@@ -1097,7 +1100,8 @@ struct intel_plane {
 			     const struct intel_plane_state *plane_state);
 	void (*update_slave)(struct intel_plane *plane,
 			     const struct intel_crtc_state *crtc_state,
-			     const struct intel_plane_state *plane_state);
+			     const struct intel_plane_state *master_plane_state,
+			     const struct intel_plane_state *slave_plane_state);
 	void (*disable_plane)(struct intel_plane *plane,
 			      const struct intel_crtc_state *crtc_state);
 	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index f0956fecdea4..bca7ff8a8907 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -346,10 +346,11 @@ skl_plane_max_stride(struct intel_plane *plane,
 static void
 skl_program_scaler(struct intel_plane *plane,
 		   const struct intel_crtc_state *crtc_state,
+		   const struct intel_plane_state *master_plane_state,
 		   const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	int scaler_id = plane_state->scaler_id;
 	const struct intel_scaler *scaler =
@@ -527,28 +528,29 @@ icl_program_input_csc(struct intel_plane *plane,
 static void
 skl_program_plane(struct intel_plane *plane,
 		  const struct intel_crtc_state *crtc_state,
+		  const struct intel_plane_state *master_plane_state,
 		  const struct intel_plane_state *plane_state,
-		  int color_plane, bool slave, u32 plane_ctl)
+		  int color_plane)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum plane_id plane_id = plane->id;
 	enum pipe pipe = plane->pipe;
-	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
+	const struct drm_intel_sprite_colorkey *key = &master_plane_state->ckey;
 	u32 surf_addr = plane_state->color_plane[color_plane].offset;
-	u32 stride = skl_plane_stride(plane_state, color_plane);
-	u32 aux_stride = skl_plane_stride(plane_state, 1);
+	u32 stride = skl_plane_stride(master_plane_state, plane_state, color_plane);
+	u32 aux_stride = skl_plane_stride(master_plane_state, plane_state, 1);
 	int crtc_x = plane_state->base.dst.x1;
 	int crtc_y = plane_state->base.dst.y1;
 	u32 x = plane_state->color_plane[color_plane].x;
 	u32 y = plane_state->color_plane[color_plane].y;
 	u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
 	u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
-	struct intel_plane *linked = plane_state->planar_linked_plane;
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	u8 alpha = plane_state->base.alpha >> 8;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	u8 alpha = master_plane_state->base.alpha >> 8;
 	u32 plane_color_ctl = 0;
 	unsigned long irqflags;
 	u32 keymsk, keymax;
+	u32 plane_ctl = plane_state->ctl;
 
 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
 
@@ -580,32 +582,14 @@ skl_program_plane(struct intel_plane *plane,
 	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
 		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
 
-	if (icl_is_hdr_plane(dev_priv, plane_id)) {
-		u32 cus_ctl = 0;
-
-		if (linked) {
-			/* Enable and use MPEG-2 chroma siting */
-			cus_ctl = PLANE_CUS_ENABLE |
-				PLANE_CUS_HPHASE_0 |
-				PLANE_CUS_VPHASE_SIGN_NEGATIVE |
-				PLANE_CUS_VPHASE_0_25;
-
-			if (linked->id == PLANE_SPRITE5)
-				cus_ctl |= PLANE_CUS_PLANE_7;
-			else if (linked->id == PLANE_SPRITE4)
-				cus_ctl |= PLANE_CUS_PLANE_6;
-			else
-				MISSING_CASE(linked->id);
-		}
-
-		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
-	}
+	if (icl_is_hdr_plane(dev_priv, plane_id))
+		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl);
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		I915_WRITE_FW(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);
+		icl_program_input_csc(plane, crtc_state, master_plane_state);
 
 	skl_write_plane_wm(plane, crtc_state);
 
@@ -629,8 +613,8 @@ skl_program_plane(struct intel_plane *plane,
 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
 
-	if (!slave && plane_state->scaler_id >= 0)
-		skl_program_scaler(plane, crtc_state, plane_state);
+	if (plane_state->scaler_id >= 0)
+		skl_program_scaler(plane, crtc_state, master_plane_state, plane_state);
 
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
@@ -647,17 +631,26 @@ skl_update_plane(struct intel_plane *plane,
 		color_plane = 1;
 	}
 
-	skl_program_plane(plane, crtc_state, plane_state,
-			  color_plane, false, plane_state->ctl);
+	skl_program_plane(plane, crtc_state, plane_state, plane_state, color_plane);
 }
 
 static void
 icl_update_slave(struct intel_plane *plane,
 		 const struct intel_crtc_state *crtc_state,
-		 const struct intel_plane_state *plane_state)
+		 const struct intel_plane_state *master_plane_state,
+		 const struct intel_plane_state *slave_plane_state)
 {
-	skl_program_plane(plane, crtc_state, plane_state, 0, true,
-			  plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	int color_plane = 0;
+
+	if (drm_format_info_is_yuv_semiplanar(fb->format) &&
+	    !slave_plane_state->planar_slave) {
+		/* Program the UV plane, even as slave (Big joiner). */
+		color_plane = 1;
+	}
+
+	skl_program_plane(plane, crtc_state, master_plane_state,
+			  slave_plane_state, color_plane);
 }
 
 static void
@@ -1845,6 +1838,14 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
 							     plane_state);
 
+	if (icl_is_hdr_plane(dev_priv, plane->id) && fb->format->is_yuv)
+		/* Enable and use MPEG-2 chroma siting */
+		plane_state->cus_ctl = PLANE_CUS_ENABLE |
+			PLANE_CUS_HPHASE_0 |
+			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
+	else
+		plane_state->cus_ctl = 0;
+
 	return 0;
 }
 
@@ -2513,7 +2514,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 	plane->disable_plane = skl_disable_plane;
 	plane->get_hw_state = skl_plane_get_hw_state;
 	plane->check_plane = skl_plane_check;
-	if (icl_is_nv12_y_plane(plane_id))
+	if (INTEL_GEN(dev_priv) >= 11)
 		plane->update_slave = icl_update_slave;
 
 	if (INTEL_GEN(dev_priv) >= 11)
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (12 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-10-01 16:44   ` Matt Roper
  2019-09-20 11:42 ` [PATCH 16/23] drm/i915: Program planes in bigjoiner mode Maarten Lankhorst
                   ` (14 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Make sure that when a plane is set in a bigjoiner mode, we will add
their counterpart to the atomic state as well. This will allow us to
make sure all state is available when planes are checked.

Because of the funny interactions with bigjoiner and planar YUV
formats, we may end up adding a lot of planes, so we have to keep
iterating until we no longer add any planes.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  31 +++-
 .../gpu/drm/i915/display/intel_atomic_plane.h |   4 +
 drivers/gpu/drm/i915/display/intel_display.c  | 142 ++++++++++++++++--
 .../drm/i915/display/intel_display_types.h    |  11 ++
 4 files changed, 172 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 964db7774d10..cc088676f0a2 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -182,16 +182,36 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					       old_plane_state, new_plane_state);
 }
 
-static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
-		     const struct intel_plane_state *new_plane_state)
-{
+struct intel_crtc *
+intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
+				 const struct intel_plane_state *old_plane_state,
+				 const struct intel_plane_state *new_plane_state)
+  {
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
+
 	if (new_plane_state->base.crtc)
 		return to_intel_crtc(new_plane_state->base.crtc);
 
 	if (old_plane_state->base.crtc)
 		return to_intel_crtc(old_plane_state->base.crtc);
 
+	if (new_plane_state->bigjoiner_slave) {
+		const struct intel_plane_state *new_master_plane_state =
+			intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
+
+		if (new_master_plane_state->base.crtc)
+			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
+	}
+
+	if (old_plane_state->bigjoiner_slave) {
+		const struct intel_plane_state *old_master_plane_state =
+			intel_atomic_get_old_plane_state(state, old_plane_state->bigjoiner_plane);
+
+		if (old_master_plane_state->base.crtc)
+			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
+	}
+
 	return NULL;
 }
 
@@ -206,7 +226,8 @@ static int intel_plane_atomic_check(struct drm_plane *_plane,
 	const struct intel_plane_state *old_plane_state =
 		intel_atomic_get_old_plane_state(state, plane);
 	struct intel_crtc *crtc =
-		get_crtc_from_states(old_plane_state, new_plane_state);
+		intel_plane_get_crtc_from_states(state, old_plane_state,
+						 new_plane_state);
 	const struct intel_crtc_state *old_crtc_state;
 	struct intel_crtc_state *new_crtc_state;
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 33fb85cd3909..901a50e6e2d3 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -42,5 +42,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 				    struct intel_crtc_state *crtc_state,
 				    const struct intel_plane_state *old_plane_state,
 				    struct intel_plane_state *plane_state);
+struct intel_crtc *
+intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
+				 const struct intel_plane_state *old_plane_state,
+				 const struct intel_plane_state *new_plane_state);
 
 #endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index df588bf47559..06ceac4f1436 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -11811,24 +11811,101 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
 	return true;
 }
 
+static int icl_add_dependent_planes(struct intel_atomic_state *state,
+				    struct intel_plane_state *plane_state)
+{
+	struct intel_plane_state *new_plane_state;
+	struct intel_plane *plane;
+	int ret = 0;
+
+	plane = plane_state->bigjoiner_plane;
+	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
+		new_plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(new_plane_state))
+			return PTR_ERR(new_plane_state);
+
+		ret = 1;
+	}
+
+	plane = plane_state->planar_linked_plane;
+	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
+		new_plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(new_plane_state))
+			return PTR_ERR(new_plane_state);
+
+		ret = 1;
+	}
+
+	return ret;
+}
+
 static int icl_add_linked_planes(struct intel_atomic_state *state)
 {
-	struct intel_plane *plane, *linked;
-	struct intel_plane_state *plane_state, *linked_plane_state;
+	struct intel_plane *plane;
+	struct intel_plane_state *old_plane_state, *new_plane_state;
+	struct intel_crtc *crtc, *linked_crtc;
+	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *linked_crtc_state;
+	bool added;
 	int i;
 
-	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
-		linked = plane_state->planar_linked_plane;
+	/*
+	 * Iteratively add plane_state->linked_plane and plane_state->bigjoiner_plane
+	 *
+	 * This needs to be done repeatedly, because of is a funny interaction;
+	 * the Y-plane may be assigned differently on the other bigjoiner crtc,
+	 * and we could end up with the following evil recursion, when only adding a
+	 * single plane to state:
+	 *
+	 * XRGB8888 master plane 6 adds NV12 slave Y-plane 6, which adds slave UV plane 0,
+	 * which adds master UV plane 0, which adds master Y-plane 7, which adds XRGB8888
+	 * slave plane 7.
+	 *
+	 * We could pull in even more because of old_plane_state vs new_plane_state.
+	 *
+	 * Max depth = 5 (or 7 for evil case) in this case.
+	 * Number of passes will be less, because newly added planes show up in the
+	 * same iteration round when added_plane->index > plane->index.
+	 */
+	do {
+		added = false;
 
-		if (!linked)
-			continue;
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
+			int ret, ret2;
+
+			ret = icl_add_dependent_planes(state, old_plane_state);
+			if (ret < 0)
+				return ret;
+
+			ret2 = icl_add_dependent_planes(state, new_plane_state);
+			if (ret2 < 0)
+				return ret2;
 
-		linked_plane_state = intel_atomic_get_plane_state(state, linked);
-		if (IS_ERR(linked_plane_state))
-			return PTR_ERR(linked_plane_state);
+			added |= ret || ret2;
+		}
+	} while (added);
+
+	/*
+	 * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically
+	 * when adding slave planes, because plane_state->crtc is null.
+	 */
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+		linked_crtc = old_crtc_state->bigjoiner_linked_crtc;
+		if (linked_crtc) {
+			linked_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, linked_crtc);
+
+			if (IS_ERR(linked_crtc_state))
+				return PTR_ERR(linked_crtc_state);
+		}
+
+		linked_crtc = new_crtc_state->bigjoiner_linked_crtc;
+		if (linked_crtc && linked_crtc != old_crtc_state->bigjoiner_linked_crtc) {
+			linked_crtc_state =
+				intel_atomic_get_crtc_state(&state->base, linked_crtc);
 
-		WARN_ON(linked_plane_state->planar_linked_plane != plane);
-		WARN_ON(linked_plane_state->planar_slave == plane_state->planar_slave);
+			if (IS_ERR(linked_crtc_state))
+				return PTR_ERR(linked_crtc_state);
+		}
 	}
 
 	return 0;
@@ -13799,6 +13876,7 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
 	struct intel_crtc *crtc, *slave, *master;
+	struct intel_plane *plane;
 	int i, ret = 0;
 
 	if (INTEL_GEN(dev_priv) < 11)
@@ -13894,6 +13972,48 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
 			return ret;
 	}
 
+	/*
+	 * Setup and teardown the new bigjoiner plane mappings.
+	 */
+	for_each_intel_plane(&dev_priv->drm, plane) {
+		struct intel_plane_state *plane_state;
+		struct intel_plane *other_plane = NULL;
+
+		crtc = intel_get_crtc_for_pipe(dev_priv, plane->pipe);
+		old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
+		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+
+		if (!new_crtc_state || !needs_modeset(new_crtc_state))
+			continue;
+
+		if (new_crtc_state->bigjoiner) {
+			struct intel_crtc *other_crtc =
+				new_crtc_state->bigjoiner_linked_crtc;
+			bool found = false;
+
+			for_each_intel_plane_on_crtc(&dev_priv->drm, other_crtc, other_plane) {
+				if (other_plane->id != plane->id)
+					continue;
+
+				found = true;
+				break;
+			}
+
+			/* All pipes should have identical planes. */
+			if (WARN_ON(!found))
+				return -EINVAL;
+		} else if (!old_crtc_state->bigjoiner) {
+			continue;
+		}
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		plane_state->bigjoiner_plane = other_plane;
+		plane_state->bigjoiner_slave = new_crtc_state->bigjoiner_slave;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index ace372a76330..f05f4830a529 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -571,6 +571,17 @@ struct intel_plane_state {
 	 */
 	struct intel_plane *planar_linked_plane;
 
+	/*
+	 * bigjoiner_plane:
+	 *
+	 * When 2 pipes are joined in a bigjoiner configuration,
+	 * points to the same plane on the other pipe.
+	 *
+	 * bigjoiner_slave is set on the slave pipe.
+	 */
+	struct intel_plane *bigjoiner_plane;
+	u32 bigjoiner_slave;
+
 	/*
 	 * planar_slave:
 	 * If set don't update use the linked plane's state for updating
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (13 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-26 13:06   ` Ville Syrjälä
  2019-09-20 11:42 ` [PATCH 17/23] drm/i915: Add intel_update_bigjoiner handling Maarten Lankhorst
                   ` (13 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Now that we can program planes from the update_slave callback, and
we have done all fb pinning correctly, it's time to program those
planes as well.

We use the update_slave callback as it allows us to use the
separate states correctly.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
 drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index cc088676f0a2..5db091e4ad6a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
 	}
 }
 
+void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
+					 struct intel_crtc *crtc)
+{
+	struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	struct skl_ddb_entry entries_y[I915_MAX_PLANES];
+	struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
+	u32 update_mask = new_crtc_state->update_planes;
+	struct intel_plane *plane;
+
+	memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
+	       sizeof(old_crtc_state->wm.skl.plane_ddb_y));
+	memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
+	       sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
+
+	while ((plane = skl_next_plane_to_commit(state, crtc,
+						 entries_y, entries_uv,
+						 &update_mask))) {
+		struct intel_plane_state *new_plane_state =
+			intel_atomic_get_new_plane_state(state, plane);
+		const struct intel_plane_state *master_plane_state;
+
+		if (new_plane_state->base.visible) {
+			master_plane_state =
+				intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
+
+			intel_update_slave(plane, new_crtc_state,
+					   master_plane_state, new_plane_state);
+		} else if (new_plane_state->slave) {
+			/*
+			 * bigjoiner slave + planar slave.
+			 * The correct sequence is to get from the planar slave to planar master,
+			 * then to the master plane state for the master_plane_state.
+			 */
+
+			struct intel_plane *linked = new_plane_state->linked_plane;
+			const struct intel_plane_state *uv_plane_state =
+				intel_atomic_get_new_plane_state(state, linked);
+
+			linked = uv_plane_state->bigjoiner_plane;
+			master_plane_state =
+				intel_atomic_get_new_plane_state(state, linked);
+
+			intel_update_slave(plane, new_crtc_state,
+					   master_plane_state, new_plane_state);
+		} else {
+			intel_disable_plane(plane, new_crtc_state);
+		}
+	}
+}
+
 void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
 				struct intel_crtc *crtc)
 {
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 901a50e6e2d3..1cffda2b50b5 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -30,6 +30,8 @@ void intel_plane_free(struct intel_plane *plane);
 struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
 void intel_plane_destroy_state(struct drm_plane *plane,
 			       struct drm_plane_state *state);
+void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
+					 struct intel_crtc *crtc);
 void skl_update_planes_on_crtc(struct intel_atomic_state *state,
 			       struct intel_crtc *crtc);
 void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 06ceac4f1436..acb3c5974e99 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14223,8 +14223,8 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	commit_pipe_config(state, old_crtc_state, new_crtc_state);
 
-	if (new_crtc_state->bigjoiner)
-		{/* Not supported yet */}
+	if (new_crtc_state->bigjoiner_slave)
+		icl_update_bigjoiner_planes_on_crtc(state, crtc);
 	else if (INTEL_GEN(dev_priv) >= 9)
 		skl_update_planes_on_crtc(state, crtc);
 	else
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 17/23] drm/i915: Add intel_update_bigjoiner handling.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (14 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 16/23] drm/i915: Program planes in bigjoiner mode Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 18/23] drm/i915: Disable FBC in bigjoiner configuration Maarten Lankhorst
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Enabling is done in a special sequence and to be fair, so should
plane updates be. Ideally the end user never notices the second
pipe is used, so use the vblank evasion to cover both pipes.

This way ideally everything will be tear free, and updates are
really atomic as userspace expects it.

The disable sequence still needs some love, but otherwise bigjoiner
is close to ready now.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 118 ++++++++++++++++---
 drivers/gpu/drm/i915/display/intel_sprite.c  |  22 +++-
 drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
 3 files changed, 123 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index acb3c5974e99..7f86c358cf45 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14230,7 +14230,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 	else
 		i9xx_update_planes_on_crtc(state, crtc);
 
-	intel_pipe_update_end(new_crtc_state);
+	intel_pipe_update_end(new_crtc_state, NULL);
 
 	if (new_crtc_state->update_pipe && !modeset &&
 	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
@@ -14312,6 +14312,56 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	}
 }
 
+static void intel_update_bigjoiner(struct intel_crtc *crtc,
+				   struct intel_atomic_state *state,
+				   struct intel_crtc_state *old_crtc_state,
+				   struct intel_crtc_state *new_crtc_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+	bool modeset = needs_modeset(new_crtc_state);
+	struct intel_crtc *slave = new_crtc_state->bigjoiner_linked_crtc;
+	struct intel_crtc_state *new_slave_crtc_state =
+		intel_atomic_get_new_crtc_state(state, slave);
+	struct intel_crtc_state *old_slave_crtc_state =
+		intel_atomic_get_old_crtc_state(state, slave);
+
+	if (modeset) {
+		/* Enable slave first */
+		update_scanline_offset(new_slave_crtc_state);
+		drm_calc_timestamping_constants(&slave->base, &new_slave_crtc_state->hw.transcoder_mode);
+		dev_priv->display.crtc_enable(new_slave_crtc_state, state);
+
+		/* Then master */
+		update_scanline_offset(new_crtc_state);
+		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.transcoder_mode);
+		dev_priv->display.crtc_enable(new_crtc_state, state);
+
+		/* vblanks work again, re-enable pipe CRC. */
+		intel_crtc_enable_pipe_crc(crtc);
+
+	} else {
+		intel_pre_plane_update(old_crtc_state, new_crtc_state);
+		intel_pre_plane_update(old_slave_crtc_state, new_slave_crtc_state);
+
+		if (new_crtc_state->update_pipe)
+			intel_encoders_update_pipe(crtc, new_crtc_state, state);
+	}
+
+	/*
+	 * Perform vblank evasion around commit operation, and make sure to
+	 * commit both planes simultaneously for best results.
+	 */
+	intel_pipe_update_start(new_crtc_state);
+
+	commit_pipe_config(state, old_crtc_state, new_crtc_state);
+	commit_pipe_config(state, old_slave_crtc_state, new_slave_crtc_state);
+
+	skl_update_planes_on_crtc(state, crtc);
+	icl_update_bigjoiner_planes_on_crtc(state, slave);
+
+	intel_pipe_update_end(new_crtc_state, new_slave_crtc_state);
+}
+
 static void intel_commit_modeset_enables(struct intel_atomic_state *state)
 {
 	struct intel_crtc *crtc;
@@ -14330,7 +14380,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
 static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-	struct intel_crtc *crtc;
+	struct intel_crtc *crtc, *slave;
 	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
 	unsigned int updated = 0;
 	bool progress;
@@ -14339,11 +14389,47 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 	u8 hw_enabled_slices = dev_priv->wm.skl_hw.ddb.enabled_slices;
 	u8 required_slices = state->wm_results.ddb.enabled_slices;
 	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
+	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
+	const struct intel_crtc_state *slave_crtc_state;
+	u32 dirty_pipes = state->wm_results.dirty_pipes;
+
+	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
+		if (new_crtc_state->bigjoiner_slave) {
+			/* clear dirty bit, we're updated in master */
+			dirty_pipes &= ~drm_crtc_mask(&crtc->base);
+			continue;
+		}
+
+		if (new_crtc_state->hw.active) {
+			if (new_crtc_state->bigjoiner) {
+				slave = new_crtc_state->bigjoiner_linked_crtc;
+				slave_crtc_state =
+					intel_atomic_get_new_crtc_state(state,
+									slave);
+
+				/* put both entries in */
+				new_entries[i].start = new_crtc_state->wm.skl.ddb.start;
+				new_entries[i].end = slave_crtc_state->wm.skl.ddb.end;
+			} else {
+				new_entries[i] = new_crtc_state->wm.skl.ddb;
+			}
+		}
 
-	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
 		/* ignore allocations for crtc's that have been turned off. */
-		if (new_crtc_state->hw.active)
+		if (!new_crtc_state->hw.active || needs_modeset(new_crtc_state))
+			continue;
+
+		if (old_crtc_state->bigjoiner) {
+			slave = old_crtc_state->bigjoiner_linked_crtc;
+			slave_crtc_state =
+				intel_atomic_get_old_crtc_state(state, slave);
+
+			entries[i].start = old_crtc_state->wm.skl.ddb.start;
+			entries[i].end = slave_crtc_state->wm.skl.ddb.end;
+		} else {
 			entries[i] = old_crtc_state->wm.skl.ddb;
+		}
+	}
 
 	/* If 2nd DBuf slice required, enable it here */
 	if (INTEL_GEN(dev_priv) >= 11 && required_slices > hw_enabled_slices)
@@ -14364,16 +14450,15 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 
 			pipe = crtc->pipe;
 
-			if (updated & cmask || !new_crtc_state->hw.active)
+			if (updated & cmask || !new_crtc_state->hw.active ||
+			    new_crtc_state->bigjoiner_slave)
 				continue;
 
-			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
-							entries,
+			if (skl_ddb_allocation_overlaps(&new_entries[i], entries,
 							INTEL_NUM_PIPES(dev_priv), i))
 				continue;
 
 			updated |= cmask;
-			entries[i] = new_crtc_state->wm.skl.ddb;
 
 			/*
 			 * If this is an already active pipe, it's DDB changed,
@@ -14381,18 +14466,23 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			 * then we need to wait for a vblank to pass for the
 			 * new ddb allocation to take effect.
 			 */
-			if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
-						 &old_crtc_state->wm.skl.ddb) &&
-			    !new_crtc_state->uapi.active_changed &&
-			    state->wm_results.dirty_pipes != updated)
+			if (!skl_ddb_entry_equal(&entries[i], &new_entries[i]) &&
+			    !needs_modeset(new_crtc_state) &&
+			    dirty_pipes != updated)
 				vbl_wait = true;
 
-			intel_update_crtc(crtc, state, old_crtc_state,
-					  new_crtc_state);
+			if (new_crtc_state->bigjoiner)
+				intel_update_bigjoiner(crtc, state,
+						       old_crtc_state,
+						       new_crtc_state);
+			else
+				intel_update_crtc(crtc, state, old_crtc_state,
+						  new_crtc_state);
 
 			if (vbl_wait)
 				intel_wait_for_vblank(dev_priv, pipe);
 
+			entries[i] = new_entries[i];
 			progress = true;
 		}
 	} while (progress);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index bca7ff8a8907..9337f5a8dce0 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -98,6 +98,8 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
 
 	/* FIXME needs to be calibrated sensibly */
 	min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
+						      new_crtc_state->bigjoiner ?
+						      2 * VBLANK_EVASION_TIME_US :
 						      VBLANK_EVASION_TIME_US);
 	max = vblank_start - 1;
 
@@ -188,7 +190,8 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
  * re-enables interrupts and verifies the update was actually completed
  * before a vblank.
  */
-void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
+void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
+			   struct intel_crtc_state *slave_crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
 	enum pipe pipe = crtc->pipe;
@@ -203,15 +206,24 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
 	 * Would be slightly nice to just grab the vblank count and arm the
 	 * event outside of the critical section - the spinlock might spin for a
 	 * while ... */
-	if (new_crtc_state->uapi.event) {
-		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
+	if (new_crtc_state->uapi.event || (slave_crtc_state && slave_crtc_state->uapi.event)) {
+		if (new_crtc_state->uapi.event)
+			WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
+		if (slave_crtc_state && slave_crtc_state->uapi.event)
+			WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
 
 		spin_lock(&crtc->base.dev->event_lock);
-		drm_crtc_arm_vblank_event(&crtc->base,
-				          new_crtc_state->uapi.event);
+		if (new_crtc_state->uapi.event)
+			drm_crtc_arm_vblank_event(&crtc->base,
+						  new_crtc_state->uapi.event);
+		if (slave_crtc_state && slave_crtc_state->uapi.event)
+			drm_crtc_arm_vblank_event(&crtc->base,
+						  slave_crtc_state->uapi.event);
 		spin_unlock(&crtc->base.dev->event_lock);
 
 		new_crtc_state->uapi.event = NULL;
+		if (slave_crtc_state)
+			slave_crtc_state->uapi.event = NULL;
 	}
 
 	local_irq_enable();
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h
index 229336214f68..6df62fae9368 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite.h
@@ -24,7 +24,8 @@ struct intel_plane *intel_sprite_plane_create(struct drm_i915_private *dev_priv,
 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
 				    struct drm_file *file_priv);
 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state);
-void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state);
+void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
+			   struct intel_crtc_state *slave_crtc_state);
 int intel_plane_check_stride(const struct intel_plane_state *plane_state);
 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
 int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 18/23] drm/i915: Disable FBC in bigjoiner configuration.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (15 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 17/23] drm/i915: Add intel_update_bigjoiner handling Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 19/23] drm/i915: Prepare atomic plane check for bigjoiner planes Maarten Lankhorst
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Is there any point in having FBC enabled on half a screen?
I suppose it could still save power, but just feels wrong..
Can always be enabled later again if required.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_fbc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index c6cc3775f3b8..e4d678d425e4 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -1056,6 +1056,8 @@ void intel_fbc_choose_crtc(struct drm_i915_private *dev_priv,
 			continue;
 
 		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+		if (crtc_state->bigjoiner)
+			continue;
 
 		crtc_state->enable_fbc = true;
 		crtc_chosen = true;
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 19/23] drm/i915: Prepare atomic plane check for bigjoiner planes
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (16 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 18/23] drm/i915: Disable FBC in bigjoiner configuration Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 20/23] drm/i915: Make prepare_plane_fb() work with " Maarten Lankhorst
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

A lot of delta, the main difference is that the master_plane_state is
not the same plane_state as being written to.

We read all properties like color key, crtc, fb, rotation from the
master_plane_state and coordinate properties.

The coordinate properties are different between the 2 bigjoiner planes,
as one gets the left and the other gets the right side.

Fortunately the drm core already has a src and dst rect, so we write
those for each plane separately.

In case of cursor, we don't use the clipped coordinates, but the raw
source coordinates from the master_plane_state instead.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |   7 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c |  88 +++++++-
 .../gpu/drm/i915/display/intel_atomic_plane.h |   8 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 213 ++++++++++--------
 drivers/gpu/drm/i915/display/intel_display.h  |   5 +-
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_sprite.c   |  71 +++---
 drivers/gpu/drm/i915/display/intel_sprite.h   |   6 +-
 8 files changed, 258 insertions(+), 141 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 0db04064c86e..a8f34254cd2a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -297,9 +297,10 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
 		return;
 
 	/* set scaler mode */
-	if (plane_state && plane_state->base.fb &&
-	    plane_state->base.fb->format->is_yuv &&
-	    plane_state->base.fb->format->num_planes > 1) {
+	if (plane_state && (plane_state->linked_plane ||
+	     (!plane_state->bigjoiner_slave && plane_state->base.fb &&
+	      plane_state->base.fb->format->is_yuv &&
+	      plane_state->base.fb->format->num_planes > 1))) {
 		struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 		if (IS_GEN(dev_priv, 9) &&
 		    !IS_GEMINILAKE(dev_priv)) {
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 5db091e4ad6a..a0c1d1696c8c 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -115,10 +115,11 @@ intel_plane_destroy_state(struct drm_plane *plane,
 	drm_atomic_helper_plane_destroy_state(plane, state);
 }
 
-unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
-				   const struct intel_plane_state *plane_state)
+static unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
+					  const struct intel_plane_state *master_plane_state,
+					  const struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	unsigned int cpp;
 
 	if (!plane_state->base.visible)
@@ -143,8 +144,12 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					const struct intel_plane_state *old_plane_state,
 					struct intel_plane_state *new_plane_state)
 {
+	const struct intel_plane_state *new_master_plane_state = new_plane_state;
+	const struct intel_plane_state *old_master_plane_state = old_plane_state;
 	struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
-	const struct drm_framebuffer *fb = new_plane_state->base.fb;
+	const struct drm_framebuffer *fb;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(new_plane_state->base.state);
 	int ret;
 
 	new_crtc_state->active_planes &= ~BIT(plane->id);
@@ -153,10 +158,21 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 	new_crtc_state->data_rate[plane->id] = 0;
 	new_plane_state->base.visible = false;
 
-	if (!new_plane_state->base.crtc && !old_plane_state->base.crtc)
+	if (old_plane_state->bigjoiner_slave)
+		old_master_plane_state =
+			intel_atomic_get_old_plane_state(state,
+					old_plane_state->bigjoiner_plane);
+
+	if (new_plane_state->bigjoiner_slave)
+		new_master_plane_state =
+			intel_atomic_get_new_plane_state(state,
+					new_plane_state->bigjoiner_plane);
+
+	if (!new_master_plane_state->base.crtc && !old_master_plane_state->base.crtc)
 		return 0;
 
-	ret = plane->check_plane(new_crtc_state, new_plane_state);
+	ret = plane->check_plane(new_crtc_state,
+				 new_master_plane_state, new_plane_state);
 	if (ret)
 		return ret;
 
@@ -164,6 +180,7 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 	if (new_plane_state->base.visible)
 		new_crtc_state->active_planes |= BIT(plane->id);
 
+	fb = new_master_plane_state->base.fb;
 	if (new_plane_state->base.visible &&
 	    drm_format_info_is_yuv_semiplanar(fb->format))
 		new_crtc_state->nv12_planes |= BIT(plane->id);
@@ -176,10 +193,11 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 		new_crtc_state->update_planes |= BIT(plane->id);
 
 	new_crtc_state->data_rate[plane->id] =
-		intel_plane_data_rate(new_crtc_state, new_plane_state);
+		intel_plane_data_rate(new_crtc_state, new_master_plane_state, new_plane_state);
 
 	return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state,
-					       old_plane_state, new_plane_state);
+					       old_plane_state, new_master_plane_state,
+					       new_plane_state);
 }
 
 struct intel_crtc *
@@ -441,6 +459,60 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
 	}
 }
 
+
+int intel_atomic_plane_check_scaling(struct intel_crtc_state *crtc_state,
+				     const struct intel_plane_state *master_plane_state,
+				     struct intel_plane_state *plane_state,
+				     int min_scale, int max_scale)
+{
+	struct drm_framebuffer *fb = master_plane_state->base.fb;
+	struct drm_rect *src = &plane_state->base.src;
+	struct drm_rect *dst = &plane_state->base.dst;
+	unsigned int rotation = master_plane_state->base.rotation;
+	struct drm_rect clip = {};
+	int hscale, vscale;
+
+	*src = drm_plane_state_src(&master_plane_state->base);
+	*dst = drm_plane_state_dest(&master_plane_state->base);
+
+	if (!fb) {
+		plane_state->base.visible = false;
+		return 0;
+	}
+
+	drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
+
+	/* Check scaling */
+	hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+	vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
+	if (hscale < 0 || vscale < 0) {
+		DRM_DEBUG_KMS("Invalid scaling of plane\n");
+		drm_rect_debug_print("src: ", src, true);
+		drm_rect_debug_print("dst: ", dst, false);
+		return -ERANGE;
+	}
+
+	if (crtc_state->hw.enable) {
+		clip.x2 = crtc_state->pipe_src_w;
+		clip.y2 = crtc_state->pipe_src_h;
+	}
+
+	/* right side of the image is on the slave crtc, adjust dst to match */
+	if (crtc_state->bigjoiner_slave)
+		drm_rect_translate(dst, -crtc_state->pipe_src_w, 0);
+
+	/*
+	 * FIXME: This might need further adjustment for seamless scaling
+	 * with phase information, for the 2p2 and 2p1 scenarios.
+	 */
+
+	plane_state->base.visible = drm_rect_clip_scaled(src, dst, &clip);
+
+	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+
+	return 0;
+}
+
 const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
 	.prepare_fb = intel_prepare_plane_fb,
 	.cleanup_fb = intel_cleanup_plane_fb,
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 1cffda2b50b5..c98ccf8114c3 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -18,8 +18,6 @@ struct intel_plane_state;
 
 extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
 
-unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
-				   const struct intel_plane_state *plane_state);
 void intel_update_plane(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
 			const struct intel_plane_state *plane_state);
@@ -43,10 +41,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
 				    struct intel_crtc_state *crtc_state,
 				    const struct intel_plane_state *old_plane_state,
+				    const struct intel_plane_state *master_plane_state,
 				    struct intel_plane_state *plane_state);
 struct intel_crtc *
 intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
 				 const struct intel_plane_state *old_plane_state,
 				 const struct intel_plane_state *new_plane_state);
 
+int intel_atomic_plane_check_scaling(struct intel_crtc_state *crtc_state,
+				     const struct intel_plane_state *master_plane_state,
+				     struct intel_plane_state *plane_state,
+				     int min_scale, int max_scale);
+
 #endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 7f86c358cf45..690c3d10ce44 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -2289,12 +2289,13 @@ static u32 intel_adjust_aligned_offset(int *x, int *y,
  * the x/y offsets.
  */
 static u32 intel_plane_adjust_aligned_offset(int *x, int *y,
+					     const struct intel_plane_state *master_plane_state,
 					     const struct intel_plane_state *state,
 					     int color_plane,
 					     u32 old_offset, u32 new_offset)
 {
-	return intel_adjust_aligned_offset(x, y, state->base.fb, color_plane,
-					   state->base.rotation,
+	return intel_adjust_aligned_offset(x, y, master_plane_state->base.fb, color_plane,
+					   master_plane_state->base.rotation,
 					   state->color_plane[color_plane].stride,
 					   old_offset, new_offset);
 }
@@ -2365,14 +2366,15 @@ static u32 intel_compute_aligned_offset(struct drm_i915_private *dev_priv,
 }
 
 static u32 intel_plane_compute_aligned_offset(int *x, int *y,
-					      const struct intel_plane_state *state,
+					      const struct intel_plane_state *master_plane_state,
+					      const struct intel_plane_state *plane_state,
 					      int color_plane)
 {
-	struct intel_plane *intel_plane = to_intel_plane(state->base.plane);
+	struct intel_plane *intel_plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
-	const struct drm_framebuffer *fb = state->base.fb;
-	unsigned int rotation = state->base.rotation;
-	int pitch = state->color_plane[color_plane].stride;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
+	int pitch = plane_state->color_plane[color_plane].stride;
 	u32 alignment;
 
 	if (intel_plane->id == PLANE_CURSOR)
@@ -2594,11 +2596,12 @@ bool intel_plane_can_remap(const struct intel_plane_state *plane_state)
 	return true;
 }
 
-static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
+static bool intel_plane_needs_remap(const struct intel_plane_state *master_plane_state,
+				    const struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	u32 stride, max_stride;
 
 	/*
@@ -2608,7 +2611,7 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
 	if (!plane_state->base.visible)
 		return false;
 
-	if (!intel_plane_can_remap(plane_state))
+	if (!intel_plane_can_remap(master_plane_state))
 		return false;
 
 	/*
@@ -2788,14 +2791,15 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 }
 
 static void
-intel_plane_remap_gtt(struct intel_plane_state *plane_state)
+intel_plane_remap_gtt(const struct intel_plane_state *master_plane_state,
+		      struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(plane_state->base.plane->dev);
-	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_framebuffer *fb = master_plane_state->base.fb;
 	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 	struct intel_rotation_info *info = &plane_state->view.rotated;
-	unsigned int rotation = plane_state->base.rotation;
+	unsigned int rotation = master_plane_state->base.rotation;
 	int i, num_planes = fb->format->num_planes;
 	unsigned int tile_size = intel_tile_size(dev_priv);
 	unsigned int src_x, src_y;
@@ -2901,11 +2905,12 @@ intel_plane_remap_gtt(struct intel_plane_state *plane_state)
 }
 
 static int
-intel_plane_compute_gtt(struct intel_plane_state *plane_state)
+intel_plane_compute_gtt(const struct intel_plane_state *master_plane_state,
+			struct intel_plane_state *plane_state)
 {
 	const struct intel_framebuffer *fb =
-		to_intel_framebuffer(plane_state->base.fb);
-	unsigned int rotation = plane_state->base.rotation;
+		to_intel_framebuffer(master_plane_state->base.fb);
+	unsigned int rotation = master_plane_state->base.rotation;
 	int i, num_planes;
 
 	if (!fb)
@@ -2913,8 +2918,8 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
 
 	num_planes = fb->base.format->num_planes;
 
-	if (intel_plane_needs_remap(plane_state)) {
-		intel_plane_remap_gtt(plane_state);
+	if (intel_plane_needs_remap(master_plane_state, plane_state)) {
+		intel_plane_remap_gtt(master_plane_state, plane_state);
 
 		/*
 		 * Sometimes even remapping can't overcome
@@ -2922,7 +2927,7 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
 		 * big plane sizes and suitably misaligned
 		 * offsets.
 		 */
-		return intel_plane_check_stride(plane_state);
+		return intel_plane_check_stride(master_plane_state, plane_state);
 	}
 
 	intel_fill_fb_ggtt_view(&plane_state->view, &fb->base, rotation);
@@ -2946,7 +2951,7 @@ intel_plane_compute_gtt(struct intel_plane_state *plane_state)
 				fb->base.width << 16, fb->base.height << 16,
 				DRM_MODE_ROTATE_270);
 
-	return intel_plane_check_stride(plane_state);
+	return intel_plane_check_stride(master_plane_state, plane_state);
 }
 
 static int i9xx_format_to_fourcc(int format)
@@ -3363,10 +3368,11 @@ static int icl_max_plane_height(void)
 	return 4320;
 }
 
-static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
+static bool skl_check_main_ccs_coordinates(const struct intel_plane_state *master_plane_state,
+					   struct intel_plane_state *plane_state,
 					   int main_x, int main_y, u32 main_offset)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int hsub = fb->format->hsub;
 	int vsub = fb->format->vsub;
 	int aux_x = plane_state->color_plane[1].x;
@@ -3385,7 +3391,7 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
 
 		x = aux_x / hsub;
 		y = aux_y / vsub;
-		aux_offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 1,
+		aux_offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 1,
 							       aux_offset, aux_offset - alignment);
 		aux_x = x * hsub + aux_x % hsub;
 		aux_y = y * vsub + aux_y % vsub;
@@ -3401,11 +3407,12 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
 	return true;
 }
 
-static int skl_check_main_surface(struct intel_plane_state *plane_state)
+static int skl_check_main_surface(const struct intel_plane_state *master_plane_state,
+				  struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane_state->base.plane->dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	int x = plane_state->base.src.x1 >> 16;
 	int y = plane_state->base.src.y1 >> 16;
 	int w = drm_rect_width(&plane_state->base.src) >> 16;
@@ -3433,7 +3440,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 	}
 
 	intel_add_fb_offsets(&x, &y, plane_state, 0);
-	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 0);
+	offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 0);
 	alignment = intel_surf_alignment(fb, 0);
 
 	/*
@@ -3442,7 +3449,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 	 * sure that is what we will get.
 	 */
 	if (offset > aux_offset)
-		offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+		offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
 							   offset, aux_offset & ~(alignment - 1));
 
 	/*
@@ -3460,7 +3467,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 				return -EINVAL;
 			}
 
-			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+			offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
 								   offset, offset - alignment);
 		}
 	}
@@ -3470,11 +3477,11 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 	 * they match with the main surface x/y offsets.
 	 */
 	if (is_ccs_modifier(fb->modifier)) {
-		while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+		while (!skl_check_main_ccs_coordinates(master_plane_state, plane_state, x, y, offset)) {
 			if (offset == 0)
 				break;
 
-			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
+			offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,
 								   offset, offset - alignment);
 		}
 
@@ -3499,10 +3506,11 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 	return 0;
 }
 
-static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
+static int skl_check_nv12_aux_surface(const struct intel_plane_state *master_plane_state,
+				      struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	int max_width = skl_max_plane_width(fb, 1, rotation);
 	int max_height = 4096;
 	int x = plane_state->base.src.x1 >> 17;
@@ -3512,7 +3520,7 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 	u32 offset;
 
 	intel_add_fb_offsets(&x, &y, plane_state, 1);
-	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
+	offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 1);
 
 	/* FIXME not quite sure how/if these apply to the chroma plane */
 	if (w > max_width || h > max_height) {
@@ -3528,7 +3536,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 	return 0;
 }
 
-static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
+static int skl_check_ccs_aux_surface(const struct intel_plane_state *master_plane_state,
+				     struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	int src_x = plane_state->base.src.x1 >> 16;
@@ -3540,7 +3549,7 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
 	u32 offset;
 
 	intel_add_fb_offsets(&x, &y, plane_state, 1);
-	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
+	offset = intel_plane_compute_aligned_offset(&x, &y, master_plane_state, plane_state, 1);
 
 	plane_state->color_plane[1].offset = offset;
 	plane_state->color_plane[1].x = x * hsub + src_x % hsub;
@@ -3549,12 +3558,13 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
 	return 0;
 }
 
-int skl_check_plane_surface(struct intel_plane_state *plane_state)
+int skl_check_plane_surface(const struct intel_plane_state *master_plane_state,
+			    struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int ret;
 
-	ret = intel_plane_compute_gtt(plane_state);
+	ret = intel_plane_compute_gtt(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -3566,11 +3576,11 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
 	 * the main surface setup depends on it.
 	 */
 	if (drm_format_info_is_yuv_semiplanar(fb->format)) {
-		ret = skl_check_nv12_aux_surface(plane_state);
+		ret = skl_check_nv12_aux_surface(master_plane_state, plane_state);
 		if (ret)
 			return ret;
 	} else if (is_ccs_modifier(fb->modifier)) {
-		ret = skl_check_ccs_aux_surface(plane_state);
+		ret = skl_check_ccs_aux_surface(master_plane_state, plane_state);
 		if (ret)
 			return ret;
 	} else {
@@ -3579,11 +3589,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
 		plane_state->color_plane[1].y = 0;
 	}
 
-	ret = skl_check_main_surface(plane_state);
-	if (ret)
-		return ret;
-
-	return 0;
+	return skl_check_main_surface(master_plane_state, plane_state);
 }
 
 unsigned int
@@ -3694,7 +3700,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 	u32 offset;
 	int ret;
 
-	ret = intel_plane_compute_gtt(plane_state);
+	ret = intel_plane_compute_gtt(plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -3708,6 +3714,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
 
 	if (INTEL_GEN(dev_priv) >= 4)
 		offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
+							    plane_state,
 							    plane_state, 0);
 	else
 		offset = 0;
@@ -3759,6 +3766,7 @@ static bool i9xx_plane_has_windowing(struct intel_plane *plane)
 
 static int
 i9xx_plane_check(struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *master_plane_state,
 		 struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
@@ -3784,7 +3792,7 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
 	if (!plane_state->base.visible)
 		return 0;
 
-	ret = intel_plane_check_src_coordinates(plane_state);
+	ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -5549,12 +5557,13 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
  *    error - requested scaling cannot be supported or other error condition
  */
 static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
+				   const struct intel_plane_state *master_plane_state,
 				   struct intel_plane_state *plane_state)
 {
 	struct intel_plane *intel_plane =
 		to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
-	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int ret;
 	bool force_detach = !fb || !plane_state->base.visible;
 	bool need_scaler = false;
@@ -5577,7 +5586,7 @@ static int skl_update_scaler_plane(struct intel_crtc_state *crtc_state,
 		return ret;
 
 	/* check colorkey */
-	if (plane_state->ckey.flags) {
+	if (master_plane_state->ckey.flags) {
 		DRM_DEBUG_KMS("[PLANE:%d:%s] scaling with color key not allowed",
 			      intel_plane->base.base.id,
 			      intel_plane->base.name);
@@ -10662,11 +10671,12 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	return active;
 }
 
-static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
+static u32 intel_cursor_base(const struct intel_plane_state *master_plane_state,
+			     const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(plane_state->base.plane->dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 	u32 base;
 
@@ -10679,19 +10689,24 @@ static u32 intel_cursor_base(const struct intel_plane_state *plane_state)
 
 	/* ILK+ do this automagically */
 	if (HAS_GMCH(dev_priv) &&
-	    plane_state->base.rotation & DRM_MODE_ROTATE_180)
-		base += (plane_state->base.crtc_h *
-			 plane_state->base.crtc_w - 1) * fb->format->cpp[0];
+	    master_plane_state->base.rotation & DRM_MODE_ROTATE_180)
+		base += (master_plane_state->base.crtc_h *
+			 master_plane_state->base.crtc_w - 1) * fb->format->cpp[0];
 
 	return base;
 }
 
-static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
+static u32 intel_cursor_position(const struct intel_crtc_state *crtc_state,
+				 const struct intel_plane_state *master_plane_state,
+				 const struct intel_plane_state *plane_state)
 {
-	int x = plane_state->base.crtc_x;
-	int y = plane_state->base.crtc_y;
+	int x = master_plane_state->base.crtc_x;
+	int y = master_plane_state->base.crtc_y;
 	u32 pos = 0;
 
+	if (plane_state->bigjoiner_slave)
+		x -= crtc_state->pipe_src_w;
+
 	if (x < 0) {
 		pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
 		x = -x;
@@ -10718,13 +10733,14 @@ static bool intel_cursor_size_ok(const struct intel_plane_state *plane_state)
 		height > 0 && height <= config->cursor_height;
 }
 
-static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
+static int intel_cursor_check_surface(const struct intel_plane_state *master_plane_state,
+				      struct intel_plane_state *plane_state)
 {
 	int src_x, src_y;
 	u32 offset;
 	int ret;
 
-	ret = intel_plane_compute_gtt(plane_state);
+	ret = intel_plane_compute_gtt(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -10736,6 +10752,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
 
 	intel_add_fb_offsets(&src_x, &src_y, plane_state, 0);
 	offset = intel_plane_compute_aligned_offset(&src_x, &src_y,
+						    master_plane_state,
 						    plane_state, 0);
 
 	if (src_x != 0 || src_y != 0) {
@@ -10749,6 +10766,7 @@ static int intel_cursor_check_surface(struct intel_plane_state *plane_state)
 }
 
 static int intel_check_cursor(struct intel_crtc_state *crtc_state,
+			      const struct intel_plane_state *master_plane_state,
 			      struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
@@ -10759,22 +10777,21 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 		return -EINVAL;
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_scaling(crtc_state, master_plane_state,
+					       plane_state,
+					       DRM_PLANE_HELPER_NO_SCALING,
+					       DRM_PLANE_HELPER_NO_SCALING);
 	if (ret)
 		return ret;
 
-	ret = intel_cursor_check_surface(plane_state);
+	ret = intel_cursor_check_surface(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
 	if (!plane_state->base.visible)
 		return 0;
 
-	ret = intel_plane_check_src_coordinates(plane_state);
+	ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -10819,12 +10836,13 @@ static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
 }
 
 static int i845_check_cursor(struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *master_plane_state,
 			     struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int ret;
 
-	ret = intel_check_cursor(crtc_state, plane_state);
+	ret = intel_check_cursor(crtc_state, master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -10877,8 +10895,8 @@ static void i845_update_cursor(struct intel_plane *plane,
 
 		size = (height << 12) | width;
 
-		base = intel_cursor_base(plane_state);
-		pos = intel_cursor_position(plane_state);
+		base = intel_cursor_base(plane_state, plane_state);
+		pos = intel_cursor_position(crtc_state, plane_state, plane_state);
 	}
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
@@ -11032,15 +11050,16 @@ static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
 }
 
 static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *master_plane_state,
 			     struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	enum pipe pipe = plane->pipe;
 	int ret;
 
-	ret = intel_check_cursor(crtc_state, plane_state);
+	ret = intel_check_cursor(crtc_state, master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -11049,17 +11068,17 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Check for which cursor types we support */
-	if (!i9xx_cursor_size_ok(plane_state)) {
+	if (!i9xx_cursor_size_ok(master_plane_state)) {
 		DRM_DEBUG("Cursor dimension %dx%d not supported\n",
-			  plane_state->base.crtc_w,
-			  plane_state->base.crtc_h);
+			  master_plane_state->base.crtc_w,
+			  master_plane_state->base.crtc_h);
 		return -EINVAL;
 	}
 
 	WARN_ON(plane_state->base.visible &&
-		plane_state->color_plane[0].stride != fb->pitches[0]);
+		master_plane_state->color_plane[0].stride != fb->pitches[0]);
 
-	if (fb->pitches[0] != plane_state->base.crtc_w * fb->format->cpp[0]) {
+	if (fb->pitches[0] != master_plane_state->base.crtc_w * fb->format->cpp[0]) {
 		DRM_DEBUG_KMS("Invalid cursor stride (%u) (cursor width %d)\n",
 			      fb->pitches[0], plane_state->base.crtc_w);
 		return -EINVAL;
@@ -11076,19 +11095,20 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
 	 * Refuse the put the cursor into that compromised position.
 	 */
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
-	    plane_state->base.visible && plane_state->base.crtc_x < 0) {
+	    plane_state->base.visible && master_plane_state->base.crtc_x < 0) {
 		DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
 		return -EINVAL;
 	}
 
-	plane_state->ctl = i9xx_cursor_ctl(crtc_state, plane_state);
+	plane_state->ctl = i9xx_cursor_ctl(crtc_state, master_plane_state);
 
 	return 0;
 }
 
-static void i9xx_update_cursor(struct intel_plane *plane,
-			       const struct intel_crtc_state *crtc_state,
-			       const struct intel_plane_state *plane_state)
+static void i9xx_update_cursor_slave(struct intel_plane *plane,
+				     const struct intel_crtc_state *crtc_state,
+				     const struct intel_plane_state *master_plane_state,
+				     const struct intel_plane_state *plane_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
@@ -11099,11 +11119,11 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 		cntl = plane_state->ctl |
 			i9xx_cursor_ctl_crtc(crtc_state);
 
-		if (plane_state->base.crtc_h != plane_state->base.crtc_w)
-			fbc_ctl = CUR_FBC_CTL_EN | (plane_state->base.crtc_h - 1);
+		if (master_plane_state->base.crtc_h != master_plane_state->base.crtc_w)
+			fbc_ctl = CUR_FBC_CTL_EN | (master_plane_state->base.crtc_h - 1);
 
-		base = intel_cursor_base(plane_state);
-		pos = intel_cursor_position(plane_state);
+		base = intel_cursor_base(master_plane_state, plane_state);
+		pos = intel_cursor_position(crtc_state, master_plane_state, plane_state);
 	}
 
 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
@@ -11151,10 +11171,17 @@ static void i9xx_update_cursor(struct intel_plane *plane,
 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
 }
 
+static void i9xx_update_cursor(struct intel_plane *plane,
+			       const struct intel_crtc_state *crtc_state,
+			       const struct intel_plane_state *plane_state)
+{
+	i9xx_update_cursor_slave(plane, crtc_state, plane_state, plane_state);
+}
+
 static void i9xx_disable_cursor(struct intel_plane *plane,
 				const struct intel_crtc_state *crtc_state)
 {
-	i9xx_update_cursor(plane, crtc_state, NULL);
+	i9xx_update_cursor_slave(plane, crtc_state, NULL, NULL);
 }
 
 static bool i9xx_cursor_get_hw_state(struct intel_plane *plane,
@@ -11662,6 +11689,7 @@ static bool needs_scaling(const struct intel_plane_state *state)
 int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
 				    struct intel_crtc_state *crtc_state,
 				    const struct intel_plane_state *old_plane_state,
+				    const struct intel_plane_state *master_plane_state,
 				    struct intel_plane_state *plane_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -11674,7 +11702,7 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 	int ret;
 
 	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
-		ret = skl_update_scaler_plane(crtc_state, plane_state);
+		ret = skl_update_scaler_plane(crtc_state, master_plane_state, plane_state);
 		if (ret)
 			return ret;
 	}
@@ -15269,7 +15297,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 	 * wait for it to complete in the slowpath
 	 */
 	if (!crtc_state->hw.active || needs_modeset(crtc_state) ||
-	    crtc_state->update_pipe)
+	    crtc_state->update_pipe || crtc_state->bigjoiner)
 		goto slow;
 
 	old_plane_state = plane->state;
@@ -15539,6 +15567,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 	} else {
 		cursor->max_stride = i9xx_cursor_max_stride;
 		cursor->update_plane = i9xx_update_cursor;
+		cursor->update_slave = i9xx_update_cursor_slave;
 		cursor->disable_plane = i9xx_disable_cursor;
 		cursor->get_hw_state = i9xx_cursor_get_hw_state;
 		cursor->check_plane = i9xx_check_cursor;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 764d05d13b9e..a8b2198fcef1 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -562,8 +562,9 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
 u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
 u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
 		     const struct intel_plane_state *plane_state,
-		     int plane);
-int skl_check_plane_surface(struct intel_plane_state *plane_state);
+		     int color_plane);
+int skl_check_plane_surface(const struct intel_plane_state *master_plane_state,
+			    struct intel_plane_state *plane_state);
 int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
 int skl_format_to_fourcc(int format, bool rgb_order, bool alpha);
 unsigned int i9xx_plane_max_stride(struct intel_plane *plane,
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f05f4830a529..154fb07a62eb 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1117,6 +1117,7 @@ struct intel_plane {
 			      const struct intel_crtc_state *crtc_state);
 	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
 	int (*check_plane)(struct intel_crtc_state *crtc_state,
+			   const struct intel_plane_state *master_plane_state,
 			   struct intel_plane_state *plane_state);
 };
 
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 9337f5a8dce0..00d5f7eb0c29 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -250,11 +250,12 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
 #endif
 }
 
-int intel_plane_check_stride(const struct intel_plane_state *plane_state)
+int intel_plane_check_stride(const struct intel_plane_state *master_plane_state,
+			     const struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	u32 stride, max_stride;
 
 	/*
@@ -263,7 +264,7 @@ int intel_plane_check_stride(const struct intel_plane_state *plane_state)
 	 * with a false positive when the remapping didn't
 	 * kick in due the plane being invisible.
 	 */
-	if (intel_plane_can_remap(plane_state) &&
+	if (intel_plane_can_remap(master_plane_state) &&
 	    !plane_state->base.visible)
 		return 0;
 
@@ -282,12 +283,13 @@ int intel_plane_check_stride(const struct intel_plane_state *plane_state)
 	return 0;
 }
 
-int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
+int intel_plane_check_src_coordinates(const struct intel_plane_state *master_plane_state,
+				      struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	struct drm_rect *src = &plane_state->base.src;
 	u32 src_x, src_y, src_w, src_h, hsub, vsub;
-	bool rotated = drm_rotation_90_or_270(plane_state->base.rotation);
+	bool rotated = drm_rotation_90_or_270(master_plane_state->base.rotation);
 
 	/*
 	 * Hardware doesn't handle subpixel coordinates.
@@ -1574,6 +1576,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
 
 static int
 g4x_sprite_check(struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *master_plane_state,
 		 struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
@@ -1592,10 +1595,9 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_scaling(crtc_state,
+					       master_plane_state, plane_state,
+					       min_scale, max_scale);
 	if (ret)
 		return ret;
 
@@ -1606,7 +1608,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
 	if (!plane_state->base.visible)
 		return 0;
 
-	ret = intel_plane_check_src_coordinates(plane_state);
+	ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -1641,6 +1643,7 @@ int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
 
 static int
 vlv_sprite_check(struct intel_crtc_state *crtc_state,
+		 const struct intel_plane_state *master_plane_state,
 		 struct intel_plane_state *plane_state)
 {
 	int ret;
@@ -1649,11 +1652,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_scaling(crtc_state,
+					       master_plane_state, plane_state,
+					       DRM_PLANE_HELPER_NO_SCALING,
+					       DRM_PLANE_HELPER_NO_SCALING);
 	if (ret)
 		return ret;
 
@@ -1664,7 +1666,7 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
 	if (!plane_state->base.visible)
 		return 0;
 
-	ret = intel_plane_check_src_coordinates(plane_state);
+	ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -1777,10 +1779,11 @@ static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_s
 	return 0;
 }
 
-static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
+static int skl_plane_check_nv12_rotation(const struct intel_plane_state *master_plane_state,
+					 const struct intel_plane_state *plane_state)
 {
-	const struct drm_framebuffer *fb = plane_state->base.fb;
-	unsigned int rotation = plane_state->base.rotation;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
+	unsigned int rotation = master_plane_state->base.rotation;
 	int src_w = drm_rect_width(&plane_state->base.src) >> 16;
 
 	/* Display WA #1106 */
@@ -1795,33 +1798,37 @@ static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_s
 }
 
 static int skl_plane_check(struct intel_crtc_state *crtc_state,
+			   const struct intel_plane_state *master_plane_state,
 			   struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
 	int ret;
 
+	/*
+	 * it's ok to check slave plane_state here, master_plane_state is already checked
+	 * in its own skl_plane_check call.
+	 */
 	ret = skl_plane_check_fb(crtc_state, plane_state);
 	if (ret)
 		return ret;
 
 	/* use scaler when colorkey is not required */
-	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
+	if (!master_plane_state->ckey.flags && intel_fb_scalable(fb)) {
 		min_scale = 1;
 		max_scale = skl_max_scale(crtc_state, fb->format);
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_scaling(crtc_state,
+					       master_plane_state, plane_state,
+					       min_scale, max_scale);
 	if (ret)
 		return ret;
 
-	ret = skl_check_plane_surface(plane_state);
+	ret = skl_check_plane_surface(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -1832,11 +1839,11 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = intel_plane_check_src_coordinates(plane_state);
+	ret = intel_plane_check_src_coordinates(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
-	ret = skl_plane_check_nv12_rotation(plane_state);
+	ret = skl_plane_check_nv12_rotation(master_plane_state, plane_state);
 	if (ret)
 		return ret;
 
@@ -1844,11 +1851,11 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 	if (!(plane_state->base.alpha >> 8))
 		plane_state->base.visible = false;
 
-	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
+	plane_state->ctl = skl_plane_ctl(crtc_state, master_plane_state);
 
 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
-							     plane_state);
+							     master_plane_state);
 
 	if (icl_is_hdr_plane(dev_priv, plane->id) && fb->format->is_yuv)
 		/* Enable and use MPEG-2 chroma siting */
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.h b/drivers/gpu/drm/i915/display/intel_sprite.h
index 6df62fae9368..453b153b303e 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.h
+++ b/drivers/gpu/drm/i915/display/intel_sprite.h
@@ -26,8 +26,10 @@ int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state);
 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state,
 			   struct intel_crtc_state *slave_crtc_state);
-int intel_plane_check_stride(const struct intel_plane_state *plane_state);
-int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state);
+int intel_plane_check_stride(const struct intel_plane_state *master_plane_state,
+			     const struct intel_plane_state *plane_state);
+int intel_plane_check_src_coordinates(const struct intel_plane_state *master_plane_state,
+				      struct intel_plane_state *plane_state);
 int chv_plane_check_rotation(const struct intel_plane_state *plane_state);
 struct intel_plane *
 skl_universal_plane_create(struct drm_i915_private *dev_priv,
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 20/23] drm/i915: Make prepare_plane_fb() work with bigjoiner planes
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (17 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 19/23] drm/i915: Prepare atomic plane check for bigjoiner planes Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 21/23] drm/i915: Make sure watermarks work correctly with bigjoiner as well Maarten Lankhorst
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Similar to plane programming, we need a separate master_plane_state from
which we will read all atomic properties, and plane_state for the real
coordinates.

Although we add all planes with icl_add_linked_planes(),
icl_check_nv12_planes() may add extra Y planes on the slave CRTC.
For those planes, the corresponding planes on the master CRTC
are not added, so we have to be slightly more careful in that case.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  2 +-
 .../gpu/drm/i915/display/intel_atomic_plane.h |  4 ++
 drivers/gpu/drm/i915/display/intel_display.c  | 71 +++++++++++--------
 3 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index a0c1d1696c8c..9fca9e90af58 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -204,7 +204,7 @@ struct intel_crtc *
 intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
 				 const struct intel_plane_state *old_plane_state,
 				 const struct intel_plane_state *new_plane_state)
-  {
+{
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
 
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index c98ccf8114c3..d789a1886908 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -52,5 +52,9 @@ int intel_atomic_plane_check_scaling(struct intel_crtc_state *crtc_state,
 				     const struct intel_plane_state *master_plane_state,
 				     struct intel_plane_state *plane_state,
 				     int min_scale, int max_scale);
+struct intel_crtc *
+intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
+				 const struct intel_plane_state *old_plane_state,
+				 const struct intel_plane_state *new_plane_state);
 
 #endif /* __INTEL_ATOMIC_PLANE_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 690c3d10ce44..8e1fab0fe7b5 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14929,11 +14929,12 @@ static void add_rps_boost_after_vblank(struct drm_crtc *crtc,
 	add_wait_queue(drm_crtc_vblank_waitqueue(crtc), &wait->wait);
 }
 
-static int intel_plane_pin_fb(struct intel_plane_state *plane_state)
+static int intel_plane_pin_fb(const struct intel_plane_state *master_plane_state,
+			      struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	struct drm_framebuffer *fb = plane_state->base.fb;
+	struct drm_framebuffer *fb = master_plane_state->base.fb;
 	struct i915_vma *vma;
 
 	if (plane->id == PLANE_CURSOR &&
@@ -14992,21 +14993,27 @@ static void fb_obj_bump_render_priority(struct drm_i915_gem_object *obj)
  * Returns 0 on success, negative error code on failure.
  */
 int
-intel_prepare_plane_fb(struct drm_plane *plane,
-		       struct drm_plane_state *new_state)
+intel_prepare_plane_fb(struct drm_plane *drm_plane,
+		       struct drm_plane_state *_new_plane_state)
 {
-	struct intel_atomic_state *intel_state =
-		to_intel_atomic_state(new_state->state);
-	struct drm_i915_private *dev_priv = to_i915(plane->dev);
-	struct drm_framebuffer *fb = new_state->fb;
-	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->state->fb);
+	struct intel_plane *plane = to_intel_plane(drm_plane);
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(_new_plane_state->state);
+	struct intel_plane_state *new_plane_state = to_intel_plane_state(_new_plane_state);
+	const struct intel_plane_state *old_plane_state =
+		intel_atomic_get_old_plane_state(state, plane);
+	const struct intel_plane_state *new_master_plane_state = new_plane_state;
+	struct drm_i915_gem_object *obj, *old_obj;
+	struct intel_crtc *crtc;
 	int ret;
 
-	if (old_obj) {
-		struct intel_crtc_state *crtc_state =
-			intel_atomic_get_new_crtc_state(intel_state,
-							to_intel_crtc(plane->state->crtc));
+	old_obj = intel_fb_obj(old_plane_state->base.fb);
+	if (!old_plane_state->bigjoiner_slave && old_obj) {
+		struct intel_crtc_state *crtc_state;
+
+		crtc = to_intel_crtc(old_plane_state->base.crtc);
+		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 
 		/* Big Hammer, we also need to ensure that any pending
 		 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
@@ -15020,7 +15027,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		 * can safely continue.
 		 */
 		if (needs_modeset(crtc_state)) {
-			ret = i915_sw_fence_await_reservation(&intel_state->commit_ready,
+			ret = i915_sw_fence_await_reservation(&state->commit_ready,
 							      old_obj->base.resv, NULL,
 							      false, 0,
 							      GFP_KERNEL);
@@ -15029,19 +15036,18 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		}
 	}
 
-	if (new_state->fence) { /* explicit fencing */
-		ret = i915_sw_fence_await_dma_fence(&intel_state->commit_ready,
-						    new_state->fence,
+	if (new_plane_state->base.fence) { /* explicit fencing */
+		ret = i915_sw_fence_await_dma_fence(&state->commit_ready,
+						    new_plane_state->base.fence,
 						    I915_FENCE_TIMEOUT,
 						    GFP_KERNEL);
 		if (ret < 0)
 			return ret;
 	}
 
-	if (to_intel_plane_state(new_state)->planar_slave) {
-		struct intel_plane_state *new_plane_state = to_intel_plane_state(new_state);
+	if (new_plane_state->planar_slave) {
 		const struct intel_plane_state *linked_plane_state =
-			intel_atomic_get_new_plane_state(intel_state, new_plane_state->planar_linked_plane);
+			intel_atomic_get_new_plane_state(state, new_plane_state->planar_linked_plane);
 
 		/*
 		 * We are a planar slave, VMA is on our planar master,
@@ -15055,6 +15061,12 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		return 0;
 	}
 
+	if (new_plane_state->bigjoiner_slave)
+		new_master_plane_state = intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
+
+	crtc = intel_plane_get_crtc_from_states(state, old_plane_state,
+						new_plane_state);
+	obj = intel_fb_obj(new_master_plane_state->base.fb);
 	if (!obj)
 		return 0;
 
@@ -15068,7 +15080,7 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 		return ret;
 	}
 
-	ret = intel_plane_pin_fb(to_intel_plane_state(new_state));
+	ret = intel_plane_pin_fb(new_master_plane_state, new_plane_state);
 
 	mutex_unlock(&dev_priv->drm.struct_mutex);
 	i915_gem_object_unpin_pages(obj);
@@ -15078,10 +15090,10 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 	fb_obj_bump_render_priority(obj);
 	intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_DIRTYFB);
 
-	if (!new_state->fence) { /* implicit fencing */
+	if (!new_plane_state->base.fence) { /* implicit fencing */
 		struct dma_fence *fence;
 
-		ret = i915_sw_fence_await_reservation(&intel_state->commit_ready,
+		ret = i915_sw_fence_await_reservation(&state->commit_ready,
 						      obj->base.resv, NULL,
 						      false, I915_FENCE_TIMEOUT,
 						      GFP_KERNEL);
@@ -15090,11 +15102,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 
 		fence = dma_resv_get_excl_rcu(obj->base.resv);
 		if (fence) {
-			add_rps_boost_after_vblank(new_state->crtc, fence);
+			add_rps_boost_after_vblank(&crtc->base, fence);
 			dma_fence_put(fence);
 		}
 	} else {
-		add_rps_boost_after_vblank(new_state->crtc, new_state->fence);
+		add_rps_boost_after_vblank(&crtc->base, new_plane_state->base.fence);
 	}
 
 	/*
@@ -15105,9 +15117,9 @@ intel_prepare_plane_fb(struct drm_plane *plane,
 	 * that are not quite steady state without resorting to forcing
 	 * maximum clocks following a vblank miss (see do_rps_boost()).
 	 */
-	if (!intel_state->rps_interactive) {
+	if (!state->rps_interactive) {
 		intel_rps_mark_interactive(dev_priv, true);
-		intel_state->rps_interactive = true;
+		state->rps_interactive = true;
 	}
 
 	return 0;
@@ -15354,7 +15366,8 @@ intel_legacy_cursor_update(struct drm_plane *plane,
 	if (ret)
 		goto out_free;
 
-	ret = intel_plane_pin_fb(to_intel_plane_state(new_plane_state));
+	ret = intel_plane_pin_fb(to_intel_plane_state(new_plane_state),
+				 to_intel_plane_state(new_plane_state));
 	if (ret)
 		goto out_unlock;
 
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 21/23] drm/i915: Make sure watermarks work correctly with bigjoiner as well.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (18 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 20/23] drm/i915: Make prepare_plane_fb() work with " Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 22/23] drm/i915: Add debugfs dumping for bigjoiner Maarten Lankhorst
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

For bigjoiner, we cannot do drm_atomic_crtc_state_for_each_plane_state()
on the crtc, because planes don't match the drm core state.
We need a separate master_plane_state for all the properties,
and a slave_plane_state for the rectangles/visibility etc.

This is similar to how we handle the Y plane, because it won't be
directly calculated either. Instead it's calculated from the master
crtc.

Add a intel_atomic_crtc_state_for_each_plane_state macro, which
iterates over master_plane_state and obtains slave_plane_state
as well. This cleans up code slightly as well.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |   2 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c |   4 +-
 drivers/gpu/drm/i915/display/intel_display.h  |  20 +-
 drivers/gpu/drm/i915/intel_pm.c               | 201 ++++++++++--------
 4 files changed, 134 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index a8f34254cd2a..add77e33e54e 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -297,7 +297,7 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
 		return;
 
 	/* set scaler mode */
-	if (plane_state && (plane_state->linked_plane ||
+	if (plane_state && (plane_state->planar_linked_plane ||
 	     (!plane_state->bigjoiner_slave && plane_state->base.fb &&
 	      plane_state->base.fb->format->is_yuv &&
 	      plane_state->base.fb->format->num_planes > 1))) {
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 9fca9e90af58..f471bb30c20a 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -414,14 +414,14 @@ void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
 
 			intel_update_slave(plane, new_crtc_state,
 					   master_plane_state, new_plane_state);
-		} else if (new_plane_state->slave) {
+		} else if (new_plane_state->planar_slave) {
 			/*
 			 * bigjoiner slave + planar slave.
 			 * The correct sequence is to get from the planar slave to planar master,
 			 * then to the master plane state for the master_plane_state.
 			 */
 
-			struct intel_plane *linked = new_plane_state->linked_plane;
+			struct intel_plane *linked = new_plane_state->planar_linked_plane;
 			const struct intel_plane_state *uv_plane_state =
 				intel_atomic_get_new_plane_state(state, linked);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index a8b2198fcef1..14717a59e677 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -350,7 +350,7 @@ enum phy_fia {
 			    &(dev)->mode_config.plane_list,		\
 			    base.head)					\
 		for_each_if((plane_mask) &				\
-			    drm_plane_mask(&intel_plane->base)))
+			    drm_plane_mask(&intel_plane->base))
 
 #define for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane)	\
 	list_for_each_entry(intel_plane,				\
@@ -440,6 +440,24 @@ enum phy_fia {
 	     (__i)--) \
 		for_each_if(crtc)
 
+#define intel_atomic_crtc_state_for_each_plane_state( \
+		  plane, master_plane_state, plane_state, \
+		  crtc_state) \
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
+		  (((crtc_state)->bigjoiner_slave ? \
+			intel_atomic_get_new_crtc_state( \
+				to_intel_atomic_state((crtc_state)->uapi.state), \
+				(crtc_state)->bigjoiner_linked_crtc) : \
+				(crtc_state))->uapi.plane_mask)) \
+		for_each_if ((((master_plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \
+			      ((plane) = (master_plane_state)->bigjoiner_slave ? \
+					 (master_plane_state)->bigjoiner_plane : \
+					 (plane)), \
+			      ((plane_state) = (master_plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (master_plane_state))))
+
 void intel_link_compute_m_n(u16 bpp, int nlanes,
 			    int pixel_clock, int link_clock,
 			    struct intel_link_m_n *m_n,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index acc87b8431f3..eb389b7ac578 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -812,8 +812,10 @@ static int intel_wm_num_levels(struct drm_i915_private *dev_priv)
 	return dev_priv->wm.max_level + 1;
 }
 
-static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
-				   const struct intel_plane_state *plane_state)
+static bool
+intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
+		       const struct intel_plane_state *master_plane_state,
+		       const struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
 
@@ -830,7 +832,7 @@ static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
 	 * around this problem with the watermark code.
 	 */
 	if (plane->id == PLANE_CURSOR)
-		return plane_state->base.fb != NULL;
+		return master_plane_state->base.fb != NULL;
 	else
 		return plane_state->base.visible;
 }
@@ -1114,7 +1116,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	if (latency == 0)
 		return USHRT_MAX;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -1212,7 +1214,7 @@ static bool g4x_raw_plane_wm_compute(struct intel_crtc_state *crtc_state,
 	bool dirty = false;
 	int level;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state)) {
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state)) {
 		dirty |= g4x_raw_plane_wm_set(crtc_state, 0, plane_id, 0);
 		if (plane_id == PLANE_PRIMARY)
 			dirty |= g4x_raw_fbc_wm_set(crtc_state, 0, 0);
@@ -1622,7 +1624,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 	if (dev_priv->wm.pri_latency[level] == 0)
 		return USHRT_MAX;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -1789,7 +1791,7 @@ static bool vlv_raw_plane_wm_compute(struct intel_crtc_state *crtc_state,
 	int level;
 	bool dirty = false;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state)) {
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state)) {
 		dirty |= vlv_raw_plane_wm_set(crtc_state, 0, plane_id, 0);
 		goto out;
 	}
@@ -2504,7 +2506,7 @@ static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state,
 	if (mem_value == 0)
 		return U32_MAX;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -2536,7 +2538,7 @@ static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state,
 	if (mem_value == 0)
 		return U32_MAX;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -2562,7 +2564,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
 	if (mem_value == 0)
 		return U32_MAX;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -2579,7 +2581,7 @@ static u32 ilk_compute_fbc_wm(const struct intel_crtc_state *crtc_state,
 {
 	int cpp;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
 	cpp = plane_state->base.fb->format->cpp[0];
@@ -4064,6 +4066,7 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
  */
 static uint_fixed_16_16_t
 skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state,
+			   const struct intel_plane_state *master_plane_state,
 			   const struct intel_plane_state *plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
@@ -4071,7 +4074,8 @@ skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state,
 	uint_fixed_16_16_t fp_w_ratio, fp_h_ratio;
 	uint_fixed_16_16_t downscale_h, downscale_w;
 
-	if (WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state)))
+	if (WARN_ON(!intel_wm_plane_visible(crtc_state,
+					    master_plane_state, plane_state)))
 		return u32_to_fixed16(0);
 
 	/* n.b., src is 16.16 fixed point, dst is whole integer */
@@ -4080,10 +4084,10 @@ skl_plane_downscale_amount(const struct intel_crtc_state *crtc_state,
 		 * Cursors only support 0/180 degree rotation,
 		 * hence no need to account for rotation here.
 		 */
-		src_w = plane_state->base.src_w >> 16;
-		src_h = plane_state->base.src_h >> 16;
-		dst_w = plane_state->base.crtc_w;
-		dst_h = plane_state->base.crtc_h;
+		src_w = master_plane_state->base.src_w >> 16;
+		src_h = master_plane_state->base.src_h >> 16;
+		dst_w = master_plane_state->base.crtc_w;
+		dst_h = master_plane_state->base.crtc_h;
 	} else {
 		/*
 		 * Src coordinates are already rotated by 270 degrees for
@@ -4141,9 +4145,10 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 				  struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
-	struct drm_atomic_state *state = crtc_state->uapi.state;
-	struct drm_plane *plane;
-	const struct drm_plane_state *drm_plane_state;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(crtc_state->uapi.state);
+	struct intel_plane *plane;
+	const struct intel_plane_state *master_plane_state, *plane_state;
 	int crtc_clock, dotclk;
 	u32 pipe_max_pixel_rate;
 	uint_fixed_16_16_t pipe_downscale;
@@ -4152,21 +4157,24 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 	if (!crtc_state->hw.enable)
 		return 0;
 
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, master_plane_state,
+						     plane_state, crtc_state) {
 		uint_fixed_16_16_t plane_downscale;
 		uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
 		int bpp;
-		const struct intel_plane_state *plane_state =
-			to_intel_plane_state(drm_plane_state);
 
-		if (!intel_wm_plane_visible(crtc_state, plane_state))
+		if (!intel_wm_plane_visible(crtc_state,
+					    master_plane_state, plane_state))
 			continue;
 
-		if (WARN_ON(!plane_state->base.fb))
+		if (WARN_ON(!master_plane_state->base.fb))
 			return -EINVAL;
 
-		plane_downscale = skl_plane_downscale_amount(crtc_state, plane_state);
-		bpp = plane_state->base.fb->format->cpp[0] * 8;
+		plane_downscale = skl_plane_downscale_amount(crtc_state,
+							     master_plane_state,
+							     plane_state);
+
+		bpp = master_plane_state->base.fb->format->cpp[0] * 8;
 		if (bpp == 64)
 			plane_downscale = mul_fixed16(plane_downscale,
 						      fp_9_div_8);
@@ -4178,7 +4186,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 	pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
 
 	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
-	dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
+	dotclk = state->cdclk.logical.cdclk;
 
 	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
 		dotclk *= 2;
@@ -4195,11 +4203,12 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
 
 static u64
 skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
+			     const struct intel_plane_state *master_plane_state,
 			     const struct intel_plane_state *plane_state,
 			     int color_plane)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	u32 data_rate;
 	u32 width = 0, height = 0;
 	uint_fixed_16_16_t down_scale_amount;
@@ -4231,7 +4240,9 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
 
 	data_rate = width * height;
 
-	down_scale_amount = skl_plane_downscale_amount(crtc_state, plane_state);
+	down_scale_amount = skl_plane_downscale_amount(crtc_state,
+						       master_plane_state,
+						       plane_state);
 
 	rate = mul_round_up_u32_fixed16(data_rate, down_scale_amount);
 
@@ -4244,28 +4255,25 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate,
 				 u64 *uv_plane_data_rate)
 {
-	struct drm_atomic_state *state = crtc_state->uapi.state;
-	struct drm_plane *plane;
-	const struct drm_plane_state *drm_plane_state;
+	struct intel_plane *plane;
+	const struct intel_plane_state *master_plane_state, *plane_state;
 	u64 total_data_rate = 0;
 
-	if (WARN_ON(!state))
-		return 0;
-
 	/* Calculate and cache data rate for each plane */
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
-		enum plane_id plane_id = to_intel_plane(plane)->id;
-		const struct intel_plane_state *plane_state =
-			to_intel_plane_state(drm_plane_state);
+	intel_atomic_crtc_state_for_each_plane_state(plane, master_plane_state,
+						     plane_state, crtc_state) {
+		enum plane_id plane_id = plane->id;
 		u64 rate;
 
 		/* packed/y */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state,
+						    plane_state, 0);
 		plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 
 		/* uv-plane */
-		rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+		rate = skl_plane_relative_data_rate(crtc_state, plane_state,
+						    plane_state, 1);
 		uv_plane_data_rate[plane_id] = rate;
 		total_data_rate += rate;
 	}
@@ -4277,47 +4285,52 @@ static u64
 icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate)
 {
-	struct drm_plane *plane;
-	const struct drm_plane_state *drm_plane_state;
+	const struct intel_plane_state *master_plane_state, *plane_state;
+	struct intel_plane *plane;
 	u64 total_data_rate = 0;
 
 	if (WARN_ON(!crtc_state->uapi.state))
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
-		const struct intel_plane_state *plane_state =
-			to_intel_plane_state(drm_plane_state);
-		enum plane_id plane_id = to_intel_plane(plane)->id;
+	intel_atomic_crtc_state_for_each_plane_state(plane, master_plane_state,
+						     plane_state, crtc_state) {
+		enum plane_id plane_id = plane->id;
 		u64 rate;
 
 		if (!plane_state->planar_linked_plane) {
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state,
+							    master_plane_state,
+							    plane_state, 0);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
 		} else {
 			enum plane_id y_plane_id;
 
 			/*
-			 * The slave plane might not iterate in
-			 * drm_atomic_crtc_state_for_each_plane_state(),
-			 * and needs the master plane state which may be
-			 * NULL if we try get_new_plane_state(), so we
-			 * always calculate from the master.
-			 */
+			* The slave plane might not iterate in
+			* intel_atomic_crtc_state_for_each_plane_state(),
+			* and needs the master plane state which may be
+			* NULL if we try get_new_plane_state(), so we
+			* always calculate from the master.
+			*/
 			if (plane_state->planar_slave)
 				continue;
 
 			/* Y plane rate is calculated on the slave */
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
+			rate = skl_plane_relative_data_rate(crtc_state,
+							    master_plane_state,
+							    plane_state, 0);
 			y_plane_id = plane_state->planar_linked_plane->id;
 			plane_data_rate[y_plane_id] = rate;
 			total_data_rate += rate;
 
-			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 1);
+			rate = skl_plane_relative_data_rate(crtc_state,
+							    master_plane_state,
+							    plane_state, 1);
 			plane_data_rate[plane_id] = rate;
 			total_data_rate += rate;
-		}
+		  }
 	}
 
 	return total_data_rate;
@@ -4608,13 +4621,15 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
 
 static u32
 skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
+			      const struct intel_plane_state *master_plane_state,
 			      const struct intel_plane_state *plane_state)
 {
 	u64 adjusted_pixel_rate;
 	uint_fixed_16_16_t downscale_amount;
 
 	/* Shouldn't reach here on disabled planes... */
-	if (WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state)))
+	if (WARN_ON(!intel_wm_plane_visible(crtc_state,
+					    master_plane_state, plane_state)))
 		return 0;
 
 	/*
@@ -4622,7 +4637,9 @@ skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
 	 * with additional adjustments for plane-specific scaling.
 	 */
 	adjusted_pixel_rate = crtc_state->pixel_rate;
-	downscale_amount = skl_plane_downscale_amount(crtc_state, plane_state);
+	downscale_amount = skl_plane_downscale_amount(crtc_state,
+						      master_plane_state,
+						      plane_state);
 
 	return mul_round_up_u32_fixed16(adjusted_pixel_rate,
 					    downscale_amount);
@@ -4721,15 +4738,16 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
 
 static int
 skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
+			    const struct intel_plane_state *master_plane_state,
 			    const struct intel_plane_state *plane_state,
 			    struct skl_wm_params *wp, int color_plane)
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
-	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_framebuffer *fb = master_plane_state->base.fb;
 	int width;
 
 	if (plane->id == PLANE_CURSOR) {
-		width = plane_state->base.crtc_w;
+		width = master_plane_state->base.crtc_w;
 	} else {
 		/*
 		 * Src coordinates are already rotated by 270 degrees for
@@ -4741,8 +4759,8 @@ skl_compute_plane_wm_params(const struct intel_crtc_state *crtc_state,
 
 	return skl_compute_wm_params(crtc_state, width,
 				     fb->format, fb->modifier,
-				     plane_state->base.rotation,
-				     skl_adjusted_plane_pixel_rate(crtc_state, plane_state),
+				     master_plane_state->base.rotation,
+				     skl_adjusted_plane_pixel_rate(crtc_state, master_plane_state, plane_state),
 				     wp, color_plane);
 }
 
@@ -4977,6 +4995,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
 }
 
 static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
+				     const struct intel_plane_state *master_plane_state,
 				     const struct intel_plane_state *plane_state,
 				     enum plane_id plane_id, int color_plane)
 {
@@ -4984,8 +5003,8 @@ static int skl_build_plane_wm_single(struct intel_crtc_state *crtc_state,
 	struct skl_wm_params wm_params;
 	int ret;
 
-	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
-					  &wm_params, color_plane);
+	ret = skl_compute_plane_wm_params(crtc_state, master_plane_state,
+					  plane_state, &wm_params, color_plane);
 	if (ret)
 		return ret;
 
@@ -5007,7 +5026,7 @@ static int skl_build_plane_wm_uv(struct intel_crtc_state *crtc_state,
 
 	/* uv plane watermarks must also be validated for NV12/Planar */
 	ret = skl_compute_plane_wm_params(crtc_state, plane_state,
-					  &wm_params, 1);
+					  plane_state, &wm_params, 1);
 	if (ret)
 		return ret;
 
@@ -5024,10 +5043,10 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
 	enum plane_id plane_id = plane->id;
 	int ret;
 
-	if (!intel_wm_plane_visible(crtc_state, plane_state))
+	if (!intel_wm_plane_visible(crtc_state, plane_state, plane_state))
 		return 0;
 
-	ret = skl_build_plane_wm_single(crtc_state, plane_state,
+	ret = skl_build_plane_wm_single(crtc_state, plane_state, plane_state,
 					plane_id, 0);
 	if (ret)
 		return ret;
@@ -5043,6 +5062,7 @@ static int skl_build_plane_wm(struct intel_crtc_state *crtc_state,
 }
 
 static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
+			      const struct intel_plane_state *master_plane_state,
 			      const struct intel_plane_state *plane_state)
 {
 	enum plane_id plane_id = to_intel_plane(plane_state->base.plane)->id;
@@ -5053,27 +5073,28 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	if (plane_state->planar_linked_plane) {
-		const struct drm_framebuffer *fb = plane_state->base.fb;
+		const struct drm_framebuffer *fb = master_plane_state->base.fb;
 		enum plane_id y_plane_id = plane_state->planar_linked_plane->id;
 
-		WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state));
+		WARN_ON(!intel_wm_plane_visible(crtc_state,
+						master_plane_state,
+						plane_state));
 		WARN_ON(!fb->format->is_yuv ||
 			fb->format->num_planes == 1);
 
-		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						y_plane_id, 0);
+		ret = skl_build_plane_wm_single(crtc_state, master_plane_state,
+						plane_state, y_plane_id, 0);
 		if (ret)
 			return ret;
 
-		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 1);
-		if (ret)
-			return ret;
-	} else if (intel_wm_plane_visible(crtc_state, plane_state)) {
-		ret = skl_build_plane_wm_single(crtc_state, plane_state,
-						plane_id, 0);
+		ret = skl_build_plane_wm_single(crtc_state, master_plane_state,
+						plane_state, plane_id, 1);
 		if (ret)
 			return ret;
+	} else if (intel_wm_plane_visible(crtc_state,
+					  master_plane_state, plane_state)) {
+		ret = skl_build_plane_wm_single(crtc_state, master_plane_state,
+						plane_state, plane_id, 0);
 	}
 
 	return 0;
@@ -5083,8 +5104,8 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
 	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
-	struct drm_plane *plane;
-	const struct drm_plane_state *drm_plane_state;
+	const struct intel_plane_state *master_plane_state, *plane_state;
+	struct intel_plane *plane;
 	int ret;
 
 	/*
@@ -5093,15 +5114,17 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 	 */
 	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
 
-	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state,
-						   &crtc_state->uapi) {
-		const struct intel_plane_state *plane_state =
-			to_intel_plane_state(drm_plane_state);
+	intel_atomic_crtc_state_for_each_plane_state(plane, master_plane_state,
+						     plane_state, crtc_state) {
+		if (INTEL_GEN(dev_priv) >= 11) {
+			ret = icl_build_plane_wm(crtc_state,
+						 master_plane_state,
+						 plane_state);
+		} else {
+			ret = skl_build_plane_wm(crtc_state,
+						 master_plane_state);
+		}
 
-		if (INTEL_GEN(dev_priv) >= 11)
-			ret = icl_build_plane_wm(crtc_state, plane_state);
-		else
-			ret = skl_build_plane_wm(crtc_state, plane_state);
 		if (ret)
 			return ret;
 	}
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 22/23] drm/i915: Add debugfs dumping for bigjoiner.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (19 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 21/23] drm/i915: Make sure watermarks work correctly with bigjoiner as well Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 11:42 ` [PATCH 23/23] HAX to make it work on the icelake test system Maarten Lankhorst
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

It's useful to know what the actual clipped state is, rather than
the unclipped crtc properties.

This is useful when a plane is spread across 2 crtc's, where the
slave crtc has no own plane properties but derives its clipped
values from the master crtc.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 40 ++++++++++++-----------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 1c4c3972fd23..c3d12ab37cad 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2661,42 +2661,31 @@ static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 	struct intel_plane *intel_plane;
 
 	for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
-		struct drm_plane_state *state;
+		struct intel_plane_state *state;
 		struct drm_plane *plane = &intel_plane->base;
 		struct drm_format_name_buf format_name;
 		char rot_str[48];
 
-		if (!plane->state) {
-			seq_puts(m, "plane->state is NULL!\n");
-			continue;
-		}
-
-		state = plane->state;
+		state = to_intel_plane_state(plane->state);
 
-		if (state->fb) {
-			drm_get_format_name(state->fb->format->format,
+		if (state->base.fb) {
+			drm_get_format_name(state->base.fb->format->format,
 					    &format_name);
+		} else if (state->bigjoiner_slave) {
+			sprintf(format_name.str, "(slave)");
 		} else {
 			sprintf(format_name.str, "N/A");
 		}
 
-		plane_rotation(rot_str, sizeof(rot_str), state->rotation);
+		plane_rotation(rot_str, sizeof(rot_str), state->base.rotation);
 
-		seq_printf(m, "\t--Plane id %d: type=%s, crtc_pos=%4dx%4d, crtc_size=%4dx%4d, src_pos=%d.%04ux%d.%04u, src_size=%d.%04ux%d.%04u, format=%s, rotation=%s\n",
+		seq_printf(m, "\t--Plane id %d: type=%s, %sclipped crtc="DRM_RECT_FMT", clipped src="DRM_RECT_FP_FMT", format=%s, rotation=%s\n",
 			   plane->base.id,
 			   plane_type(intel_plane->base.type),
-			   state->crtc_x, state->crtc_y,
-			   state->crtc_w, state->crtc_h,
-			   (state->src_x >> 16),
-			   ((state->src_x & 0xffff) * 15625) >> 10,
-			   (state->src_y >> 16),
-			   ((state->src_y & 0xffff) * 15625) >> 10,
-			   (state->src_w >> 16),
-			   ((state->src_w & 0xffff) * 15625) >> 10,
-			   (state->src_h >> 16),
-			   ((state->src_h & 0xffff) * 15625) >> 10,
-			   format_name.str,
-			   rot_str);
+			   state->base.visible ? "visible, " : "",
+			   DRM_RECT_ARG(&state->base.dst),
+			   DRM_RECT_FP_ARG(&state->base.src),
+			   format_name.str, rot_str);
 	}
 }
 
@@ -2752,6 +2741,11 @@ static int i915_display_info(struct seq_file *m, void *unused)
 			   yesno(pipe_config->hw.active),
 			   pipe_config->pipe_src_w, pipe_config->pipe_src_h,
 			   yesno(pipe_config->dither), pipe_config->pipe_bpp);
+		if (pipe_config->bigjoiner)
+			seq_printf(m, "\tLinked to [CRTC:%d:%s] as a %s\n",
+				   pipe_config->bigjoiner_linked_crtc->base.base.id,
+				   pipe_config->bigjoiner_linked_crtc->base.name,
+				   pipe_config->bigjoiner_slave ? "slave" : "master");
 
 		if (pipe_config->hw.active) {
 			struct intel_plane *cursor =
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* [PATCH 23/23] HAX to make it work on the icelake test system
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (20 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 22/23] drm/i915: Add debugfs dumping for bigjoiner Maarten Lankhorst
@ 2019-09-20 11:42 ` Maarten Lankhorst
  2019-09-20 14:52 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Patchwork
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-20 11:42 UTC (permalink / raw)
  To: intel-gfx

Can't figure out how it works, so just removing it..

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 4 ++--
 include/drm/drm_dp_helper.h     | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index f373798d82f6..a990073c7adf 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1374,7 +1374,7 @@ u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
 		if (slice_cap1 & DP_DSC_4_PER_DP_DSC_SINK)
 			return 4;
 		if (slice_cap1 & DP_DSC_2_PER_DP_DSC_SINK)
-			return 2;
+			return 4;
 		if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
 			return 1;
 	} else {
@@ -1398,7 +1398,7 @@ u8 drm_dp_dsc_sink_max_slice_count(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE],
 		if (slice_cap1 & DP_DSC_4_PER_DP_DSC_SINK)
 			return 4;
 		if (slice_cap1 & DP_DSC_2_PER_DP_DSC_SINK)
-			return 2;
+			return 4;
 		if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
 			return 1;
 	}
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index ed1a985745ba..065b65350fce 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1222,6 +1222,7 @@ int drm_dp_dsc_sink_supported_input_bpcs(const u8 dsc_dpc[DP_DSC_RECEIVER_CAP_SI
 static inline bool
 drm_dp_sink_supports_dsc(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
 {
+	return dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT];
 	return dsc_dpcd[DP_DSC_SUPPORT - DP_DSC_SUPPORT] &
 		DP_DSC_DECOMPRESSION_IS_SUPPORTED;
 }
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 82+ messages in thread

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (21 preceding siblings ...)
  2019-09-20 11:42 ` [PATCH 23/23] HAX to make it work on the icelake test system Maarten Lankhorst
@ 2019-09-20 14:52 ` Patchwork
  2019-09-20 14:59 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Patchwork @ 2019-09-20 14:52 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
URL   : https://patchwork.freedesktop.org/series/66998/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
5a06a0350a83 drm/i915/dp: Fix dsc bpp calculations, v2.
30142b729b5c HAX drm/i915: Disable FEC entirely for now
-:14: WARNING:BAD_SIGN_OFF: 'Not-signed-off-by:' is the preferred signature form
#14: 
Not-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

-:40: ERROR:MISSING_SIGN_OFF: Missing Signed-off-by: line(s)

total: 1 errors, 1 warnings, 0 checks, 19 lines checked
2bb73b0ec47e drm/i915: Prepare to split crtc state in uapi and hw state
-:11: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line)
#11: 
- crtc, *_changed flags, event, commit, state, mode_blob, (plane/connector/encoder)_mask.

-:2112: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#2112: FILE: drivers/gpu/drm/i915/display/intel_display.c:11201:
+	crtc_state->uapi.active = crtc_state->uapi.enable = true;

-:2810: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#2810: FILE: drivers/gpu/drm/i915/display/intel_display.c:16692:
+		crtc_state->hw.active = crtc_state->hw.enable =

-:3965: ERROR:CODE_INDENT: code indent should use tabs where possible
#3965: FILE: drivers/gpu/drm/i915/display/intel_sprite.c:211:
+^I^I^I^I          new_crtc_state->uapi.event);$

-:3965: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#3965: FILE: drivers/gpu/drm/i915/display/intel_sprite.c:211:
+		drm_crtc_arm_vblank_event(&crtc->base,
+				          new_crtc_state->uapi.event);

total: 1 errors, 1 warnings, 3 checks, 4348 lines checked
8fa117d4a277 drm/i915: Handle a few more cases for hw/sw split
fb10f9c4dae1 drm/i915: Complete sw/hw split
89bdbc955927 drm/i915: Get rid of crtc_state->fb_changed
1997dbaaa507 drm/i915: Remove begin/finish_crtc_commit.
35e0e945926a drm/i915: Rename planar linked plane variables
11b08875cb14 drm/i915: Do not add all planes when checking scalers on glk+
c5ac35a82acd drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
02ae546be7ff drm/i915: Try to make bigjoiner work in atomic check.
-:143: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#143: FILE: drivers/gpu/drm/i915/display/intel_display.c:11826:
+				intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);

-:191: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#191: FILE: drivers/gpu/drm/i915/display/intel_display.c:12326:
+	crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;

-:217: WARNING:LONG_LINE: line over 100 characters
#217: FILE: drivers/gpu/drm/i915/display/intel_display.c:13625:
+	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;

-:280: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#280: FILE: drivers/gpu/drm/i915/display/intel_display.c:13688:
+			slave = new_crtc_state->bigjoiner_linked_crtc =

-:290: WARNING:UNNECESSARY_ELSE: else is not generally useful after a break or return
#290: FILE: drivers/gpu/drm/i915/display/intel_display.c:13698:
+				return -EINVAL;
+			} else {

-:348: ERROR:OPEN_BRACE: that open brace { should be on the previous line
#348: FILE: drivers/gpu/drm/i915/display/intel_display.c:13930:
+	if (new_crtc_state->bigjoiner)
+		{/* Not supported yet */}

total: 1 errors, 2 warnings, 3 checks, 391 lines checked
fe1d38cc6ac9 drm/i915: Enable big joiner support in enable and disable sequences.
-:121: WARNING:LONG_LINE_COMMENT: line over 100 characters
#121: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4087:
+		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

-:123: WARNING:LONG_LINE: line over 100 characters
#123: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4089:
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;

-:231: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#231: FILE: drivers/gpu/drm/i915/display/intel_display.c:6527:
+			I915_WRITE(PIPE_MULT(cpu_transcoder),
+				  pipe_config->pixel_multiplier - 1);

-:239: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#239: FILE: drivers/gpu/drm/i915/display/intel_display.c:6531:
+			intel_cpu_transcoder_set_m_n(pipe_config,
+						    &pipe_config->fdi_m_n, NULL);

-:348: WARNING:BLOCK_COMMENT_STYLE: Block comments should align the * on each line
#348: FILE: drivers/gpu/drm/i915/display/intel_display.c:8353:
+		/*
+		  * transcoder is programmed to the full mode,

-:567: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#567: FILE: drivers/gpu/drm/i915/display/intel_display.c:13044:
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
 	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);

-:776: CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#776: FILE: drivers/gpu/drm/i915/display/intel_display_types.h:789:
+#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE	(1<<1) /* bigjoiner slave, partial readout */
                                          	  ^

total: 0 errors, 4 warnings, 3 checks, 934 lines checked
0334bd232823 drm/i915: Make hardware readout work on i915.
-:73: WARNING:LONG_LINE: line over 100 characters
#73: FILE: drivers/gpu/drm/i915/display/intel_display.c:10038:
+		    (I915_READ(PLANE_SURF(bigjoiner_pipe, plane_id)) & 0xfffff000) == plane_config->base) {

-:74: WARNING:LONG_LINE: line over 100 characters
#74: FILE: drivers/gpu/drm/i915/display/intel_display.c:10039:
+			val = I915_READ(PLANE_SIZE(crtc_state->bigjoiner_linked_crtc->pipe, plane_id));

-:109: WARNING:LONG_LINE: line over 100 characters
#109: FILE: drivers/gpu/drm/i915/display/intel_display.c:17173:
+				WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));

-:136: WARNING:BLOCK_COMMENT_STYLE: Block comments should align the * on each line
#136: FILE: drivers/gpu/drm/i915/display/intel_display.c:17238:
+				/*
+				* FIXME don't have the fb yet, so can't

total: 0 errors, 4 warnings, 0 checks, 119 lines checked
87f053dd9d78 drm/i915: Prepare update_slave() for bigjoiner plane updates
-:138: WARNING:LONG_LINE: line over 100 characters
#138: FILE: drivers/gpu/drm/i915/display/intel_display.c:14806:
+			intel_atomic_get_new_plane_state(intel_state, new_plane_state->planar_linked_plane);

total: 0 errors, 1 warnings, 0 checks, 318 lines checked
5c48f75472bd drm/i915: Link planes in a bigjoiner configuration.
-:28: ERROR:OPEN_BRACE: open brace '{' following function definitions go on the next line
#28: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:185:
+struct intel_crtc *
+intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
+				 const struct intel_plane_state *old_plane_state,
+				 const struct intel_plane_state *new_plane_state)
+  {

-:32: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#32: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:189:
+  {$

-:157: WARNING:LONG_LINE: line over 100 characters
#157: FILE: drivers/gpu/drm/i915/display/intel_display.c:11872:
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {

total: 1 errors, 2 warnings, 0 checks, 242 lines checked
dfcb59743ad5 drm/i915: Program planes in bigjoiner mode.
-:49: WARNING:LONG_LINE: line over 100 characters
#49: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:395:
+				intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);

total: 0 errors, 1 warnings, 0 checks, 77 lines checked
a4c555a8c16c drm/i915: Add intel_update_bigjoiner handling.
-:51: WARNING:LONG_LINE: line over 100 characters
#51: FILE: drivers/gpu/drm/i915/display/intel_display.c:14331:
+		drm_calc_timestamping_constants(&slave->base, &new_slave_crtc_state->hw.transcoder_mode);

total: 0 errors, 1 warnings, 0 checks, 223 lines checked
fda4e645a05a drm/i915: Disable FBC in bigjoiner configuration.
b38045c74b32 drm/i915: Prepare atomic plane check for bigjoiner planes
-:35: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#35: FILE: drivers/gpu/drm/i915/display/intel_atomic.c:301:
+	if (plane_state && (plane_state->linked_plane ||
+	     (!plane_state->bigjoiner_slave && plane_state->base.fb &&

-:82: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#82: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:164:
+			intel_atomic_get_old_plane_state(state,
+					old_plane_state->bigjoiner_plane);

-:87: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#87: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:169:
+			intel_atomic_get_new_plane_state(state,
+					new_plane_state->bigjoiner_plane);

-:124: CHECK:LINE_SPACING: Please don't use multiple blank lines
#124: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:462:
 
+

-:360: WARNING:LONG_LINE: line over 100 characters
#360: FILE: drivers/gpu/drm/i915/display/intel_display.c:3394:
+		aux_offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 1,

-:394: WARNING:LONG_LINE: line over 100 characters
#394: FILE: drivers/gpu/drm/i915/display/intel_display.c:3452:
+		offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,

-:403: WARNING:LONG_LINE: line over 100 characters
#403: FILE: drivers/gpu/drm/i915/display/intel_display.c:3470:
+			offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,

-:412: WARNING:LONG_LINE: line over 100 characters
#412: FILE: drivers/gpu/drm/i915/display/intel_display.c:3480:
+		while (!skl_check_main_ccs_coordinates(master_plane_state, plane_state, x, y, offset)) {

-:417: WARNING:LONG_LINE: line over 100 characters
#417: FILE: drivers/gpu/drm/i915/display/intel_display.c:3484:
+			offset = intel_plane_adjust_aligned_offset(&x, &y, master_plane_state, plane_state, 0,

total: 0 errors, 5 warnings, 4 checks, 955 lines checked
00bf77afbf1c drm/i915: Make prepare_plane_fb() work with bigjoiner planes
-:133: WARNING:LONG_LINE: line over 100 characters
#133: FILE: drivers/gpu/drm/i915/display/intel_display.c:15050:
+			intel_atomic_get_new_plane_state(state, new_plane_state->planar_linked_plane);

-:142: WARNING:LONG_LINE: line over 100 characters
#142: FILE: drivers/gpu/drm/i915/display/intel_display.c:15065:
+		new_master_plane_state = intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);

total: 0 errors, 2 warnings, 0 checks, 167 lines checked
2f481b21d19e drm/i915: Make sure watermarks work correctly with bigjoiner as well.
-:32: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#32: FILE: drivers/gpu/drm/i915/display/intel_atomic.c:301:
+	if (plane_state && (plane_state->planar_linked_plane ||
 	     (!plane_state->bigjoiner_slave && plane_state->base.fb &&

-:73: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#73: FILE: drivers/gpu/drm/i915/display/intel_display.h:443:
+#define intel_atomic_crtc_state_for_each_plane_state( \
+		  plane, master_plane_state, plane_state, \
+		  crtc_state) \
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
+		  (((crtc_state)->bigjoiner_slave ? \
+			intel_atomic_get_new_crtc_state( \
+				to_intel_atomic_state((crtc_state)->uapi.state), \
+				(crtc_state)->bigjoiner_linked_crtc) : \
+				(crtc_state))->uapi.plane_mask)) \
+		for_each_if ((((master_plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \
+			      ((plane) = (master_plane_state)->bigjoiner_slave ? \
+					 (master_plane_state)->bigjoiner_plane : \
+					 (plane)), \
+			      ((plane_state) = (master_plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (master_plane_state))))

-:73: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'plane' - possible side-effects?
#73: FILE: drivers/gpu/drm/i915/display/intel_display.h:443:
+#define intel_atomic_crtc_state_for_each_plane_state( \
+		  plane, master_plane_state, plane_state, \
+		  crtc_state) \
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
+		  (((crtc_state)->bigjoiner_slave ? \
+			intel_atomic_get_new_crtc_state( \
+				to_intel_atomic_state((crtc_state)->uapi.state), \
+				(crtc_state)->bigjoiner_linked_crtc) : \
+				(crtc_state))->uapi.plane_mask)) \
+		for_each_if ((((master_plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \
+			      ((plane) = (master_plane_state)->bigjoiner_slave ? \
+					 (master_plane_state)->bigjoiner_plane : \
+					 (plane)), \
+			      ((plane_state) = (master_plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (master_plane_state))))

-:73: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'master_plane_state' - possible side-effects?
#73: FILE: drivers/gpu/drm/i915/display/intel_display.h:443:
+#define intel_atomic_crtc_state_for_each_plane_state( \
+		  plane, master_plane_state, plane_state, \
+		  crtc_state) \
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
+		  (((crtc_state)->bigjoiner_slave ? \
+			intel_atomic_get_new_crtc_state( \
+				to_intel_atomic_state((crtc_state)->uapi.state), \
+				(crtc_state)->bigjoiner_linked_crtc) : \
+				(crtc_state))->uapi.plane_mask)) \
+		for_each_if ((((master_plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \
+			      ((plane) = (master_plane_state)->bigjoiner_slave ? \
+					 (master_plane_state)->bigjoiner_plane : \
+					 (plane)), \
+			      ((plane_state) = (master_plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (master_plane_state))))

-:73: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'crtc_state' - possible side-effects?
#73: FILE: drivers/gpu/drm/i915/display/intel_display.h:443:
+#define intel_atomic_crtc_state_for_each_plane_state( \
+		  plane, master_plane_state, plane_state, \
+		  crtc_state) \
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
+		  (((crtc_state)->bigjoiner_slave ? \
+			intel_atomic_get_new_crtc_state( \
+				to_intel_atomic_state((crtc_state)->uapi.state), \
+				(crtc_state)->bigjoiner_linked_crtc) : \
+				(crtc_state))->uapi.plane_mask)) \
+		for_each_if ((((master_plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \
+			      ((plane) = (master_plane_state)->bigjoiner_slave ? \
+					 (master_plane_state)->bigjoiner_plane : \
+					 (plane)), \
+			      ((plane_state) = (master_plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (master_plane_state))))

-:82: WARNING:SPACING: space prohibited between function name and open parenthesis '('
#82: FILE: drivers/gpu/drm/i915/display/intel_display.h:452:
+		for_each_if ((((master_plane_state) = \

-:83: WARNING:LONG_LINE: line over 100 characters
#83: FILE: drivers/gpu/drm/i915/display/intel_display.h:453:
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))), \

-:88: WARNING:LONG_LINE: line over 100 characters
#88: FILE: drivers/gpu/drm/i915/display/intel_display.h:458:
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \

-:116: CHECK:COMPARISON_TO_NULL: Comparison to NULL could be written "master_plane_state->base.fb"
#116: FILE: drivers/gpu/drm/i915/intel_pm.c:835:
+		return master_plane_state->base.fb != NULL;

-:408: WARNING:TABSTOP: Statements should start on a tabstop
#408: FILE: drivers/gpu/drm/i915/intel_pm.c:4333:
+		  }

-:466: WARNING:LONG_LINE: line over 100 characters
#466: FILE: drivers/gpu/drm/i915/intel_pm.c:4763:
+				     skl_adjusted_plane_pixel_rate(crtc_state, master_plane_state, plane_state),

total: 1 errors, 5 warnings, 5 checks, 522 lines checked
6841b8e381a7 drm/i915: Add debugfs dumping for bigjoiner.
-:52: WARNING:LONG_LINE: line over 100 characters
#52: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2682:
+		seq_printf(m, "\t--Plane id %d: type=%s, %sclipped crtc="DRM_RECT_FMT", clipped src="DRM_RECT_FP_FMT", format=%s, rotation=%s\n",

-:52: CHECK:CONCATENATED_STRING: Concatenated strings should use spaces between elements
#52: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2682:
+		seq_printf(m, "\t--Plane id %d: type=%s, %sclipped crtc="DRM_RECT_FMT", clipped src="DRM_RECT_FP_FMT", format=%s, rotation=%s\n",

total: 0 errors, 1 warnings, 1 checks, 65 lines checked
4fc8d6917d96 HAX to make it work on the icelake test system

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* ✗ Fi.CI.SPARSE: warning for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (22 preceding siblings ...)
  2019-09-20 14:52 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Patchwork
@ 2019-09-20 14:59 ` Patchwork
  2019-09-20 15:16 ` ✓ Fi.CI.BAT: success " Patchwork
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Patchwork @ 2019-09-20 14:59 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
URL   : https://patchwork.freedesktop.org/series/66998/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.6.0
Commit: drm/i915/dp: Fix dsc bpp calculations, v2.
Okay!

Commit: HAX drm/i915: Disable FEC entirely for now
Okay!

Commit: drm/i915: Prepare to split crtc state in uapi and hw state
Okay!

Commit: drm/i915: Handle a few more cases for hw/sw split
Okay!

Commit: drm/i915: Complete sw/hw split
Okay!

Commit: drm/i915: Get rid of crtc_state->fb_changed
Okay!

Commit: drm/i915: Remove begin/finish_crtc_commit.
Okay!

Commit: drm/i915: Rename planar linked plane variables
Okay!

Commit: drm/i915: Do not add all planes when checking scalers on glk+
Okay!

Commit: drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
Okay!

Commit: drm/i915: Try to make bigjoiner work in atomic check.
Okay!

Commit: drm/i915: Enable big joiner support in enable and disable sequences.
Okay!

Commit: drm/i915: Make hardware readout work on i915.
Okay!

Commit: drm/i915: Prepare update_slave() for bigjoiner plane updates
Okay!

Commit: drm/i915: Link planes in a bigjoiner configuration.
Okay!

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* ✓ Fi.CI.BAT: success for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (23 preceding siblings ...)
  2019-09-20 14:59 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-09-20 15:16 ` Patchwork
  2019-09-20 16:38 ` [Intel-gfx] [PATCH 01/23] " Ville Syrjälä
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 82+ messages in thread
From: Patchwork @ 2019-09-20 15:16 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
URL   : https://patchwork.freedesktop.org/series/66998/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_6928 -> Patchwork_14476
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/

Known issues
------------

  Here are the changes found in Patchwork_14476 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@i915_module_load@reload:
    - fi-icl-u3:          [PASS][1] -> [DMESG-WARN][2] ([fdo#107724] / [fdo#111214])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/fi-icl-u3/igt@i915_module_load@reload.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/fi-icl-u3/igt@i915_module_load@reload.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-kbl-7500u:       [PASS][3] -> [FAIL][4] ([fdo#111407])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html

  
#### Possible fixes ####

  * igt@gem_ctx_switch@legacy-render:
    - fi-icl-u2:          [INCOMPLETE][5] ([fdo#107713] / [fdo#111381]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/fi-icl-u2/igt@gem_ctx_switch@legacy-render.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/fi-icl-u2/igt@gem_ctx_switch@legacy-render.html

  * igt@i915_module_load@reload:
    - fi-blb-e6850:       [INCOMPLETE][7] ([fdo#107718]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/fi-blb-e6850/igt@i915_module_load@reload.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/fi-blb-e6850/igt@i915_module_load@reload.html

  * igt@kms_addfb_basic@addfb25-x-tiled:
    - fi-icl-u3:          [DMESG-WARN][9] ([fdo#107724]) -> [PASS][10] +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/fi-icl-u3/igt@kms_addfb_basic@addfb25-x-tiled.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/fi-icl-u3/igt@kms_addfb_basic@addfb25-x-tiled.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#111214]: https://bugs.freedesktop.org/show_bug.cgi?id=111214
  [fdo#111381]: https://bugs.freedesktop.org/show_bug.cgi?id=111381
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407


Participating hosts (54 -> 45)
------------------------------

  Additional (1): fi-hsw-4770r 
  Missing    (10): fi-ilk-m540 fi-bxt-dsi fi-hsw-4200u fi-glk-dsi fi-byt-squawks fi-bsw-cyan fi-pnv-d510 fi-icl-y fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6928 -> Patchwork_14476

  CI-20190529: 20190529
  CI_DRM_6928: 74bb5b031ca11c7036f7be21f42a73a057fc8da8 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5194: 531d3d02d5e7a2a84d61b92b28fa01b822afc399 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_14476: 4fc8d6917d9641566f066833c6cd4a367858864a @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

4fc8d6917d96 HAX to make it work on the icelake test system
6841b8e381a7 drm/i915: Add debugfs dumping for bigjoiner.
2f481b21d19e drm/i915: Make sure watermarks work correctly with bigjoiner as well.
00bf77afbf1c drm/i915: Make prepare_plane_fb() work with bigjoiner planes
b38045c74b32 drm/i915: Prepare atomic plane check for bigjoiner planes
fda4e645a05a drm/i915: Disable FBC in bigjoiner configuration.
a4c555a8c16c drm/i915: Add intel_update_bigjoiner handling.
dfcb59743ad5 drm/i915: Program planes in bigjoiner mode.
5c48f75472bd drm/i915: Link planes in a bigjoiner configuration.
87f053dd9d78 drm/i915: Prepare update_slave() for bigjoiner plane updates
0334bd232823 drm/i915: Make hardware readout work on i915.
fe1d38cc6ac9 drm/i915: Enable big joiner support in enable and disable sequences.
02ae546be7ff drm/i915: Try to make bigjoiner work in atomic check.
c5ac35a82acd drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
11b08875cb14 drm/i915: Do not add all planes when checking scalers on glk+
35e0e945926a drm/i915: Rename planar linked plane variables
1997dbaaa507 drm/i915: Remove begin/finish_crtc_commit.
89bdbc955927 drm/i915: Get rid of crtc_state->fb_changed
fb10f9c4dae1 drm/i915: Complete sw/hw split
8fa117d4a277 drm/i915: Handle a few more cases for hw/sw split
2bb73b0ec47e drm/i915: Prepare to split crtc state in uapi and hw state
30142b729b5c HAX drm/i915: Disable FEC entirely for now
5a06a0350a83 drm/i915/dp: Fix dsc bpp calculations, v2.

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/index.html
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [Intel-gfx] [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (24 preceding siblings ...)
  2019-09-20 15:16 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-09-20 16:38 ` Ville Syrjälä
  2019-09-23 12:52   ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 Maarten Lankhorst
  2019-09-21 12:06 ` [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Sasha Levin
                   ` (2 subsequent siblings)
  28 siblings, 1 reply; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-20 16:38 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, stable

On Fri, Sep 20, 2019 at 01:42:13PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> Together with the next commit, this causes FEC to work correctly
> with big joiner, while also having the correct refresh rate
> reported in kms_setmode.basic.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  19 +-
>  drivers/gpu/drm/i915/display/intel_display.c |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c      | 195 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
>  4 files changed, 128 insertions(+), 93 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 3e6394139964..1b59b852874b 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> +	/* fec adds overhead to the data M/N values, correct for it */
> +	if (pipe_config->fec_enable)
> +		dotclock = intel_dp_fec_to_mode_clock(dotclock);
> +
>  	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>  }
>  
> @@ -4031,7 +4035,9 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	case TRANS_DDI_MODE_SELECT_FDI:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
>  		break;
> -	case TRANS_DDI_MODE_SELECT_DP_SST:
> +	case TRANS_DDI_MODE_SELECT_DP_SST: {
> +		struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> +
>  		if (encoder->type == INTEL_OUTPUT_EDP)
>  			pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
>  		else
> @@ -4039,7 +4045,18 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			pipe_config->fec_enable =
> +				I915_READ(intel_dp->regs.dp_tp_ctl) &
> +					  DP_TP_CTL_FEC_ENABLE;

Side note: That looks broken for the init/resume readout.
I knew there was a reason I didn't quite like the idea of
intel_dp->regs...

> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
> +	}
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
>  		pipe_config->lane_count =
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index e0033d99f6e3..7996864e6f7c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -12773,6 +12773,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index ccaf9f00b747..4dfb78dc7fa2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +static inline u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> +{
> +	return div_u64(mul_u32_u32(fec_clock,
> +				   DP_DSC_FEC_OVERHEAD_FACTOR),
> +		       1000000U);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2182,6 +2280,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
>  					   DP_DPCD_QUIRK_CONSTANT_N);
>  	int ret = 0, output_bpp;
> +	u32 data_clock;
>  
>  	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
>  		pipe_config->has_pch_encoder = true;
> @@ -2244,9 +2343,14 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  	else
>  		output_bpp = intel_dp_output_bpp(pipe_config, pipe_config->pipe_bpp);
>  
> +	if (pipe_config->fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(adjusted_mode->crtc_clock);
> +	else
> +		data_clock = adjusted_mode->crtc_clock;

This looks wrong to me. The link M/N are used the regenerate the
stream clock from the link symbol clock. AFAICS the only effect FEC
should have is that the overhead may require us to bump the LS clock
a bit higher. But the M/N is stil computed simply as the ratio
between LS clock and stream clock.

The data M/N do need to account for FEC. I guess that's the problem
you're trying to address here?

> +
>  	intel_link_compute_m_n(output_bpp,
>  			       pipe_config->lane_count,
> -			       adjusted_mode->crtc_clock,
> +			       data_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
>  			       constant_n);
> @@ -4363,91 +4467,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..e9f11e698697 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (25 preceding siblings ...)
  2019-09-20 16:38 ` [Intel-gfx] [PATCH 01/23] " Ville Syrjälä
@ 2019-09-21 12:06 ` Sasha Levin
  2019-09-21 15:22 ` ✗ Fi.CI.IGT: failure for series starting with [01/23] " Patchwork
  2019-09-23 19:10 ` ✗ Fi.CI.BUILD: failure for series starting with drm/i915/dp: Fix dsc bpp calculations, v4. (rev3) Patchwork
  28 siblings, 0 replies; 82+ messages in thread
From: Sasha Levin @ 2019-09-21 12:06 UTC (permalink / raw)
  To: Sasha Levin, Maarten Lankhorst, intel-gfx; +Cc: stable

Hi,

[This is an automated email]

This commit has been processed because it contains a "Fixes:" tag,
fixing commit: d9218c8f6cf4 drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC.

The bot has tested the following trees: v5.2.16.

v5.2.16: Failed to apply! Possible dependencies:
    3c053a96ef5f ("drm/i915/dp: Program VSC Header and DB for Pixel Encoding/Colorimetry Format")
    7afc7f816870 ("drm/i915: Drop the _INCOMPLETE for has_infoframe")
    8e9d645c6831 ("drm/i915/dp: Add a config function for YCBCR420 outputs")


NOTE: The patch will not be queued to stable trees until it is upstream.

How should we proceed with this patch?

--
Thanks,
Sasha
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* ✗ Fi.CI.IGT: failure for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (26 preceding siblings ...)
  2019-09-21 12:06 ` [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Sasha Levin
@ 2019-09-21 15:22 ` Patchwork
  2019-09-23 10:43   ` Maarten Lankhorst
  2019-09-23 19:10 ` ✗ Fi.CI.BUILD: failure for series starting with drm/i915/dp: Fix dsc bpp calculations, v4. (rev3) Patchwork
  28 siblings, 1 reply; 82+ messages in thread
From: Patchwork @ 2019-09-21 15:22 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
URL   : https://patchwork.freedesktop.org/series/66998/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_6928_full -> Patchwork_14476_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_14476_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_14476_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_14476_full:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_plane_lowres@pipe-a-tiling-x:
    - shard-snb:          [PASS][1] -> [FAIL][2] +3 similar issues
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb6/igt@kms_plane_lowres@pipe-a-tiling-x.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_plane_lowres@pipe-a-tiling-x.html

  * igt@kms_plane_lowres@pipe-a-tiling-yf:
    - shard-skl:          [PASS][3] -> [FAIL][4] +11 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@kms_plane_lowres@pipe-a-tiling-yf.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl8/igt@kms_plane_lowres@pipe-a-tiling-yf.html

  * igt@kms_plane_lowres@pipe-b-tiling-x:
    - shard-glk:          [PASS][5] -> [FAIL][6] +11 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
    - shard-apl:          [PASS][7] -> [FAIL][8] +8 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html

  * igt@kms_plane_lowres@pipe-b-tiling-y:
    - shard-iclb:         NOTRUN -> [FAIL][9]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-b-tiling-y.html

  * igt@kms_plane_lowres@pipe-c-tiling-none:
    - shard-iclb:         [PASS][10] -> [FAIL][11] +10 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-c-tiling-none.html
    - shard-hsw:          [PASS][12] -> [FAIL][13] +5 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_plane_lowres@pipe-c-tiling-none.html

  * igt@kms_plane_lowres@pipe-c-tiling-y:
    - shard-apl:          NOTRUN -> [FAIL][14]
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_plane_lowres@pipe-c-tiling-y.html

  * igt@kms_plane_lowres@pipe-c-tiling-yf:
    - shard-kbl:          [PASS][15] -> [FAIL][16] +11 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl1/igt@kms_plane_lowres@pipe-c-tiling-yf.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl3/igt@kms_plane_lowres@pipe-c-tiling-yf.html

  
Known issues
------------

  Here are the changes found in Patchwork_14476_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_shared@exec-single-timeline-bsd:
    - shard-iclb:         [PASS][17] -> [SKIP][18] ([fdo#110841])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@gem_ctx_shared@exec-single-timeline-bsd.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb1/igt@gem_ctx_shared@exec-single-timeline-bsd.html

  * igt@gem_exec_schedule@preempt-queue-bsd1:
    - shard-iclb:         [PASS][19] -> [SKIP][20] ([fdo#109276]) +37 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_exec_schedule@preempt-queue-bsd1.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preempt-queue-bsd1.html

  * igt@gem_exec_schedule@reorder-wide-bsd:
    - shard-iclb:         [PASS][21] -> [SKIP][22] ([fdo#111325]) +6 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html

  * igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen:
    - shard-apl:          [PASS][23] -> [INCOMPLETE][24] ([fdo#103927]) +3 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
    - shard-hsw:          [PASS][25] -> [FAIL][26] ([fdo#105767])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
    - shard-iclb:         [PASS][27] -> [FAIL][28] ([fdo#103167]) +4 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html

  * igt@kms_plane@pixel-format-pipe-a-planes:
    - shard-iclb:         [PASS][29] -> [DMESG-FAIL][30] ([fdo#107724]) +5 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@kms_plane@pixel-format-pipe-a-planes.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_plane@pixel-format-pipe-a-planes.html

  * igt@kms_plane_scaling@pipe-b-scaler-with-rotation:
    - shard-iclb:         [PASS][31] -> [DMESG-WARN][32] ([fdo#107724]) +7 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [PASS][33] -> [SKIP][34] ([fdo#109441]) +4 similar issues
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@kms_rotation_crc@bad-pixel-format:
    - shard-iclb:         [PASS][35] -> [DMESG-WARN][36] ([fdo#107724] / [fdo#108336])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_rotation_crc@bad-pixel-format.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_rotation_crc@bad-pixel-format.html

  * igt@kms_vblank@pipe-b-ts-continuation-suspend:
    - shard-apl:          [PASS][37] -> [DMESG-WARN][38] ([fdo#108566]) +3 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl8/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl3/igt@kms_vblank@pipe-b-ts-continuation-suspend.html

  * igt@kms_vblank@pipe-c-query-forked-hang:
    - shard-hsw:          [PASS][39] -> [INCOMPLETE][40] ([fdo#103540])
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_vblank@pipe-c-query-forked-hang.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_vblank@pipe-c-query-forked-hang.html

  
#### Possible fixes ####

  * igt@gem_exec_schedule@independent-bsd2:
    - shard-iclb:         [SKIP][41] ([fdo#109276]) -> [PASS][42] +14 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@independent-bsd2.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@independent-bsd2.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [SKIP][43] ([fdo#111325]) -> [PASS][44] +7 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_tiled_swapping@non-threaded:
    - shard-glk:          [DMESG-WARN][45] ([fdo#108686]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk4/igt@gem_tiled_swapping@non-threaded.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk4/igt@gem_tiled_swapping@non-threaded.html

  * igt@i915_suspend@sysfs-reader:
    - shard-apl:          [DMESG-WARN][47] ([fdo#108566]) -> [PASS][48] +4 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@i915_suspend@sysfs-reader.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@i915_suspend@sysfs-reader.html

  * igt@kms_cursor_crc@pipe-c-cursor-suspend:
    - shard-skl:          [INCOMPLETE][49] ([fdo#110741]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl6/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl7/igt@kms_cursor_crc@pipe-c-cursor-suspend.html

  * igt@kms_flip@flip-vs-dpms-interruptible:
    - shard-iclb:         [INCOMPLETE][51] ([fdo#107713]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_flip@flip-vs-dpms-interruptible.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_flip@flip-vs-dpms-interruptible.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-snb:          [DMESG-WARN][53] ([fdo#102365]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb4/igt@kms_flip@flip-vs-suspend-interruptible.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite:
    - shard-iclb:         [FAIL][55] ([fdo#103167]) -> [PASS][56] +2 similar issues
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html

  * igt@kms_frontbuffer_tracking@psr-suspend:
    - shard-skl:          [INCOMPLETE][57] ([fdo#104108] / [fdo#106978]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl9/igt@kms_frontbuffer_tracking@psr-suspend.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl1/igt@kms_frontbuffer_tracking@psr-suspend.html

  * igt@kms_plane_cursor@pipe-a-primary-size-128:
    - shard-kbl:          [DMESG-WARN][59] ([fdo#103558] / [fdo#105602]) -> [PASS][60] +37 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_plane_cursor@pipe-a-primary-size-128.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_plane_cursor@pipe-a-primary-size-128.html

  * igt@kms_psr@psr2_sprite_mmap_gtt:
    - shard-iclb:         [SKIP][61] ([fdo#109441]) -> [PASS][62] +3 similar issues
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_psr@psr2_sprite_mmap_gtt.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_psr@psr2_sprite_mmap_gtt.html

  * igt@kms_setmode@basic:
    - shard-apl:          [FAIL][63] ([fdo#99912]) -> [PASS][64]
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_setmode@basic.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_setmode@basic.html
    - shard-hsw:          [FAIL][65] ([fdo#99912]) -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw6/igt@kms_setmode@basic.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-a-ts-continuation-suspend:
    - shard-apl:          [INCOMPLETE][67] ([fdo#103927]) -> [PASS][68] +2 similar issues
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl8/igt@kms_vblank@pipe-a-ts-continuation-suspend.html

  * igt@perf@blocking:
    - shard-skl:          [FAIL][69] ([fdo#110728]) -> [PASS][70] +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@perf@blocking.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl3/igt@perf@blocking.html

  
#### Warnings ####

  * igt@gem_ctx_isolation@vcs1-nonpriv:
    - shard-iclb:         [FAIL][71] ([fdo#111329]) -> [SKIP][72] ([fdo#109276])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_ctx_isolation@vcs1-nonpriv.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv.html

  * igt@gem_mocs_settings@mocs-isolation-bsd2:
    - shard-iclb:         [FAIL][73] ([fdo#111330]) -> [SKIP][74] ([fdo#109276]) +1 similar issue
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_mocs_settings@mocs-isolation-bsd2.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_mocs_settings@mocs-isolation-bsd2.html

  * igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d:
    - shard-kbl:          [SKIP][75] ([fdo#105602] / [fdo#109271] / [fdo#109278]) -> [SKIP][76] ([fdo#109271] / [fdo#109278]) +3 similar issues
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-apl:          [DMESG-WARN][77] ([fdo#108566]) -> [INCOMPLETE][78] ([fdo#103927])
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_panel_fitting@legacy:
    - shard-kbl:          [SKIP][79] ([fdo#105602] / [fdo#109271]) -> [SKIP][80] ([fdo#109271]) +30 similar issues
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_panel_fitting@legacy.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_panel_fitting@legacy.html

  
  [fdo#102365]: https://bugs.freedesktop.org/show_bug.cgi?id=102365
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
  [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
  [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
  [fdo#106978]: https://bugs.freedesktop.org/show_bug.cgi?id=106978
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
  [fdo#108336]: https://bugs.freedesktop.org/show_bug.cgi?id=108336
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#110728]: https://bugs.freedesktop.org/show_bug.cgi?id=110728
  [fdo#110741]: https://bugs.freedesktop.org/show_bug.cgi?id=110741
  [fdo#110841]: https://bugs.freedesktop.org/show_bug.cgi?id=110841
  [fdo#111325]: https://bugs.freedesktop.org/show_bug.cgi?id=111325
  [fdo#111329]: https://bugs.freedesktop.org/show_bug.cgi?id=111329
  [fdo#111330]: https://bugs.freedesktop.org/show_bug.cgi?id=111330
  [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912


Participating hosts (9 -> 9)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_6928 -> Patchwork_14476

  CI-20190529: 20190529
  CI_DRM_6928: 74bb5b031ca11c7036f7be21f42a73a057fc8da8 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5194: 531d3d02d5e7a2a84d61b92b28fa01b822afc399 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_14476: 4fc8d6917d9641566f066833c6cd4a367858864a @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: ✗ Fi.CI.IGT: failure for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
  2019-09-21 15:22 ` ✗ Fi.CI.IGT: failure for series starting with [01/23] " Patchwork
@ 2019-09-23 10:43   ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-23 10:43 UTC (permalink / raw)
  To: intel-gfx

Op 21-09-2019 om 17:22 schreef Patchwork:
> == Series Details ==
>
> Series: series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2.
> URL   : https://patchwork.freedesktop.org/series/66998/
> State : failure
>
> == Summary ==
>
> CI Bug Log - changes from CI_DRM_6928_full -> Patchwork_14476_full
> ====================================================
>
> Summary
> -------
>
>   **FAILURE**
>
>   Serious unknown changes coming with Patchwork_14476_full absolutely need to be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_14476_full, please notify your bug team to allow them
>   to document this new failure mode, which will reduce false positives in CI.
>
>   
>
> Possible new issues
> -------------------
>
>   Here are the unknown changes that may have been introduced in Patchwork_14476_full:
>
> ### IGT changes ###
>
> #### Possible regressions ####
>
>   * igt@kms_plane_lowres@pipe-a-tiling-x:
>     - shard-snb:          [PASS][1] -> [FAIL][2] +3 similar issues
>    [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb6/igt@kms_plane_lowres@pipe-a-tiling-x.html
>    [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_plane_lowres@pipe-a-tiling-x.html
>
>   * igt@kms_plane_lowres@pipe-a-tiling-yf:
>     - shard-skl:          [PASS][3] -> [FAIL][4] +11 similar issues
>    [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@kms_plane_lowres@pipe-a-tiling-yf.html
>    [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl8/igt@kms_plane_lowres@pipe-a-tiling-yf.html
>
>   * igt@kms_plane_lowres@pipe-b-tiling-x:
>     - shard-glk:          [PASS][5] -> [FAIL][6] +11 similar issues
>    [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
>    [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk2/igt@kms_plane_lowres@pipe-b-tiling-x.html
>     - shard-apl:          [PASS][7] -> [FAIL][8] +8 similar issues
>    [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
>    [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
>
>   * igt@kms_plane_lowres@pipe-b-tiling-y:
>     - shard-iclb:         NOTRUN -> [FAIL][9]
>    [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-b-tiling-y.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-none:
>     - shard-iclb:         [PASS][10] -> [FAIL][11] +10 similar issues
>    [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_plane_lowres@pipe-c-tiling-none.html
>    [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_plane_lowres@pipe-c-tiling-none.html
>     - shard-hsw:          [PASS][12] -> [FAIL][13] +5 similar issues
>    [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_plane_lowres@pipe-c-tiling-none.html
>    [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_plane_lowres@pipe-c-tiling-none.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-y:
>     - shard-apl:          NOTRUN -> [FAIL][14]
>    [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_plane_lowres@pipe-c-tiling-y.html
>
>   * igt@kms_plane_lowres@pipe-c-tiling-yf:
>     - shard-kbl:          [PASS][15] -> [FAIL][16] +11 similar issues
>    [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl1/igt@kms_plane_lowres@pipe-c-tiling-yf.html
>    [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl3/igt@kms_plane_lowres@pipe-c-tiling-yf.html
kms_plane_lowres is failing because of the debugfs changes to i915_display_info, rest of tests pass. Needs some fixes to igt. :)
>   
> Known issues
> ------------
>
>   Here are the changes found in Patchwork_14476_full that come from known issues:
>
> ### IGT changes ###
>
> #### Issues hit ####
>
>   * igt@gem_ctx_shared@exec-single-timeline-bsd:
>     - shard-iclb:         [PASS][17] -> [SKIP][18] ([fdo#110841])
>    [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@gem_ctx_shared@exec-single-timeline-bsd.html
>    [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb1/igt@gem_ctx_shared@exec-single-timeline-bsd.html
>
>   * igt@gem_exec_schedule@preempt-queue-bsd1:
>     - shard-iclb:         [PASS][19] -> [SKIP][20] ([fdo#109276]) +37 similar issues
>    [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_exec_schedule@preempt-queue-bsd1.html
>    [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preempt-queue-bsd1.html
>
>   * igt@gem_exec_schedule@reorder-wide-bsd:
>     - shard-iclb:         [PASS][21] -> [SKIP][22] ([fdo#111325]) +6 similar issues
>    [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html
>    [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@reorder-wide-bsd.html
>
>   * igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen:
>     - shard-apl:          [PASS][23] -> [INCOMPLETE][24] ([fdo#103927]) +3 similar issues
>    [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html
>    [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_cursor_crc@pipe-b-cursor-64x21-offscreen.html
>
>   * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy:
>     - shard-hsw:          [PASS][25] -> [FAIL][26] ([fdo#105767])
>    [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
>    [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw4/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-legacy.html
>
>   * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt:
>     - shard-iclb:         [PASS][27] -> [FAIL][28] ([fdo#103167]) +4 similar issues
>    [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
>    [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-shrfb-plflip-blt.html
>
>   * igt@kms_plane@pixel-format-pipe-a-planes:
>     - shard-iclb:         [PASS][29] -> [DMESG-FAIL][30] ([fdo#107724]) +5 similar issues
>    [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@kms_plane@pixel-format-pipe-a-planes.html
>    [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_plane@pixel-format-pipe-a-planes.html
>
>   * igt@kms_plane_scaling@pipe-b-scaler-with-rotation:
>     - shard-iclb:         [PASS][31] -> [DMESG-WARN][32] ([fdo#107724]) +7 similar issues
>    [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb6/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html
>    [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_plane_scaling@pipe-b-scaler-with-rotation.html
>
>   * igt@kms_psr@psr2_sprite_plane_move:
>     - shard-iclb:         [PASS][33] -> [SKIP][34] ([fdo#109441]) +4 similar issues
>    [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html
>    [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb3/igt@kms_psr@psr2_sprite_plane_move.html
>
>   * igt@kms_rotation_crc@bad-pixel-format:
>     - shard-iclb:         [PASS][35] -> [DMESG-WARN][36] ([fdo#107724] / [fdo#108336])
>    [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@kms_rotation_crc@bad-pixel-format.html
>    [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_rotation_crc@bad-pixel-format.html
>
>   * igt@kms_vblank@pipe-b-ts-continuation-suspend:
>     - shard-apl:          [PASS][37] -> [DMESG-WARN][38] ([fdo#108566]) +3 similar issues
>    [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl8/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
>    [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl3/igt@kms_vblank@pipe-b-ts-continuation-suspend.html
>
>   * igt@kms_vblank@pipe-c-query-forked-hang:
>     - shard-hsw:          [PASS][39] -> [INCOMPLETE][40] ([fdo#103540])
>    [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw5/igt@kms_vblank@pipe-c-query-forked-hang.html
>    [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_vblank@pipe-c-query-forked-hang.html
>
>   
> #### Possible fixes ####
>
>   * igt@gem_exec_schedule@independent-bsd2:
>     - shard-iclb:         [SKIP][41] ([fdo#109276]) -> [PASS][42] +14 similar issues
>    [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb3/igt@gem_exec_schedule@independent-bsd2.html
>    [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@gem_exec_schedule@independent-bsd2.html
>
>   * igt@gem_exec_schedule@preemptive-hang-bsd:
>     - shard-iclb:         [SKIP][43] ([fdo#111325]) -> [PASS][44] +7 similar issues
>    [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@gem_exec_schedule@preemptive-hang-bsd.html
>    [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_exec_schedule@preemptive-hang-bsd.html
>
>   * igt@gem_tiled_swapping@non-threaded:
>     - shard-glk:          [DMESG-WARN][45] ([fdo#108686]) -> [PASS][46]
>    [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-glk4/igt@gem_tiled_swapping@non-threaded.html
>    [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-glk4/igt@gem_tiled_swapping@non-threaded.html
>
>   * igt@i915_suspend@sysfs-reader:
>     - shard-apl:          [DMESG-WARN][47] ([fdo#108566]) -> [PASS][48] +4 similar issues
>    [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl1/igt@i915_suspend@sysfs-reader.html
>    [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@i915_suspend@sysfs-reader.html
>
>   * igt@kms_cursor_crc@pipe-c-cursor-suspend:
>     - shard-skl:          [INCOMPLETE][49] ([fdo#110741]) -> [PASS][50]
>    [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl6/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
>    [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl7/igt@kms_cursor_crc@pipe-c-cursor-suspend.html
>
>   * igt@kms_flip@flip-vs-dpms-interruptible:
>     - shard-iclb:         [INCOMPLETE][51] ([fdo#107713]) -> [PASS][52]
>    [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_flip@flip-vs-dpms-interruptible.html
>    [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@kms_flip@flip-vs-dpms-interruptible.html
>
>   * igt@kms_flip@flip-vs-suspend-interruptible:
>     - shard-snb:          [DMESG-WARN][53] ([fdo#102365]) -> [PASS][54]
>    [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-snb4/igt@kms_flip@flip-vs-suspend-interruptible.html
>    [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-snb2/igt@kms_flip@flip-vs-suspend-interruptible.html
>
>   * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite:
>     - shard-iclb:         [FAIL][55] ([fdo#103167]) -> [PASS][56] +2 similar issues
>    [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
>    [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
>
>   * igt@kms_frontbuffer_tracking@psr-suspend:
>     - shard-skl:          [INCOMPLETE][57] ([fdo#104108] / [fdo#106978]) -> [PASS][58]
>    [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl9/igt@kms_frontbuffer_tracking@psr-suspend.html
>    [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl1/igt@kms_frontbuffer_tracking@psr-suspend.html
>
>   * igt@kms_plane_cursor@pipe-a-primary-size-128:
>     - shard-kbl:          [DMESG-WARN][59] ([fdo#103558] / [fdo#105602]) -> [PASS][60] +37 similar issues
>    [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_plane_cursor@pipe-a-primary-size-128.html
>    [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_plane_cursor@pipe-a-primary-size-128.html
>
>   * igt@kms_psr@psr2_sprite_mmap_gtt:
>     - shard-iclb:         [SKIP][61] ([fdo#109441]) -> [PASS][62] +3 similar issues
>    [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb1/igt@kms_psr@psr2_sprite_mmap_gtt.html
>    [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb2/igt@kms_psr@psr2_sprite_mmap_gtt.html
>
>   * igt@kms_setmode@basic:
>     - shard-apl:          [FAIL][63] ([fdo#99912]) -> [PASS][64]
>    [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_setmode@basic.html
>    [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl6/igt@kms_setmode@basic.html
>     - shard-hsw:          [FAIL][65] ([fdo#99912]) -> [PASS][66]
>    [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-hsw6/igt@kms_setmode@basic.html
>    [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-hsw6/igt@kms_setmode@basic.html
>
>   * igt@kms_vblank@pipe-a-ts-continuation-suspend:
>     - shard-apl:          [INCOMPLETE][67] ([fdo#103927]) -> [PASS][68] +2 similar issues
>    [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl4/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
>    [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl8/igt@kms_vblank@pipe-a-ts-continuation-suspend.html
>
>   * igt@perf@blocking:
>     - shard-skl:          [FAIL][69] ([fdo#110728]) -> [PASS][70] +1 similar issue
>    [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-skl7/igt@perf@blocking.html
>    [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-skl3/igt@perf@blocking.html
>
>   
> #### Warnings ####
>
>   * igt@gem_ctx_isolation@vcs1-nonpriv:
>     - shard-iclb:         [FAIL][71] ([fdo#111329]) -> [SKIP][72] ([fdo#109276])
>    [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_ctx_isolation@vcs1-nonpriv.html
>    [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb8/igt@gem_ctx_isolation@vcs1-nonpriv.html
>
>   * igt@gem_mocs_settings@mocs-isolation-bsd2:
>     - shard-iclb:         [FAIL][73] ([fdo#111330]) -> [SKIP][74] ([fdo#109276]) +1 similar issue
>    [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-iclb4/igt@gem_mocs_settings@mocs-isolation-bsd2.html
>    [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-iclb5/igt@gem_mocs_settings@mocs-isolation-bsd2.html
>
>   * igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d:
>     - shard-kbl:          [SKIP][75] ([fdo#105602] / [fdo#109271] / [fdo#109278]) -> [SKIP][76] ([fdo#109271] / [fdo#109278]) +3 similar issues
>    [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html
>    [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_busy@extended-pageflip-modeset-hang-oldfb-render-d.html
>
>   * igt@kms_flip@flip-vs-suspend-interruptible:
>     - shard-apl:          [DMESG-WARN][77] ([fdo#108566]) -> [INCOMPLETE][78] ([fdo#103927])
>    [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-apl3/igt@kms_flip@flip-vs-suspend-interruptible.html
>    [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-apl2/igt@kms_flip@flip-vs-suspend-interruptible.html
>
>   * igt@kms_panel_fitting@legacy:
>     - shard-kbl:          [SKIP][79] ([fdo#105602] / [fdo#109271]) -> [SKIP][80] ([fdo#109271]) +30 similar issues
>    [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_6928/shard-kbl6/igt@kms_panel_fitting@legacy.html
>    [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/shard-kbl4/igt@kms_panel_fitting@legacy.html
>
>   
>   [fdo#102365]: https://bugs.freedesktop.org/show_bug.cgi?id=102365
>   [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
>   [fdo#103540]: https://bugs.freedesktop.org/show_bug.cgi?id=103540
>   [fdo#103558]: https://bugs.freedesktop.org/show_bug.cgi?id=103558
>   [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
>   [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
>   [fdo#105602]: https://bugs.freedesktop.org/show_bug.cgi?id=105602
>   [fdo#105767]: https://bugs.freedesktop.org/show_bug.cgi?id=105767
>   [fdo#106978]: https://bugs.freedesktop.org/show_bug.cgi?id=106978
>   [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
>   [fdo#107724]: https://bugs.freedesktop.org/show_bug.cgi?id=107724
>   [fdo#108336]: https://bugs.freedesktop.org/show_bug.cgi?id=108336
>   [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
>   [fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
>   [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
>   [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
>   [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
>   [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
>   [fdo#110728]: https://bugs.freedesktop.org/show_bug.cgi?id=110728
>   [fdo#110741]: https://bugs.freedesktop.org/show_bug.cgi?id=110741
>   [fdo#110841]: https://bugs.freedesktop.org/show_bug.cgi?id=110841
>   [fdo#111325]: https://bugs.freedesktop.org/show_bug.cgi?id=111325
>   [fdo#111329]: https://bugs.freedesktop.org/show_bug.cgi?id=111329
>   [fdo#111330]: https://bugs.freedesktop.org/show_bug.cgi?id=111330
>   [fdo#99912]: https://bugs.freedesktop.org/show_bug.cgi?id=99912
>
>
> Participating hosts (9 -> 9)
> ------------------------------
>
>   No changes in participating hosts
>
>
> Build changes
> -------------
>
>   * CI: CI-20190529 -> None
>   * Linux: CI_DRM_6928 -> Patchwork_14476
>
>   CI-20190529: 20190529
>   CI_DRM_6928: 74bb5b031ca11c7036f7be21f42a73a057fc8da8 @ git://anongit.freedesktop.org/gfx-ci/linux
>   IGT_5194: 531d3d02d5e7a2a84d61b92b28fa01b822afc399 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
>   Patchwork_14476: 4fc8d6917d9641566f066833c6cd4a367858864a @ git://anongit.freedesktop.org/gfx-ci/linux
>   piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit
>
> == Logs ==
>
> For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_14476/


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
  2019-09-20 16:38 ` [Intel-gfx] [PATCH 01/23] " Ville Syrjälä
@ 2019-09-23 12:52   ` Maarten Lankhorst
  2019-09-23 13:03       ` Ville Syrjälä
                       ` (2 more replies)
  0 siblings, 3 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-23 12:52 UTC (permalink / raw)
  To: intel-gfx
  Cc: Ville Syrjälä, Maarten Lankhorst, stable, Manasi Navare

There was a integer wraparound when mode_clock became too high,
and we didn't correct for the FEC overhead factor when dividing,
with the calculations breaking at HBR3.

As a result our calculated bpp was way too high, and the link width
limitation never came into effect.

Print out the resulting bpp calcululations as a sanity check, just
in case we ever have to debug it later on again.

We also used the wrong factor for FEC. While bspec mentions 2.4%,
all the calculations use 1/0.972261, and the same ratio should be
applied to data M/N as well, so use it there when FEC is enabled.

Make sure we don't break hw readout, and read out FEC enable state
and correct the DDI clock readout for the new values.

This fixes the FIFO underrun we are seeing with FEC enabled.

Changes since v2:
- Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
- Fix initial hardware readout for FEC. (Ville)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
Cc: <stable@vger.kernel.org> # v5.0+
Cc: Manasi Navare <manasi.d.navare@intel.com>
---
Thanks, that fixed the FIFO underrun, making the disablement patch obsolete.
Bigjoiner is now completely working as intended. :)

 drivers/gpu/drm/i915/display/intel_ddi.c     |  21 ++
 drivers/gpu/drm/i915/display/intel_display.c |  13 +-
 drivers/gpu/drm/i915/display/intel_display.h |   2 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 191 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.h      |   7 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
 6 files changed, 137 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0c0da9f6c2e8..3e77b30d91d5 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
 	if (pipe_config->pixel_multiplier)
 		dotclock /= pipe_config->pixel_multiplier;
 
+	/* fec adds overhead to the data M/N values, correct for it */
+	if (pipe_config->fec_enable)
+		dotclock = intel_dp_fec_to_mode_clock(dotclock);
+
 	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
 }
 
@@ -4045,6 +4049,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		pipe_config->lane_count =
 			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
 		intel_dp_get_m_n(intel_crtc, pipe_config);
+
+		if (INTEL_GEN(dev_priv) >= 11) {
+			i915_reg_t dp_tp_ctl;
+
+			if (IS_GEN(dev_priv, 11))
+				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
+			else
+				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
+
+			pipe_config->fec_enable =
+				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
+
+			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
+				      encoder->base.base.id, encoder->base.name,
+				      pipe_config->fec_enable);
+		}
+
 		break;
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 5ecf54270181..31698a57773f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 	pipe_config->fdi_lanes = lane;
 
 	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
-			       link_bw, &pipe_config->fdi_m_n, false);
+			       link_bw, &pipe_config->fdi_m_n, false, false);
 
 	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
 	if (ret == -EDEADLK)
@@ -7538,11 +7538,15 @@ void
 intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
 		       int pixel_clock, int link_clock,
 		       struct intel_link_m_n *m_n,
-		       bool constant_n)
+		       bool constant_n, bool fec_enable)
 {
-	m_n->tu = 64;
+	u32 data_clock = bits_per_pixel * pixel_clock;
+
+	if (fec_enable)
+		data_clock = intel_dp_mode_to_fec_clock(data_clock);
 
-	compute_m_n(bits_per_pixel * pixel_clock,
+	m_n->tu = 64;
+	compute_m_n(data_clock,
 		    link_clock * nlanes * 8,
 		    &m_n->gmch_m, &m_n->gmch_n,
 		    constant_n);
@@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
 	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
 	PIPE_CONF_CHECK_BOOL(has_infoframe);
+	PIPE_CONF_CHECK_BOOL(fec_enable);
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 5cea6f8e107a..4b9e18e5a263 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -443,7 +443,7 @@ enum phy_fia {
 void intel_link_compute_m_n(u16 bpp, int nlanes,
 			    int pixel_clock, int link_clock,
 			    struct intel_link_m_n *m_n,
-			    bool constant_n);
+			    bool constant_n, bool fec_enable);
 bool is_ccs_modifier(u64 modifier);
 void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
 u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 829559f97440..2d3f4183f99d 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -76,8 +76,8 @@
 #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
 #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
 
-/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
-#define DP_DSC_FEC_OVERHEAD_FACTOR		976
+/* DP DSC FEC Overhead factor = 1/(0.972261) */
+#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
 
 /* Compliance test status bits  */
 #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
@@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	return 0;
 }
 
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
+{
+	return div_u64(mul_u32_u32(mode_clock, 1000000U),
+		       DP_DSC_FEC_OVERHEAD_FACTOR);
+}
+
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
+{
+	return div_u64(mul_u32_u32(fec_clock,
+				   DP_DSC_FEC_OVERHEAD_FACTOR),
+		       1000000U);
+}
+
+static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
+				       u32 mode_clock, u32 mode_hdisplay)
+{
+	u32 bits_per_pixel, max_bpp_small_joiner_ram;
+	int i;
+
+	/*
+	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
+	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
+	 * for SST -> TimeSlotsPerMTP is 1,
+	 * for MST -> TimeSlotsPerMTP has to be calculated
+	 */
+	bits_per_pixel = (link_clock * lane_count * 8) /
+			 intel_dp_mode_to_fec_clock(mode_clock);
+	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
+
+	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
+
+	/*
+	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
+	 * check, output bpp from small joiner RAM check)
+	 */
+	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+
+	/* Error out if the max bpp is less than smallest allowed valid bpp */
+	if (bits_per_pixel < valid_dsc_bpp[0]) {
+		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
+			      bits_per_pixel, valid_dsc_bpp[0]);
+		return 0;
+	}
+
+	/* Find the nearest match in the array of known BPPs from VESA */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
+		if (bits_per_pixel < valid_dsc_bpp[i + 1])
+			break;
+	}
+	bits_per_pixel = valid_dsc_bpp[i];
+
+	/*
+	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
+	 * fractional part is 0
+	 */
+	return bits_per_pixel << 4;
+}
+
+static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+				       int mode_clock, int mode_hdisplay)
+{
+	u8 min_slice_count, i;
+	int max_slice_width;
+
+	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_0);
+	else
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_1);
+
+	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
+	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
+		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
+			      max_slice_width);
+		return 0;
+	}
+	/* Also take into account max slice width */
+	min_slice_count = min_t(u8, min_slice_count,
+				DIV_ROUND_UP(mode_hdisplay,
+					     max_slice_width));
+
+	/* Find the closest match to the valid slice count values */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
+		if (valid_dsc_slicecount[i] >
+		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+						    false))
+			break;
+		if (min_slice_count  <= valid_dsc_slicecount[i])
+			return valid_dsc_slicecount[i];
+	}
+
+	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+	return 0;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -2259,7 +2357,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 			       adjusted_mode->crtc_clock,
 			       pipe_config->port_clock,
 			       &pipe_config->dp_m_n,
-			       constant_n);
+			       constant_n, pipe_config->fec_enable);
 
 	if (intel_connector->panel.downclock_mode != NULL &&
 		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
@@ -2269,7 +2367,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 					       intel_connector->panel.downclock_mode->clock,
 					       pipe_config->port_clock,
 					       &pipe_config->dp_m2_n2,
-					       constant_n);
+					       constant_n, pipe_config->fec_enable);
 	}
 
 	if (!HAS_DDI(dev_priv))
@@ -4373,91 +4471,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 		DP_DPRX_ESI_LEN;
 }
 
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay)
-{
-	u16 bits_per_pixel, max_bpp_small_joiner_ram;
-	int i;
-
-	/*
-	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
-	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
-	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
-	 * for MST -> TimeSlotsPerMTP has to be calculated
-	 */
-	bits_per_pixel = (link_clock * lane_count * 8 *
-			  DP_DSC_FEC_OVERHEAD_FACTOR) /
-		mode_clock;
-
-	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
-		mode_hdisplay;
-
-	/*
-	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
-	 * check, output bpp from small joiner RAM check)
-	 */
-	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-	/* Error out if the max bpp is less than smallest allowed valid bpp */
-	if (bits_per_pixel < valid_dsc_bpp[0]) {
-		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
-		return 0;
-	}
-
-	/* Find the nearest match in the array of known BPPs from VESA */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
-		if (bits_per_pixel < valid_dsc_bpp[i + 1])
-			break;
-	}
-	bits_per_pixel = valid_dsc_bpp[i];
-
-	/*
-	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-	 * fractional part is 0
-	 */
-	return bits_per_pixel << 4;
-}
-
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-				int mode_clock,
-				int mode_hdisplay)
-{
-	u8 min_slice_count, i;
-	int max_slice_width;
-
-	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_0);
-	else
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_1);
-
-	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
-	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
-		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-			      max_slice_width);
-		return 0;
-	}
-	/* Also take into account max slice width */
-	min_slice_count = min_t(u8, min_slice_count,
-				DIV_ROUND_UP(mode_hdisplay,
-					     max_slice_width));
-
-	/* Find the closest match to the valid slice count values */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-		if (valid_dsc_slicecount[i] >
-		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-						    false))
-			break;
-		if (min_slice_count  <= valid_dsc_slicecount[i])
-			return valid_dsc_slicecount[i];
-	}
-
-	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
-	return 0;
-}
-
 static void
 intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
 			       const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e01d1f89409d..2147d3c14870 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay);
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
-				int mode_hdisplay);
 
 bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
@@ -119,4 +115,7 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index eeeb3f933aa4..cf4d851a5139 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 			       adjusted_mode->crtc_clock,
 			       crtc_state->port_clock,
 			       &crtc_state->dp_m_n,
-			       constant_n);
+			       constant_n, crtc_state->fec_enable);
 	crtc_state->dp_m_n.tu = slots;
 
 	return 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
  2019-09-23 12:52   ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 Maarten Lankhorst
@ 2019-09-23 13:03       ` Ville Syrjälä
  2019-09-23 14:22       ` kbuild test robot
  2019-09-23 15:53     ` Manasi Navare
  2 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-23 13:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, stable, Manasi Navare

On Mon, Sep 23, 2019 at 02:52:52PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> This fixes the FIFO underrun we are seeing with FEC enabled.
> 
> Changes since v2:
> - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> - Fix initial hardware readout for FEC. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
> Thanks, that fixed the FIFO underrun, making the disablement patch obsolete.
> Bigjoiner is now completely working as intended. :)
> 
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  21 ++
>  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 191 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   7 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  6 files changed, 137 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 0c0da9f6c2e8..3e77b30d91d5 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> +	/* fec adds overhead to the data M/N values, correct for it */
> +	if (pipe_config->fec_enable)
> +		dotclock = intel_dp_fec_to_mode_clock(dotclock);

That's still nonsense.

> +
>  	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>  }
>  
> @@ -4045,6 +4049,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			i915_reg_t dp_tp_ctl;
> +
> +			if (IS_GEN(dev_priv, 11))
> +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> +			else
> +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> +
> +			pipe_config->fec_enable =
> +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> +
> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 5ecf54270181..31698a57773f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n, false);
> +			       link_bw, &pipe_config->fdi_m_n, false, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EDEADLK)
> @@ -7538,11 +7538,15 @@ void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
>  		       struct intel_link_m_n *m_n,
> -		       bool constant_n)
> +		       bool constant_n, bool fec_enable)
>  {
> -	m_n->tu = 64;
> +	u32 data_clock = bits_per_pixel * pixel_clock;
> +
> +	if (fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
>  
> -	compute_m_n(bits_per_pixel * pixel_clock,
> +	m_n->tu = 64;
> +	compute_m_n(data_clock,
>  		    link_clock * nlanes * 8,
>  		    &m_n->gmch_m, &m_n->gmch_n,
>  		    constant_n);
> @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 5cea6f8e107a..4b9e18e5a263 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -443,7 +443,7 @@ enum phy_fia {
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> -			    bool constant_n);
> +			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 829559f97440..2d3f4183f99d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> +{
> +	return div_u64(mul_u32_u32(fec_clock,
> +				   DP_DSC_FEC_OVERHEAD_FACTOR),
> +		       1000000U);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2259,7 +2357,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
> -			       constant_n);
> +			       constant_n, pipe_config->fec_enable);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -2269,7 +2367,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					       intel_connector->panel.downclock_mode->clock,
>  					       pipe_config->port_clock,
>  					       &pipe_config->dp_m2_n2,
> -					       constant_n);
> +					       constant_n, pipe_config->fec_enable);
>  	}
>  
>  	if (!HAS_DDI(dev_priv))
> @@ -4373,91 +4471,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..2147d3c14870 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,7 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..cf4d851a5139 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       crtc_state->port_clock,
>  			       &crtc_state->dp_m_n,
> -			       constant_n);
> +			       constant_n, crtc_state->fec_enable);
>  	crtc_state->dp_m_n.tu = slots;
>  
>  	return 0;
> -- 
> 2.20.1

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
@ 2019-09-23 13:03       ` Ville Syrjälä
  0 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-23 13:03 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, stable

On Mon, Sep 23, 2019 at 02:52:52PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> This fixes the FIFO underrun we are seeing with FEC enabled.
> 
> Changes since v2:
> - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> - Fix initial hardware readout for FEC. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
> Thanks, that fixed the FIFO underrun, making the disablement patch obsolete.
> Bigjoiner is now completely working as intended. :)
> 
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  21 ++
>  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 191 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   7 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  6 files changed, 137 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 0c0da9f6c2e8..3e77b30d91d5 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> +	/* fec adds overhead to the data M/N values, correct for it */
> +	if (pipe_config->fec_enable)
> +		dotclock = intel_dp_fec_to_mode_clock(dotclock);

That's still nonsense.

> +
>  	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>  }
>  
> @@ -4045,6 +4049,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			i915_reg_t dp_tp_ctl;
> +
> +			if (IS_GEN(dev_priv, 11))
> +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> +			else
> +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> +
> +			pipe_config->fec_enable =
> +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> +
> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 5ecf54270181..31698a57773f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n, false);
> +			       link_bw, &pipe_config->fdi_m_n, false, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EDEADLK)
> @@ -7538,11 +7538,15 @@ void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
>  		       struct intel_link_m_n *m_n,
> -		       bool constant_n)
> +		       bool constant_n, bool fec_enable)
>  {
> -	m_n->tu = 64;
> +	u32 data_clock = bits_per_pixel * pixel_clock;
> +
> +	if (fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
>  
> -	compute_m_n(bits_per_pixel * pixel_clock,
> +	m_n->tu = 64;
> +	compute_m_n(data_clock,
>  		    link_clock * nlanes * 8,
>  		    &m_n->gmch_m, &m_n->gmch_n,
>  		    constant_n);
> @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 5cea6f8e107a..4b9e18e5a263 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -443,7 +443,7 @@ enum phy_fia {
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> -			    bool constant_n);
> +			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 829559f97440..2d3f4183f99d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> +{
> +	return div_u64(mul_u32_u32(fec_clock,
> +				   DP_DSC_FEC_OVERHEAD_FACTOR),
> +		       1000000U);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2259,7 +2357,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
> -			       constant_n);
> +			       constant_n, pipe_config->fec_enable);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -2269,7 +2367,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					       intel_connector->panel.downclock_mode->clock,
>  					       pipe_config->port_clock,
>  					       &pipe_config->dp_m2_n2,
> -					       constant_n);
> +					       constant_n, pipe_config->fec_enable);
>  	}
>  
>  	if (!HAS_DDI(dev_priv))
> @@ -4373,91 +4471,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..2147d3c14870 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,7 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..cf4d851a5139 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       crtc_state->port_clock,
>  			       &crtc_state->dp_m_n,
> -			       constant_n);
> +			       constant_n, crtc_state->fec_enable);
>  	crtc_state->dp_m_n.tu = slots;
>  
>  	return 0;
> -- 
> 2.20.1

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now
  2019-09-20 11:42 ` [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now Maarten Lankhorst
@ 2019-09-23 13:08   ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-23 13:08 UTC (permalink / raw)
  To: Intel Graphics Development

Op 20-09-2019 om 13:42 schreef Maarten Lankhorst:
> I get a permanent FIFO underrun when enabling FEC with big joiner,
> so for now disable it.
>
> It seems that even at 1024x768 resolution without bigjoiner we don't
> get a working configuration. Flag is set but vblank timing shows that
> vblanks are delivered slightly faster, so the extra overhead we
> calculated for data M/N goes unused.
>
> Not-Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 4dfb78dc7fa2..02242a16640b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1877,7 +1877,8 @@ static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>  				  const struct intel_crtc_state *pipe_config)
>  {
> -	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
> +	/* HACK: Disable FEC until we solved FIFO underruns */
> +	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
>  		return false;
>  
>  	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
> @@ -2024,8 +2025,9 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  	int pipe_bpp;
>  	int ret;
>  
> +	/* HACK: Disable FEC until we solved FIFO underruns */
>  	pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
> -		intel_dp_supports_fec(intel_dp, pipe_config);
> +		intel_dp_supports_fec(intel_dp, pipe_config) && 0;
>  
>  	if (!intel_dp_supports_dsc(intel_dp, pipe_config))
>  		return -EINVAL;

With v3 of the previous patch, this is now obsolete and confirmed working on ICL.

So this can finally be dropped. :)

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
  2019-09-23 12:52   ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 Maarten Lankhorst
@ 2019-09-23 14:22       ` kbuild test robot
  2019-09-23 14:22       ` kbuild test robot
  2019-09-23 15:53     ` Manasi Navare
  2 siblings, 0 replies; 82+ messages in thread
From: kbuild test robot @ 2019-09-23 14:22 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: kbuild-all, intel-gfx, stable

[-- Attachment #1: Type: text/plain, Size: 7236 bytes --]

Hi Maarten,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[cannot apply to v5.3 next-20190920]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-dp-Fix-dsc-bpp-calculations-v3/20190923-205540
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-defconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/display/intel_ddi.c: In function 'intel_ddi_get_config':
>> drivers/gpu/drm/i915/display/intel_ddi.c:3905:17: error: implicit declaration of function 'TGL_DP_TP_CTL'; did you mean 'DP_TP_CTL'? [-Werror=implicit-function-declaration]
        dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
                    ^~~~~~~~~~~~~
                    DP_TP_CTL
>> drivers/gpu/drm/i915/display/intel_ddi.c:3905:15: error: incompatible types when assigning to type 'i915_reg_t {aka struct <anonymous>}' from type 'int'
        dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
                  ^
   cc1: some warnings being treated as errors

vim +3905 drivers/gpu/drm/i915/display/intel_ddi.c

  3826	
  3827	void intel_ddi_get_config(struct intel_encoder *encoder,
  3828				  struct intel_crtc_state *pipe_config)
  3829	{
  3830		struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
  3831		struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
  3832		enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
  3833		u32 temp, flags = 0;
  3834	
  3835		/* XXX: DSI transcoder paranoia */
  3836		if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
  3837			return;
  3838	
  3839		temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
  3840		if (temp & TRANS_DDI_PHSYNC)
  3841			flags |= DRM_MODE_FLAG_PHSYNC;
  3842		else
  3843			flags |= DRM_MODE_FLAG_NHSYNC;
  3844		if (temp & TRANS_DDI_PVSYNC)
  3845			flags |= DRM_MODE_FLAG_PVSYNC;
  3846		else
  3847			flags |= DRM_MODE_FLAG_NVSYNC;
  3848	
  3849		pipe_config->base.adjusted_mode.flags |= flags;
  3850	
  3851		switch (temp & TRANS_DDI_BPC_MASK) {
  3852		case TRANS_DDI_BPC_6:
  3853			pipe_config->pipe_bpp = 18;
  3854			break;
  3855		case TRANS_DDI_BPC_8:
  3856			pipe_config->pipe_bpp = 24;
  3857			break;
  3858		case TRANS_DDI_BPC_10:
  3859			pipe_config->pipe_bpp = 30;
  3860			break;
  3861		case TRANS_DDI_BPC_12:
  3862			pipe_config->pipe_bpp = 36;
  3863			break;
  3864		default:
  3865			break;
  3866		}
  3867	
  3868		switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
  3869		case TRANS_DDI_MODE_SELECT_HDMI:
  3870			pipe_config->has_hdmi_sink = true;
  3871	
  3872			pipe_config->infoframes.enable |=
  3873				intel_hdmi_infoframes_enabled(encoder, pipe_config);
  3874	
  3875			if (pipe_config->infoframes.enable)
  3876				pipe_config->has_infoframe = true;
  3877	
  3878			if (temp & TRANS_DDI_HDMI_SCRAMBLING)
  3879				pipe_config->hdmi_scrambling = true;
  3880			if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
  3881				pipe_config->hdmi_high_tmds_clock_ratio = true;
  3882			/* fall through */
  3883		case TRANS_DDI_MODE_SELECT_DVI:
  3884			pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
  3885			pipe_config->lane_count = 4;
  3886			break;
  3887		case TRANS_DDI_MODE_SELECT_FDI:
  3888			pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
  3889			break;
  3890		case TRANS_DDI_MODE_SELECT_DP_SST:
  3891			if (encoder->type == INTEL_OUTPUT_EDP)
  3892				pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
  3893			else
  3894				pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
  3895			pipe_config->lane_count =
  3896				((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
  3897			intel_dp_get_m_n(intel_crtc, pipe_config);
  3898	
  3899			if (INTEL_GEN(dev_priv) >= 11) {
  3900				i915_reg_t dp_tp_ctl;
  3901	
  3902				if (IS_GEN(dev_priv, 11))
  3903					dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
  3904				else
> 3905					dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
  3906	
  3907				pipe_config->fec_enable =
  3908					I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
  3909	
  3910				DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
  3911					      encoder->base.base.id, encoder->base.name,
  3912					      pipe_config->fec_enable);
  3913			}
  3914	
  3915			break;
  3916		case TRANS_DDI_MODE_SELECT_DP_MST:
  3917			pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
  3918			pipe_config->lane_count =
  3919				((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
  3920			intel_dp_get_m_n(intel_crtc, pipe_config);
  3921			break;
  3922		default:
  3923			break;
  3924		}
  3925	
  3926		pipe_config->has_audio =
  3927			intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
  3928	
  3929		if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
  3930		    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
  3931			/*
  3932			 * This is a big fat ugly hack.
  3933			 *
  3934			 * Some machines in UEFI boot mode provide us a VBT that has 18
  3935			 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
  3936			 * unknown we fail to light up. Yet the same BIOS boots up with
  3937			 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
  3938			 * max, not what it tells us to use.
  3939			 *
  3940			 * Note: This will still be broken if the eDP panel is not lit
  3941			 * up by the BIOS, and thus we can't get the mode at module
  3942			 * load.
  3943			 */
  3944			DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
  3945				      pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
  3946			dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
  3947		}
  3948	
  3949		intel_ddi_clock_get(encoder, pipe_config);
  3950	
  3951		if (IS_GEN9_LP(dev_priv))
  3952			pipe_config->lane_lat_optim_mask =
  3953				bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
  3954	
  3955		intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
  3956	
  3957		intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
  3958	
  3959		intel_read_infoframe(encoder, pipe_config,
  3960				     HDMI_INFOFRAME_TYPE_AVI,
  3961				     &pipe_config->infoframes.avi);
  3962		intel_read_infoframe(encoder, pipe_config,
  3963				     HDMI_INFOFRAME_TYPE_SPD,
  3964				     &pipe_config->infoframes.spd);
  3965		intel_read_infoframe(encoder, pipe_config,
  3966				     HDMI_INFOFRAME_TYPE_VENDOR,
  3967				     &pipe_config->infoframes.hdmi);
  3968		intel_read_infoframe(encoder, pipe_config,
  3969				     HDMI_INFOFRAME_TYPE_DRM,
  3970				     &pipe_config->infoframes.drm);
  3971	}
  3972	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28068 bytes --]

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
@ 2019-09-23 14:22       ` kbuild test robot
  0 siblings, 0 replies; 82+ messages in thread
From: kbuild test robot @ 2019-09-23 14:22 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, kbuild-all, stable

[-- Attachment #1: Type: text/plain, Size: 7236 bytes --]

Hi Maarten,

I love your patch! Yet something to improve:

[auto build test ERROR on drm-intel/for-linux-next]
[cannot apply to v5.3 next-20190920]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Maarten-Lankhorst/drm-i915-dp-Fix-dsc-bpp-calculations-v3/20190923-205540
base:   git://anongit.freedesktop.org/drm-intel for-linux-next
config: i386-defconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/display/intel_ddi.c: In function 'intel_ddi_get_config':
>> drivers/gpu/drm/i915/display/intel_ddi.c:3905:17: error: implicit declaration of function 'TGL_DP_TP_CTL'; did you mean 'DP_TP_CTL'? [-Werror=implicit-function-declaration]
        dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
                    ^~~~~~~~~~~~~
                    DP_TP_CTL
>> drivers/gpu/drm/i915/display/intel_ddi.c:3905:15: error: incompatible types when assigning to type 'i915_reg_t {aka struct <anonymous>}' from type 'int'
        dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
                  ^
   cc1: some warnings being treated as errors

vim +3905 drivers/gpu/drm/i915/display/intel_ddi.c

  3826	
  3827	void intel_ddi_get_config(struct intel_encoder *encoder,
  3828				  struct intel_crtc_state *pipe_config)
  3829	{
  3830		struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
  3831		struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
  3832		enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
  3833		u32 temp, flags = 0;
  3834	
  3835		/* XXX: DSI transcoder paranoia */
  3836		if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
  3837			return;
  3838	
  3839		temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
  3840		if (temp & TRANS_DDI_PHSYNC)
  3841			flags |= DRM_MODE_FLAG_PHSYNC;
  3842		else
  3843			flags |= DRM_MODE_FLAG_NHSYNC;
  3844		if (temp & TRANS_DDI_PVSYNC)
  3845			flags |= DRM_MODE_FLAG_PVSYNC;
  3846		else
  3847			flags |= DRM_MODE_FLAG_NVSYNC;
  3848	
  3849		pipe_config->base.adjusted_mode.flags |= flags;
  3850	
  3851		switch (temp & TRANS_DDI_BPC_MASK) {
  3852		case TRANS_DDI_BPC_6:
  3853			pipe_config->pipe_bpp = 18;
  3854			break;
  3855		case TRANS_DDI_BPC_8:
  3856			pipe_config->pipe_bpp = 24;
  3857			break;
  3858		case TRANS_DDI_BPC_10:
  3859			pipe_config->pipe_bpp = 30;
  3860			break;
  3861		case TRANS_DDI_BPC_12:
  3862			pipe_config->pipe_bpp = 36;
  3863			break;
  3864		default:
  3865			break;
  3866		}
  3867	
  3868		switch (temp & TRANS_DDI_MODE_SELECT_MASK) {
  3869		case TRANS_DDI_MODE_SELECT_HDMI:
  3870			pipe_config->has_hdmi_sink = true;
  3871	
  3872			pipe_config->infoframes.enable |=
  3873				intel_hdmi_infoframes_enabled(encoder, pipe_config);
  3874	
  3875			if (pipe_config->infoframes.enable)
  3876				pipe_config->has_infoframe = true;
  3877	
  3878			if (temp & TRANS_DDI_HDMI_SCRAMBLING)
  3879				pipe_config->hdmi_scrambling = true;
  3880			if (temp & TRANS_DDI_HIGH_TMDS_CHAR_RATE)
  3881				pipe_config->hdmi_high_tmds_clock_ratio = true;
  3882			/* fall through */
  3883		case TRANS_DDI_MODE_SELECT_DVI:
  3884			pipe_config->output_types |= BIT(INTEL_OUTPUT_HDMI);
  3885			pipe_config->lane_count = 4;
  3886			break;
  3887		case TRANS_DDI_MODE_SELECT_FDI:
  3888			pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
  3889			break;
  3890		case TRANS_DDI_MODE_SELECT_DP_SST:
  3891			if (encoder->type == INTEL_OUTPUT_EDP)
  3892				pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
  3893			else
  3894				pipe_config->output_types |= BIT(INTEL_OUTPUT_DP);
  3895			pipe_config->lane_count =
  3896				((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
  3897			intel_dp_get_m_n(intel_crtc, pipe_config);
  3898	
  3899			if (INTEL_GEN(dev_priv) >= 11) {
  3900				i915_reg_t dp_tp_ctl;
  3901	
  3902				if (IS_GEN(dev_priv, 11))
  3903					dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
  3904				else
> 3905					dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
  3906	
  3907				pipe_config->fec_enable =
  3908					I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
  3909	
  3910				DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
  3911					      encoder->base.base.id, encoder->base.name,
  3912					      pipe_config->fec_enable);
  3913			}
  3914	
  3915			break;
  3916		case TRANS_DDI_MODE_SELECT_DP_MST:
  3917			pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
  3918			pipe_config->lane_count =
  3919				((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
  3920			intel_dp_get_m_n(intel_crtc, pipe_config);
  3921			break;
  3922		default:
  3923			break;
  3924		}
  3925	
  3926		pipe_config->has_audio =
  3927			intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
  3928	
  3929		if (encoder->type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.bpp &&
  3930		    pipe_config->pipe_bpp > dev_priv->vbt.edp.bpp) {
  3931			/*
  3932			 * This is a big fat ugly hack.
  3933			 *
  3934			 * Some machines in UEFI boot mode provide us a VBT that has 18
  3935			 * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
  3936			 * unknown we fail to light up. Yet the same BIOS boots up with
  3937			 * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
  3938			 * max, not what it tells us to use.
  3939			 *
  3940			 * Note: This will still be broken if the eDP panel is not lit
  3941			 * up by the BIOS, and thus we can't get the mode at module
  3942			 * load.
  3943			 */
  3944			DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
  3945				      pipe_config->pipe_bpp, dev_priv->vbt.edp.bpp);
  3946			dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
  3947		}
  3948	
  3949		intel_ddi_clock_get(encoder, pipe_config);
  3950	
  3951		if (IS_GEN9_LP(dev_priv))
  3952			pipe_config->lane_lat_optim_mask =
  3953				bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
  3954	
  3955		intel_ddi_compute_min_voltage_level(dev_priv, pipe_config);
  3956	
  3957		intel_hdmi_read_gcp_infoframe(encoder, pipe_config);
  3958	
  3959		intel_read_infoframe(encoder, pipe_config,
  3960				     HDMI_INFOFRAME_TYPE_AVI,
  3961				     &pipe_config->infoframes.avi);
  3962		intel_read_infoframe(encoder, pipe_config,
  3963				     HDMI_INFOFRAME_TYPE_SPD,
  3964				     &pipe_config->infoframes.spd);
  3965		intel_read_infoframe(encoder, pipe_config,
  3966				     HDMI_INFOFRAME_TYPE_VENDOR,
  3967				     &pipe_config->infoframes.hdmi);
  3968		intel_read_infoframe(encoder, pipe_config,
  3969				     HDMI_INFOFRAME_TYPE_DRM,
  3970				     &pipe_config->infoframes.drm);
  3971	}
  3972	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28068 bytes --]

[-- Attachment #3: Type: text/plain, Size: 159 bytes --]

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4.
  2019-09-23 13:03       ` Ville Syrjälä
  (?)
@ 2019-09-23 14:49       ` Maarten Lankhorst
  2019-09-23 14:50         ` Maarten Lankhorst
  2019-09-23 14:57         ` Ville Syrjälä
  -1 siblings, 2 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-23 14:49 UTC (permalink / raw)
  To: intel-gfx
  Cc: Ville Syrjälä, Maarten Lankhorst, stable, Manasi Navare

There was a integer wraparound when mode_clock became too high,
and we didn't correct for the FEC overhead factor when dividing,
with the calculations breaking at HBR3.

As a result our calculated bpp was way too high, and the link width
limitation never came into effect.

Print out the resulting bpp calcululations as a sanity check, just
in case we ever have to debug it later on again.

We also used the wrong factor for FEC. While bspec mentions 2.4%,
all the calculations use 1/0.972261, and the same ratio should be
applied to data M/N as well, so use it there when FEC is enabled.

Make sure we don't break hw readout, and read out FEC enable state
and correct the DDI clock readout for the new values.

This fixes the FIFO underrun we are seeing with FEC enabled.

Changes since v2:
- Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
- Fix initial hardware readout for FEC. (Ville)
Changes since v3:
- Remove bogus fec_to_mode_clock. (Ville)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
Cc: <stable@vger.kernel.org> # v5.0+
Cc: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  17 ++
 drivers/gpu/drm/i915/display/intel_display.c |  13 +-
 drivers/gpu/drm/i915/display/intel_display.h |   2 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 184 ++++++++++---------
 drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
 6 files changed, 125 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0c0da9f6c2e8..1cb297abd111 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4045,6 +4045,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		pipe_config->lane_count =
 			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
 		intel_dp_get_m_n(intel_crtc, pipe_config);
+
+		if (INTEL_GEN(dev_priv) >= 11) {
+			i915_reg_t dp_tp_ctl;
+
+			if (IS_GEN(dev_priv, 11))
+				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
+			else
+				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
+
+			pipe_config->fec_enable =
+				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
+
+			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
+				      encoder->base.base.id, encoder->base.name,
+				      pipe_config->fec_enable);
+		}
+
 		break;
 	case TRANS_DDI_MODE_SELECT_DP_MST:
 		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 5ecf54270181..31698a57773f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
 	pipe_config->fdi_lanes = lane;
 
 	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
-			       link_bw, &pipe_config->fdi_m_n, false);
+			       link_bw, &pipe_config->fdi_m_n, false, false);
 
 	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
 	if (ret == -EDEADLK)
@@ -7538,11 +7538,15 @@ void
 intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
 		       int pixel_clock, int link_clock,
 		       struct intel_link_m_n *m_n,
-		       bool constant_n)
+		       bool constant_n, bool fec_enable)
 {
-	m_n->tu = 64;
+	u32 data_clock = bits_per_pixel * pixel_clock;
+
+	if (fec_enable)
+		data_clock = intel_dp_mode_to_fec_clock(data_clock);
 
-	compute_m_n(bits_per_pixel * pixel_clock,
+	m_n->tu = 64;
+	compute_m_n(data_clock,
 		    link_clock * nlanes * 8,
 		    &m_n->gmch_m, &m_n->gmch_n,
 		    constant_n);
@@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
 	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
 	PIPE_CONF_CHECK_BOOL(has_infoframe);
+	PIPE_CONF_CHECK_BOOL(fec_enable);
 
 	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 5cea6f8e107a..4b9e18e5a263 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -443,7 +443,7 @@ enum phy_fia {
 void intel_link_compute_m_n(u16 bpp, int nlanes,
 			    int pixel_clock, int link_clock,
 			    struct intel_link_m_n *m_n,
-			    bool constant_n);
+			    bool constant_n, bool fec_enable);
 bool is_ccs_modifier(u64 modifier);
 void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
 u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 829559f97440..2b1e71f992b0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -76,8 +76,8 @@
 #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
 #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
 
-/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
-#define DP_DSC_FEC_OVERHEAD_FACTOR		976
+/* DP DSC FEC Overhead factor = 1/(0.972261) */
+#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
 
 /* Compliance test status bits  */
 #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
@@ -492,6 +492,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
 	return 0;
 }
 
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
+{
+	return div_u64(mul_u32_u32(mode_clock, 1000000U),
+		       DP_DSC_FEC_OVERHEAD_FACTOR);
+}
+
+static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
+				       u32 mode_clock, u32 mode_hdisplay)
+{
+	u32 bits_per_pixel, max_bpp_small_joiner_ram;
+	int i;
+
+	/*
+	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
+	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
+	 * for SST -> TimeSlotsPerMTP is 1,
+	 * for MST -> TimeSlotsPerMTP has to be calculated
+	 */
+	bits_per_pixel = (link_clock * lane_count * 8) /
+			 intel_dp_mode_to_fec_clock(mode_clock);
+	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
+
+	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
+	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
+	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
+
+	/*
+	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
+	 * check, output bpp from small joiner RAM check)
+	 */
+	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
+
+	/* Error out if the max bpp is less than smallest allowed valid bpp */
+	if (bits_per_pixel < valid_dsc_bpp[0]) {
+		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
+			      bits_per_pixel, valid_dsc_bpp[0]);
+		return 0;
+	}
+
+	/* Find the nearest match in the array of known BPPs from VESA */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
+		if (bits_per_pixel < valid_dsc_bpp[i + 1])
+			break;
+	}
+	bits_per_pixel = valid_dsc_bpp[i];
+
+	/*
+	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
+	 * fractional part is 0
+	 */
+	return bits_per_pixel << 4;
+}
+
+static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+				       int mode_clock, int mode_hdisplay)
+{
+	u8 min_slice_count, i;
+	int max_slice_width;
+
+	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_0);
+	else
+		min_slice_count = DIV_ROUND_UP(mode_clock,
+					       DP_DSC_MAX_ENC_THROUGHPUT_1);
+
+	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
+	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
+		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
+			      max_slice_width);
+		return 0;
+	}
+	/* Also take into account max slice width */
+	min_slice_count = min_t(u8, min_slice_count,
+				DIV_ROUND_UP(mode_hdisplay,
+					     max_slice_width));
+
+	/* Find the closest match to the valid slice count values */
+	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
+		if (valid_dsc_slicecount[i] >
+		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+						    false))
+			break;
+		if (min_slice_count  <= valid_dsc_slicecount[i])
+			return valid_dsc_slicecount[i];
+	}
+
+	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
+	return 0;
+}
+
 static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
 		    struct drm_display_mode *mode)
@@ -2259,7 +2350,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 			       adjusted_mode->crtc_clock,
 			       pipe_config->port_clock,
 			       &pipe_config->dp_m_n,
-			       constant_n);
+			       constant_n, pipe_config->fec_enable);
 
 	if (intel_connector->panel.downclock_mode != NULL &&
 		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
@@ -2269,7 +2360,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
 					       intel_connector->panel.downclock_mode->clock,
 					       pipe_config->port_clock,
 					       &pipe_config->dp_m2_n2,
-					       constant_n);
+					       constant_n, pipe_config->fec_enable);
 	}
 
 	if (!HAS_DDI(dev_priv))
@@ -4373,91 +4464,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
 		DP_DPRX_ESI_LEN;
 }
 
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay)
-{
-	u16 bits_per_pixel, max_bpp_small_joiner_ram;
-	int i;
-
-	/*
-	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
-	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
-	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
-	 * for MST -> TimeSlotsPerMTP has to be calculated
-	 */
-	bits_per_pixel = (link_clock * lane_count * 8 *
-			  DP_DSC_FEC_OVERHEAD_FACTOR) /
-		mode_clock;
-
-	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
-	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
-		mode_hdisplay;
-
-	/*
-	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
-	 * check, output bpp from small joiner RAM check)
-	 */
-	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
-
-	/* Error out if the max bpp is less than smallest allowed valid bpp */
-	if (bits_per_pixel < valid_dsc_bpp[0]) {
-		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
-		return 0;
-	}
-
-	/* Find the nearest match in the array of known BPPs from VESA */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
-		if (bits_per_pixel < valid_dsc_bpp[i + 1])
-			break;
-	}
-	bits_per_pixel = valid_dsc_bpp[i];
-
-	/*
-	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
-	 * fractional part is 0
-	 */
-	return bits_per_pixel << 4;
-}
-
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
-				int mode_clock,
-				int mode_hdisplay)
-{
-	u8 min_slice_count, i;
-	int max_slice_width;
-
-	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_0);
-	else
-		min_slice_count = DIV_ROUND_UP(mode_clock,
-					       DP_DSC_MAX_ENC_THROUGHPUT_1);
-
-	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
-	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
-		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
-			      max_slice_width);
-		return 0;
-	}
-	/* Also take into account max slice width */
-	min_slice_count = min_t(u8, min_slice_count,
-				DIV_ROUND_UP(mode_hdisplay,
-					     max_slice_width));
-
-	/* Find the closest match to the valid slice count values */
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
-		if (valid_dsc_slicecount[i] >
-		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
-						    false))
-			break;
-		if (min_slice_count  <= valid_dsc_slicecount[i])
-			return valid_dsc_slicecount[i];
-	}
-
-	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
-	return 0;
-}
-
 static void
 intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
 			       const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
index e01d1f89409d..a194b5b6da05 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
 bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
 bool
 intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
-u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
-				int mode_clock, int mode_hdisplay);
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
-				int mode_hdisplay);
 
 bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
 bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
@@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
 	return ~((1 << lane_count) - 1) & 0xf;
 }
 
+u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
+
 #endif /* __INTEL_DP_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index eeeb3f933aa4..cf4d851a5139 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
 			       adjusted_mode->crtc_clock,
 			       crtc_state->port_clock,
 			       &crtc_state->dp_m_n,
-			       constant_n);
+			       constant_n, crtc_state->fec_enable);
 	crtc_state->dp_m_n.tu = slots;
 
 	return 0;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4.
  2019-09-23 14:49       ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4 Maarten Lankhorst
@ 2019-09-23 14:50         ` Maarten Lankhorst
  2019-09-23 14:57         ` Ville Syrjälä
  1 sibling, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-23 14:50 UTC (permalink / raw)
  To: intel-gfx; +Cc: Ville Syrjälä, stable, Manasi Navare

Op 23-09-2019 om 16:49 schreef Maarten Lankhorst:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
>
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
>
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
>
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
>
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
Note to self, needs this removed from commit msg.
> This fixes the FIFO underrun we are seeing with FEC enabled.
>
> Changes since v2:
> - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> - Fix initial hardware readout for FEC. (Ville)
> Changes since v3:
> - Remove bogus fec_to_mode_clock. (Ville)
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  17 ++
>  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 184 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  6 files changed, 125 insertions(+), 99 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 0c0da9f6c2e8..1cb297abd111 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4045,6 +4045,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			i915_reg_t dp_tp_ctl;
> +
> +			if (IS_GEN(dev_priv, 11))
> +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> +			else
> +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> +
> +			pipe_config->fec_enable =
> +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> +
> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 5ecf54270181..31698a57773f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n, false);
> +			       link_bw, &pipe_config->fdi_m_n, false, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EDEADLK)
> @@ -7538,11 +7538,15 @@ void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
>  		       struct intel_link_m_n *m_n,
> -		       bool constant_n)
> +		       bool constant_n, bool fec_enable)
>  {
> -	m_n->tu = 64;
> +	u32 data_clock = bits_per_pixel * pixel_clock;
> +
> +	if (fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
>  
> -	compute_m_n(bits_per_pixel * pixel_clock,
> +	m_n->tu = 64;
> +	compute_m_n(data_clock,
>  		    link_clock * nlanes * 8,
>  		    &m_n->gmch_m, &m_n->gmch_n,
>  		    constant_n);
> @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 5cea6f8e107a..4b9e18e5a263 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -443,7 +443,7 @@ enum phy_fia {
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> -			    bool constant_n);
> +			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 829559f97440..2b1e71f992b0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2259,7 +2350,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
> -			       constant_n);
> +			       constant_n, pipe_config->fec_enable);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -2269,7 +2360,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					       intel_connector->panel.downclock_mode->clock,
>  					       pipe_config->port_clock,
>  					       &pipe_config->dp_m2_n2,
> -					       constant_n);
> +					       constant_n, pipe_config->fec_enable);
>  	}
>  
>  	if (!HAS_DDI(dev_priv))
> @@ -4373,91 +4464,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..a194b5b6da05 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..cf4d851a5139 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       crtc_state->port_clock,
>  			       &crtc_state->dp_m_n,
> -			       constant_n);
> +			       constant_n, crtc_state->fec_enable);
>  	crtc_state->dp_m_n.tu = slots;
>  
>  	return 0;



^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4.
  2019-09-23 14:49       ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4 Maarten Lankhorst
  2019-09-23 14:50         ` Maarten Lankhorst
@ 2019-09-23 14:57         ` Ville Syrjälä
  2019-09-23 15:56           ` Manasi Navare
  2019-09-23 15:56           ` [Intel-gfx] " Ville Syrjälä
  1 sibling, 2 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-23 14:57 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, stable, Manasi Navare

On Mon, Sep 23, 2019 at 04:49:47PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> This fixes the FIFO underrun we are seeing with FEC enabled.
> 
> Changes since v2:
> - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> - Fix initial hardware readout for FEC. (Ville)
> Changes since v3:
> - Remove bogus fec_to_mode_clock. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  17 ++
>  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 184 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  6 files changed, 125 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 0c0da9f6c2e8..1cb297abd111 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4045,6 +4045,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			i915_reg_t dp_tp_ctl;
> +
> +			if (IS_GEN(dev_priv, 11))
> +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> +			else
> +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> +
> +			pipe_config->fec_enable =
> +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;

Can you split the fec_enable readout/state check into a separate
patch?

I wonder how the lack of this stuff was missed when FEC was adeed...

> +
> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);

I'd just include it as part of the normal state dump.

> +		}
> +
>  		break;
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 5ecf54270181..31698a57773f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n, false);
> +			       link_bw, &pipe_config->fdi_m_n, false, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EDEADLK)
> @@ -7538,11 +7538,15 @@ void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
>  		       struct intel_link_m_n *m_n,
> -		       bool constant_n)
> +		       bool constant_n, bool fec_enable)
>  {
> -	m_n->tu = 64;
> +	u32 data_clock = bits_per_pixel * pixel_clock;
> +
> +	if (fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
>  
> -	compute_m_n(bits_per_pixel * pixel_clock,
> +	m_n->tu = 64;
> +	compute_m_n(data_clock,
>  		    link_clock * nlanes * 8,
>  		    &m_n->gmch_m, &m_n->gmch_n,
>  		    constant_n);
> @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 5cea6f8e107a..4b9e18e5a263 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -443,7 +443,7 @@ enum phy_fia {
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> -			    bool constant_n);
> +			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 829559f97440..2b1e71f992b0 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2259,7 +2350,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
> -			       constant_n);
> +			       constant_n, pipe_config->fec_enable);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -2269,7 +2360,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					       intel_connector->panel.downclock_mode->clock,
>  					       pipe_config->port_clock,
>  					       &pipe_config->dp_m2_n2,
> -					       constant_n);
> +					       constant_n, pipe_config->fec_enable);
>  	}
>  
>  	if (!HAS_DDI(dev_priv))
> @@ -4373,91 +4464,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..a194b5b6da05 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..cf4d851a5139 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       crtc_state->port_clock,
>  			       &crtc_state->dp_m_n,
> -			       constant_n);
> +			       constant_n, crtc_state->fec_enable);
>  	crtc_state->dp_m_n.tu = slots;
>  
>  	return 0;
> -- 
> 2.20.1

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3.
  2019-09-23 12:52   ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 Maarten Lankhorst
  2019-09-23 13:03       ` Ville Syrjälä
  2019-09-23 14:22       ` kbuild test robot
@ 2019-09-23 15:53     ` Manasi Navare
  2 siblings, 0 replies; 82+ messages in thread
From: Manasi Navare @ 2019-09-23 15:53 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, Ville Syrjälä, stable

On Mon, Sep 23, 2019 at 02:52:52PM +0200, Maarten Lankhorst wrote:
> There was a integer wraparound when mode_clock became too high,
> and we didn't correct for the FEC overhead factor when dividing,
> with the calculations breaking at HBR3.
> 
> As a result our calculated bpp was way too high, and the link width
> limitation never came into effect.
> 
> Print out the resulting bpp calcululations as a sanity check, just
> in case we ever have to debug it later on again.
> 
> We also used the wrong factor for FEC. While bspec mentions 2.4%,
> all the calculations use 1/0.972261, and the same ratio should be
> applied to data M/N as well, so use it there when FEC is enabled.
> 
> Make sure we don't break hw readout, and read out FEC enable state
> and correct the DDI clock readout for the new values.
> 
> This fixes the FIFO underrun we are seeing with FEC enabled.
> 
> Changes since v2:
> - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> - Fix initial hardware readout for FEC. (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> Cc: <stable@vger.kernel.org> # v5.0+
> Cc: Manasi Navare <manasi.d.navare@intel.com>
> ---
> Thanks, that fixed the FIFO underrun, making the disablement patch obsolete.
> Bigjoiner is now completely working as intended. :)

Thats great, so the FEC adjustments in the compute m_n was the thing that was mising
because of which we were seeing the underruns?

I think Anusha missed it when she implemented FEC along with DSC because back then
we only had eDP DSC panels where we do no enable FEC and didnt have any FEC DSC DP panels.

Thanks for tha catch and the fix.

Regards
Manasi

> 
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  21 ++
>  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 191 ++++++++++---------
>  drivers/gpu/drm/i915/display/intel_dp.h      |   7 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  6 files changed, 137 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 0c0da9f6c2e8..3e77b30d91d5 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1479,6 +1479,10 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> +	/* fec adds overhead to the data M/N values, correct for it */
> +	if (pipe_config->fec_enable)
> +		dotclock = intel_dp_fec_to_mode_clock(dotclock);
> +
>  	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>  }
>  
> @@ -4045,6 +4049,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		pipe_config->lane_count =
>  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
>  		intel_dp_get_m_n(intel_crtc, pipe_config);
> +
> +		if (INTEL_GEN(dev_priv) >= 11) {
> +			i915_reg_t dp_tp_ctl;
> +
> +			if (IS_GEN(dev_priv, 11))
> +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> +			else
> +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> +
> +			pipe_config->fec_enable =
> +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> +
> +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> +				      encoder->base.base.id, encoder->base.name,
> +				      pipe_config->fec_enable);
> +		}
> +
>  		break;
>  	case TRANS_DDI_MODE_SELECT_DP_MST:
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 5ecf54270181..31698a57773f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  	pipe_config->fdi_lanes = lane;
>  
>  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> -			       link_bw, &pipe_config->fdi_m_n, false);
> +			       link_bw, &pipe_config->fdi_m_n, false, false);
>  
>  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
>  	if (ret == -EDEADLK)
> @@ -7538,11 +7538,15 @@ void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  		       int pixel_clock, int link_clock,
>  		       struct intel_link_m_n *m_n,
> -		       bool constant_n)
> +		       bool constant_n, bool fec_enable)
>  {
> -	m_n->tu = 64;
> +	u32 data_clock = bits_per_pixel * pixel_clock;
> +
> +	if (fec_enable)
> +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
>  
> -	compute_m_n(bits_per_pixel * pixel_clock,
> +	m_n->tu = 64;
> +	compute_m_n(data_clock,
>  		    link_clock * nlanes * 8,
>  		    &m_n->gmch_m, &m_n->gmch_n,
>  		    constant_n);
> @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> +	PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 5cea6f8e107a..4b9e18e5a263 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -443,7 +443,7 @@ enum phy_fia {
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>  			    int pixel_clock, int link_clock,
>  			    struct intel_link_m_n *m_n,
> -			    bool constant_n);
> +			    bool constant_n, bool fec_enable);
>  bool is_ccs_modifier(u64 modifier);
>  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 829559f97440..2d3f4183f99d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -76,8 +76,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
>  
> -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> @@ -492,6 +492,104 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
>  	return 0;
>  }
>  
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> +{
> +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> +}
> +
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> +{
> +	return div_u64(mul_u32_u32(fec_clock,
> +				   DP_DSC_FEC_OVERHEAD_FACTOR),
> +		       1000000U);
> +}
> +
> +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay)
> +{
> +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> +	int i;
> +
> +	/*
> +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> +	 * for SST -> TimeSlotsPerMTP is 1,
> +	 * for MST -> TimeSlotsPerMTP has to be calculated
> +	 */
> +	bits_per_pixel = (link_clock * lane_count * 8) /
> +			 intel_dp_mode_to_fec_clock(mode_clock);
> +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> +
> +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> +
> +	/*
> +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> +	 * check, output bpp from small joiner RAM check)
> +	 */
> +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> +
> +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> +			      bits_per_pixel, valid_dsc_bpp[0]);
> +		return 0;
> +	}
> +
> +	/* Find the nearest match in the array of known BPPs from VESA */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> +			break;
> +	}
> +	bits_per_pixel = valid_dsc_bpp[i];
> +
> +	/*
> +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> +	 * fractional part is 0
> +	 */
> +	return bits_per_pixel << 4;
> +}
> +
> +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> +				       int mode_clock, int mode_hdisplay)
> +{
> +	u8 min_slice_count, i;
> +	int max_slice_width;
> +
> +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> +	else
> +		min_slice_count = DIV_ROUND_UP(mode_clock,
> +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> +
> +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> +			      max_slice_width);
> +		return 0;
> +	}
> +	/* Also take into account max slice width */
> +	min_slice_count = min_t(u8, min_slice_count,
> +				DIV_ROUND_UP(mode_hdisplay,
> +					     max_slice_width));
> +
> +	/* Find the closest match to the valid slice count values */
> +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> +		if (valid_dsc_slicecount[i] >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> +						    false))
> +			break;
> +		if (min_slice_count  <= valid_dsc_slicecount[i])
> +			return valid_dsc_slicecount[i];
> +	}
> +
> +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> +	return 0;
> +}
> +
>  static enum drm_mode_status
>  intel_dp_mode_valid(struct drm_connector *connector,
>  		    struct drm_display_mode *mode)
> @@ -2259,7 +2357,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       pipe_config->port_clock,
>  			       &pipe_config->dp_m_n,
> -			       constant_n);
> +			       constant_n, pipe_config->fec_enable);
>  
>  	if (intel_connector->panel.downclock_mode != NULL &&
>  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> @@ -2269,7 +2367,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  					       intel_connector->panel.downclock_mode->clock,
>  					       pipe_config->port_clock,
>  					       &pipe_config->dp_m2_n2,
> -					       constant_n);
> +					       constant_n, pipe_config->fec_enable);
>  	}
>  
>  	if (!HAS_DDI(dev_priv))
> @@ -4373,91 +4471,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
>  		DP_DPRX_ESI_LEN;
>  }
>  
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay)
> -{
> -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> -	int i;
> -
> -	/*
> -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> -	 * for MST -> TimeSlotsPerMTP has to be calculated
> -	 */
> -	bits_per_pixel = (link_clock * lane_count * 8 *
> -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> -		mode_clock;
> -
> -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> -		mode_hdisplay;
> -
> -	/*
> -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> -	 * check, output bpp from small joiner RAM check)
> -	 */
> -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> -
> -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> -		return 0;
> -	}
> -
> -	/* Find the nearest match in the array of known BPPs from VESA */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> -			break;
> -	}
> -	bits_per_pixel = valid_dsc_bpp[i];
> -
> -	/*
> -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> -	 * fractional part is 0
> -	 */
> -	return bits_per_pixel << 4;
> -}
> -
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				int mode_clock,
> -				int mode_hdisplay)
> -{
> -	u8 min_slice_count, i;
> -	int max_slice_width;
> -
> -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> -	else
> -		min_slice_count = DIV_ROUND_UP(mode_clock,
> -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> -
> -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> -			      max_slice_width);
> -		return 0;
> -	}
> -	/* Also take into account max slice width */
> -	min_slice_count = min_t(u8, min_slice_count,
> -				DIV_ROUND_UP(mode_hdisplay,
> -					     max_slice_width));
> -
> -	/* Find the closest match to the valid slice count values */
> -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> -			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> -	}
> -
> -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> -	return 0;
> -}
> -
>  static void
>  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
>  			       const struct intel_crtc_state *crtc_state)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> index e01d1f89409d..2147d3c14870 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
>  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
>  bool
>  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> -				int mode_clock, int mode_hdisplay);
> -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> -				int mode_hdisplay);
>  
>  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
>  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> @@ -119,4 +115,7 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
>  	return ~((1 << lane_count) - 1) & 0xf;
>  }
>  
> +u32 intel_dp_fec_to_mode_clock(u32 fec_clock);
> +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
>  #endif /* __INTEL_DP_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..cf4d851a5139 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  			       adjusted_mode->crtc_clock,
>  			       crtc_state->port_clock,
>  			       &crtc_state->dp_m_n,
> -			       constant_n);
> +			       constant_n, crtc_state->fec_enable);
>  	crtc_state->dp_m_n.tu = slots;
>  
>  	return 0;
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4.
  2019-09-23 14:57         ` Ville Syrjälä
@ 2019-09-23 15:56           ` Manasi Navare
  2019-09-23 15:56           ` [Intel-gfx] " Ville Syrjälä
  1 sibling, 0 replies; 82+ messages in thread
From: Manasi Navare @ 2019-09-23 15:56 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: Maarten Lankhorst, intel-gfx, stable

On Mon, Sep 23, 2019 at 05:57:57PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 23, 2019 at 04:49:47PM +0200, Maarten Lankhorst wrote:
> > There was a integer wraparound when mode_clock became too high,
> > and we didn't correct for the FEC overhead factor when dividing,
> > with the calculations breaking at HBR3.
> > 
> > As a result our calculated bpp was way too high, and the link width
> > limitation never came into effect.
> > 
> > Print out the resulting bpp calcululations as a sanity check, just
> > in case we ever have to debug it later on again.
> > 
> > We also used the wrong factor for FEC. While bspec mentions 2.4%,
> > all the calculations use 1/0.972261, and the same ratio should be
> > applied to data M/N as well, so use it there when FEC is enabled.
> > 
> > Make sure we don't break hw readout, and read out FEC enable state
> > and correct the DDI clock readout for the new values.
> > 
> > This fixes the FIFO underrun we are seeing with FEC enabled.
> > 
> > Changes since v2:
> > - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> > - Fix initial hardware readout for FEC. (Ville)
> > Changes since v3:
> > - Remove bogus fec_to_mode_clock. (Ville)
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> > Cc: <stable@vger.kernel.org> # v5.0+
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c     |  17 ++
> >  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
> >  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
> >  drivers/gpu/drm/i915/display/intel_dp.c      | 184 ++++++++++---------
> >  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
> >  6 files changed, 125 insertions(+), 99 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 0c0da9f6c2e8..1cb297abd111 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -4045,6 +4045,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  		pipe_config->lane_count =
> >  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
> >  		intel_dp_get_m_n(intel_crtc, pipe_config);
> > +
> > +		if (INTEL_GEN(dev_priv) >= 11) {
> > +			i915_reg_t dp_tp_ctl;
> > +
> > +			if (IS_GEN(dev_priv, 11))
> > +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);
> > +			else
> > +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> > +
> > +			pipe_config->fec_enable =
> > +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> 
> Can you split the fec_enable readout/state check into a separate
> patch?
> 
> I wonder how the lack of this stuff was missed when FEC was adeed...
> 

We never had any FEC DP panel when this initial FEC enabling stuff was added,
Anusha did test it with the FPGA based emulator that had FEC but we still missed the m_n
correction as there were no underruns reported that time.

Thanks Ville and Maarten for catching this and fixing it.

Manasi

> > +
> > +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> > +				      encoder->base.base.id, encoder->base.name,
> > +				      pipe_config->fec_enable);
> 
> I'd just include it as part of the normal state dump.
> 
> > +		}
> > +
> >  		break;
> >  	case TRANS_DDI_MODE_SELECT_DP_MST:
> >  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 5ecf54270181..31698a57773f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> >  	pipe_config->fdi_lanes = lane;
> >  
> >  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> > -			       link_bw, &pipe_config->fdi_m_n, false);
> > +			       link_bw, &pipe_config->fdi_m_n, false, false);
> >  
> >  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
> >  	if (ret == -EDEADLK)
> > @@ -7538,11 +7538,15 @@ void
> >  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
> >  		       int pixel_clock, int link_clock,
> >  		       struct intel_link_m_n *m_n,
> > -		       bool constant_n)
> > +		       bool constant_n, bool fec_enable)
> >  {
> > -	m_n->tu = 64;
> > +	u32 data_clock = bits_per_pixel * pixel_clock;
> > +
> > +	if (fec_enable)
> > +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
> >  
> > -	compute_m_n(bits_per_pixel * pixel_clock,
> > +	m_n->tu = 64;
> > +	compute_m_n(data_clock,
> >  		    link_clock * nlanes * 8,
> >  		    &m_n->gmch_m, &m_n->gmch_n,
> >  		    constant_n);
> > @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
> >  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
> >  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> > +	PIPE_CONF_CHECK_BOOL(fec_enable);
> >  
> >  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > index 5cea6f8e107a..4b9e18e5a263 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -443,7 +443,7 @@ enum phy_fia {
> >  void intel_link_compute_m_n(u16 bpp, int nlanes,
> >  			    int pixel_clock, int link_clock,
> >  			    struct intel_link_m_n *m_n,
> > -			    bool constant_n);
> > +			    bool constant_n, bool fec_enable);
> >  bool is_ccs_modifier(u64 modifier);
> >  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
> >  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 829559f97440..2b1e71f992b0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -76,8 +76,8 @@
> >  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
> >  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
> >  
> > -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> > -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> > +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> > +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
> >  
> >  /* Compliance test status bits  */
> >  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> > @@ -492,6 +492,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
> >  	return 0;
> >  }
> >  
> > +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> > +{
> > +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> > +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> > +}
> > +
> > +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> > +				       u32 mode_clock, u32 mode_hdisplay)
> > +{
> > +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> > +	int i;
> > +
> > +	/*
> > +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> > +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> > +	 * for SST -> TimeSlotsPerMTP is 1,
> > +	 * for MST -> TimeSlotsPerMTP has to be calculated
> > +	 */
> > +	bits_per_pixel = (link_clock * lane_count * 8) /
> > +			 intel_dp_mode_to_fec_clock(mode_clock);
> > +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> > +
> > +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> > +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> > +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> > +
> > +	/*
> > +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> > +	 * check, output bpp from small joiner RAM check)
> > +	 */
> > +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> > +
> > +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> > +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> > +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> > +			      bits_per_pixel, valid_dsc_bpp[0]);
> > +		return 0;
> > +	}
> > +
> > +	/* Find the nearest match in the array of known BPPs from VESA */
> > +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> > +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> > +			break;
> > +	}
> > +	bits_per_pixel = valid_dsc_bpp[i];
> > +
> > +	/*
> > +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> > +	 * fractional part is 0
> > +	 */
> > +	return bits_per_pixel << 4;
> > +}
> > +
> > +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > +				       int mode_clock, int mode_hdisplay)
> > +{
> > +	u8 min_slice_count, i;
> > +	int max_slice_width;
> > +
> > +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> > +		min_slice_count = DIV_ROUND_UP(mode_clock,
> > +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> > +	else
> > +		min_slice_count = DIV_ROUND_UP(mode_clock,
> > +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> > +
> > +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> > +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> > +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> > +			      max_slice_width);
> > +		return 0;
> > +	}
> > +	/* Also take into account max slice width */
> > +	min_slice_count = min_t(u8, min_slice_count,
> > +				DIV_ROUND_UP(mode_hdisplay,
> > +					     max_slice_width));
> > +
> > +	/* Find the closest match to the valid slice count values */
> > +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > +		if (valid_dsc_slicecount[i] >
> > +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > +						    false))
> > +			break;
> > +		if (min_slice_count  <= valid_dsc_slicecount[i])
> > +			return valid_dsc_slicecount[i];
> > +	}
> > +
> > +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > +	return 0;
> > +}
> > +
> >  static enum drm_mode_status
> >  intel_dp_mode_valid(struct drm_connector *connector,
> >  		    struct drm_display_mode *mode)
> > @@ -2259,7 +2350,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >  			       adjusted_mode->crtc_clock,
> >  			       pipe_config->port_clock,
> >  			       &pipe_config->dp_m_n,
> > -			       constant_n);
> > +			       constant_n, pipe_config->fec_enable);
> >  
> >  	if (intel_connector->panel.downclock_mode != NULL &&
> >  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> > @@ -2269,7 +2360,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >  					       intel_connector->panel.downclock_mode->clock,
> >  					       pipe_config->port_clock,
> >  					       &pipe_config->dp_m2_n2,
> > -					       constant_n);
> > +					       constant_n, pipe_config->fec_enable);
> >  	}
> >  
> >  	if (!HAS_DDI(dev_priv))
> > @@ -4373,91 +4464,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
> >  		DP_DPRX_ESI_LEN;
> >  }
> >  
> > -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> > -				int mode_clock, int mode_hdisplay)
> > -{
> > -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> > -	int i;
> > -
> > -	/*
> > -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> > -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> > -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> > -	 * for MST -> TimeSlotsPerMTP has to be calculated
> > -	 */
> > -	bits_per_pixel = (link_clock * lane_count * 8 *
> > -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> > -		mode_clock;
> > -
> > -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> > -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> > -		mode_hdisplay;
> > -
> > -	/*
> > -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> > -	 * check, output bpp from small joiner RAM check)
> > -	 */
> > -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> > -
> > -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> > -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> > -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> > -		return 0;
> > -	}
> > -
> > -	/* Find the nearest match in the array of known BPPs from VESA */
> > -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> > -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> > -			break;
> > -	}
> > -	bits_per_pixel = valid_dsc_bpp[i];
> > -
> > -	/*
> > -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> > -	 * fractional part is 0
> > -	 */
> > -	return bits_per_pixel << 4;
> > -}
> > -
> > -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > -				int mode_clock,
> > -				int mode_hdisplay)
> > -{
> > -	u8 min_slice_count, i;
> > -	int max_slice_width;
> > -
> > -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> > -		min_slice_count = DIV_ROUND_UP(mode_clock,
> > -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> > -	else
> > -		min_slice_count = DIV_ROUND_UP(mode_clock,
> > -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> > -
> > -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> > -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> > -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> > -			      max_slice_width);
> > -		return 0;
> > -	}
> > -	/* Also take into account max slice width */
> > -	min_slice_count = min_t(u8, min_slice_count,
> > -				DIV_ROUND_UP(mode_hdisplay,
> > -					     max_slice_width));
> > -
> > -	/* Find the closest match to the valid slice count values */
> > -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > -		if (valid_dsc_slicecount[i] >
> > -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > -						    false))
> > -			break;
> > -		if (min_slice_count  <= valid_dsc_slicecount[i])
> > -			return valid_dsc_slicecount[i];
> > -	}
> > -
> > -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > -	return 0;
> > -}
> > -
> >  static void
> >  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
> >  			       const struct intel_crtc_state *crtc_state)
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> > index e01d1f89409d..a194b5b6da05 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> > @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> >  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
> >  bool
> >  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> > -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> > -				int mode_clock, int mode_hdisplay);
> > -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> > -				int mode_hdisplay);
> >  
> >  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
> >  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> > @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
> >  	return ~((1 << lane_count) - 1) & 0xf;
> >  }
> >  
> > +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> > +
> >  #endif /* __INTEL_DP_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index eeeb3f933aa4..cf4d851a5139 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  			       adjusted_mode->crtc_clock,
> >  			       crtc_state->port_clock,
> >  			       &crtc_state->dp_m_n,
> > -			       constant_n);
> > +			       constant_n, crtc_state->fec_enable);
> >  	crtc_state->dp_m_n.tu = slots;
> >  
> >  	return 0;
> > -- 
> > 2.20.1
> 
> -- 
> Ville Syrjälä
> Intel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [Intel-gfx] [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4.
  2019-09-23 14:57         ` Ville Syrjälä
  2019-09-23 15:56           ` Manasi Navare
@ 2019-09-23 15:56           ` Ville Syrjälä
  1 sibling, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-23 15:56 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx, stable

On Mon, Sep 23, 2019 at 05:57:57PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 23, 2019 at 04:49:47PM +0200, Maarten Lankhorst wrote:
> > There was a integer wraparound when mode_clock became too high,
> > and we didn't correct for the FEC overhead factor when dividing,
> > with the calculations breaking at HBR3.
> > 
> > As a result our calculated bpp was way too high, and the link width
> > limitation never came into effect.
> > 
> > Print out the resulting bpp calcululations as a sanity check, just
> > in case we ever have to debug it later on again.
> > 
> > We also used the wrong factor for FEC. While bspec mentions 2.4%,
> > all the calculations use 1/0.972261, and the same ratio should be
> > applied to data M/N as well, so use it there when FEC is enabled.
> > 
> > Make sure we don't break hw readout, and read out FEC enable state
> > and correct the DDI clock readout for the new values.
> > 
> > This fixes the FIFO underrun we are seeing with FEC enabled.
> > 
> > Changes since v2:
> > - Handle fec_enable in intel_link_compute_m_n, so only data M/N is adjusted. (Ville)
> > - Fix initial hardware readout for FEC. (Ville)
> > Changes since v3:
> > - Remove bogus fec_to_mode_clock. (Ville)
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Fixes: d9218c8f6cf4 ("drm/i915/dp: Add helpers for Compressed BPP and Slice Count for DSC")
> > Cc: <stable@vger.kernel.org> # v5.0+
> > Cc: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c     |  17 ++
> >  drivers/gpu/drm/i915/display/intel_display.c |  13 +-
> >  drivers/gpu/drm/i915/display/intel_display.h |   2 +-
> >  drivers/gpu/drm/i915/display/intel_dp.c      | 184 ++++++++++---------
> >  drivers/gpu/drm/i915/display/intel_dp.h      |   6 +-
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
> >  6 files changed, 125 insertions(+), 99 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 0c0da9f6c2e8..1cb297abd111 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -4045,6 +4045,23 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  		pipe_config->lane_count =
> >  			((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
> >  		intel_dp_get_m_n(intel_crtc, pipe_config);
> > +
> > +		if (INTEL_GEN(dev_priv) >= 11) {
> > +			i915_reg_t dp_tp_ctl;
> > +
> > +			if (IS_GEN(dev_priv, 11))
> > +				dp_tp_ctl = DP_TP_CTL(pipe_config->cpu_transcoder);

Oh, and pre-tgl DP_TP_CTL is per port.

> > +			else
> > +				dp_tp_ctl = TGL_DP_TP_CTL(pipe_config->cpu_transcoder);
> > +
> > +			pipe_config->fec_enable =
> > +				I915_READ(dp_tp_ctl) & DP_TP_CTL_FEC_ENABLE;
> 
> Can you split the fec_enable readout/state check into a separate
> patch?
> 
> I wonder how the lack of this stuff was missed when FEC was adeed...
> 
> > +
> > +			DRM_DEBUG_KMS("[ENCODER:%d:%s] Fec status: %u\n",
> > +				      encoder->base.base.id, encoder->base.name,
> > +				      pipe_config->fec_enable);
> 
> I'd just include it as part of the normal state dump.
> 
> > +		}
> > +
> >  		break;
> >  	case TRANS_DDI_MODE_SELECT_DP_MST:
> >  		pipe_config->output_types |= BIT(INTEL_OUTPUT_DP_MST);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 5ecf54270181..31698a57773f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -7291,7 +7291,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
> >  	pipe_config->fdi_lanes = lane;
> >  
> >  	intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
> > -			       link_bw, &pipe_config->fdi_m_n, false);
> > +			       link_bw, &pipe_config->fdi_m_n, false, false);
> >  
> >  	ret = ironlake_check_fdi_lanes(dev, intel_crtc->pipe, pipe_config);
> >  	if (ret == -EDEADLK)
> > @@ -7538,11 +7538,15 @@ void
> >  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
> >  		       int pixel_clock, int link_clock,
> >  		       struct intel_link_m_n *m_n,
> > -		       bool constant_n)
> > +		       bool constant_n, bool fec_enable)
> >  {
> > -	m_n->tu = 64;
> > +	u32 data_clock = bits_per_pixel * pixel_clock;
> > +
> > +	if (fec_enable)
> > +		data_clock = intel_dp_mode_to_fec_clock(data_clock);
> >  
> > -	compute_m_n(bits_per_pixel * pixel_clock,
> > +	m_n->tu = 64;
> > +	compute_m_n(data_clock,
> >  		    link_clock * nlanes * 8,
> >  		    &m_n->gmch_m, &m_n->gmch_n,
> >  		    constant_n);
> > @@ -12832,6 +12836,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
> >  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
> >  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> > +	PIPE_CONF_CHECK_BOOL(fec_enable);
> >  
> >  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > index 5cea6f8e107a..4b9e18e5a263 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -443,7 +443,7 @@ enum phy_fia {
> >  void intel_link_compute_m_n(u16 bpp, int nlanes,
> >  			    int pixel_clock, int link_clock,
> >  			    struct intel_link_m_n *m_n,
> > -			    bool constant_n);
> > +			    bool constant_n, bool fec_enable);
> >  bool is_ccs_modifier(u64 modifier);
> >  void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
> >  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 829559f97440..2b1e71f992b0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -76,8 +76,8 @@
> >  #define DP_DSC_MAX_ENC_THROUGHPUT_0		340000
> >  #define DP_DSC_MAX_ENC_THROUGHPUT_1		400000
> >  
> > -/* DP DSC FEC Overhead factor = (100 - 2.4)/100 */
> > -#define DP_DSC_FEC_OVERHEAD_FACTOR		976
> > +/* DP DSC FEC Overhead factor = 1/(0.972261) */
> > +#define DP_DSC_FEC_OVERHEAD_FACTOR		972261
> >  
> >  /* Compliance test status bits  */
> >  #define INTEL_DP_RESOLUTION_SHIFT_MASK	0
> > @@ -492,6 +492,97 @@ int intel_dp_get_link_train_fallback_values(struct intel_dp *intel_dp,
> >  	return 0;
> >  }
> >  
> > +u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
> > +{
> > +	return div_u64(mul_u32_u32(mode_clock, 1000000U),
> > +		       DP_DSC_FEC_OVERHEAD_FACTOR);
> > +}
> > +
> > +static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> > +				       u32 mode_clock, u32 mode_hdisplay)
> > +{
> > +	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> > +	int i;
> > +
> > +	/*
> > +	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> > +	 * (LinkSymbolClock)* 8 * (TimeSlotsPerMTP)
> > +	 * for SST -> TimeSlotsPerMTP is 1,
> > +	 * for MST -> TimeSlotsPerMTP has to be calculated
> > +	 */
> > +	bits_per_pixel = (link_clock * lane_count * 8) /
> > +			 intel_dp_mode_to_fec_clock(mode_clock);
> > +	DRM_DEBUG_KMS("Max link bpp: %u\n", bits_per_pixel);
> > +
> > +	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> > +	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> > +	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> > +
> > +	/*
> > +	 * Greatest allowed DSC BPP = MIN (output BPP from available Link BW
> > +	 * check, output bpp from small joiner RAM check)
> > +	 */
> > +	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> > +
> > +	/* Error out if the max bpp is less than smallest allowed valid bpp */
> > +	if (bits_per_pixel < valid_dsc_bpp[0]) {
> > +		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> > +			      bits_per_pixel, valid_dsc_bpp[0]);
> > +		return 0;
> > +	}
> > +
> > +	/* Find the nearest match in the array of known BPPs from VESA */
> > +	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> > +		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> > +			break;
> > +	}
> > +	bits_per_pixel = valid_dsc_bpp[i];
> > +
> > +	/*
> > +	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> > +	 * fractional part is 0
> > +	 */
> > +	return bits_per_pixel << 4;
> > +}
> > +
> > +static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > +				       int mode_clock, int mode_hdisplay)
> > +{
> > +	u8 min_slice_count, i;
> > +	int max_slice_width;
> > +
> > +	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> > +		min_slice_count = DIV_ROUND_UP(mode_clock,
> > +					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> > +	else
> > +		min_slice_count = DIV_ROUND_UP(mode_clock,
> > +					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> > +
> > +	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> > +	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> > +		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> > +			      max_slice_width);
> > +		return 0;
> > +	}
> > +	/* Also take into account max slice width */
> > +	min_slice_count = min_t(u8, min_slice_count,
> > +				DIV_ROUND_UP(mode_hdisplay,
> > +					     max_slice_width));
> > +
> > +	/* Find the closest match to the valid slice count values */
> > +	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > +		if (valid_dsc_slicecount[i] >
> > +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > +						    false))
> > +			break;
> > +		if (min_slice_count  <= valid_dsc_slicecount[i])
> > +			return valid_dsc_slicecount[i];
> > +	}
> > +
> > +	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > +	return 0;
> > +}
> > +
> >  static enum drm_mode_status
> >  intel_dp_mode_valid(struct drm_connector *connector,
> >  		    struct drm_display_mode *mode)
> > @@ -2259,7 +2350,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >  			       adjusted_mode->crtc_clock,
> >  			       pipe_config->port_clock,
> >  			       &pipe_config->dp_m_n,
> > -			       constant_n);
> > +			       constant_n, pipe_config->fec_enable);
> >  
> >  	if (intel_connector->panel.downclock_mode != NULL &&
> >  		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
> > @@ -2269,7 +2360,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> >  					       intel_connector->panel.downclock_mode->clock,
> >  					       pipe_config->port_clock,
> >  					       &pipe_config->dp_m2_n2,
> > -					       constant_n);
> > +					       constant_n, pipe_config->fec_enable);
> >  	}
> >  
> >  	if (!HAS_DDI(dev_priv))
> > @@ -4373,91 +4464,6 @@ intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector)
> >  		DP_DPRX_ESI_LEN;
> >  }
> >  
> > -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> > -				int mode_clock, int mode_hdisplay)
> > -{
> > -	u16 bits_per_pixel, max_bpp_small_joiner_ram;
> > -	int i;
> > -
> > -	/*
> > -	 * Available Link Bandwidth(Kbits/sec) = (NumberOfLanes)*
> > -	 * (LinkSymbolClock)* 8 * ((100-FECOverhead)/100)*(TimeSlotsPerMTP)
> > -	 * FECOverhead = 2.4%, for SST -> TimeSlotsPerMTP is 1,
> > -	 * for MST -> TimeSlotsPerMTP has to be calculated
> > -	 */
> > -	bits_per_pixel = (link_clock * lane_count * 8 *
> > -			  DP_DSC_FEC_OVERHEAD_FACTOR) /
> > -		mode_clock;
> > -
> > -	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> > -	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER /
> > -		mode_hdisplay;
> > -
> > -	/*
> > -	 * Greatest allowed DSC BPP = MIN (output BPP from avaialble Link BW
> > -	 * check, output bpp from small joiner RAM check)
> > -	 */
> > -	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> > -
> > -	/* Error out if the max bpp is less than smallest allowed valid bpp */
> > -	if (bits_per_pixel < valid_dsc_bpp[0]) {
> > -		DRM_DEBUG_KMS("Unsupported BPP %d\n", bits_per_pixel);
> > -		return 0;
> > -	}
> > -
> > -	/* Find the nearest match in the array of known BPPs from VESA */
> > -	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp) - 1; i++) {
> > -		if (bits_per_pixel < valid_dsc_bpp[i + 1])
> > -			break;
> > -	}
> > -	bits_per_pixel = valid_dsc_bpp[i];
> > -
> > -	/*
> > -	 * Compressed BPP in U6.4 format so multiply by 16, for Gen 11,
> > -	 * fractional part is 0
> > -	 */
> > -	return bits_per_pixel << 4;
> > -}
> > -
> > -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > -				int mode_clock,
> > -				int mode_hdisplay)
> > -{
> > -	u8 min_slice_count, i;
> > -	int max_slice_width;
> > -
> > -	if (mode_clock <= DP_DSC_PEAK_PIXEL_RATE)
> > -		min_slice_count = DIV_ROUND_UP(mode_clock,
> > -					       DP_DSC_MAX_ENC_THROUGHPUT_0);
> > -	else
> > -		min_slice_count = DIV_ROUND_UP(mode_clock,
> > -					       DP_DSC_MAX_ENC_THROUGHPUT_1);
> > -
> > -	max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
> > -	if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
> > -		DRM_DEBUG_KMS("Unsupported slice width %d by DP DSC Sink device\n",
> > -			      max_slice_width);
> > -		return 0;
> > -	}
> > -	/* Also take into account max slice width */
> > -	min_slice_count = min_t(u8, min_slice_count,
> > -				DIV_ROUND_UP(mode_hdisplay,
> > -					     max_slice_width));
> > -
> > -	/* Find the closest match to the valid slice count values */
> > -	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > -		if (valid_dsc_slicecount[i] >
> > -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > -						    false))
> > -			break;
> > -		if (min_slice_count  <= valid_dsc_slicecount[i])
> > -			return valid_dsc_slicecount[i];
> > -	}
> > -
> > -	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > -	return 0;
> > -}
> > -
> >  static void
> >  intel_pixel_encoding_setup_vsc(struct intel_dp *intel_dp,
> >  			       const struct intel_crtc_state *crtc_state)
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.h b/drivers/gpu/drm/i915/display/intel_dp.h
> > index e01d1f89409d..a194b5b6da05 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.h
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> > @@ -103,10 +103,6 @@ bool intel_dp_source_supports_hbr2(struct intel_dp *intel_dp);
> >  bool intel_dp_source_supports_hbr3(struct intel_dp *intel_dp);
> >  bool
> >  intel_dp_get_link_status(struct intel_dp *intel_dp, u8 *link_status);
> > -u16 intel_dp_dsc_get_output_bpp(int link_clock, u8 lane_count,
> > -				int mode_clock, int mode_hdisplay);
> > -u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp, int mode_clock,
> > -				int mode_hdisplay);
> >  
> >  bool intel_dp_read_dpcd(struct intel_dp *intel_dp);
> >  bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp);
> > @@ -119,4 +115,6 @@ static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
> >  	return ~((1 << lane_count) - 1) & 0xf;
> >  }
> >  
> > +u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> > +
> >  #endif /* __INTEL_DP_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index eeeb3f933aa4..cf4d851a5139 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -81,7 +81,7 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
> >  			       adjusted_mode->crtc_clock,
> >  			       crtc_state->port_clock,
> >  			       &crtc_state->dp_m_n,
> > -			       constant_n);
> > +			       constant_n, crtc_state->fec_enable);
> >  	crtc_state->dp_m_n.tu = slots;
> >  
> >  	return 0;
> > -- 
> > 2.20.1
> 
> -- 
> Ville Syrjälä
> Intel
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 82+ messages in thread

* ✗ Fi.CI.BUILD: failure for series starting with drm/i915/dp: Fix dsc bpp calculations, v4. (rev3)
  2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
                   ` (27 preceding siblings ...)
  2019-09-21 15:22 ` ✗ Fi.CI.IGT: failure for series starting with [01/23] " Patchwork
@ 2019-09-23 19:10 ` Patchwork
  28 siblings, 0 replies; 82+ messages in thread
From: Patchwork @ 2019-09-23 19:10 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with drm/i915/dp: Fix dsc bpp calculations, v4. (rev3)
URL   : https://patchwork.freedesktop.org/series/66998/
State : failure

== Summary ==

Applying: drm/i915/dp: Fix dsc bpp calculations, v4.
Applying: HAX drm/i915: Disable FEC entirely for now
Applying: drm/i915: Prepare to split crtc state in uapi and hw state
Using index info to reconstruct a base tree...
M	drivers/gpu/drm/i915/display/intel_audio.c
M	drivers/gpu/drm/i915/display/intel_color.c
M	drivers/gpu/drm/i915/display/intel_ddi.c
M	drivers/gpu/drm/i915/display/intel_display.c
M	drivers/gpu/drm/i915/display/intel_display_types.h
M	drivers/gpu/drm/i915/display/intel_dp.c
M	drivers/gpu/drm/i915/display/intel_dp_mst.c
M	drivers/gpu/drm/i915/display/intel_dpll_mgr.c
M	drivers/gpu/drm/i915/display/intel_hdmi.c
M	drivers/gpu/drm/i915/i915_debugfs.c
Falling back to patching base and 3-way merge...
Auto-merging drivers/gpu/drm/i915/i915_debugfs.c
Auto-merging drivers/gpu/drm/i915/display/intel_hdmi.c
Auto-merging drivers/gpu/drm/i915/display/intel_dpll_mgr.c
Auto-merging drivers/gpu/drm/i915/display/intel_dp_mst.c
Auto-merging drivers/gpu/drm/i915/display/intel_dp.c
Auto-merging drivers/gpu/drm/i915/display/intel_display_types.h
Auto-merging drivers/gpu/drm/i915/display/intel_display.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/display/intel_display.c
Auto-merging drivers/gpu/drm/i915/display/intel_ddi.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/display/intel_ddi.c
Auto-merging drivers/gpu/drm/i915/display/intel_color.c
CONFLICT (content): Merge conflict in drivers/gpu/drm/i915/display/intel_color.c
Auto-merging drivers/gpu/drm/i915/display/intel_audio.c
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0003 drm/i915: Prepare to split crtc state in uapi and hw state
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state
  2019-09-20 11:42 ` [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state Maarten Lankhorst
@ 2019-09-24 23:40   ` Matt Roper
  2019-09-25  9:09     ` Maarten Lankhorst
  0 siblings, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-24 23:40 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:15PM +0200, Maarten Lankhorst wrote:
> We want to split drm_crtc_state into the user visible state
> and actual hardware state. To prepare for this, we need some
> ground rules what should be in each state:
> 
> In uapi we use:
> - crtc, *_changed flags, event, commit, state, mode_blob, (plane/connector/encoder)_mask.
> 
> In hw state we use what's displayed in hardware:
> - enable, active, (adjusted) mode, color property blobs.

I'd suggest elaborating a bit that the union we add in this patch is
just an intermediate step and that the end goal is that we'll eventually
be maintaining two separate copies of some of the data.

> 
> clear_intel_crtc_state and hw readout need to be updated for these rules,
> which will allow us to enable 2 joined pipes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

It might be worth providing some Coccinelle rules to apply these changes
in a semi-automated manner; otherwise it's going to be a hassle to
constantly resolve conflicts with pretty much any other display patches
that land upstream.

Otherwise,

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c        |  18 +-
>  drivers/gpu/drm/i915/display/intel_atomic.c   |  14 +-
>  .../gpu/drm/i915/display/intel_atomic_plane.c |   6 +-
>  drivers/gpu/drm/i915/display/intel_audio.c    |  12 +-
>  drivers/gpu/drm/i915/display/intel_bw.c       |   4 +-
>  drivers/gpu/drm/i915/display/intel_cdclk.c    |  16 +-
>  drivers/gpu/drm/i915/display/intel_color.c    | 180 +++---
>  drivers/gpu/drm/i915/display/intel_crt.c      |  24 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  34 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 540 +++++++++---------
>  .../drm/i915/display/intel_display_types.h    |  28 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |  42 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   6 +-
>  drivers/gpu/drm/i915/display/intel_dpio_phy.c |  14 +-
>  drivers/gpu/drm/i915/display/intel_dpll_mgr.c |  20 +-
>  drivers/gpu/drm/i915/display/intel_dvo.c      |  14 +-
>  drivers/gpu/drm/i915/display/intel_fbc.c      |   2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  62 +-
>  drivers/gpu/drm/i915/display/intel_lspcon.c   |   4 +-
>  drivers/gpu/drm/i915/display/intel_lvds.c     |  12 +-
>  drivers/gpu/drm/i915/display/intel_panel.c    |  14 +-
>  drivers/gpu/drm/i915/display/intel_pipe_crc.c |   6 +-
>  drivers/gpu/drm/i915/display/intel_psr.c      |  10 +-
>  drivers/gpu/drm/i915/display/intel_sdvo.c     |  22 +-
>  drivers/gpu/drm/i915/display/intel_sprite.c   |  25 +-
>  drivers/gpu/drm/i915/display/intel_tv.c       |   8 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     |  12 +-
>  drivers/gpu/drm/i915/display/vlv_dsi.c        |  20 +-
>  drivers/gpu/drm/i915/i915_debugfs.c           |  14 +-
>  drivers/gpu/drm/i915/intel_pm.c               | 180 +++---
>  30 files changed, 699 insertions(+), 664 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 6e398c33a524..0e24b8e257e5 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -276,7 +276,7 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
>  
>  	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
>  		const struct drm_display_mode *adjusted_mode =
> -					&pipe_config->base.adjusted_mode;
> +					&pipe_config->hw.adjusted_mode;
>  		u32 dss_ctl2;
>  		u16 hactive = adjusted_mode->crtc_hdisplay;
>  		u16 dl_buffer_depth;
> @@ -625,7 +625,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	enum pipe pipe = intel_crtc->pipe;
>  	u32 tmp;
>  	enum port port;
> @@ -768,7 +768,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	const struct drm_display_mode *adjusted_mode =
> -					&pipe_config->base.adjusted_mode;
> +					&pipe_config->hw.adjusted_mode;
>  	enum port port;
>  	enum transcoder dsi_trans;
>  	/* horizontal timings */
> @@ -1216,7 +1216,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
>  {
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	struct drm_display_mode *adjusted_mode =
> -					&pipe_config->base.adjusted_mode;
> +					&pipe_config->hw.adjusted_mode;
>  
>  	if (intel_dsi->dual_link) {
>  		adjusted_mode->crtc_hdisplay *= 2;
> @@ -1242,16 +1242,16 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>  				 struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  
>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>  	pipe_config->port_clock =
>  		cnl_calc_wrpll_link(dev_priv, &pipe_config->dpll_hw_state);
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = intel_dsi->pclk;
> +	pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
>  	if (intel_dsi->dual_link)
> -		pipe_config->base.adjusted_mode.crtc_clock *= 2;
> +		pipe_config->hw.adjusted_mode.crtc_clock *= 2;
>  
>  	gen11_dsi_get_timings(encoder, pipe_config);
>  	pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
> @@ -1265,11 +1265,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
>  	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
>  						   base);
>  	struct intel_connector *intel_connector = intel_dsi->attached_connector;
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	const struct drm_display_mode *fixed_mode =
>  					intel_connector->panel.fixed_mode;
>  	struct drm_display_mode *adjusted_mode =
> -					&pipe_config->base.adjusted_mode;
> +					&pipe_config->hw.adjusted_mode;
>  
>  	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
>  	intel_fixed_panel_mode(fixed_mode, adjusted_mode);
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 698802da07b7..f4440ede95c5 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -186,13 +186,14 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector)
>  struct drm_crtc_state *
>  intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  {
> +	const struct intel_crtc_state *old_crtc_state = to_intel_crtc_state(crtc->state);
>  	struct intel_crtc_state *crtc_state;
>  
> -	crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
> +	crtc_state = kmemdup(old_crtc_state, sizeof(*crtc_state), GFP_KERNEL);
>  	if (!crtc_state)
>  		return NULL;
>  
> -	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
> +	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>  
>  	crtc_state->update_pipe = false;
>  	crtc_state->disable_lp_wm = false;
> @@ -205,7 +206,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	crtc_state->fb_bits = 0;
>  	crtc_state->update_planes = 0;
>  
> -	return &crtc_state->base;
> +	return &crtc_state->uapi;
>  }
>  
>  /**
> @@ -220,7 +221,10 @@ void
>  intel_crtc_destroy_state(struct drm_crtc *crtc,
>  			 struct drm_crtc_state *state)
>  {
> -	drm_atomic_helper_crtc_destroy_state(crtc, state);
> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
> +
> +	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> +	kfree(crtc_state);
>  }
>  
>  static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state,
> @@ -316,7 +320,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
>  	struct intel_plane_state *plane_state = NULL;
>  	struct intel_crtc_scaler_state *scaler_state =
>  		&crtc_state->scaler_state;
> -	struct drm_atomic_state *drm_state = crtc_state->base.state;
> +	struct drm_atomic_state *drm_state = crtc_state->uapi.state;
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
>  	int num_scalers_need;
>  	int i;
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 476ef0906ba0..1f50b15ec704 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -271,7 +271,7 @@ void intel_update_plane(struct intel_plane *plane,
>  			const struct intel_crtc_state *crtc_state,
>  			const struct intel_plane_state *plane_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	trace_intel_update_plane(&plane->base, crtc);
>  	plane->update_plane(plane, crtc_state, plane_state);
> @@ -281,7 +281,7 @@ void intel_update_slave(struct intel_plane *plane,
>  			const struct intel_crtc_state *crtc_state,
>  			const struct intel_plane_state *plane_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	trace_intel_update_plane(&plane->base, crtc);
>  	plane->update_slave(plane, crtc_state, plane_state);
> @@ -290,7 +290,7 @@ void intel_update_slave(struct intel_plane *plane,
>  void intel_disable_plane(struct intel_plane *plane,
>  			 const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	trace_intel_disable_plane(&plane->base, crtc);
>  	plane->disable_plane(plane, crtc_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
> index aac089c79ceb..2ecf1df0eeda 100644
> --- a/drivers/gpu/drm/i915/display/intel_audio.c
> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
> @@ -233,7 +233,7 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
>  static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
>  {
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	int i;
>  
>  	for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
> @@ -554,7 +554,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder,
>  				    const struct drm_connector_state *old_conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	enum pipe pipe = crtc->pipe;
>  	enum port port = encoder->port;
>  	u32 tmp, eldv;
> @@ -601,7 +601,7 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
>  				   const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_connector *connector = conn_state->connector;
>  	enum pipe pipe = crtc->pipe;
>  	enum port port = encoder->port;
> @@ -691,10 +691,10 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_connector *connector = conn_state->connector;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	enum port port = encoder->port;
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -752,7 +752,7 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct i915_audio_component *acomp = dev_priv->audio_component;
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	enum port port = encoder->port;
>  	enum pipe pipe = crtc->pipe;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
> index 688858ebe4d0..a83a297be9a4 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -264,7 +264,7 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat
>  
>  static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	unsigned int data_rate = 0;
>  	enum plane_id plane_id;
>  
> @@ -285,7 +285,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_
>  void intel_bw_crtc_update(struct intel_bw_state *bw_state,
>  			  const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	bw_state->data_rate[crtc->pipe] =
>  		intel_bw_crtc_data_rate(crtc_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 43564295b864..17ffe7fbaa21 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -1917,10 +1917,10 @@ static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv,
>  int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv =
> -		to_i915(crtc_state->base.crtc->dev);
> +		to_i915(crtc_state->uapi.crtc->dev);
>  	int min_cdclk;
>  
> -	if (!crtc_state->base.enable)
> +	if (!crtc_state->hw.enable)
>  		return 0;
>  
>  	min_cdclk = intel_pixel_rate_to_cdclk(dev_priv, crtc_state->pixel_rate);
> @@ -2043,7 +2043,7 @@ static u8 bxt_compute_min_voltage_level(struct intel_atomic_state *state)
>  	       sizeof(state->min_voltage_level));
>  
>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (crtc_state->base.enable)
> +		if (crtc_state->hw.enable)
>  			state->min_voltage_level[i] =
>  				crtc_state->min_voltage_level;
>  		else
> @@ -2129,7 +2129,7 @@ static int skl_dpll0_vco(struct intel_atomic_state *state)
>  		vco = dev_priv->skl_preferred_vco_freq;
>  
>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!crtc_state->base.enable)
> +		if (!crtc_state->hw.enable)
>  			continue;
>  
>  		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
> @@ -2255,11 +2255,11 @@ static int intel_modeset_all_pipes(struct intel_atomic_state *state)
>  		if (IS_ERR(crtc_state))
>  			return PTR_ERR(crtc_state);
>  
> -		if (!crtc_state->base.active ||
> -		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
> +		if (!crtc_state->hw.active ||
> +		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
>  			continue;
>  
> -		crtc_state->base.mode_changed = true;
> +		crtc_state->uapi.mode_changed = true;
>  
>  		ret = drm_atomic_add_affected_connectors(&state->base,
>  							 &crtc->base);
> @@ -2310,7 +2310,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
>  		crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
>  		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>  		if (crtc_state &&
> -		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
> +		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
>  			pipe = INVALID_PIPE;
>  	} else {
>  		pipe = INVALID_PIPE;
> diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
> index 318308dc136c..9b058907ef4e 100644
> --- a/drivers/gpu/drm/i915/display/intel_color.c
> +++ b/drivers/gpu/drm/i915/display/intel_color.c
> @@ -101,10 +101,10 @@ static bool lut_is_legacy(const struct drm_property_blob *lut)
>  
>  static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
>  {
> -	return !crtc_state->base.degamma_lut &&
> -		!crtc_state->base.ctm &&
> -		crtc_state->base.gamma_lut &&
> -		lut_is_legacy(crtc_state->base.gamma_lut);
> +	return !crtc_state->hw.degamma_lut &&
> +		!crtc_state->hw.ctm &&
> +		crtc_state->hw.gamma_lut &&
> +		lut_is_legacy(crtc_state->hw.gamma_lut);
>  }
>  
>  /*
> @@ -189,7 +189,7 @@ static void icl_update_output_csc(struct intel_crtc *crtc,
>  
>  static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	/*
>  	 * FIXME if there's a gamma LUT after the CSC, we should
> @@ -203,7 +203,7 @@ static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
>  static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
>  				u16 coeffs[9])
>  {
> -	const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
> +	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
>  	const u64 *input;
>  	u64 temp[9];
>  	int i;
> @@ -254,11 +254,11 @@ static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
>  
>  static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	bool limited_color_range = ilk_csc_limited_range(crtc_state);
>  
> -	if (crtc_state->base.ctm) {
> +	if (crtc_state->hw.ctm) {
>  		u16 coeff[9];
>  
>  		ilk_csc_convert_ctm(crtc_state, coeff);
> @@ -293,10 +293,10 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>  
>  static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
> -	if (crtc_state->base.ctm) {
> +	if (crtc_state->hw.ctm) {
>  		u16 coeff[9];
>  
>  		ilk_csc_convert_ctm(crtc_state, coeff);
> @@ -322,12 +322,12 @@ static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>   */
>  static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> -	if (crtc_state->base.ctm) {
> -		const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
> +	if (crtc_state->hw.ctm) {
> +		const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
>  		u16 coeffs[9] = {};
>  		int i;
>  
> @@ -388,7 +388,7 @@ static u32 ilk_lut_10(const struct drm_color_lut *color)
>  static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
>  				    const struct drm_property_blob *blob)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	int i;
> @@ -419,12 +419,12 @@ static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
>  
>  static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
> +	i9xx_load_luts_internal(crtc_state, crtc_state->hw.gamma_lut);
>  }
>  
>  static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
> @@ -437,7 +437,7 @@ static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
>  
>  static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
> @@ -452,7 +452,7 @@ static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
>  
>  static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
> @@ -462,7 +462,7 @@ static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
>  
>  static void skl_color_commit(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val = 0;
> @@ -508,8 +508,8 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
>  
>  static void i965_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>  
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>  		i9xx_load_luts(crtc_state);
> @@ -531,8 +531,8 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
>  
>  static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>  
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>  		i9xx_load_luts(crtc_state);
> @@ -632,9 +632,9 @@ static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
>  
>  static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>  
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
>  		i9xx_load_luts(crtc_state);
> @@ -655,9 +655,9 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
>  
>  static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>  
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
>  		i9xx_load_luts(crtc_state);
> @@ -678,11 +678,11 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
>  
>  static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
> -	const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
> +	const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
>  	u32 i;
>  
>  	/*
> @@ -717,7 +717,7 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
>  
>  static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
> @@ -744,8 +744,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat
>  
>  static void glk_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	/*
>  	 * On GLK+ both pipe CSC and degamma LUT are controlled
> @@ -755,7 +755,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
>  	 * the degama LUT so that we don't have to reload
>  	 * it every time the pipe CSC is being enabled.
>  	 */
> -	if (crtc_state->base.degamma_lut)
> +	if (crtc_state->hw.degamma_lut)
>  		glk_load_degamma_lut(crtc_state);
>  	else
>  		glk_load_degamma_lut_linear(crtc_state);
> @@ -786,7 +786,7 @@ static void
>  icl_load_gcmax(const struct intel_crtc_state *crtc_state,
>  	       const struct drm_color_lut *color)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -799,9 +799,9 @@ icl_load_gcmax(const struct intel_crtc_state *crtc_state,
>  static void
>  icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
> +	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
>  	const struct drm_color_lut *lut = blob->data;
>  	enum pipe pipe = crtc->pipe;
>  	u32 i;
> @@ -828,9 +828,9 @@ icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
>  static void
>  icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
> +	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
>  	const struct drm_color_lut *lut = blob->data;
>  	const struct drm_color_lut *entry;
>  	enum pipe pipe = crtc->pipe;
> @@ -880,10 +880,10 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
>  
>  static void icl_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
> -	if (crtc_state->base.degamma_lut)
> +	if (crtc_state->hw.degamma_lut)
>  		glk_load_degamma_lut(crtc_state);
>  
>  	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
> @@ -958,9 +958,9 @@ static void chv_load_cgm_gamma(struct intel_crtc *crtc,
>  
>  static void chv_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>  
>  	cherryview_load_csc_matrix(crtc_state);
>  
> @@ -978,28 +978,28 @@ static void chv_load_luts(const struct intel_crtc_state *crtc_state)
>  
>  void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	dev_priv->display.load_luts(crtc_state);
>  }
>  
>  void intel_color_commit(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	dev_priv->display.color_commit(crtc_state);
>  }
>  
>  int intel_color_check(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	return dev_priv->display.color_check(crtc_state);
>  }
>  
>  void intel_color_get_config(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	if (dev_priv->display.read_luts)
>  		dev_priv->display.read_luts(crtc_state);
> @@ -1023,16 +1023,16 @@ static bool need_plane_update(struct intel_plane *plane,
>  static int
>  intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(new_crtc_state->base.state);
> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>  	const struct intel_crtc_state *old_crtc_state =
>  		intel_atomic_get_old_crtc_state(state, crtc);
>  	struct intel_plane *plane;
>  
> -	if (!new_crtc_state->base.active ||
> -	    drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
> +	if (!new_crtc_state->hw.active ||
> +	    drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
>  		return 0;
>  
>  	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
> @@ -1074,9 +1074,9 @@ static int check_lut_size(const struct drm_property_blob *lut, int expected)
>  
>  static int check_luts(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>  	int gamma_length, degamma_length;
>  	u32 gamma_tests, degamma_tests;
>  
> @@ -1124,7 +1124,7 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
>  		return ret;
>  
>  	crtc_state->gamma_enable =
> -		crtc_state->base.gamma_lut &&
> +		crtc_state->hw.gamma_lut &&
>  		!crtc_state->c8_planes;
>  
>  	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
> @@ -1143,11 +1143,11 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
>  	if (crtc_state_is_legacy_gamma(crtc_state))
>  		return 0;
>  
> -	if (crtc_state->base.degamma_lut)
> +	if (crtc_state->hw.degamma_lut)
>  		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
> -	if (crtc_state->base.ctm)
> +	if (crtc_state->hw.ctm)
>  		cgm_mode |= CGM_PIPE_MODE_CSC;
> -	if (crtc_state->base.gamma_lut)
> +	if (crtc_state->hw.gamma_lut)
>  		cgm_mode |= CGM_PIPE_MODE_GAMMA;
>  
>  	return cgm_mode;
> @@ -1206,7 +1206,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
>  		return ret;
>  
>  	crtc_state->gamma_enable =
> -		crtc_state->base.gamma_lut &&
> +		crtc_state->hw.gamma_lut &&
>  		!crtc_state->c8_planes;
>  
>  	/*
> @@ -1232,8 +1232,8 @@ static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
>  	if (!crtc_state->gamma_enable ||
>  	    crtc_state_is_legacy_gamma(crtc_state))
>  		return GAMMA_MODE_MODE_8BIT;
> -	else if (crtc_state->base.gamma_lut &&
> -		 crtc_state->base.degamma_lut)
> +	else if (crtc_state->hw.gamma_lut &&
> +		 crtc_state->hw.degamma_lut)
>  		return GAMMA_MODE_MODE_SPLIT;
>  	else
>  		return GAMMA_MODE_MODE_10BIT;
> @@ -1247,7 +1247,7 @@ static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
>  	 * CSC comes after the LUT in degamma, RGB->YCbCr,
>  	 * and RGB full->limited range mode.
>  	 */
> -	if (crtc_state->base.degamma_lut ||
> +	if (crtc_state->hw.degamma_lut ||
>  	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
>  	    limited_color_range)
>  		return 0;
> @@ -1265,13 +1265,13 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
>  		return ret;
>  
>  	crtc_state->gamma_enable =
> -		(crtc_state->base.gamma_lut ||
> -		 crtc_state->base.degamma_lut) &&
> +		(crtc_state->hw.gamma_lut ||
> +		 crtc_state->hw.degamma_lut) &&
>  		!crtc_state->c8_planes;
>  
>  	crtc_state->csc_enable =
>  		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
> -		crtc_state->base.ctm || limited_color_range;
> +		crtc_state->hw.ctm || limited_color_range;
>  
>  	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
>  
> @@ -1302,14 +1302,14 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
>  		return ret;
>  
>  	crtc_state->gamma_enable =
> -		crtc_state->base.gamma_lut &&
> +		crtc_state->hw.gamma_lut &&
>  		!crtc_state->c8_planes;
>  
>  	/* On GLK+ degamma LUT is controlled by csc_enable */
>  	crtc_state->csc_enable =
> -		crtc_state->base.degamma_lut ||
> +		crtc_state->hw.degamma_lut ||
>  		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
> -		crtc_state->base.ctm || crtc_state->limited_color_range;
> +		crtc_state->hw.ctm || crtc_state->limited_color_range;
>  
>  	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
>  
> @@ -1326,14 +1326,14 @@ static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
>  {
>  	u32 gamma_mode = 0;
>  
> -	if (crtc_state->base.degamma_lut)
> +	if (crtc_state->hw.degamma_lut)
>  		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
>  
> -	if (crtc_state->base.gamma_lut &&
> +	if (crtc_state->hw.gamma_lut &&
>  	    !crtc_state->c8_planes)
>  		gamma_mode |= POST_CSC_GAMMA_ENABLE;
>  
> -	if (!crtc_state->base.gamma_lut ||
> +	if (!crtc_state->hw.gamma_lut ||
>  	    crtc_state_is_legacy_gamma(crtc_state))
>  		gamma_mode |= GAMMA_MODE_MODE_8BIT;
>  	else
> @@ -1346,7 +1346,7 @@ static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
>  {
>  	u32 csc_mode = 0;
>  
> -	if (crtc_state->base.ctm)
> +	if (crtc_state->hw.ctm)
>  		csc_mode |= ICL_CSC_ENABLE;
>  
>  	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
> @@ -1423,7 +1423,7 @@ static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
>  
>  int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!crtc_state->gamma_enable)
> @@ -1532,7 +1532,7 @@ static u32 intel_color_lut_pack(u32 val, u32 bit_precision)
>  static struct drm_property_blob *
>  i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	struct drm_property_blob *blob;
> @@ -1566,13 +1566,13 @@ i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
>  
>  static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
>  {
> -	crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
> +	crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>  }
>  
>  static struct drm_property_blob *
>  i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>  	enum pipe pipe = crtc->pipe;
> @@ -1613,15 +1613,15 @@ i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
>  static void i965_read_luts(struct intel_crtc_state *crtc_state)
>  {
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>  	else
> -		crtc_state->base.gamma_lut = i965_read_lut_10p6(crtc_state);
> +		crtc_state->uapi.gamma_lut = i965_read_lut_10p6(crtc_state);
>  }
>  
>  static struct drm_property_blob *
>  chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>  	enum pipe pipe = crtc->pipe;
> @@ -1655,15 +1655,15 @@ chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
>  static void chv_read_luts(struct intel_crtc_state *crtc_state)
>  {
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>  	else
> -		crtc_state->base.gamma_lut = chv_read_cgm_lut(crtc_state);
> +		crtc_state->uapi.gamma_lut = chv_read_cgm_lut(crtc_state);
>  }
>  
>  static struct drm_property_blob *
>  ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>  	enum pipe pipe = crtc->pipe;
> @@ -1696,15 +1696,15 @@ ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
>  static void ilk_read_luts(struct intel_crtc_state *crtc_state)
>  {
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>  	else
> -		crtc_state->base.gamma_lut = ilk_read_lut_10(crtc_state);
> +		crtc_state->uapi.gamma_lut = ilk_read_lut_10(crtc_state);
>  }
>  
>  static struct drm_property_blob *
>  glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	int hw_lut_size = ivb_lut_10_size(prec_index);
>  	enum pipe pipe = crtc->pipe;
> @@ -1742,9 +1742,9 @@ glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
>  static void glk_read_luts(struct intel_crtc_state *crtc_state)
>  {
>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>  	else
> -		crtc_state->base.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
> +		crtc_state->uapi.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
>  }
>  
>  void intel_color_init(struct intel_crtc *crtc)
> diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
> index e6e8d4a82044..35a25172b269 100644
> --- a/drivers/gpu/drm/i915/display/intel_crt.c
> +++ b/drivers/gpu/drm/i915/display/intel_crt.c
> @@ -132,9 +132,9 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
>  {
>  	pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
>  
> -	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
> +	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>  }
>  
>  static void hsw_crt_get_config(struct intel_encoder *encoder,
> @@ -144,13 +144,13 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
>  
>  	intel_ddi_get_config(encoder, pipe_config);
>  
> -	pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
> +	pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
>  					      DRM_MODE_FLAG_NHSYNC |
>  					      DRM_MODE_FLAG_PVSYNC |
>  					      DRM_MODE_FLAG_NVSYNC);
> -	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
> +	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
> +	pipe_config->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
>  }
>  
>  /* Note: The caller is required to filter out dpms modes not supported by the
> @@ -161,8 +161,8 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_crt *crt = intel_encoder_to_crt(encoder);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>  	u32 adpa;
>  
>  	if (INTEL_GEN(dev_priv) >= 5)
> @@ -271,7 +271,7 @@ static void hsw_pre_enable_crt(struct intel_encoder *encoder,
>  			       const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum pipe pipe = crtc->pipe;
>  
>  	WARN_ON(!crtc_state->has_pch_encoder);
> @@ -288,7 +288,7 @@ static void hsw_enable_crt(struct intel_encoder *encoder,
>  			   const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum pipe pipe = crtc->pipe;
>  
>  	WARN_ON(!crtc_state->has_pch_encoder);
> @@ -358,7 +358,7 @@ static int intel_crt_compute_config(struct intel_encoder *encoder,
>  				    struct drm_connector_state *conn_state)
>  {
>  	struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return -EINVAL;
> @@ -373,7 +373,7 @@ static int pch_crt_compute_config(struct intel_encoder *encoder,
>  				  struct drm_connector_state *conn_state)
>  {
>  	struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return -EINVAL;
> @@ -390,7 +390,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return -EINVAL;
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 1b59b852874b..c775fd205915 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1483,7 +1483,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>  	if (pipe_config->fec_enable)
>  		dotclock = intel_dp_fec_to_mode_clock(dotclock);
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>  }
>  
>  static void icl_ddi_clock_get(struct intel_encoder *encoder,
> @@ -1698,7 +1698,7 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
>  
>  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 temp;
> @@ -1752,7 +1752,7 @@ void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
>  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>  				    bool state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 temp;
> @@ -1774,7 +1774,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>  static u32
>  intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
> @@ -1806,9 +1806,9 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>  		BUG();
>  	}
>  
> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
>  		temp |= TRANS_DDI_PVSYNC;
> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
>  		temp |= TRANS_DDI_PHSYNC;
>  
>  	if (cpu_transcoder == TRANSCODER_EDP) {
> @@ -1861,7 +1861,7 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>  
>  void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 temp;
> @@ -1877,7 +1877,7 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
>  static void
>  intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 temp;
> @@ -1889,7 +1889,7 @@ intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
>  
>  void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
> @@ -2187,7 +2187,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>  
>  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
>  	enum port port = encoder->port;
> @@ -2205,7 +2205,7 @@ void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
>  
>  void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  
>  	if (cpu_transcoder != TRANSCODER_EDP) {
> @@ -3421,7 +3421,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
>  				 const struct intel_crtc_state *crtc_state,
>  				 const struct drm_connector_state *conn_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -3846,7 +3846,7 @@ intel_ddi_update_prepare(struct intel_atomic_state *state,
>  	WARN_ON(crtc && crtc->active);
>  
>  	intel_tc_port_get_link(enc_to_dig_port(&encoder->base), required_lanes);
> -	if (crtc_state && crtc_state->base.active)
> +	if (crtc_state && crtc_state->hw.active)
>  		intel_update_active_dpll(state, crtc, encoder);
>  }
>  
> @@ -3976,7 +3976,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  			  struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	u32 temp, flags = 0;
>  
> @@ -3994,7 +3994,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	else
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
>  	switch (temp & TRANS_DDI_BPC_MASK) {
>  	case TRANS_DDI_BPC_6:
> @@ -4136,7 +4136,7 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder,
>  				    struct intel_crtc_state *pipe_config,
>  				    struct drm_connector_state *conn_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	enum port port = encoder->port;
>  	int ret;
> @@ -4267,7 +4267,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
>  
>  	WARN_ON(!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI));
>  
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return 0;
>  
>  	if (!crtc_state->hdmi_high_tmds_clock_ratio &&
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 7996864e6f7c..6818cbd00ac2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -518,7 +518,7 @@ icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
>  static bool
>  needs_modeset(const struct intel_crtc_state *state)
>  {
> -	return drm_atomic_crtc_needs_modeset(&state->base);
> +	return drm_atomic_crtc_needs_modeset(&state->uapi);
>  }
>  
>  /*
> @@ -632,7 +632,7 @@ i9xx_select_p2_div(const struct intel_limit *limit,
>  		   const struct intel_crtc_state *crtc_state,
>  		   int target)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>  		/*
> @@ -668,7 +668,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit,
>  		    int target, int refclk, struct dpll *match_clock,
>  		    struct dpll *best_clock)
>  {
> -	struct drm_device *dev = crtc_state->base.crtc->dev;
> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>  	struct dpll clock;
>  	int err = target;
>  
> @@ -726,7 +726,7 @@ pnv_find_best_dpll(const struct intel_limit *limit,
>  		   int target, int refclk, struct dpll *match_clock,
>  		   struct dpll *best_clock)
>  {
> -	struct drm_device *dev = crtc_state->base.crtc->dev;
> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>  	struct dpll clock;
>  	int err = target;
>  
> @@ -782,7 +782,7 @@ g4x_find_best_dpll(const struct intel_limit *limit,
>  		   int target, int refclk, struct dpll *match_clock,
>  		   struct dpll *best_clock)
>  {
> -	struct drm_device *dev = crtc_state->base.crtc->dev;
> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>  	struct dpll clock;
>  	int max_n;
>  	bool found = false;
> @@ -876,7 +876,7 @@ vlv_find_best_dpll(const struct intel_limit *limit,
>  		   int target, int refclk, struct dpll *match_clock,
>  		   struct dpll *best_clock)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct dpll clock;
>  	unsigned int bestppm = 1000000;
> @@ -936,7 +936,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
>  		   int target, int refclk, struct dpll *match_clock,
>  		   struct dpll *best_clock)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	unsigned int best_error_ppm;
>  	struct dpll clock;
> @@ -1015,7 +1015,7 @@ bool intel_crtc_active(struct intel_crtc *crtc)
>  	 * for atomic.
>  	 */
>  	return crtc->active && crtc->base.primary->state->fb &&
> -		crtc->config->base.adjusted_mode.crtc_clock;
> +		crtc->config->hw.adjusted_mode.crtc_clock;
>  }
>  
>  enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
> @@ -1069,7 +1069,7 @@ static void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
>  static void
>  intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (INTEL_GEN(dev_priv) >= 4) {
> @@ -1528,7 +1528,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc,
>  
>  static void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -1619,7 +1619,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
>  
>  static void ironlake_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	i915_reg_t reg;
> @@ -1763,7 +1763,7 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
>  
>  static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	/*
>  	 * On i965gm the hardware frame counter reads
> @@ -1783,7 +1783,7 @@ static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state
>  
>  static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	drm_crtc_set_max_vblank_count(&crtc->base,
>  				      intel_crtc_max_vblank_count(crtc_state));
> @@ -1792,7 +1792,7 @@ static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
>  
>  static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
> @@ -1850,7 +1850,7 @@ static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
>  
>  static void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
> @@ -3116,14 +3116,14 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state,
>  	plane_state->base.visible = visible;
>  
>  	if (visible)
> -		crtc_state->base.plane_mask |= drm_plane_mask(&plane->base);
> +		crtc_state->uapi.plane_mask |= drm_plane_mask(&plane->base);
>  	else
> -		crtc_state->base.plane_mask &= ~drm_plane_mask(&plane->base);
> +		crtc_state->uapi.plane_mask &= ~drm_plane_mask(&plane->base);
>  }
>  
>  static void fixup_active_planes(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	struct drm_plane *plane;
>  
>  	/*
> @@ -3134,7 +3134,7 @@ static void fixup_active_planes(struct intel_crtc_state *crtc_state)
>  	crtc_state->active_planes = 0;
>  
>  	drm_for_each_plane_mask(plane, &dev_priv->drm,
> -				crtc_state->base.plane_mask)
> +				crtc_state->uapi.plane_mask)
>  		crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
>  }
>  
> @@ -3608,7 +3608,7 @@ i9xx_plane_max_stride(struct intel_plane *plane,
>  
>  static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 dspcntr = 0;
>  
> @@ -3762,7 +3762,7 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
>  		return ret;
>  
>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
> -						  &crtc_state->base,
> +						  &crtc_state->uapi,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  i9xx_plane_has_windowing(plane),
> @@ -3938,7 +3938,7 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
>   */
>  static void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	const struct intel_crtc_scaler_state *scaler_state =
>  		&crtc_state->scaler_state;
>  	int i;
> @@ -4133,7 +4133,7 @@ static u32 cnl_plane_ctl_flip(unsigned int reflect)
>  
>  u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	u32 plane_ctl = 0;
>  
>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> @@ -4189,7 +4189,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
>  
>  u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	u32 plane_color_ctl = 0;
>  
>  	if (INTEL_GEN(dev_priv) >= 11)
> @@ -4411,11 +4411,11 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
>  static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state,
>  				     const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
> -	crtc->base.mode = new_crtc_state->base.mode;
> +	crtc->base.mode = new_crtc_state->uapi.mode;
>  
>  	/*
>  	 * Update pipe size and adjust fitter if needed: the reason for this is
> @@ -4844,7 +4844,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
>  
>  static void ironlake_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>  	enum pipe pipe = intel_crtc->pipe;
>  	i915_reg_t reg;
> @@ -5005,9 +5005,9 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
>  /* Program iCLKIP clock to the desired frequency */
>  static void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	int clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	int clock = crtc_state->hw.adjusted_mode.crtc_clock;
>  	u32 divsel, phaseinc, auxdiv, phasedir = 0;
>  	u32 temp;
>  
> @@ -5121,7 +5121,7 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
>  static void ironlake_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state,
>  						enum pipe pch_transcoder)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  
> @@ -5164,7 +5164,7 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool e
>  
>  static void ivybridge_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	switch (crtc->pipe) {
> @@ -5194,7 +5194,7 @@ static struct intel_encoder *
>  intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>  			   const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	const struct drm_connector_state *connector_state;
>  	const struct drm_connector *connector;
>  	struct intel_encoder *encoder = NULL;
> @@ -5226,7 +5226,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>  static void ironlake_pch_enable(const struct intel_atomic_state *state,
>  				const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	enum pipe pipe = crtc->pipe;
> @@ -5280,7 +5280,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
>  	if (HAS_PCH_CPT(dev_priv) &&
>  	    intel_crtc_has_dp_encoder(crtc_state)) {
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc_state->base.adjusted_mode;
> +			&crtc_state->hw.adjusted_mode;
>  		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
>  		i915_reg_t reg = TRANS_DP_CTL(pipe);
>  		enum port port;
> @@ -5310,7 +5310,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
>  static void lpt_pch_enable(const struct intel_atomic_state *state,
>  			   const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  
> @@ -5427,10 +5427,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  	struct intel_crtc_scaler_state *scaler_state =
>  		&crtc_state->scaler_state;
>  	struct intel_crtc *intel_crtc =
> -		to_intel_crtc(crtc_state->base.crtc);
> +		to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  
>  	/*
>  	 * Src coordinates are already rotated by 270 degrees for
> @@ -5446,7 +5446,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  	 * Once NV12 is enabled, handle it here while allocating scaler
>  	 * for NV12.
>  	 */
> -	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
> +	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->hw.enable &&
>  	    need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>  		DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
>  		return -EINVAL;
> @@ -5518,13 +5518,13 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>   */
>  int skl_update_scaler_crtc(struct intel_crtc_state *state)
>  {
> -	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &state->hw.adjusted_mode;
>  	bool need_scaler = false;
>  
>  	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
>  		need_scaler = true;
>  
> -	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
> +	return skl_update_scaler(state, !state->hw.active, SKL_CRTC_INDEX,
>  				 &state->scaler_state.scaler_id,
>  				 state->pipe_src_w, state->pipe_src_h,
>  				 adjusted_mode->crtc_hdisplay,
> @@ -5624,7 +5624,7 @@ static void skylake_scaler_disable(struct intel_crtc *crtc)
>  
>  static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	const struct intel_crtc_scaler_state *scaler_state =
> @@ -5661,7 +5661,7 @@ static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
>  
>  static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -5682,7 +5682,7 @@ static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
>  
>  void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  
> @@ -5718,7 +5718,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
>  
>  void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  
> @@ -5828,7 +5828,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
>  static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
>  				       const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!old_crtc_state->ips_enabled)
> @@ -5844,7 +5844,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
>  	 * Disable IPS before we program the LUT.
>  	 */
>  	if (IS_HASWELL(dev_priv) &&
> -	    (new_crtc_state->base.color_mgmt_changed ||
> +	    (new_crtc_state->uapi.color_mgmt_changed ||
>  	     new_crtc_state->update_pipe) &&
>  	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
>  		return true;
> @@ -5855,7 +5855,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
>  static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
>  				       const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!new_crtc_state->ips_enabled)
> @@ -5871,7 +5871,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
>  	 * Re-enable IPS after the LUT has been programmed.
>  	 */
>  	if (IS_HASWELL(dev_priv) &&
> -	    (new_crtc_state->base.color_mgmt_changed ||
> +	    (new_crtc_state->uapi.color_mgmt_changed ||
>  	     new_crtc_state->update_pipe) &&
>  	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
>  		return true;
> @@ -5881,7 +5881,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
>  	 * forcibly enable IPS on the first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe &&
> -	    old_crtc_state->base.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		return true;
>  
>  	return !old_crtc_state->ips_enabled;
> @@ -5912,10 +5912,10 @@ static bool needs_scalerclk_wa(struct drm_i915_private *dev_priv,
>  
>  static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct drm_atomic_state *state = old_crtc_state->base.state;
> +	struct drm_atomic_state *state = old_crtc_state->uapi.state;
>  	struct intel_crtc_state *pipe_config =
>  		intel_atomic_get_new_crtc_state(to_intel_atomic_state(state),
>  						crtc);
> @@ -5925,7 +5925,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>  
>  	intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
>  
> -	if (pipe_config->update_wm_post && pipe_config->base.active)
> +	if (pipe_config->update_wm_post && pipe_config->hw.active)
>  		intel_update_watermarks(crtc);
>  
>  	if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
> @@ -5955,10 +5955,10 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>  static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>  				   struct intel_crtc_state *pipe_config)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct drm_atomic_state *state = old_crtc_state->base.state;
> +	struct drm_atomic_state *state = old_crtc_state->uapi.state;
>  	struct drm_plane *primary = crtc->base.primary;
>  	struct drm_plane_state *old_primary_state =
>  		drm_atomic_get_old_plane_state(state, primary);
> @@ -6003,7 +6003,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>  	 * event which is after the vblank start event, so we need to have a
>  	 * wait-for-vblank between disabling the plane and the pipe.
>  	 */
> -	if (HAS_GMCH(dev_priv) && old_crtc_state->base.active &&
> +	if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&
>  	    pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
>  		intel_wait_for_vblank(dev_priv, crtc->pipe);
>  
> @@ -6015,7 +6015,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>  	 * WaCxSRDisabledForSpriteScaling:ivb
>  	 */
>  	if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev) &&
> -	    old_crtc_state->base.active)
> +	    old_crtc_state->hw.active)
>  		intel_wait_for_vblank(dev_priv, crtc->pipe);
>  
>  	/*
> @@ -6310,7 +6310,7 @@ static void intel_encoders_update_pipe(struct intel_crtc *crtc,
>  
>  static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
>  
>  	plane->disable_plane(plane, crtc_state);
> @@ -6319,7 +6319,7 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat
>  static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
>  				 struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -6453,7 +6453,7 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
>  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  				struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum pipe pipe = intel_crtc->pipe, hsw_workaround_pipe;
> @@ -6562,7 +6562,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  
>  static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -6578,7 +6578,7 @@ static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>  static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  				  struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -6637,7 +6637,7 @@ static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  				 struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
> @@ -6671,7 +6671,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  
>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!crtc_state->gmch_pfit.control)
> @@ -6801,14 +6801,14 @@ intel_aux_power_domain(struct intel_digital_port *dig_port)
>  
>  static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct drm_encoder *encoder;
>  	enum pipe pipe = crtc->pipe;
>  	u64 mask;
>  	enum transcoder transcoder = crtc_state->cpu_transcoder;
>  
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return 0;
>  
>  	mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
> @@ -6818,7 +6818,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>  		mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
>  
>  	drm_for_each_encoder_mask(encoder, &dev_priv->drm,
> -				  crtc_state->base.encoder_mask) {
> +				  crtc_state->uapi.encoder_mask) {
>  		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
>  
>  		mask |= BIT_ULL(intel_encoder->power_domain);
> @@ -6836,7 +6836,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>  static u64
>  modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum intel_display_power_domain domain;
>  	u64 domains, new_domains, old_domains;
> @@ -6865,7 +6865,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
>  static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
>  				   struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -6921,7 +6921,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
>  
>  static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	I915_WRITE(FP0(crtc->pipe), crtc_state->dpll_hw_state.fp0);
> @@ -6931,7 +6931,7 @@ static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
>  static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
>  			     struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -6981,7 +6981,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
>  
>  static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!old_crtc_state->gmch_pfit.control)
> @@ -6997,7 +6997,7 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>  static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  			      struct intel_atomic_state *state)
>  {
> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>  	struct drm_device *dev = crtc->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> @@ -7165,8 +7165,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>  		if (!crtc_state)
>  			return;
>  
> -		I915_STATE_WARN(!crtc_state->base.active,
> -		      "connector is active, but attached crtc isn't\n");
> +		I915_STATE_WARN(!crtc_state->hw.active,
> +				"connector is active, but attached crtc isn't\n");
>  
>  		if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
>  			return;
> @@ -7177,8 +7177,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>  		I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
>  			"attached encoder crtc differs from connector crtc\n");
>  	} else {
> -		I915_STATE_WARN(crtc_state && crtc_state->base.active,
> -			"attached crtc is active, but connector isn't\n");
> +		I915_STATE_WARN(crtc_state && crtc_state->hw.active,
> +				"attached crtc is active, but connector isn't\n");
>  		I915_STATE_WARN(!crtc_state && conn_state->best_encoder,
>  			"best encoder set without crtc!\n");
>  	}
> @@ -7186,7 +7186,7 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>  
>  static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
>  {
> -	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
> +	if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
>  		return crtc_state->fdi_lanes;
>  
>  	return 0;
> @@ -7196,7 +7196,7 @@ static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
>  				     struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct drm_atomic_state *state = pipe_config->base.state;
> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>  	struct intel_crtc *other_crtc;
>  	struct intel_crtc_state *other_crtc_state;
>  
> @@ -7269,7 +7269,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  				       struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_device *dev = intel_crtc->base.dev;
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int lane, link_bw, fdi_dotclock, ret;
>  	bool needs_recompute = false;
>  
> @@ -7315,7 +7315,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>  
>  bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	/* IPS only exists on ULT machines and is tied to pipe A. */
> @@ -7345,9 +7345,9 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
>  static bool hsw_compute_ips_config(struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv =
> -		to_i915(crtc_state->base.crtc->dev);
> +		to_i915(crtc_state->uapi.crtc->dev);
>  	struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  
>  	if (!hsw_crtc_state_ips_capable(crtc_state))
>  		return false;
> @@ -7386,7 +7386,7 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>  {
>  	u32 pixel_rate;
>  
> -	pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
> +	pixel_rate = pipe_config->hw.adjusted_mode.crtc_clock;
>  
>  	/*
>  	 * We only use IF-ID interlacing. If we ever use
> @@ -7419,12 +7419,12 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>  
>  static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	if (HAS_GMCH(dev_priv))
>  		/* FIXME calculate proper pipe pixel rate for GMCH pfit */
>  		crtc_state->pixel_rate =
> -			crtc_state->base.adjusted_mode.crtc_clock;
> +			crtc_state->hw.adjusted_mode.crtc_clock;
>  	else
>  		crtc_state->pixel_rate =
>  			ilk_pipe_pixel_rate(crtc_state);
> @@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  				     struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int clock_limit = dev_priv->max_dotclk_freq;
>  
>  	if (INTEL_GEN(dev_priv) < 4) {
> @@ -7460,7 +7460,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  
>  	if ((pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
>  	     pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) &&
> -	     pipe_config->base.ctm) {
> +	     pipe_config->hw.ctm) {
>  		/*
>  		 * There is only one pipe CSC unit per pipe, and we need that
>  		 * for output conversion from RGB->YCBCR. So if CTM is already
> @@ -7629,7 +7629,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
>  static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
>  					 const struct intel_link_m_n *m_n)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -7656,7 +7656,7 @@ static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_sta
>  					 const struct intel_link_m_n *m_n,
>  					 const struct intel_link_m_n *m2_n2)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder transcoder = crtc_state->cpu_transcoder;
> @@ -7969,7 +7969,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
>  	if (!pipe_config)
>  		return -ENOMEM;
>  
> -	pipe_config->base.crtc = &crtc->base;
> +	pipe_config->uapi.crtc = &crtc->base;
>  	pipe_config->pixel_multiplier = 1;
>  	pipe_config->dpll = *dpll;
>  
> @@ -8129,11 +8129,11 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc,
>  
>  static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>  	u32 crtc_vtotal, crtc_vblank_end;
>  	int vsyncshift = 0;
>  
> @@ -8191,7 +8191,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
>  
>  static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -8212,39 +8212,39 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
>  	u32 tmp;
>  
>  	tmp = I915_READ(HTOTAL(cpu_transcoder));
> -	pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
> -	pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
>  
>  	if (!transcoder_is_dsi(cpu_transcoder)) {
>  		tmp = I915_READ(HBLANK(cpu_transcoder));
> -		pipe_config->base.adjusted_mode.crtc_hblank_start =
> +		pipe_config->hw.adjusted_mode.crtc_hblank_start =
>  							(tmp & 0xffff) + 1;
> -		pipe_config->base.adjusted_mode.crtc_hblank_end =
> +		pipe_config->hw.adjusted_mode.crtc_hblank_end =
>  						((tmp >> 16) & 0xffff) + 1;
>  	}
>  	tmp = I915_READ(HSYNC(cpu_transcoder));
> -	pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
> -	pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
>  
>  	tmp = I915_READ(VTOTAL(cpu_transcoder));
> -	pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
> -	pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
>  
>  	if (!transcoder_is_dsi(cpu_transcoder)) {
>  		tmp = I915_READ(VBLANK(cpu_transcoder));
> -		pipe_config->base.adjusted_mode.crtc_vblank_start =
> +		pipe_config->hw.adjusted_mode.crtc_vblank_start =
>  							(tmp & 0xffff) + 1;
> -		pipe_config->base.adjusted_mode.crtc_vblank_end =
> +		pipe_config->hw.adjusted_mode.crtc_vblank_end =
>  						((tmp >> 16) & 0xffff) + 1;
>  	}
>  	tmp = I915_READ(VSYNC(cpu_transcoder));
> -	pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
> -	pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
> +	pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
>  
>  	if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
> -		pipe_config->base.adjusted_mode.crtc_vtotal += 1;
> -		pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
> +		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
> +		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
>  	}
>  }
>  
> @@ -8259,27 +8259,27 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
>  
> -	pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
> -	pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
> +	pipe_config->hw.mode.vdisplay = pipe_config->pipe_src_h;
> +	pipe_config->hw.mode.hdisplay = pipe_config->pipe_src_w;
>  }
>  
>  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>  				 struct intel_crtc_state *pipe_config)
>  {
> -	mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
> -	mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
> -	mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
> -	mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
> +	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
> +	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
> +	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
> +	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
>  
> -	mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
> -	mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
> -	mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
> -	mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
> +	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> +	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> +	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> +	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
>  
> -	mode->flags = pipe_config->base.adjusted_mode.flags;
> +	mode->flags = pipe_config->hw.adjusted_mode.flags;
>  	mode->type = DRM_MODE_TYPE_DRIVER;
>  
> -	mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
> +	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
>  
>  	mode->hsync = drm_mode_hsync(mode);
>  	mode->vrefresh = drm_mode_vrefresh(mode);
> @@ -8288,7 +8288,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>  
>  static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 pipeconf;
>  
> @@ -8325,7 +8325,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  		}
>  	}
>  
> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
>  		if (INTEL_GEN(dev_priv) < 4 ||
>  		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
>  			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
> @@ -8757,7 +8757,7 @@ static void intel_get_crtc_ycbcr_config(struct intel_crtc *crtc,
>  
>  static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> @@ -8880,7 +8880,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
>  	 * but in case the pipe is enabled w/o any ports we need a sane
>  	 * default.
>  	 */
> -	pipe_config->base.adjusted_mode.crtc_clock =
> +	pipe_config->hw.adjusted_mode.crtc_clock =
>  		pipe_config->port_clock / pipe_config->pixel_multiplier;
>  
>  	ret = true;
> @@ -9395,7 +9395,7 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
>  
>  static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
> @@ -9423,7 +9423,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  	if (crtc_state->dither)
>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>  
> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		val |= PIPECONF_INTERLACED_ILK;
>  	else
>  		val |= PIPECONF_PROGRESSIVE;
> @@ -9439,7 +9439,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  
>  static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	u32 val = 0;
> @@ -9447,7 +9447,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  	if (IS_HASWELL(dev_priv) && crtc_state->dither)
>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>  
> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		val |= PIPECONF_INTERLACED_ILK;
>  	else
>  		val |= PIPECONF_PROGRESSIVE;
> @@ -9458,7 +9458,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>  
>  static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 val = 0;
>  
> @@ -9644,7 +9644,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  	const struct intel_limit *limit;
>  	int refclk = 120000;
>  
> @@ -10060,7 +10060,7 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  
>  	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
>  	    INTEL_GEN(dev_priv) >= 11) {
> @@ -10608,7 +10608,7 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
>  	}
>  
>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
> -						  &crtc_state->base,
> +						  &crtc_state->uapi,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  true, true);
> @@ -10791,7 +10791,7 @@ i9xx_cursor_max_stride(struct intel_plane *plane,
>  
>  static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 cntl = 0;
>  
> @@ -11198,12 +11198,12 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
>  		goto fail;
>  	}
>  
> -	crtc_state->base.active = crtc_state->base.enable = true;
> +	crtc_state->uapi.active = crtc_state->uapi.enable = true;
>  
>  	if (!mode)
>  		mode = &load_detect_mode;
>  
> -	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
> +	ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi, mode);
>  	if (ret)
>  		goto fail;
>  
> @@ -11411,7 +11411,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
>  	 * we may need some idea for the dotclock anyway.
>  	 * Calculate one based on the FDI configuration.
>  	 */
> -	pipe_config->base.adjusted_mode.crtc_clock =
> +	pipe_config->hw.adjusted_mode.crtc_clock =
>  		intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
>  					 &pipe_config->fdi_m_n);
>  }
> @@ -11441,7 +11441,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
>  		return NULL;
>  	}
>  
> -	crtc_state->base.crtc = &crtc->base;
> +	crtc_state->uapi.crtc = &crtc->base;
>  
>  	if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) {
>  		kfree(crtc_state);
> @@ -11512,12 +11512,12 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
>  				    const struct intel_plane_state *old_plane_state,
>  				    struct intel_plane_state *plane_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	bool mode_changed = needs_modeset(crtc_state);
> -	bool was_crtc_enabled = old_crtc_state->base.active;
> -	bool is_crtc_enabled = crtc_state->base.active;
> +	bool was_crtc_enabled = old_crtc_state->hw.active;
> +	bool is_crtc_enabled = crtc_state->hw.active;
>  	bool turn_off, turn_on, visible, was_visible;
>  	struct drm_framebuffer *fb = plane_state->base.fb;
>  	int ret;
> @@ -11692,9 +11692,9 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
>  
>  static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
>  	struct intel_plane *plane, *linked;
>  	struct intel_plane_state *plane_state;
>  	int i;
> @@ -11764,9 +11764,9 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  
>  static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(new_crtc_state->base.state);
> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>  	const struct intel_crtc_state *old_crtc_state =
>  		intel_atomic_get_old_crtc_state(state, crtc);
>  
> @@ -11784,10 +11784,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  	bool mode_changed = needs_modeset(crtc_state);
>  
>  	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
> -	    mode_changed && !crtc_state->base.active)
> +	    mode_changed && !crtc_state->hw.active)
>  		crtc_state->update_wm_post = true;
>  
> -	if (mode_changed && crtc_state->base.enable &&
> +	if (mode_changed && crtc_state->hw.enable &&
>  	    dev_priv->display.crtc_compute_clock &&
>  	    !WARN_ON(crtc_state->shared_dpll)) {
>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
> @@ -11800,10 +11800,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  	 * when C8 planes are getting enabled/disabled.
>  	 */
>  	if (c8_planes_changed(crtc_state))
> -		crtc_state->base.color_mgmt_changed = true;
> +		crtc_state->uapi.color_mgmt_changed = true;
>  
>  	if (mode_changed || crtc_state->update_pipe ||
> -	    crtc_state->base.color_mgmt_changed) {
> +	    crtc_state->uapi.color_mgmt_changed) {
>  		ret = intel_color_check(crtc_state);
>  		if (ret)
>  			return ret;
> @@ -11925,7 +11925,7 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
>  			  struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct drm_atomic_state *state = pipe_config->base.state;
> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>  	struct drm_connector *connector;
>  	struct drm_connector_state *connector_state;
>  	int bpp, i;
> @@ -12078,7 +12078,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>  				   struct intel_atomic_state *state,
>  				   const char *context)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	const struct intel_plane_state *plane_state;
>  	struct intel_plane *plane;
> @@ -12087,14 +12087,14 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>  
>  	DRM_DEBUG_KMS("[CRTC:%d:%s] enable: %s %s\n",
>  		      crtc->base.base.id, crtc->base.name,
> -		      yesno(pipe_config->base.enable), context);
> +		      yesno(pipe_config->hw.enable), context);
>  
> -	if (!pipe_config->base.enable)
> +	if (!pipe_config->hw.enable)
>  		goto dump_planes;
>  
>  	snprintf_output_types(buf, sizeof(buf), pipe_config->output_types);
>  	DRM_DEBUG_KMS("active: %s, output_types: %s (0x%x), output format: %s\n",
> -		      yesno(pipe_config->base.active),
> +		      yesno(pipe_config->hw.active),
>  		      buf, pipe_config->output_types,
>  		      output_formats(pipe_config->output_format));
>  
> @@ -12134,10 +12134,10 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>  		intel_dump_infoframe(dev_priv, &pipe_config->infoframes.hdmi);
>  
>  	DRM_DEBUG_KMS("requested mode:\n");
> -	drm_mode_debug_printmodeline(&pipe_config->base.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
>  	DRM_DEBUG_KMS("adjusted mode:\n");
> -	drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
> -	intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
> +	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> +	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
>  	DRM_DEBUG_KMS("port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
>  		      pipe_config->port_clock,
>  		      pipe_config->pipe_src_w, pipe_config->pipe_src_h,
> @@ -12255,7 +12255,7 @@ static int
>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv =
> -		to_i915(crtc_state->base.crtc->dev);
> +		to_i915(crtc_state->uapi.crtc->dev);
>  	struct intel_crtc_state *saved_state;
>  
>  	saved_state = kzalloc(sizeof(*saved_state), GFP_KERNEL);
> @@ -12278,9 +12278,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  		saved_state->wm = crtc_state->wm;
>  
>  	/* Keep base drm_crtc_state intact, only clear our extended struct */
> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, base));
> -	memcpy(&crtc_state->base + 1, &saved_state->base + 1,
> -	       sizeof(*crtc_state) - sizeof(crtc_state->base));
> +	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
> +	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
> +	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
> +	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
>  
>  	kfree(saved_state);
>  	return 0;
> @@ -12289,8 +12290,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  static int
>  intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  {
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> -	struct drm_atomic_state *state = pipe_config->base.state;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>  	struct intel_encoder *encoder;
>  	struct drm_connector *connector;
>  	struct drm_connector_state *connector_state;
> @@ -12310,13 +12311,13 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * positive or negative polarity is requested, treat this as meaning
>  	 * negative polarity.
>  	 */
> -	if (!(pipe_config->base.adjusted_mode.flags &
> +	if (!(pipe_config->hw.adjusted_mode.flags &
>  	      (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
>  
> -	if (!(pipe_config->base.adjusted_mode.flags &
> +	if (!(pipe_config->hw.adjusted_mode.flags &
>  	      (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
>  
>  	ret = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
>  					pipe_config);
> @@ -12333,7 +12334,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * computation to clearly distinguish it from the adjusted mode, which
>  	 * can be changed by the connectors in the below retry loop.
>  	 */
> -	drm_mode_get_hv_timing(&pipe_config->base.mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -12366,7 +12367,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	pipe_config->pixel_multiplier = 1;
>  
>  	/* Fill in default crtc timings, allow encoders to overwrite them. */
> -	drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
> +	drm_mode_set_crtcinfo(&pipe_config->hw.adjusted_mode,
>  			      CRTC_STEREO_DOUBLE);
>  
>  	/* Pass our mode to the connectors and the CRTC to give them a chance to
> @@ -12391,7 +12392,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	/* Set default port clock if not overwritten by the encoder. Needs to be
>  	 * done afterwards in case the encoder adjusts the mode. */
>  	if (!pipe_config->port_clock)
> -		pipe_config->port_clock = pipe_config->base.adjusted_mode.crtc_clock
> +		pipe_config->port_clock = pipe_config->hw.adjusted_mode.crtc_clock
>  			* pipe_config->pixel_multiplier;
>  
>  	ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
> @@ -12555,12 +12556,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  			  const struct intel_crtc_state *pipe_config,
>  			  bool fastset)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(current_config->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
>  	bool ret = true;
>  	u32 bp_gamma = 0;
>  	bool fixup_inherited = fastset &&
> -		(current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> -		!(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED);
> +		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> +		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
>  
>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
> @@ -12749,19 +12750,19 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_X(output_types);
>  
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
>  
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
>  
>  	PIPE_CONF_CHECK_I(pixel_multiplier);
>  	PIPE_CONF_CHECK_I(output_format);
> @@ -12777,17 +12778,17 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> -	PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
> +	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>  			      DRM_MODE_FLAG_INTERLACE);
>  
>  	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>  				      DRM_MODE_FLAG_PHSYNC);
> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>  				      DRM_MODE_FLAG_NHSYNC);
> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>  				      DRM_MODE_FLAG_PVSYNC);
> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>  				      DRM_MODE_FLAG_NVSYNC);
>  	}
>  
> @@ -12826,7 +12827,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  		bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
>  		if (bp_gamma)
> -			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, base.gamma_lut, bp_gamma);
> +			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, uapi.gamma_lut, bp_gamma);
>  
>  	}
>  
> @@ -12871,7 +12872,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
>  		PIPE_CONF_CHECK_I(pipe_bpp);
>  
> -	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
> +	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
>  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>  
>  	PIPE_CONF_CHECK_I(min_voltage_level);
> @@ -12902,7 +12903,7 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
>  	if (pipe_config->has_pch_encoder) {
>  		int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
>  							    &pipe_config->fdi_m_n);
> -		int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
> +		int dotclock = pipe_config->hw.adjusted_mode.crtc_clock;
>  
>  		/*
>  		 * FDI already provided one idea for the dotclock.
> @@ -12930,7 +12931,7 @@ static void verify_wm_state(struct intel_crtc *crtc,
>  	const enum pipe pipe = crtc->pipe;
>  	int plane, level, max_level = ilk_wm_max_level(dev_priv);
>  
> -	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->base.active)
> +	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->hw.active)
>  		return;
>  
>  	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
> @@ -13139,12 +13140,12 @@ verify_crtc_state(struct intel_crtc *crtc,
>  	struct drm_atomic_state *state;
>  	bool active;
>  
> -	state = old_crtc_state->base.state;
> -	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->base);
> +	state = old_crtc_state->uapi.state;
> +	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>  	pipe_config = old_crtc_state;
>  	memset(pipe_config, 0, sizeof(*pipe_config));
> -	pipe_config->base.crtc = &crtc->base;
> -	pipe_config->base.state = state;
> +	pipe_config->uapi.crtc = &crtc->base;
> +	pipe_config->uapi.state = state;
>  
>  	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.base.id, crtc->base.name);
>  
> @@ -13152,23 +13153,26 @@ verify_crtc_state(struct intel_crtc *crtc,
>  
>  	/* we keep both pipes enabled on 830 */
>  	if (IS_I830(dev_priv))
> -		active = new_crtc_state->base.active;
> +		active = new_crtc_state->hw.active;
>  
> -	I915_STATE_WARN(new_crtc_state->base.active != active,
> -	     "crtc active state doesn't match with hw state "
> -	     "(expected %i, found %i)\n", new_crtc_state->base.active, active);
> +	I915_STATE_WARN(new_crtc_state->hw.active != active,
> +			"crtc active state doesn't match with hw state "
> +			"(expected %i, found %i)\n",
> +			new_crtc_state->hw.active, active);
>  
> -	I915_STATE_WARN(crtc->active != new_crtc_state->base.active,
> -	     "transitional active state does not match atomic hw state "
> -	     "(expected %i, found %i)\n", new_crtc_state->base.active, crtc->active);
> +	I915_STATE_WARN(crtc->active != new_crtc_state->hw.active,
> +			"transitional active state does not match atomic hw state "
> +			"(expected %i, found %i)\n",
> +			new_crtc_state->hw.active, crtc->active);
>  
>  	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
>  		enum pipe pipe;
>  
>  		active = encoder->get_hw_state(encoder, &pipe);
> -		I915_STATE_WARN(active != new_crtc_state->base.active,
> -			"[ENCODER:%i] active %i with crtc active %i\n",
> -			encoder->base.base.id, active, new_crtc_state->base.active);
> +		I915_STATE_WARN(active != new_crtc_state->hw.active,
> +				"[ENCODER:%i] active %i with crtc active %i\n",
> +				encoder->base.base.id, active,
> +				new_crtc_state->hw.active);
>  
>  		I915_STATE_WARN(active && crtc->pipe != pipe,
>  				"Encoder connected to wrong pipe %c\n",
> @@ -13180,7 +13184,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
>  
> -	if (!new_crtc_state->base.active)
> +	if (!new_crtc_state->hw.active)
>  		return;
>  
>  	intel_pipe_config_sanity_check(dev_priv, pipe_config);
> @@ -13242,7 +13246,7 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
>  
>  	crtc_mask = drm_crtc_mask(&crtc->base);
>  
> -	if (new_crtc_state->base.active)
> +	if (new_crtc_state->hw.active)
>  		I915_STATE_WARN(!(pll->active_mask & crtc_mask),
>  				"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
>  				pipe_name(drm_crtc_index(&crtc->base)), pll->active_mask);
> @@ -13320,7 +13324,7 @@ intel_modeset_verify_disabled(struct drm_i915_private *dev_priv,
>  
>  static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	/*
> @@ -13351,7 +13355,7 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
>  	 * answer that's slightly in the future.
>  	 */
>  	if (IS_GEN(dev_priv, 2)) {
> -		const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
> +		const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>  		int vtotal;
>  
>  		vtotal = adjusted_mode->crtc_vtotal;
> @@ -13401,7 +13405,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
>  
>  	/* look at all crtc's that are going to be enabled in during modeset */
>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
> -		if (!crtc_state->base.active ||
> +		if (!crtc_state->hw.active ||
>  		    !needs_modeset(crtc_state))
>  			continue;
>  
> @@ -13426,7 +13430,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
>  
>  		crtc_state->hsw_workaround_pipe = INVALID_PIPE;
>  
> -		if (!crtc_state->base.active ||
> +		if (!crtc_state->hw.active ||
>  		    needs_modeset(crtc_state))
>  			continue;
>  
> @@ -13469,12 +13473,12 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
>  
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
> -		if (new_crtc_state->base.active)
> +		if (new_crtc_state->hw.active)
>  			state->active_pipes |= BIT(crtc->pipe);
>  		else
>  			state->active_pipes &= ~BIT(crtc->pipe);
>  
> -		if (old_crtc_state->base.active != new_crtc_state->base.active)
> +		if (old_crtc_state->hw.active != new_crtc_state->hw.active)
>  			state->active_pipe_changes |= BIT(crtc->pipe);
>  	}
>  
> @@ -13513,7 +13517,7 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
>  	if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
>  		return;
>  
> -	new_crtc_state->base.mode_changed = false;
> +	new_crtc_state->uapi.mode_changed = false;
>  	new_crtc_state->update_pipe = true;
>  
>  	/*
> @@ -13548,9 +13552,9 @@ static int intel_atomic_check(struct drm_device *dev,
>  	/* Catch I915_MODE_FLAG_INHERITED */
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
> -		if (new_crtc_state->base.mode.private_flags !=
> -		    old_crtc_state->base.mode.private_flags)
> -			new_crtc_state->base.mode_changed = true;
> +		if (new_crtc_state->hw.mode.private_flags !=
> +		    old_crtc_state->hw.mode.private_flags)
> +			new_crtc_state->uapi.mode_changed = true;
>  	}
>  
>  	ret = drm_atomic_helper_check_modeset(dev, &state->base);
> @@ -13562,7 +13566,7 @@ static int intel_atomic_check(struct drm_device *dev,
>  		if (!needs_modeset(new_crtc_state))
>  			continue;
>  
> -		if (!new_crtc_state->base.enable) {
> +		if (!new_crtc_state->uapi.enable) {
>  			any_ms = true;
>  			continue;
>  		}
> @@ -13719,11 +13723,10 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>  	intel_check_pch_fifo_underruns(dev_priv);
>  
>  	/* FIXME unify this for all platforms */
> -	if (!new_crtc_state->base.active &&
> +	if (!new_crtc_state->hw.active &&
>  	    !HAS_GMCH(dev_priv) &&
>  	    dev_priv->display.initial_watermarks)
> -		dev_priv->display.initial_watermarks(state,
> -						     new_crtc_state);
> +		dev_priv->display.initial_watermarks(state, new_crtc_state);
>  }
>  
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> @@ -13746,7 +13749,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>  
> -		if (old_crtc_state->base.active)
> +		if (old_crtc_state->hw.active)
>  			intel_old_crtc_state_disables(state,
>  						      old_crtc_state,
>  						      new_crtc_state,
> @@ -13761,7 +13764,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
>  	int i;
>  
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> -		if (!new_crtc_state->base.active)
> +		if (!new_crtc_state->hw.active)
>  			continue;
>  
>  		intel_update_crtc(crtc, state, old_crtc_state,
> @@ -13784,7 +13787,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
>  		/* ignore allocations for crtc's that have been turned off. */
> -		if (new_crtc_state->base.active)
> +		if (new_crtc_state->hw.active)
>  			entries[i] = old_crtc_state->wm.skl.ddb;
>  
>  	/* If 2nd DBuf slice required, enable it here */
> @@ -13806,7 +13809,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  
>  			pipe = crtc->pipe;
>  
> -			if (updated & cmask || !new_crtc_state->base.active)
> +			if (updated & cmask || !new_crtc_state->hw.active)
>  				continue;
>  
>  			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> @@ -13825,7 +13828,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  			 */
>  			if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
>  						 &old_crtc_state->wm.skl.ddb) &&
> -			    !new_crtc_state->base.active_changed &&
> +			    !new_crtc_state->uapi.active_changed &&
>  			    state->wm_results.dirty_pipes != updated)
>  				vbl_wait = true;
>  
> @@ -13958,12 +13961,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  		bool modeset = needs_modeset(new_crtc_state);
>  
>  		/* Complete events for now disable pipes here. */
> -		if (modeset && !new_crtc_state->base.active && new_crtc_state->base.event) {
> +		if (modeset && !new_crtc_state->hw.active && new_crtc_state->uapi.event) {
>  			spin_lock_irq(&dev->event_lock);
> -			drm_crtc_send_vblank_event(&crtc->base, new_crtc_state->base.event);
> +			drm_crtc_send_vblank_event(&crtc->base,
> +						   new_crtc_state->uapi.event);
>  			spin_unlock_irq(&dev->event_lock);
>  
> -			new_crtc_state->base.event = NULL;
> +			new_crtc_state->uapi.event = NULL;
>  		}
>  	}
>  
> @@ -13994,9 +13998,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>  	drm_atomic_helper_wait_for_flip_done(dev, &state->base);
>  
>  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> -		if (new_crtc_state->base.active &&
> +		if (new_crtc_state->hw.active &&
>  		    !needs_modeset(new_crtc_state) &&
> -		    (new_crtc_state->base.color_mgmt_changed ||
> +		    (new_crtc_state->uapi.color_mgmt_changed ||
>  		     new_crtc_state->update_pipe))
>  			intel_color_load_luts(new_crtc_state);
>  	}
> @@ -14451,16 +14455,16 @@ int
>  skl_max_scale(const struct intel_crtc_state *crtc_state,
>  	      const struct drm_format_info *format)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	int max_scale;
>  	int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
>  
> -	if (!crtc_state->base.enable)
> +	if (!crtc_state->hw.enable)
>  		return DRM_PLANE_HELPER_NO_SCALING;
>  
> -	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> -	max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
> +	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
> +	max_dotclk = to_intel_atomic_state(crtc_state->uapi.state)->cdclk.logical.cdclk;
>  
>  	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
>  		max_dotclk *= 2;
> @@ -14501,7 +14505,7 @@ static void intel_begin_crtc_commit(struct intel_atomic_state *state,
>  	if (modeset)
>  		goto out;
>  
> -	if (new_crtc_state->base.color_mgmt_changed ||
> +	if (new_crtc_state->uapi.color_mgmt_changed ||
>  	    new_crtc_state->update_pipe)
>  		intel_color_commit(new_crtc_state);
>  
> @@ -14547,7 +14551,7 @@ static void intel_finish_crtc_commit(struct intel_atomic_state *state,
>  
>  	if (new_crtc_state->update_pipe &&
>  	    !needs_modeset(new_crtc_state) &&
> -	    old_crtc_state->base.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -14659,7 +14663,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>  	 * When crtc is inactive or there is a modeset pending,
>  	 * wait for it to complete in the slowpath
>  	 */
> -	if (!crtc_state->base.active || needs_modeset(crtc_state) ||
> +	if (!crtc_state->hw.active || needs_modeset(crtc_state) ||
>  	    crtc_state->update_pipe)
>  		goto slow;
>  
> @@ -14753,7 +14757,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>  out_free:
>  	if (new_crtc_state)
> -		intel_crtc_destroy_state(crtc, &new_crtc_state->base);
> +		intel_crtc_destroy_state(crtc, &new_crtc_state->uapi);
>  	if (ret)
>  		intel_plane_destroy_state(plane, new_plane_state);
>  	else
> @@ -15079,7 +15083,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
>  		ret = -ENOMEM;
>  		goto fail;
>  	}
> -	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->base);
> +	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->uapi);
>  	intel_crtc->config = crtc_state;
>  
>  	primary = intel_primary_plane_create(dev_priv, pipe);
> @@ -16455,7 +16459,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>  			   I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
>  	}
>  
> -	if (crtc_state->base.active) {
> +	if (crtc_state->hw.active) {
>  		struct intel_plane *plane;
>  
>  		/* Disable everything but the primary plane */
> @@ -16480,10 +16484,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>  
>  	/* Adjust the state of the output pipe according to whether we
>  	 * have active connectors/encoders. */
> -	if (crtc_state->base.active && !intel_crtc_has_encoders(crtc))
> +	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc))
>  		intel_crtc_disable_noatomic(&crtc->base, ctx);
>  
> -	if (crtc_state->base.active || HAS_GMCH(dev_priv)) {
> +	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
>  		/*
>  		 * We start out with underrun reporting disabled to avoid races.
>  		 * For correct bookkeeping mark this on active crtcs.
> @@ -16514,7 +16518,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>  
>  static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	/*
>  	 * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram
> @@ -16527,7 +16531,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
>  	 * road.
>  	 */
>  	return IS_GEN(dev_priv, 6) &&
> -		crtc_state->base.active &&
> +		crtc_state->hw.active &&
>  		crtc_state->shared_dpll &&
>  		crtc_state->port_clock == 0;
>  }
> @@ -16544,7 +16548,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
>  	 * encoder is active and trying to read from a pipe) and the
>  	 * pipe itself being active. */
>  	bool has_active_crtc = crtc_state &&
> -		crtc_state->base.active;
> +		crtc_state->hw.active;
>  
>  	if (crtc_state && has_bogus_dpll_config(crtc_state)) {
>  		DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n",
> @@ -16681,22 +16685,22 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		struct intel_crtc_state *crtc_state =
>  			to_intel_crtc_state(crtc->base.state);
>  
> -		__drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
> +		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>  		memset(crtc_state, 0, sizeof(*crtc_state));
> -		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->base);
> +		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>  
> -		crtc_state->base.active = crtc_state->base.enable =
> +		crtc_state->hw.active = crtc_state->hw.enable =
>  			dev_priv->display.get_pipe_config(crtc, crtc_state);
>  
> -		crtc->base.enabled = crtc_state->base.enable;
> -		crtc->active = crtc_state->base.active;
> +		crtc->base.enabled = crtc_state->hw.enable;
> +		crtc->active = crtc_state->hw.active;
>  
> -		if (crtc_state->base.active)
> +		if (crtc_state->hw.active)
>  			dev_priv->active_pipes |= BIT(crtc->pipe);
>  
>  		DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
>  			      crtc->base.base.id, crtc->base.name,
> -			      enableddisabled(crtc_state->base.active));
> +			      enableddisabled(crtc_state->hw.active));
>  	}
>  
>  	readout_plane_state(dev_priv);
> @@ -16718,7 +16722,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			struct intel_crtc_state *crtc_state =
>  				to_intel_crtc_state(crtc->base.state);
>  
> -			if (crtc_state->base.active &&
> +			if (crtc_state->hw.active &&
>  			    crtc_state->shared_dpll == pll)
>  				pll->state.crtc_mask |= 1 << crtc->pipe;
>  		}
> @@ -16752,21 +16756,24 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  	drm_connector_list_iter_begin(dev, &conn_iter);
>  	for_each_intel_connector_iter(connector, &conn_iter) {
>  		if (connector->get_hw_state(connector)) {
> -			connector->base.dpms = DRM_MODE_DPMS_ON;
> +			struct intel_crtc_state *crtc_state = NULL;
>  
> +			connector->base.dpms = DRM_MODE_DPMS_ON;
>  			encoder = connector->encoder;
>  			connector->base.encoder = &encoder->base;
>  
> -			if (encoder->base.crtc &&
> -			    encoder->base.crtc->state->active) {
> +			if (encoder->base.crtc)
> +				crtc_state = to_intel_crtc_state(encoder->base.crtc->state);
> +
> +			if (crtc_state && crtc_state->hw.active) {
>  				/*
>  				 * This has to be done during hardware readout
>  				 * because anything calling .crtc_disable may
>  				 * rely on the connector_mask being accurate.
>  				 */
> -				encoder->base.crtc->state->connector_mask |=
> +				crtc_state->uapi.connector_mask |=
>  					drm_connector_mask(&connector->base);
> -				encoder->base.crtc->state->encoder_mask |=
> +				crtc_state->uapi.encoder_mask |=
>  					drm_encoder_mask(&encoder->base);
>  			}
>  
> @@ -16789,11 +16796,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		int min_cdclk = 0;
>  
>  		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
> -		if (crtc_state->base.active) {
> +		if (crtc_state->hw.active) {
>  			intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
>  			crtc->base.mode.hdisplay = crtc_state->pipe_src_w;
>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
> -			intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state);
> +			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
> +						    crtc_state);
>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>  
>  			/*
> @@ -16805,7 +16813,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			 * set a flag to indicate that a full recalculation is
>  			 * needed on the next commit.
>  			 */
> -			crtc_state->base.mode.private_flags = I915_MODE_FLAG_INHERITED;
> +			crtc_state->hw.mode.private_flags = I915_MODE_FLAG_INHERITED;
>  
>  			intel_crtc_compute_pixel_rate(crtc_state);
>  
> @@ -16816,7 +16824,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			}
>  
>  			drm_calc_timestamping_constants(&crtc->base,
> -							&crtc_state->base.adjusted_mode);
> +							&crtc_state->hw.adjusted_mode);
>  			update_scanline_offset(crtc_state);
>  		}
>  
> @@ -16987,7 +16995,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
>  
>  		drm_crtc_vblank_reset(&crtc->base);
>  
> -		if (crtc_state->base.active)
> +		if (crtc_state->hw.active)
>  			intel_crtc_vblank_on(crtc_state);
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index d5cc4b810d9e..2c3567081e16 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -749,7 +749,31 @@ enum intel_output_format {
>  };
>  
>  struct intel_crtc_state {
> -	struct drm_crtc_state base;
> +	union {
> +	/*
> +	 * uapi (drm) state. This is the software state shown to userspace.
> +	 * In particular, the following members are used for bookkeeping:
> +	 * - crtc
> +	 * - state
> +	 * - *_changed
> +	 * - event
> +	 * - commit
> +	 * - mode_blob
> +	 */
> +	struct drm_crtc_state uapi;
> +
> +	/*
> +	 * actual hardware state, the state we program to the hardware.
> +	 * The following members are used to verify the hardware state:
> +	 * - enable
> +	 * - active
> +	 * - mode / adjusted_mode
> +	 * - color property blobs.
> +	 *
> +	 * During initial hw readout, they need to be copied to uapi.
> +	 */
> +	struct drm_crtc_state hw;
> +	};
>  
>  	/**
>  	 * quirks - bitfield with hw state readout quirks
> @@ -1091,7 +1115,7 @@ struct cxsr_latency {
>  
>  #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
>  #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
> -#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
> +#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, uapi)
>  #define to_intel_connector(x) container_of(x, struct intel_connector, base)
>  #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
>  #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 02242a16640b..2fceb71f7f70 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1966,7 +1966,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
>  				  struct intel_crtc_state *pipe_config,
>  				  const struct link_config_limits *limits)
>  {
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int bpp, clock, lane_count;
>  	int mode_rate, link_clock, link_avail;
>  
> @@ -2020,7 +2020,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	u8 dsc_max_bpc;
>  	int pipe_bpp;
>  	int ret;
> @@ -2131,7 +2131,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
>  			     struct intel_crtc_state *pipe_config,
>  			     struct drm_connector_state *conn_state)
>  {
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct link_config_limits limits;
>  	int common_len;
> @@ -2219,8 +2219,8 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
>  {
>  	const struct drm_display_info *info = &connector->display_info;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +		&crtc_state->hw.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	int ret;
>  
>  	if (!drm_mode_is_420_only(info, adjusted_mode) ||
> @@ -2248,7 +2248,7 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
>  	const struct intel_digital_connector_state *intel_conn_state =
>  		to_intel_digital_connector_state(conn_state);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  
>  	if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
>  		/*
> @@ -2271,11 +2271,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>  			struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base);
>  	enum port port = encoder->port;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
>  	struct intel_digital_connector_state *intel_conn_state =
>  		to_intel_digital_connector_state(conn_state);
> @@ -2395,8 +2395,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	enum port port = encoder->port;
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  
>  	intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
>  				 pipe_config->lane_count,
> @@ -2993,7 +2993,7 @@ static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
>  static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
>  				const struct intel_crtc_state *pipe_config)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	assert_pipe_disabled(dev_priv, crtc->pipe);
> @@ -3033,7 +3033,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
>  static void ironlake_edp_pll_off(struct intel_dp *intel_dp,
>  				 const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	assert_pipe_disabled(dev_priv, crtc->pipe);
> @@ -3193,7 +3193,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	u32 tmp, flags = 0;
>  	enum port port = encoder->port;
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  
>  	if (encoder->type == INTEL_OUTPUT_EDP)
>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
> @@ -3228,7 +3228,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>  			flags |= DRM_MODE_FLAG_NVSYNC;
>  	}
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
>  	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
>  		pipe_config->limited_color_range = true;
> @@ -3245,7 +3245,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>  			pipe_config->port_clock = 270000;
>  	}
>  
> -	pipe_config->base.adjusted_mode.crtc_clock =
> +	pipe_config->hw.adjusted_mode.crtc_clock =
>  		intel_dotclock_calculate(pipe_config->port_clock,
>  					 &pipe_config->dp_m_n);
>  
> @@ -3460,7 +3460,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	u32 dp_reg = I915_READ(intel_dp->output_reg);
>  	enum pipe pipe = crtc->pipe;
>  	intel_wakeref_t wakeref;
> @@ -3593,7 +3593,7 @@ static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	lockdep_assert_held(&dev_priv->pps_mutex);
>  
> @@ -4115,7 +4115,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	enum port port = encoder->port;
>  	u32 DP = intel_dp->DP;
>  
> @@ -4876,7 +4876,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
>  
>  	WARN_ON(!intel_crtc_has_dp_encoder(crtc_state));
>  
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return 0;
>  
>  	if (conn_state->commit &&
> @@ -6695,7 +6695,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
>  				    int refresh_rate)
>  {
>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
>  
>  	if (refresh_rate <= 0) {
> @@ -6728,7 +6728,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
>  		return;
>  	}
>  
> -	if (!crtc_state->base.active) {
> +	if (!crtc_state->hw.active) {
>  		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
>  		return;
>  	}
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index eeeb3f933aa4..76f066b1dfe5 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -42,13 +42,13 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>  					    struct drm_connector_state *conn_state,
>  					    struct link_config_limits *limits)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>  	struct intel_dp *intel_dp = &intel_mst->primary->dp;
>  	struct intel_connector *connector =
>  		to_intel_connector(conn_state->connector);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	void *port = connector->port;
>  	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
>  					   DP_DPCD_QUIRK_CONSTANT_N);
> @@ -99,7 +99,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>  	struct intel_digital_connector_state *intel_conn_state =
>  		to_intel_digital_connector_state(conn_state);
>  	const struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  	void *port = connector->port;
>  	struct link_config_limits limits;
>  	int ret;
> diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
> index 556d1b30f06a..704f38681c4b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
> +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
> @@ -739,7 +739,7 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
>  
> @@ -783,7 +783,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  	unsigned int lane_mask =
> @@ -864,7 +864,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  	int data, i, stagger;
> @@ -953,7 +953,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
>  			      const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
>  	u32 val;
>  
>  	vlv_dpio_get(dev_priv);
> @@ -1016,7 +1016,7 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -1046,7 +1046,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>  	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  	u32 val;
> @@ -1075,7 +1075,7 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
>  {
>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>  	enum pipe pipe = crtc->pipe;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> index 98288edf88f0..43c12bcfe3b2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
> @@ -136,7 +136,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>   */
>  void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>  
> @@ -163,7 +163,7 @@ void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
>   */
>  void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>  	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
> @@ -208,7 +208,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
>   */
>  void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>  	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
> @@ -825,7 +825,7 @@ hsw_ddi_hdmi_get_dpll(struct intel_atomic_state *state,
>  static struct intel_shared_dpll *
>  hsw_ddi_dp_get_dpll(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	struct intel_shared_dpll *pll;
>  	enum intel_dpll_id pll_id;
>  	int clock = crtc_state->port_clock;
> @@ -1734,7 +1734,7 @@ static bool
>  bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
>  			  struct bxt_clk_div *clk_div)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct dpll best_clock;
>  
>  	/* Calculate HDMI div */
> @@ -2257,7 +2257,7 @@ static bool
>  cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
>  			struct skl_wrpll_params *wrpll_params)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	u32 afe_clock = crtc_state->port_clock * 5;
>  	u32 ref_clock;
>  	u32 dco_min = 7998000;
> @@ -2523,7 +2523,7 @@ static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = {
>  static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
>  				  struct skl_wrpll_params *pll_params)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	const struct icl_combo_pll_params *params =
>  		dev_priv->cdclk.hw.ref == 24000 ?
>  		icl_dp_combo_pll_24MHz_values :
> @@ -2545,7 +2545,7 @@ static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
>  static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
>  			     struct skl_wrpll_params *pll_params)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	*pll_params = dev_priv->cdclk.hw.ref == 24000 ?
>  			icl_tbt_pll_24MHz_values : icl_tbt_pll_19_2MHz_values;
> @@ -2556,7 +2556,7 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
>  				struct intel_encoder *encoder,
>  				struct intel_dpll_hw_state *pll_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	u32 cfgcr0, cfgcr1;
>  	struct skl_wrpll_params pll_params = { 0 };
>  	bool ret;
> @@ -2682,7 +2682,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
>  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
>  				  struct intel_dpll_hw_state *pll_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	int refclk_khz = dev_priv->cdclk.hw.ref;
>  	int clock = crtc_state->port_clock;
>  	u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
> index 34193d04597a..af0149e32bf4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -178,9 +178,9 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
>  	else
>  		flags |= DRM_MODE_FLAG_NVSYNC;
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>  }
>  
>  static void intel_disable_dvo(struct intel_encoder *encoder,
> @@ -207,8 +207,8 @@ static void intel_enable_dvo(struct intel_encoder *encoder,
>  	u32 temp = I915_READ(dvo_reg);
>  
>  	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
> -					 &pipe_config->base.mode,
> -					 &pipe_config->base.adjusted_mode);
> +					 &pipe_config->hw.mode,
> +					 &pipe_config->hw.adjusted_mode);
>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
>  	I915_READ(dvo_reg);
> @@ -253,7 +253,7 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder,
>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
>  	const struct drm_display_mode *fixed_mode =
>  		intel_dvo->attached_connector->panel.fixed_mode;
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  
>  	/*
>  	 * If we have timings from the BIOS for the panel, put them in
> @@ -277,8 +277,8 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder,
>  				 const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
>  	enum pipe pipe = crtc->pipe;
>  	u32 dvo_val;
> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
> index 3111ecaeabd0..c6cc3775f3b8 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
> @@ -667,7 +667,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
>  	cache->vma = NULL;
>  	cache->flags = 0;
>  
> -	cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
> +	cache->crtc.mode_flags = crtc_state->hw.adjusted_mode.flags;
>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
>  		cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index 14e350f5ecc8..e1dbf641be79 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -279,7 +279,7 @@ static void ibx_write_infoframe(struct intel_encoder *encoder,
>  {
>  	const u32 *data = frame;
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>  	u32 val = I915_READ(reg);
>  	int i;
> @@ -315,7 +315,7 @@ static void ibx_read_infoframe(struct intel_encoder *encoder,
>  			       void *frame, ssize_t len)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	u32 val, *data = frame;
>  	int i;
>  
> @@ -334,7 +334,7 @@ static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>  	i915_reg_t reg = TVIDEO_DIP_CTL(pipe);
>  	u32 val = I915_READ(reg);
>  
> @@ -356,7 +356,7 @@ static void cpt_write_infoframe(struct intel_encoder *encoder,
>  {
>  	const u32 *data = frame;
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>  	u32 val = I915_READ(reg);
>  	int i;
> @@ -395,7 +395,7 @@ static void cpt_read_infoframe(struct intel_encoder *encoder,
>  			       void *frame, ssize_t len)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	u32 val, *data = frame;
>  	int i;
>  
> @@ -414,7 +414,7 @@ static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>  	u32 val = I915_READ(TVIDEO_DIP_CTL(pipe));
>  
>  	if ((val & VIDEO_DIP_ENABLE) == 0)
> @@ -432,7 +432,7 @@ static void vlv_write_infoframe(struct intel_encoder *encoder,
>  {
>  	const u32 *data = frame;
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
>  	u32 val = I915_READ(reg);
>  	int i;
> @@ -468,7 +468,7 @@ static void vlv_read_infoframe(struct intel_encoder *encoder,
>  			       void *frame, ssize_t len)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	u32 val, *data = frame;
>  	int i;
>  
> @@ -487,7 +487,7 @@ static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>  	u32 val = I915_READ(VLV_TVIDEO_DIP_CTL(pipe));
>  
>  	if ((val & VIDEO_DIP_ENABLE) == 0)
> @@ -700,7 +700,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
>  {
>  	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	struct drm_connector *connector = conn_state->connector;
>  	int ret;
>  
> @@ -787,7 +787,7 @@ intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
>  
>  	ret = drm_hdmi_vendor_infoframe_from_display_mode(frame,
>  							  conn_state->connector,
> -							  &crtc_state->base.adjusted_mode);
> +							  &crtc_state->hw.adjusted_mode);
>  	if (WARN_ON(ret))
>  		return false;
>  
> @@ -948,7 +948,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
>  					 const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	i915_reg_t reg;
>  
>  	if ((crtc_state->infoframes.enable &
> @@ -973,7 +973,7 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
>  				   struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	i915_reg_t reg;
>  
>  	if ((crtc_state->infoframes.enable &
> @@ -1010,7 +1010,7 @@ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
>  
>  	/* Enable default_phase whenever the display mode is suitably aligned */
>  	if (gcp_default_phase_possible(crtc_state->pipe_bpp,
> -				       &crtc_state->base.adjusted_mode))
> +				       &crtc_state->hw.adjusted_mode))
>  		crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE;
>  }
>  
> @@ -1020,7 +1020,7 @@ static void ibx_set_infoframes(struct intel_encoder *encoder,
>  			       const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
>  	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
> @@ -1079,7 +1079,7 @@ static void cpt_set_infoframes(struct intel_encoder *encoder,
>  			       const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>  	u32 val = I915_READ(reg);
> @@ -1128,7 +1128,7 @@ static void vlv_set_infoframes(struct intel_encoder *encoder,
>  			       const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
>  	u32 val = I915_READ(reg);
> @@ -1724,9 +1724,9 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>  	u32 hdmi_val;
>  
>  	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
> @@ -1817,7 +1817,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
>  	    tmp & HDMI_COLOR_RANGE_16_235)
>  		pipe_config->limited_color_range = true;
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
>  	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
>  		dotclock = pipe_config->port_clock * 2 / 3;
> @@ -1827,7 +1827,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>  
>  	pipe_config->lane_count = 4;
>  
> @@ -1848,7 +1848,7 @@ static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
>  				    const struct intel_crtc_state *pipe_config,
>  				    const struct drm_connector_state *conn_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  
>  	WARN_ON(!pipe_config->has_hdmi_sink);
>  	DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
> @@ -1934,7 +1934,7 @@ static void cpt_enable_hdmi(struct intel_encoder *encoder,
>  {
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	enum pipe pipe = crtc->pipe;
>  	u32 temp;
> @@ -1998,7 +1998,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	struct intel_digital_port *intel_dig_port =
>  		hdmi_to_dig_port(intel_hdmi);
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	u32 temp;
>  
>  	temp = I915_READ(intel_hdmi->hdmi_reg);
> @@ -2198,12 +2198,12 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
>  				     int bpc)
>  {
>  	struct drm_i915_private *dev_priv =
> -		to_i915(crtc_state->base.crtc->dev);
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +		to_i915(crtc_state->uapi.crtc->dev);
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct drm_connector_state *connector_state;
>  	struct drm_connector *connector;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	int i;
>  
>  	if (HAS_GMCH(dev_priv))
> @@ -2228,7 +2228,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
>  	for_each_new_connector_in_state(state, connector, connector_state, i) {
>  		const struct drm_display_info *info = &connector->display_info;
>  
> -		if (connector_state->crtc != crtc_state->base.crtc)
> +		if (connector_state->crtc != crtc_state->uapi.crtc)
>  			continue;
>  
>  		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
> @@ -2269,7 +2269,7 @@ static bool
>  intel_hdmi_ycbcr420_config(struct drm_connector *connector,
>  			   struct intel_crtc_state *config)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(config->uapi.crtc);
>  
>  	if (!connector->ycbcr_420_allowed) {
>  		DRM_ERROR("Platform doesn't support YCBCR420 output\n");
> @@ -2324,7 +2324,7 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
>  {
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	int bpc, clock = adjusted_mode->crtc_clock;
>  
>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
> @@ -2366,7 +2366,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
>  {
>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	struct drm_connector *connector = conn_state->connector;
>  	struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
>  	struct intel_digital_connector_state *intel_conn_state =
> diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
> index f8f1308643a9..5145ff8b962b 100644
> --- a/drivers/gpu/drm/i915/display/intel_lspcon.c
> +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
> @@ -189,7 +189,7 @@ void lspcon_ycbcr420_config(struct drm_connector *connector,
>  {
>  	const struct drm_display_info *info = &connector->display_info;
>  	const struct drm_display_mode *adjusted_mode =
> -					&crtc_state->base.adjusted_mode;
> +					&crtc_state->hw.adjusted_mode;
>  
>  	if (drm_mode_is_420_only(info, adjusted_mode) &&
>  	    connector->ycbcr_420_allowed) {
> @@ -475,7 +475,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
>  	struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
>  	struct intel_lspcon *lspcon = &dig_port->lspcon;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  
>  	if (!lspcon->active) {
>  		DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
> index c786abdc3336..0f77e5a8b7ff 100644
> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
> @@ -135,7 +135,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
>  	else
>  		flags |= DRM_MODE_FLAG_PVSYNC;
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
>  	if (INTEL_GEN(dev_priv) < 5)
>  		pipe_config->gmch_pfit.lvds_border_bits =
> @@ -148,7 +148,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
>  		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
>  	}
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>  }
>  
>  static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
> @@ -230,8 +230,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
>  {
>  	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	enum pipe pipe = crtc->pipe;
>  	u32 temp;
>  
> @@ -392,8 +392,8 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
>  		to_lvds_encoder(&intel_encoder->base);
>  	struct intel_connector *intel_connector =
>  		lvds_encoder->attached_connector;
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	unsigned int lvds_bpp;
>  
>  	/* Should never happen!! */
> diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
> index bc14e9c0285a..6f3eaae3761f 100644
> --- a/drivers/gpu/drm/i915/display/intel_panel.c
> +++ b/drivers/gpu/drm/i915/display/intel_panel.c
> @@ -178,7 +178,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
>  			struct intel_crtc_state *pipe_config,
>  			int fitting_mode)
>  {
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int x = 0, y = 0, width = 0, height = 0;
>  
>  	/* Native modes don't need fitting */
> @@ -300,7 +300,7 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
>  static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
>  			      u32 *pfit_control)
>  {
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	u32 scaled_width = adjusted_mode->crtc_hdisplay *
>  		pipe_config->pipe_src_h;
>  	u32 scaled_height = pipe_config->pipe_src_w *
> @@ -321,7 +321,7 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
>  			      u32 *pfit_control, u32 *pfit_pgm_ratios,
>  			      u32 *border)
>  {
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	u32 scaled_width = adjusted_mode->crtc_hdisplay *
>  		pipe_config->pipe_src_h;
>  	u32 scaled_height = pipe_config->pipe_src_w *
> @@ -380,7 +380,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>  	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  
>  	/* Native modes don't need fitting */
>  	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
> @@ -1047,7 +1047,7 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>  	u32 ctl, ctl2;
>  
>  	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
> @@ -1077,7 +1077,7 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>  	u32 pwm_ctl, val;
>  
>  	/* Controller 1 uses the utility pin. */
> @@ -1189,7 +1189,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>  	struct intel_panel *panel = &connector->panel;
> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>  
>  	if (!panel->backlight.present)
>  		return;
> diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> index 6260a2082719..2746512f4466 100644
> --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
> @@ -309,13 +309,13 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
>  		goto put_state;
>  	}
>  
> -	pipe_config->base.mode_changed = pipe_config->has_psr;
> +	pipe_config->uapi.mode_changed = pipe_config->has_psr;
>  	pipe_config->crc_enabled = enable;
>  
>  	if (IS_HASWELL(dev_priv) &&
> -	    pipe_config->base.active && crtc->pipe == PIPE_A &&
> +	    pipe_config->hw.active && crtc->pipe == PIPE_A &&
>  	    pipe_config->cpu_transcoder == TRANSCODER_EDP)
> -		pipe_config->base.mode_changed = true;
> +		pipe_config->uapi.mode_changed = true;
>  
>  	ret = drm_atomic_commit(state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index b3c7eef53bf3..8988dbe8c19e 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -538,8 +538,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>  				    struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -	int crtc_hdisplay = crtc_state->base.adjusted_mode.crtc_hdisplay;
> -	int crtc_vdisplay = crtc_state->base.adjusted_mode.crtc_vdisplay;
> +	int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
> +	int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
>  	int psr_max_h = 0, psr_max_v = 0;
>  
>  	if (!dev_priv->psr.sink_psr2_support)
> @@ -605,7 +605,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	int psr_setup_time;
>  
>  	if (!CAN_PSR(dev_priv))
> @@ -745,7 +745,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
>  
>  	dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state);
>  	dev_priv->psr.busy_frontbuffer_bits = 0;
> -	dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
> +	dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>  	dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
>  
>  	/*
> @@ -988,7 +988,7 @@ void intel_psr_update(struct intel_dp *intel_dp,
>  int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
>  			    u32 *out_value)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  
>  	if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index adeb1c840976..f74c528d5d68 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1087,7 +1087,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo,
>  {
>  	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	int ret;
>  
>  	if (!crtc_state->has_hdmi_sink)
> @@ -1276,8 +1276,8 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  		to_intel_sdvo_connector_state(conn_state);
>  	struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> -	struct drm_display_mode *mode = &pipe_config->base.mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
> +	struct drm_display_mode *mode = &pipe_config->hw.mode;
>  
>  	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
>  	pipe_config->pipe_bpp = 8*3;
> @@ -1429,13 +1429,13 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  				  const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>  	const struct intel_sdvo_connector_state *sdvo_state =
>  		to_intel_sdvo_connector_state(conn_state);
>  	const struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
> -	const struct drm_display_mode *mode = &crtc_state->base.mode;
> +	const struct drm_display_mode *mode = &crtc_state->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1629,7 +1629,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>  			flags |= DRM_MODE_FLAG_NVSYNC;
>  	}
>  
> -	pipe_config->base.adjusted_mode.flags |= flags;
> +	pipe_config->hw.adjusted_mode.flags |= flags;
>  
>  	/*
>  	 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
> @@ -1649,7 +1649,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>  	if (pipe_config->pixel_multiplier)
>  		dotclock /= pipe_config->pixel_multiplier;
>  
> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>  
>  	/* Cross check the port pixel multiplier with the sdvo encoder state. */
>  	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
> @@ -1701,7 +1701,7 @@ static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo,
>  				    const struct drm_connector_state *conn_state)
>  {
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	struct drm_connector *connector = conn_state->connector;
>  	u8 *eld = connector->eld;
>  
> @@ -1723,7 +1723,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	u32 temp;
>  
>  	if (old_crtc_state->has_audio)
> @@ -1785,7 +1785,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder,
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	u32 temp;
>  	bool input1, input2;
>  	int i;
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 7a7078d0ba23..a602e21c5fd5 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -81,9 +81,9 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
>   */
>  void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
>  	long timeout = msecs_to_jiffies_timeout(1);
>  	int scanline, min, max, vblank_start;
>  	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
> @@ -190,7 +190,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>   */
>  void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	enum pipe pipe = crtc->pipe;
>  	int scanline_end = intel_get_crtc_scanline(crtc);
>  	u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
> @@ -203,14 +203,15 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
>  	 * Would be slightly nice to just grab the vblank count and arm the
>  	 * event outside of the critical section - the spinlock might spin for a
>  	 * while ... */
> -	if (new_crtc_state->base.event) {
> +	if (new_crtc_state->uapi.event) {
>  		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
>  
>  		spin_lock(&crtc->base.dev->event_lock);
> -		drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
> +		drm_crtc_arm_vblank_event(&crtc->base,
> +				          new_crtc_state->uapi.event);
>  		spin_unlock(&crtc->base.dev->event_lock);
>  
> -		new_crtc_state->base.event = NULL;
> +		new_crtc_state->uapi.event = NULL;
>  	}
>  
>  	local_irq_enable();
> @@ -1515,7 +1516,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
>  	const struct drm_rect *dst = &plane_state->base.dst;
>  	int src_x, src_w, src_h, crtc_w, crtc_h;
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	unsigned int cpp = fb->format->cpp[0];
>  	unsigned int width_bytes;
>  	int min_width, min_height;
> @@ -1587,7 +1588,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
>  	}
>  
>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
> -						  &crtc_state->base,
> +						  &crtc_state->uapi,
>  						  min_scale, max_scale,
>  						  true, true);
>  	if (ret)
> @@ -1644,7 +1645,7 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
>  		return ret;
>  
>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
> -						  &crtc_state->base,
> +						  &crtc_state->uapi,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  DRM_PLANE_HELPER_NO_SCALING,
>  						  true, true);
> @@ -1728,8 +1729,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
>  	}
>  
>  	/* Y-tiling is not supported in IF-ID Interlace mode */
> -	if (crtc_state->base.enable &&
> -	    crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
> +	if (crtc_state->hw.enable &&
> +	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
>  	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
>  	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
>  	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
> @@ -1809,7 +1810,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
>  	}
>  
>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
> -						  &crtc_state->base,
> +						  &crtc_state->uapi,
>  						  min_scale, max_scale,
>  						  true, true);
>  	if (ret)
> diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
> index b70221f5112a..96a3d9348471 100644
> --- a/drivers/gpu/drm/i915/display/intel_tv.c
> +++ b/drivers/gpu/drm/i915/display/intel_tv.c
> @@ -924,7 +924,7 @@ intel_enable_tv(struct intel_encoder *encoder,
>  
>  	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
>  	intel_wait_for_vblank(dev_priv,
> -			      to_intel_crtc(pipe_config->base.crtc)->pipe);
> +			      to_intel_crtc(pipe_config->uapi.crtc)->pipe);
>  
>  	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
>  }
> @@ -1086,7 +1086,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  	struct drm_display_mode mode = {};
>  	u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
>  	struct tv_mode tv_mode = {};
> @@ -1189,7 +1189,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
>  		to_intel_tv_connector_state(conn_state);
>  	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
>  	struct drm_display_mode *adjusted_mode =
> -		&pipe_config->base.adjusted_mode;
> +		&pipe_config->hw.adjusted_mode;
>  	int hdisplay = adjusted_mode->crtc_hdisplay;
>  	int vdisplay = adjusted_mode->crtc_vdisplay;
>  
> @@ -1418,7 +1418,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder,
>  				const struct drm_connector_state *conn_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_tv *intel_tv = enc_to_tv(encoder);
>  	const struct intel_tv_connector_state *tv_conn_state =
>  		to_intel_tv_connector_state(conn_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
> index d4fb7f16f9f6..38c181499505 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -329,8 +329,8 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>  	int column_index = 0;
>  	u8 line_buf_depth = 0;
>  
> -	vdsc_cfg->pic_width = pipe_config->base.adjusted_mode.crtc_hdisplay;
> -	vdsc_cfg->pic_height = pipe_config->base.adjusted_mode.crtc_vdisplay;
> +	vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
> +	vdsc_cfg->pic_height = pipe_config->hw.adjusted_mode.crtc_vdisplay;
>  	vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
>  					     pipe_config->dsc_params.slice_count);
>  	/*
> @@ -459,7 +459,7 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>  enum intel_display_power_domain
>  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *i915 = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  
>  	/*
> @@ -483,7 +483,7 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
>  						const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
>  	enum pipe pipe = crtc->pipe;
> @@ -902,7 +902,7 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
>  void intel_dsc_enable(struct intel_encoder *encoder,
>  		      const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> @@ -938,7 +938,7 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>  
>  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
> index 50064cde0724..16f93d1e71e5 100644
> --- a/drivers/gpu/drm/i915/display/vlv_dsi.c
> +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
> @@ -261,9 +261,9 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder,
>  	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
>  						   base);
>  	struct intel_connector *intel_connector = intel_dsi->attached_connector;
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int ret;
>  
>  	DRM_DEBUG_KMS("\n");
> @@ -624,7 +624,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	enum port port;
>  
> @@ -746,7 +746,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
>  				 const struct drm_connector_state *conn_state)
>  {
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
> -	struct drm_crtc *crtc = pipe_config->base.crtc;
> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	enum pipe pipe = intel_crtc->pipe;
> @@ -1032,9 +1032,9 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
>  	struct drm_device *dev = encoder->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct drm_display_mode *adjusted_mode =
> -					&pipe_config->base.adjusted_mode;
> +					&pipe_config->hw.adjusted_mode;
>  	struct drm_display_mode *adjusted_mode_sw;
> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>  	unsigned int lane_count = intel_dsi->lane_count;
>  	unsigned int bpp, fmt;
> @@ -1045,7 +1045,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
>  				crtc_hblank_start_sw, crtc_hblank_end_sw;
>  
>  	/* FIXME: hw readout should not depend on SW state */
> -	adjusted_mode_sw = &crtc->config->base.adjusted_mode;
> +	adjusted_mode_sw = &crtc->config->hw.adjusted_mode;
>  
>  	/*
>  	 * Atleast one port is active as encoder->get_config called only if
> @@ -1204,7 +1204,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
>  	}
>  
>  	if (pclk) {
> -		pipe_config->base.adjusted_mode.crtc_clock = pclk;
> +		pipe_config->hw.adjusted_mode.crtc_clock = pclk;
>  		pipe_config->port_clock = pclk;
>  	}
>  }
> @@ -1315,9 +1315,9 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
>  	struct drm_encoder *encoder = &intel_encoder->base;
>  	struct drm_device *dev = encoder->dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	enum port port;
>  	unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
>  	u32 val, tmp;
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index 43db50095257..1c4c3972fd23 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -2749,11 +2749,11 @@ static int i915_display_info(struct seq_file *m, void *unused)
>  
>  		seq_printf(m, "CRTC %d: pipe: %c, active=%s, (size=%dx%d), dither=%s, bpp=%d\n",
>  			   crtc->base.base.id, pipe_name(crtc->pipe),
> -			   yesno(pipe_config->base.active),
> +			   yesno(pipe_config->hw.active),
>  			   pipe_config->pipe_src_w, pipe_config->pipe_src_h,
>  			   yesno(pipe_config->dither), pipe_config->pipe_bpp);
>  
> -		if (pipe_config->base.active) {
> +		if (pipe_config->hw.active) {
>  			struct intel_plane *cursor =
>  				to_intel_plane(crtc->base.cursor);
>  
> @@ -4204,11 +4204,11 @@ static int i915_drrs_ctl_set(void *data, u64 val)
>  
>  		crtc_state = to_intel_crtc_state(crtc->base.state);
>  
> -		if (!crtc_state->base.active ||
> +		if (!crtc_state->hw.active ||
>  		    !crtc_state->has_drrs)
>  			goto out;
>  
> -		commit = crtc_state->base.commit;
> +		commit = crtc_state->uapi.commit;
>  		if (commit) {
>  			ret = wait_for_completion_interruptible(&commit->hw_done);
>  			if (ret)
> @@ -4220,7 +4220,7 @@ static int i915_drrs_ctl_set(void *data, u64 val)
>  			struct intel_encoder *encoder;
>  			struct intel_dp *intel_dp;
>  
> -			if (!(crtc_state->base.connector_mask &
> +			if (!(crtc_state->uapi.connector_mask &
>  			      drm_connector_mask(connector)))
>  				continue;
>  
> @@ -4279,14 +4279,14 @@ i915_fifo_underrun_reset_write(struct file *filp,
>  			return ret;
>  
>  		crtc_state = to_intel_crtc_state(intel_crtc->base.state);
> -		commit = crtc_state->base.commit;
> +		commit = crtc_state->uapi.commit;
>  		if (commit) {
>  			ret = wait_for_completion_interruptible(&commit->hw_done);
>  			if (!ret)
>  				ret = wait_for_completion_interruptible(&commit->flip_done);
>  		}
>  
> -		if (!ret && crtc_state->base.active) {
> +		if (!ret && crtc_state->hw.active) {
>  			DRM_DEBUG_KMS("Re-arming FIFO underruns on pipe %c\n",
>  				      pipe_name(intel_crtc->pipe));
>  
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 6aa40f546226..edabf2cf4440 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -484,7 +484,7 @@ static const int pessimal_latency_ns = 5000;
>  
>  static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
>  	enum pipe pipe = crtc->pipe;
> @@ -818,7 +818,7 @@ static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>  
>  	/* FIXME check the 'enable' instead */
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return false;
>  
>  	/*
> @@ -871,7 +871,7 @@ static void pineview_update_wm(struct intel_crtc *unused_crtc)
>  	crtc = single_enabled_crtc(dev_priv);
>  	if (crtc) {
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc->config->base.adjusted_mode;
> +			&crtc->config->hw.adjusted_mode;
>  		const struct drm_framebuffer *fb =
>  			crtc->base.primary->state->fb;
>  		int cpp = fb->format->cpp[0];
> @@ -1107,7 +1107,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
>  	unsigned int clock, htotal, cpp, width, wm;
>  
> @@ -1167,7 +1167,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
>  static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>  				 int level, enum plane_id plane_id, u16 value)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	bool dirty = false;
>  
>  	for (; level < intel_wm_num_levels(dev_priv); level++) {
> @@ -1183,7 +1183,7 @@ static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>  static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state,
>  			       int level, u16 value)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	bool dirty = false;
>  
>  	/* NORMAL level doesn't have an FBC watermark */
> @@ -1285,7 +1285,7 @@ static bool g4x_raw_plane_wm_is_valid(const struct intel_crtc_state *crtc_state,
>  static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
>  				     int level)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  
>  	if (level > dev_priv->wm.max_level)
>  		return false;
> @@ -1323,9 +1323,9 @@ static void g4x_invalidate_wms(struct intel_crtc *crtc,
>  
>  static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  	struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
>  	int num_active_planes = hweight8(crtc_state->active_planes &
>  					 ~BIT(PLANE_CURSOR));
> @@ -1412,17 +1412,17 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  
>  static int g4x_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate;
>  	const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal;
>  	struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(new_crtc_state->base.state);
> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>  	const struct intel_crtc_state *old_crtc_state =
>  		intel_atomic_get_old_crtc_state(intel_state, crtc);
>  	const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal;
>  	enum plane_id plane_id;
>  
> -	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
> +	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
>  		*intermediate = *optimal;
>  
>  		intermediate->cxsr = false;
> @@ -1554,8 +1554,8 @@ static void g4x_program_watermarks(struct drm_i915_private *dev_priv)
>  static void g4x_initial_watermarks(struct intel_atomic_state *state,
>  				   struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	mutex_lock(&dev_priv->wm.wm_mutex);
>  	crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate;
> @@ -1566,8 +1566,8 @@ static void g4x_initial_watermarks(struct intel_atomic_state *state,
>  static void g4x_optimize_watermarks(struct intel_atomic_state *state,
>  				    struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	if (!crtc_state->wm.need_postvbl_update)
>  		return;
> @@ -1616,7 +1616,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	unsigned int clock, htotal, cpp, width, wm;
>  
>  	if (dev_priv->wm.pri_latency[level] == 0)
> @@ -1654,7 +1654,7 @@ static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes)
>  
>  static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	const struct g4x_pipe_wm *raw =
>  		&crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2];
>  	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
> @@ -1766,7 +1766,7 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
>  static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>  				 int level, enum plane_id plane_id, u16 value)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	int num_levels = intel_wm_num_levels(dev_priv);
>  	bool dirty = false;
>  
> @@ -1841,16 +1841,16 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
>  
>  static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_atomic_state *state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
>  	const struct vlv_fifo_state *fifo_state =
>  		&crtc_state->wm.vlv.fifo_state;
>  	int num_active_planes = hweight8(crtc_state->active_planes &
>  					 ~BIT(PLANE_CURSOR));
> -	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base);
> +	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
>  	const struct intel_plane_state *old_plane_state;
>  	const struct intel_plane_state *new_plane_state;
>  	struct intel_plane *plane;
> @@ -1949,7 +1949,7 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
>  				   struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_uncore *uncore = &dev_priv->uncore;
>  	const struct vlv_fifo_state *fifo_state =
> @@ -2045,17 +2045,17 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
>  
>  static int vlv_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate;
>  	const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal;
>  	struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(new_crtc_state->base.state);
> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>  	const struct intel_crtc_state *old_crtc_state =
>  		intel_atomic_get_old_crtc_state(intel_state, crtc);
>  	const struct vlv_wm_state *active = &old_crtc_state->wm.vlv.optimal;
>  	int level;
>  
> -	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
> +	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
>  		*intermediate = *optimal;
>  
>  		intermediate->cxsr = false;
> @@ -2173,8 +2173,8 @@ static void vlv_program_watermarks(struct drm_i915_private *dev_priv)
>  static void vlv_initial_watermarks(struct intel_atomic_state *state,
>  				   struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	mutex_lock(&dev_priv->wm.wm_mutex);
>  	crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate;
> @@ -2185,8 +2185,8 @@ static void vlv_initial_watermarks(struct intel_atomic_state *state,
>  static void vlv_optimize_watermarks(struct intel_atomic_state *state,
>  				    struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	if (!crtc_state->wm.need_postvbl_update)
>  		return;
> @@ -2211,7 +2211,7 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
>  		/* self-refresh has much higher latency */
>  		static const int sr_latency_ns = 12000;
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc->config->base.adjusted_mode;
> +			&crtc->config->hw.adjusted_mode;
>  		const struct drm_framebuffer *fb =
>  			crtc->base.primary->state->fb;
>  		int clock = adjusted_mode->crtc_clock;
> @@ -2292,7 +2292,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>  	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
>  	if (intel_crtc_active(crtc)) {
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc->config->base.adjusted_mode;
> +			&crtc->config->hw.adjusted_mode;
>  		const struct drm_framebuffer *fb =
>  			crtc->base.primary->state->fb;
>  		int cpp;
> @@ -2319,7 +2319,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>  	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
>  	if (intel_crtc_active(crtc)) {
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc->config->base.adjusted_mode;
> +			&crtc->config->hw.adjusted_mode;
>  		const struct drm_framebuffer *fb =
>  			crtc->base.primary->state->fb;
>  		int cpp;
> @@ -2367,7 +2367,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>  		/* self-refresh has much higher latency */
>  		static const int sr_latency_ns = 6000;
>  		const struct drm_display_mode *adjusted_mode =
> -			&enabled->config->base.adjusted_mode;
> +			&enabled->config->hw.adjusted_mode;
>  		const struct drm_framebuffer *fb =
>  			enabled->base.primary->state->fb;
>  		int clock = adjusted_mode->crtc_clock;
> @@ -2425,7 +2425,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
>  	if (crtc == NULL)
>  		return;
>  
> -	adjusted_mode = &crtc->config->base.adjusted_mode;
> +	adjusted_mode = &crtc->config->hw.adjusted_mode;
>  	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
>  				       &i845_wm_info,
>  				       dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
> @@ -2515,7 +2515,7 @@ static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state,
>  		return method1;
>  
>  	method2 = ilk_wm_method2(crtc_state->pixel_rate,
> -				 crtc_state->base.adjusted_mode.crtc_htotal,
> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&plane_state->base.dst),
>  				 cpp, mem_value);
>  
> @@ -2543,7 +2543,7 @@ static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state,
>  
>  	method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value);
>  	method2 = ilk_wm_method2(crtc_state->pixel_rate,
> -				 crtc_state->base.adjusted_mode.crtc_htotal,
> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>  				 drm_rect_width(&plane_state->base.dst),
>  				 cpp, mem_value);
>  	return min(method1, method2);
> @@ -2568,7 +2568,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
>  	cpp = plane_state->base.fb->format->cpp[0];
>  
>  	return ilk_wm_method2(crtc_state->pixel_rate,
> -			      crtc_state->base.adjusted_mode.crtc_htotal,
> +			      crtc_state->hw.adjusted_mode.crtc_htotal,
>  			      plane_state->base.crtc_w, cpp, mem_value);
>  }
>  
> @@ -2789,12 +2789,12 @@ static u32
>  hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
>  {
>  	const struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(crtc_state->base.state);
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  	const struct drm_display_mode *adjusted_mode =
> -		&crtc_state->base.adjusted_mode;
> +		&crtc_state->hw.adjusted_mode;
>  	u32 linetime, ips_linetime;
>  
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return 0;
>  	if (WARN_ON(adjusted_mode->crtc_clock == 0))
>  		return 0;
> @@ -3104,11 +3104,9 @@ static bool ilk_validate_pipe_wm(const struct drm_i915_private *dev_priv,
>  /* Compute new watermarks for the pipe */
>  static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct intel_pipe_wm *pipe_wm;
> -	struct drm_device *dev = state->dev;
> -	const struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *plane_state;
>  	const struct intel_plane_state *pristate = NULL;
> @@ -3119,7 +3117,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  
>  	pipe_wm = &crtc_state->wm.ilk.optimal;
>  
> -	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->base) {
> +	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->uapi) {
>  		const struct intel_plane_state *ps = to_intel_plane_state(plane_state);
>  
>  		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
> @@ -3130,7 +3128,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>  			curstate = ps;
>  	}
>  
> -	pipe_wm->pipe_enabled = crtc_state->base.active;
> +	pipe_wm->pipe_enabled = crtc_state->hw.active;
>  	if (sprstate) {
>  		pipe_wm->sprites_enabled = sprstate->base.visible;
>  		pipe_wm->sprites_scaled = sprstate->base.visible &&
> @@ -3187,11 +3185,11 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>   */
>  static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>  	struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate;
>  	struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(newstate->base.state);
> +		to_intel_atomic_state(newstate->uapi.state);
>  	const struct intel_crtc_state *oldstate =
>  		intel_atomic_get_old_crtc_state(intel_state, intel_crtc);
>  	const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal;
> @@ -3203,7 +3201,7 @@ static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
>  	 * and after the vblank.
>  	 */
>  	*a = newstate->wm.ilk.optimal;
> -	if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base) ||
> +	if (!newstate->hw.active || drm_atomic_crtc_needs_modeset(&newstate->uapi) ||
>  	    intel_state->skip_intermediate_wm)
>  		return 0;
>  
> @@ -3780,7 +3778,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>  	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
>  	crtc_state = to_intel_crtc_state(crtc->base.state);
>  
> -	if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		return false;
>  
>  	for_each_intel_plane_on_crtc(dev, crtc, plane) {
> @@ -3830,7 +3828,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>  	if (INTEL_GEN(dev_priv) < 11)
>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>  
> -	adjusted_mode = &crtc_state->base.adjusted_mode;
> +	adjusted_mode = &crtc_state->hw.adjusted_mode;
>  	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>  
>  	/*
> @@ -3859,16 +3857,16 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  				   struct skl_ddb_entry *alloc, /* out */
>  				   int *num_active /* out */)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
> -	struct drm_crtc *for_crtc = crtc_state->base.crtc;
> +	struct drm_crtc *for_crtc = crtc_state->uapi.crtc;
>  	const struct intel_crtc *crtc;
>  	u32 pipe_width = 0, total_width = 0, width_before_pipe = 0;
>  	enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe;
>  	u16 ddb_size;
>  	u32 i;
>  
> -	if (WARN_ON(!state) || !crtc_state->base.active) {
> +	if (WARN_ON(!state) || !crtc_state->hw.active) {
>  		alloc->start = 0;
>  		alloc->end = 0;
>  		*num_active = hweight8(dev_priv->active_pipes);
> @@ -3907,11 +3905,11 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  	 */
>  	for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
>  		const struct drm_display_mode *adjusted_mode =
> -			&crtc_state->base.adjusted_mode;
> +			&crtc_state->hw.adjusted_mode;
>  		enum pipe pipe = crtc->pipe;
>  		int hdisplay, vdisplay;
>  
> -		if (!crtc_state->base.enable)
> +		if (!crtc_state->hw.enable)
>  			continue;
>  
>  		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> @@ -3942,7 +3940,7 @@ static unsigned int
>  skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
>  		      int num_active)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	int level, max_level = ilk_wm_max_level(dev_priv);
>  	struct skl_wm_level wm = {};
>  	int ret, min_ddb_alloc = 0;
> @@ -4111,7 +4109,7 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
>  {
>  	uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
>  
> -	if (!crtc_state->base.enable)
> +	if (!crtc_state->hw.enable)
>  		return pipe_downscale;
>  
>  	if (crtc_state->pch_pfit.enabled) {
> @@ -4143,7 +4141,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  				  struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *drm_plane_state;
>  	int crtc_clock, dotclk;
> @@ -4151,10 +4149,10 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  	uint_fixed_16_16_t pipe_downscale;
>  	uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
>  
> -	if (!crtc_state->base.enable)
> +	if (!crtc_state->hw.enable)
>  		return 0;
>  
> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>  		uint_fixed_16_16_t plane_downscale;
>  		uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
>  		int bpp;
> @@ -4179,7 +4177,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>  
>  	pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
>  
> -	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
> +	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
>  	dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
>  
>  	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
> @@ -4246,7 +4244,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  				 u64 *plane_data_rate,
>  				 u64 *uv_plane_data_rate)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *drm_plane_state;
>  	u64 total_data_rate = 0;
> @@ -4255,7 +4253,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  		return 0;
>  
>  	/* Calculate and cache data rate for each plane */
> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>  		const struct intel_plane_state *plane_state =
>  			to_intel_plane_state(drm_plane_state);
> @@ -4283,11 +4281,11 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  	const struct drm_plane_state *drm_plane_state;
>  	u64 total_data_rate = 0;
>  
> -	if (WARN_ON(!crtc_state->base.state))
> +	if (WARN_ON(!crtc_state->uapi.state))
>  		return 0;
>  
>  	/* Calculate and cache data rate for each plane */
> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>  		const struct intel_plane_state *plane_state =
>  			to_intel_plane_state(drm_plane_state);
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
> @@ -4329,8 +4327,8 @@ static int
>  skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
>  		      struct skl_ddb_allocation *ddb /* out */)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> -	struct drm_crtc *crtc = crtc_state->base.crtc;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
> +	struct drm_crtc *crtc = crtc_state->uapi.crtc;
>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct skl_ddb_entry *alloc = &crtc_state->wm.skl.ddb;
> @@ -4352,7 +4350,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
>  	if (WARN_ON(!state))
>  		return 0;
>  
> -	if (!crtc_state->base.active) {
> +	if (!crtc_state->hw.active) {
>  		alloc->start = alloc->end = 0;
>  		return 0;
>  	}
> @@ -4594,7 +4592,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>  	u32 crtc_htotal;
>  	uint_fixed_16_16_t linetime_us;
>  
> -	if (!crtc_state->base.active)
> +	if (!crtc_state->hw.active)
>  		return u32_to_fixed16(0);
>  
>  	pixel_rate = crtc_state->pixel_rate;
> @@ -4602,7 +4600,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>  	if (WARN_ON(pixel_rate == 0))
>  		return u32_to_fixed16(0);
>  
> -	crtc_htotal = crtc_state->base.adjusted_mode.crtc_htotal;
> +	crtc_htotal = crtc_state->hw.adjusted_mode.crtc_htotal;
>  	linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
>  
>  	return linetime_us;
> @@ -4637,7 +4635,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>  		      u32 plane_pixel_rate, struct skl_wm_params *wp,
>  		      int color_plane)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 interm_pbpl;
>  
> @@ -4763,7 +4761,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>  				 const struct skl_wm_level *result_prev,
>  				 struct skl_wm_level *result /* out */)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	u32 latency = dev_priv->wm.skl_latency[level];
>  	uint_fixed_16_16_t method1, method2;
>  	uint_fixed_16_16_t selected_result;
> @@ -4789,14 +4787,14 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>  	method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate,
>  				 wp->cpp, latency, wp->dbuf_block_size);
>  	method2 = skl_wm_method2(wp->plane_pixel_rate,
> -				 crtc_state->base.adjusted_mode.crtc_htotal,
> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>  				 latency,
>  				 wp->plane_blocks_per_line);
>  
>  	if (wp->y_tiled) {
>  		selected_result = max_fixed16(method2, wp->y_tile_minimum);
>  	} else {
> -		if ((wp->cpp * crtc_state->base.adjusted_mode.crtc_htotal /
> +		if ((wp->cpp * crtc_state->hw.adjusted_mode.crtc_htotal /
>  		     wp->dbuf_block_size < 1) &&
>  		     (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
>  			selected_result = method2;
> @@ -4887,7 +4885,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>  		      const struct skl_wm_params *wm_params,
>  		      struct skl_wm_level *levels)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	int level, max_level = ilk_wm_max_level(dev_priv);
>  	struct skl_wm_level *result_prev = &levels[0];
>  
> @@ -4904,7 +4902,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>  static u32
>  skl_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_atomic_state *state = crtc_state->base.state;
> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
>  	uint_fixed_16_16_t linetime_us;
>  	u32 linetime_wm;
> @@ -4923,7 +4921,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
>  				      const struct skl_wm_params *wp,
>  				      struct skl_plane_wm *wm)
>  {
> -	struct drm_device *dev = crtc_state->base.crtc->dev;
> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>  	const struct drm_i915_private *dev_priv = to_i915(dev);
>  	u16 trans_min, trans_y_tile_min;
>  	const u16 trans_amount = 10; /* This is configurable amount */
> @@ -5083,7 +5081,7 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
>  
>  static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>  	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
>  	struct drm_plane *plane;
>  	const struct drm_plane_state *drm_plane_state;
> @@ -5096,7 +5094,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
>  	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
>  
>  	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state,
> -						   &crtc_state->base) {
> +						   &crtc_state->uapi) {
>  		const struct intel_plane_state *plane_state =
>  			to_intel_plane_state(drm_plane_state);
>  
> @@ -5275,8 +5273,8 @@ static int
>  skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
>  			    struct intel_crtc_state *new_crtc_state)
>  {
> -	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
> +	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	struct intel_plane *plane;
>  
> @@ -5576,7 +5574,7 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
>  		 * power well the hardware state will go out of sync
>  		 * with the software state.
>  		 */
> -		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) &&
> +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
>  		    skl_plane_wm_equals(dev_priv,
>  					&old_crtc_state->wm.skl.optimal.planes[plane_id],
>  					&new_crtc_state->wm.skl.optimal.planes[plane_id]))
> @@ -5643,7 +5641,7 @@ skl_compute_wm(struct intel_atomic_state *state)
>  static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
>  				      struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
>  	enum pipe pipe = crtc->pipe;
> @@ -5657,7 +5655,7 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
>  static void skl_initial_wm(struct intel_atomic_state *state,
>  			   struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_device *dev = intel_crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct skl_ddb_values *results = &state->wm_results;
> @@ -5667,7 +5665,7 @@ static void skl_initial_wm(struct intel_atomic_state *state,
>  
>  	mutex_lock(&dev_priv->wm.wm_mutex);
>  
> -	if (crtc_state->base.active_changed)
> +	if (crtc_state->uapi.active_changed)
>  		skl_atomic_update_crtc_wm(state, crtc_state);
>  
>  	mutex_unlock(&dev_priv->wm.wm_mutex);
> @@ -5726,8 +5724,8 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
>  static void ilk_initial_watermarks(struct intel_atomic_state *state,
>  				   struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	mutex_lock(&dev_priv->wm.wm_mutex);
>  	crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate;
> @@ -5738,8 +5736,8 @@ static void ilk_initial_watermarks(struct intel_atomic_state *state,
>  static void ilk_optimize_watermarks(struct intel_atomic_state *state,
>  				    struct intel_crtc_state *crtc_state)
>  {
> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	if (!crtc_state->wm.need_postvbl_update)
>  		return;
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split
  2019-09-20 11:42 ` [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split Maarten Lankhorst
@ 2019-09-24 23:40   ` Matt Roper
  0 siblings, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-24 23:40 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:16PM +0200, Maarten Lankhorst wrote:
> We are still looking at drm_crtc_state in a few places, convert those
> to use intel_crtc_state instead. Look at uapi/hw where appropriate.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 14 +++++++-------
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |  2 +-
>  drivers/gpu/drm/i915/display/intel_psr.c     |  4 ++--
>  3 files changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 6818cbd00ac2..32bbb5bf48f3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -16081,8 +16081,8 @@ static int intel_initial_commit(struct drm_device *dev)
>  {
>  	struct drm_atomic_state *state = NULL;
>  	struct drm_modeset_acquire_ctx ctx;
> -	struct drm_crtc *crtc;
> -	struct drm_crtc_state *crtc_state;
> +	struct intel_crtc *crtc;
> +	struct intel_crtc_state *crtc_state;
>  	int ret = 0;
>  
>  	state = drm_atomic_state_alloc(dev);
> @@ -16094,15 +16094,15 @@ static int intel_initial_commit(struct drm_device *dev)
>  retry:
>  	state->acquire_ctx = &ctx;
>  
> -	drm_for_each_crtc(crtc, dev) {
> -		crtc_state = drm_atomic_get_crtc_state(state, crtc);
> +	for_each_intel_crtc(dev, crtc) {
> +		crtc_state = intel_atomic_get_crtc_state(state, crtc);
>  		if (IS_ERR(crtc_state)) {
>  			ret = PTR_ERR(crtc_state);
>  			goto out;
>  		}
>  
> -		if (crtc_state->active) {
> -			ret = drm_atomic_add_affected_planes(state, crtc);
> +		if (crtc_state->hw.active) {
> +			ret = drm_atomic_add_affected_planes(state, &crtc->base);
>  			if (ret)
>  				goto out;
>  
> @@ -16112,7 +16112,7 @@ static int intel_initial_commit(struct drm_device *dev)
>  			 * having a proper LUT loaded. Remove once we
>  			 * have readout for pipe gamma enable.
>  			 */
> -			crtc_state->color_mgmt_changed = true;
> +			crtc_state->uapi.color_mgmt_changed = true;
>  		}
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 76f066b1dfe5..5127ec037b7b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -187,7 +187,7 @@ intel_dp_mst_atomic_check(struct drm_connector *connector,
>  
>  		if (!crtc_state ||
>  		    !drm_atomic_crtc_needs_modeset(crtc_state) ||
> -		    crtc_state->enable)
> +		    to_intel_crtc_state(crtc_state)->hw.enable)
>  			return 0;
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
> index 8988dbe8c19e..979e166f5639 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -1068,9 +1068,9 @@ static int intel_psr_fastset_force(struct drm_i915_private *dev_priv)
>  
>  		intel_crtc_state = to_intel_crtc_state(crtc_state);
>  
> -		if (crtc_state->active && intel_crtc_state->has_psr) {
> +		if (intel_crtc_state->hw.active && intel_crtc_state->has_psr) {
>  			/* Mark mode as changed to trigger a pipe->update() */
> -			crtc_state->mode_changed = true;
> +			intel_crtc_state->uapi.mode_changed = true;
>  			break;
>  		}
>  	}
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-20 11:42 ` [PATCH 05/23] drm/i915: Complete sw/hw split Maarten Lankhorst
@ 2019-09-24 23:41   ` Matt Roper
  2019-09-25  9:29     ` Maarten Lankhorst
  2019-09-25 13:01   ` Ville Syrjälä
  1 sibling, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-24 23:41 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
> Now that we separated everything into uapi and hw, it's
> time to make the split definitive. Remove the union and
> make a copy of the hw state on modeset and fastset.
> 
> Color blobs are copied in crtc atomic_check(), right
> before color management is checked.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
>  drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
>  .../drm/i915/display/intel_display_types.h    |  8 ++--
>  4 files changed, 85 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index f4440ede95c5..fb550d3cea7f 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  
>  	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>  
> +	/* copy color blobs */
> +	if (crtc_state->hw.degamma_lut)
> +		drm_property_blob_get(crtc_state->hw.degamma_lut);
> +	if (crtc_state->hw.ctm)
> +		drm_property_blob_get(crtc_state->hw.ctm);
> +	if (crtc_state->hw.gamma_lut)
> +		drm_property_blob_get(crtc_state->hw.gamma_lut);
> +
>  	crtc_state->update_pipe = false;
>  	crtc_state->disable_lp_wm = false;
>  	crtc_state->disable_cxsr = false;
> @@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	return &crtc_state->uapi;
>  }
>  
> +static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
> +{
> +	drm_property_blob_put(crtc_state->hw.degamma_lut);
> +	drm_property_blob_put(crtc_state->hw.gamma_lut);
> +	drm_property_blob_put(crtc_state->hw.ctm);
> +}
> +
> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
> +{
> +	intel_crtc_put_color_blobs(crtc_state);
> +}
> +
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
> +{
> +	intel_crtc_put_color_blobs(crtc_state);
> +
> +	if (crtc_state->uapi.degamma_lut)
> +		crtc_state->hw.degamma_lut =
> +			drm_property_blob_get(crtc_state->uapi.degamma_lut);
> +	else
> +		crtc_state->hw.degamma_lut = NULL;
> +
> +	if (crtc_state->uapi.gamma_lut)
> +		crtc_state->hw.gamma_lut =
> +			drm_property_blob_get(crtc_state->uapi.gamma_lut);
> +	else
> +		crtc_state->hw.gamma_lut = NULL;
> +
> +	if (crtc_state->uapi.ctm)
> +		crtc_state->hw.ctm =
> +			drm_property_blob_get(crtc_state->uapi.ctm);
> +	else
> +		crtc_state->hw.ctm = NULL;
> +}
> +
>  /**
>   * intel_crtc_destroy_state - destroy crtc state
>   * @crtc: drm crtc
> @@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
>  	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
>  
>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> +	intel_crtc_free_hw_state(crtc_state);
>  	kfree(crtc_state);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> index 58065d3161a3..42be91e0772a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>  			       struct drm_crtc_state *state);
> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 32bbb5bf48f3..e40485a1e503 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
>  	DRM_FORMAT_MOD_INVALID
>  };
>  
> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
>  				struct intel_crtc_state *pipe_config);
>  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
> @@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>  	crtc->enabled = false;
>  	crtc->state->connector_mask = 0;
>  	crtc->state->encoder_mask = 0;
> +	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
>  

Do we actually have any valid uapi state to copy at this point?  I
thought intel_crtc_disable_noatomic was only called during initial
hardware readout (which only updates hw state and then does a hw->uapi
copy at the end)?


>  	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
>  		encoder->base.crtc = NULL;
> @@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  
>  	if (mode_changed || crtc_state->update_pipe ||
>  	    crtc_state->uapi.color_mgmt_changed) {
> +		/* Copy color blobs to hw state */
> +		intel_crtc_copy_color_blobs(crtc_state);

The copy only matters if crtc_state->uapi.color_mgmt_changed, right?  I
guess it doesn't really matter if we call this more often than we need
to since we're not actually copying the blobs themselves, just
dropping/taking extra references.


> +
>  		ret = intel_color_check(crtc_state);
>  		if (ret)
>  			return ret;
> @@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>  	return ret;
>  }
>  
> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> +{
> +	crtc_state->hw.enable = crtc_state->uapi.enable;
> +	crtc_state->hw.active = crtc_state->uapi.active;
> +	crtc_state->hw.mode = crtc_state->uapi.mode;
> +	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
> +}
> +
> +static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +{
> +	crtc_state->uapi.enable = crtc_state->hw.enable;
> +	crtc_state->uapi.active = crtc_state->hw.active;
> +	crtc_state->uapi.mode = crtc_state->hw.mode;
> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> +}
> +
>  static int
>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  {
> @@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  	 * fixed, so that the crtc_state can be safely duplicated. For now,
>  	 * only fields that are know to not cause problems are preserved. */
>  
> +	saved_state->uapi = crtc_state->uapi;
>  	saved_state->scaler_state = crtc_state->scaler_state;
>  	saved_state->shared_dpll = crtc_state->shared_dpll;
>  	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> @@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>  		saved_state->wm = crtc_state->wm;
>  
> -	/* Keep base drm_crtc_state intact, only clear our extended struct */
> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
> -	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
> -	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
> +	intel_crtc_free_hw_state(crtc_state);
> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> +	copy_uapi_to_hw_state(crtc_state);
>  
>  	kfree(saved_state);
>  	return 0;
> @@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>  
> +	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
> +
>  	return 0;
>  }
>  
> @@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
>  
>  	state = old_crtc_state->uapi.state;
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> +	intel_crtc_free_hw_state(old_crtc_state);
> +
>  	pipe_config = old_crtc_state;
>  	memset(pipe_config, 0, sizeof(*pipe_config));
>  	pipe_config->uapi.crtc = &crtc->base;
> @@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
>  
>  		if (!new_crtc_state->uapi.enable) {
>  			any_ms = true;
> +			clear_intel_crtc_state(new_crtc_state);

Why do we need this call?  uapi is preserved during this call (and then
re-copied to hw), so it doesn't seem like this has any effect on the
uapi/hw split we're dealing with in this patch?


Matt

>  			continue;
>  		}
>  
> @@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			to_intel_crtc_state(crtc->base.state);
>  
>  		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> +		intel_crtc_free_hw_state(crtc_state);
>  		memset(crtc_state, 0, sizeof(*crtc_state));
>  		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>  
> @@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
> +			crtc_state->hw.mode = crtc->base.mode;
>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>  
>  			/*
> @@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  
>  		intel_bw_crtc_update(bw_state, crtc_state);
>  
> +		copy_hw_to_uapi_state(crtc_state);
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 2c3567081e16..e81b785cc8f2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -749,7 +749,6 @@ enum intel_output_format {
>  };
>  
>  struct intel_crtc_state {
> -	union {
>  	/*
>  	 * uapi (drm) state. This is the software state shown to userspace.
>  	 * In particular, the following members are used for bookkeeping:
> @@ -772,8 +771,11 @@ struct intel_crtc_state {
>  	 *
>  	 * During initial hw readout, they need to be copied to uapi.
>  	 */
> -	struct drm_crtc_state hw;
> -	};
> +	struct {
> +		bool active, enable;
> +		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
> +		struct drm_display_mode mode, adjusted_mode;
> +	} hw;
>  
>  	/**
>  	 * quirks - bitfield with hw state readout quirks
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed
  2019-09-20 11:42 ` [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed Maarten Lankhorst
@ 2019-09-24 23:44   ` Matt Roper
  0 siblings, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-24 23:44 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:18PM +0200, Maarten Lankhorst wrote:
> We had this as an optimization to not do a plane update, but we killed
> it off because there are so many reasons we may have to do a plane
> update or fastset that it's best to just assume everything changed.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c        |  1 -
>  drivers/gpu/drm/i915/display/intel_display.c       | 10 +---------
>  drivers/gpu/drm/i915/display/intel_display_types.h |  1 -
>  3 files changed, 1 insertion(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index fb550d3cea7f..4b4eee9c49f5 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -208,7 +208,6 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	crtc_state->disable_cxsr = false;
>  	crtc_state->update_wm_pre = false;
>  	crtc_state->update_wm_post = false;
> -	crtc_state->fb_changed = false;
>  	crtc_state->fifo_changed = false;
>  	crtc_state->wm.need_postvbl_update = false;
>  	crtc_state->fb_bits = 0;
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index e40485a1e503..520c66071e67 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -11521,7 +11521,6 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
>  	bool was_crtc_enabled = old_crtc_state->hw.active;
>  	bool is_crtc_enabled = crtc_state->hw.active;
>  	bool turn_off, turn_on, visible, was_visible;
> -	struct drm_framebuffer *fb = plane_state->base.fb;
>  	int ret;
>  
>  	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_CURSOR) {
> @@ -11555,18 +11554,11 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
>  	if (!was_visible && !visible)
>  		return 0;
>  
> -	if (fb != old_plane_state->base.fb)
> -		crtc_state->fb_changed = true;
> -
>  	turn_off = was_visible && (!visible || mode_changed);
>  	turn_on = visible && (!was_visible || mode_changed);
>  
> -	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] has [PLANE:%d:%s] with fb %i\n",
> +	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
>  			 crtc->base.base.id, crtc->base.name,
> -			 plane->base.base.id, plane->base.name,
> -			 fb ? fb->base.id : -1);
> -
> -	DRM_DEBUG_ATOMIC("[PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
>  			 plane->base.base.id, plane->base.name,
>  			 was_visible, visible,
>  			 turn_off, turn_on, mode_changed);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index e81b785cc8f2..57dbcfc126df 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -792,7 +792,6 @@ struct intel_crtc_state {
>  	bool update_pipe; /* can a fast modeset be performed? */
>  	bool disable_cxsr;
>  	bool update_wm_pre, update_wm_post; /* watermarks are updated */
> -	bool fb_changed; /* fb on any of the planes is changed */
>  	bool fifo_changed; /* FIFO split is changed */
>  
>  	/* Pipe source size (ie. panel fitter input size)
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit.
  2019-09-20 11:42 ` [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit Maarten Lankhorst
@ 2019-09-25  4:17   ` Matt Roper
  2019-09-25 14:14     ` Maarten Lankhorst
  2019-09-25 22:14   ` Manasi Navare
  1 sibling, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-25  4:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:19PM +0200, Maarten Lankhorst wrote:
> This can all be done from the intel_update_crtc function. Split out the
> pipe update into a separate function, just like is done for the planes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

The code here all looks logically correct, but I think our various
pipe functions are still somewhat confusing.  E.g.,
intel_update_pipe_config() and commit_pipe_config() have names that
make it sound like they're doing the same thing.  At the moment
intel_update_pipe_config() is basically the fastset-specific stuff, but
is there any reason most of those operations can't just be done on all
commits?  Re-writing the pfit/scaler registers or pipe chicken seems
like a pretty small number of registers to try to avoid.

If we want to keep them separate, I'd suggest renaming
intel_update_pipe_config() (and probably the 'update_pipe' flag too) to
make it more clear that it's meant for the fastset special case.


Matt

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 124 ++++++++-----------
>  1 file changed, 52 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 520c66071e67..fd8b398733b8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -136,8 +136,6 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
> -static void intel_begin_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
> -static void intel_finish_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
>  static void intel_crtc_init_scalers(struct intel_crtc *crtc,
>  				    struct intel_crtc_state *crtc_state);
>  static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state);
> @@ -13673,13 +13671,54 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
>  	return crtc->base.funcs->get_vblank_counter(&crtc->base);
>  }
>  
> +void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
> +				  struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +
> +	if (!IS_GEN(dev_priv, 2))
> +		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
> +
> +	if (crtc_state->has_pch_encoder) {
> +		enum pipe pch_transcoder =
> +			intel_crtc_pch_transcoder(crtc);
> +
> +		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
> +	}
> +}
> +
> +static void commit_pipe_config(struct intel_atomic_state *state,
> +			       struct intel_crtc_state *old_crtc_state,
> +			       struct intel_crtc_state *new_crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	bool modeset = needs_modeset(new_crtc_state);
> +
> +	if (!modeset) {
> +		if (new_crtc_state->uapi.color_mgmt_changed ||
> +		    new_crtc_state->update_pipe)
> +			intel_color_commit(new_crtc_state);
> +
> +		if (new_crtc_state->update_pipe)
> +			intel_update_pipe_config(old_crtc_state, new_crtc_state);
> +		else if (INTEL_GEN(dev_priv) >= 9)
> +			skl_detach_scalers(new_crtc_state);
> +
> +		if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> +			bdw_set_pipemisc(new_crtc_state);
> +	}
> +
> +	if (dev_priv->display.atomic_update_watermarks)
> +		dev_priv->display.atomic_update_watermarks(state,
> +							   new_crtc_state);
> +}
> +
>  static void intel_update_crtc(struct intel_crtc *crtc,
>  			      struct intel_atomic_state *state,
>  			      struct intel_crtc_state *old_crtc_state,
>  			      struct intel_crtc_state *new_crtc_state)
>  {
> -	struct drm_device *dev = state->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	bool modeset = needs_modeset(new_crtc_state);
>  	struct intel_plane_state *new_plane_state =
>  		intel_atomic_get_new_plane_state(state,
> @@ -13703,14 +13742,21 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	else if (new_plane_state)
>  		intel_fbc_enable(crtc, new_crtc_state, new_plane_state);
>  
> -	intel_begin_crtc_commit(state, crtc);
> +	/* Perform vblank evasion around commit operation */
> +	intel_pipe_update_start(new_crtc_state);
> +
> +	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>  
>  	if (INTEL_GEN(dev_priv) >= 9)
>  		skl_update_planes_on_crtc(state, crtc);
>  	else
>  		i9xx_update_planes_on_crtc(state, crtc);
>  
> -	intel_finish_crtc_commit(state, crtc);
> +	intel_pipe_update_end(new_crtc_state);
> +
> +	if (new_crtc_state->update_pipe && !modeset &&
> +	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> @@ -14507,72 +14553,6 @@ skl_max_scale(const struct intel_crtc_state *crtc_state,
>  	return max_scale;
>  }
>  
> -static void intel_begin_crtc_commit(struct intel_atomic_state *state,
> -				    struct intel_crtc *crtc)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_crtc_state *old_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, crtc);
> -	struct intel_crtc_state *new_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, crtc);
> -	bool modeset = needs_modeset(new_crtc_state);
> -
> -	/* Perform vblank evasion around commit operation */
> -	intel_pipe_update_start(new_crtc_state);
> -
> -	if (modeset)
> -		goto out;
> -
> -	if (new_crtc_state->uapi.color_mgmt_changed ||
> -	    new_crtc_state->update_pipe)
> -		intel_color_commit(new_crtc_state);
> -
> -	if (new_crtc_state->update_pipe)
> -		intel_update_pipe_config(old_crtc_state, new_crtc_state);
> -	else if (INTEL_GEN(dev_priv) >= 9)
> -		skl_detach_scalers(new_crtc_state);
> -
> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> -		bdw_set_pipemisc(new_crtc_state);
> -
> -out:
> -	if (dev_priv->display.atomic_update_watermarks)
> -		dev_priv->display.atomic_update_watermarks(state,
> -							   new_crtc_state);
> -}
> -
> -void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
> -				  struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -
> -	if (!IS_GEN(dev_priv, 2))
> -		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
> -
> -	if (crtc_state->has_pch_encoder) {
> -		enum pipe pch_transcoder =
> -			intel_crtc_pch_transcoder(crtc);
> -
> -		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
> -	}
> -}
> -
> -static void intel_finish_crtc_commit(struct intel_atomic_state *state,
> -				     struct intel_crtc *crtc)
> -{
> -	struct intel_crtc_state *old_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, crtc);
> -	struct intel_crtc_state *new_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, crtc);
> -
> -	intel_pipe_update_end(new_crtc_state);
> -
> -	if (new_crtc_state->update_pipe &&
> -	    !needs_modeset(new_crtc_state) &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> -		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
> -}
> -
>  /**
>   * intel_plane_destroy - destroy a plane
>   * @plane: plane to destroy
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 08/23] drm/i915: Rename planar linked plane variables
  2019-09-20 11:42 ` [PATCH 08/23] drm/i915: Rename planar linked plane variables Maarten Lankhorst
@ 2019-09-25  4:30   ` Matt Roper
  0 siblings, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-25  4:30 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:20PM +0200, Maarten Lankhorst wrote:
> Rename linked_plane to planar_linked_plane and slave to planar_slave,
> this will make it easier to keep apart bigjoiner linking and planar plane
> linking.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

Another good candidate for a coccinelle spatch to make rebase conflicts
easier to resolve.

> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   |  7 ++++--
>  .../gpu/drm/i915/display/intel_atomic_plane.c |  4 ++--
>  drivers/gpu/drm/i915/display/intel_display.c  | 22 +++++++++----------
>  .../drm/i915/display/intel_display_types.h    |  8 +++----
>  drivers/gpu/drm/i915/display/intel_sprite.c   |  4 ++--
>  drivers/gpu/drm/i915/intel_pm.c               | 12 +++++-----
>  6 files changed, 30 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 4b4eee9c49f5..158594e64bb9 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -311,10 +311,13 @@ static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_sta
>  			 */
>  			mode = PS_SCALER_MODE_NORMAL;
>  		} else {
> +			struct intel_plane *linked =
> +				plane_state->planar_linked_plane;
> +
>  			mode = PS_SCALER_MODE_PLANAR;
>  
> -			if (plane_state->linked_plane)
> -				mode |= PS_PLANE_Y_SEL(plane_state->linked_plane->id);
> +			if (linked)
> +				mode |= PS_PLANE_Y_SEL(linked->id);
>  		}
>  	} else if (INTEL_GEN(dev_priv) > 9 || IS_GEMINILAKE(dev_priv)) {
>  		mode = PS_SCALER_MODE_NORMAL;
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 1f50b15ec704..a1a34b9981cc 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -321,9 +321,9 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>  
>  		if (new_plane_state->base.visible) {
>  			intel_update_plane(plane, new_crtc_state, new_plane_state);
> -		} else if (new_plane_state->slave) {
> +		} else if (new_plane_state->planar_slave) {
>  			struct intel_plane *master =
> -				new_plane_state->linked_plane;
> +				new_plane_state->planar_linked_plane;
>  
>  			/*
>  			 * We update the slave plane from this function because
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index fd8b398733b8..ba52a70840fd 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -11666,7 +11666,7 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
>  	int i;
>  
>  	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> -		linked = plane_state->linked_plane;
> +		linked = plane_state->planar_linked_plane;
>  
>  		if (!linked)
>  			continue;
> @@ -11675,8 +11675,8 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
>  		if (IS_ERR(linked_plane_state))
>  			return PTR_ERR(linked_plane_state);
>  
> -		WARN_ON(linked_plane_state->linked_plane != plane);
> -		WARN_ON(linked_plane_state->slave == plane_state->slave);
> +		WARN_ON(linked_plane_state->planar_linked_plane != plane);
> +		WARN_ON(linked_plane_state->planar_slave == plane_state->planar_slave);
>  	}
>  
>  	return 0;
> @@ -11699,16 +11699,16 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  	 * in the crtc_state->active_planes mask.
>  	 */
>  	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> -		if (plane->pipe != crtc->pipe || !plane_state->linked_plane)
> +		if (plane->pipe != crtc->pipe || !plane_state->planar_linked_plane)
>  			continue;
>  
> -		plane_state->linked_plane = NULL;
> -		if (plane_state->slave && !plane_state->base.visible) {
> +		plane_state->planar_linked_plane = NULL;
> +		if (plane_state->planar_slave && !plane_state->base.visible) {
>  			crtc_state->active_planes &= ~BIT(plane->id);
>  			crtc_state->update_planes |= BIT(plane->id);
>  		}
>  
> -		plane_state->slave = false;
> +		plane_state->planar_slave = false;
>  	}
>  
>  	if (!crtc_state->nv12_planes)
> @@ -11742,10 +11742,10 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  			return -EINVAL;
>  		}
>  
> -		plane_state->linked_plane = linked;
> +		plane_state->planar_linked_plane = linked;
>  
> -		linked_state->slave = true;
> -		linked_state->linked_plane = plane;
> +		linked_state->planar_slave = true;
> +		linked_state->planar_linked_plane = plane;
>  		crtc_state->active_planes |= BIT(linked->id);
>  		crtc_state->update_planes |= BIT(linked->id);
>  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
> @@ -13221,7 +13221,7 @@ intel_verify_planes(struct intel_atomic_state *state)
>  
>  	for_each_new_intel_plane_in_state(state, plane,
>  					  plane_state, i)
> -		assert_plane(plane, plane_state->slave ||
> +		assert_plane(plane, plane_state->planar_slave ||
>  			     plane_state->base.visible);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 57dbcfc126df..394f84e5d583 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -559,24 +559,24 @@ struct intel_plane_state {
>  	int scaler_id;
>  
>  	/*
> -	 * linked_plane:
> +	 * planar_linked_plane:
>  	 *
>  	 * ICL planar formats require 2 planes that are updated as pairs.
>  	 * This member is used to make sure the other plane is also updated
>  	 * when required, and for update_slave() to find the correct
>  	 * plane_state to pass as argument.
>  	 */
> -	struct intel_plane *linked_plane;
> +	struct intel_plane *planar_linked_plane;
>  
>  	/*
> -	 * slave:
> +	 * planar_slave:
>  	 * If set don't update use the linked plane's state for updating
>  	 * this plane during atomic commit with the update_slave() callback.
>  	 *
>  	 * It's also used by the watermark code to ignore wm calculations on
>  	 * this plane. They're calculated by the linked plane's wm code.
>  	 */
> -	u32 slave;
> +	u32 planar_slave;
>  
>  	struct drm_intel_sprite_colorkey ckey;
>  };
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index a602e21c5fd5..f0956fecdea4 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -543,7 +543,7 @@ skl_program_plane(struct intel_plane *plane,
>  	u32 y = plane_state->color_plane[color_plane].y;
>  	u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
>  	u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
> -	struct intel_plane *linked = plane_state->linked_plane;
> +	struct intel_plane *linked = plane_state->planar_linked_plane;
>  	const struct drm_framebuffer *fb = plane_state->base.fb;
>  	u8 alpha = plane_state->base.alpha >> 8;
>  	u32 plane_color_ctl = 0;
> @@ -642,7 +642,7 @@ skl_update_plane(struct intel_plane *plane,
>  {
>  	int color_plane = 0;
>  
> -	if (plane_state->linked_plane) {
> +	if (plane_state->planar_linked_plane) {
>  		/* Program the UV plane */
>  		color_plane = 1;
>  	}
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index edabf2cf4440..acc87b8431f3 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4291,7 +4291,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>  		u64 rate;
>  
> -		if (!plane_state->linked_plane) {
> +		if (!plane_state->planar_linked_plane) {
>  			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
>  			plane_data_rate[plane_id] = rate;
>  			total_data_rate += rate;
> @@ -4305,12 +4305,12 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  			 * NULL if we try get_new_plane_state(), so we
>  			 * always calculate from the master.
>  			 */
> -			if (plane_state->slave)
> +			if (plane_state->planar_slave)
>  				continue;
>  
>  			/* Y plane rate is calculated on the slave */
>  			rate = skl_plane_relative_data_rate(crtc_state, plane_state, 0);
> -			y_plane_id = plane_state->linked_plane->id;
> +			y_plane_id = plane_state->planar_linked_plane->id;
>  			plane_data_rate[y_plane_id] = rate;
>  			total_data_rate += rate;
>  
> @@ -5049,12 +5049,12 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
>  	int ret;
>  
>  	/* Watermarks calculated in master */
> -	if (plane_state->slave)
> +	if (plane_state->planar_slave)
>  		return 0;
>  
> -	if (plane_state->linked_plane) {
> +	if (plane_state->planar_linked_plane) {
>  		const struct drm_framebuffer *fb = plane_state->base.fb;
> -		enum plane_id y_plane_id = plane_state->linked_plane->id;
> +		enum plane_id y_plane_id = plane_state->planar_linked_plane->id;
>  
>  		WARN_ON(!intel_wm_plane_visible(crtc_state, plane_state));
>  		WARN_ON(!fb->format->is_yuv ||
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+
  2019-09-20 11:42 ` [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+ Maarten Lankhorst
@ 2019-09-25  4:55   ` Matt Roper
  2019-09-25 12:45     ` Maarten Lankhorst
  2019-09-25 13:02     ` Ville Syrjälä
  0 siblings, 2 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-25  4:55 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:21PM +0200, Maarten Lankhorst wrote:
> We cannot switch between HQ and normal mode on GLK+, so only
> add planes on platforms where it makes sense.
> 
> We could probably restrict it even more to only add when scaler
> users toggles between 1 and 2, but lets just leave it for now.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 158594e64bb9..c50e0b218bd6 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -421,6 +421,11 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
>  			 */
>  			if (!plane) {
>  				struct drm_plane_state *state;
> +
> +				/* No need to reprogram, we're not changing scaling mode */
> +				if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> +					continue;
> +

We could probably just combine this into the existing !plane condition
and enhance the comment above that to say "Note that GLK+ scalers don't
have a HQ mode so this isn't necessary on those platforms."

Either way,

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>


>  				plane = drm_plane_from_index(&dev_priv->drm, i);
>  				state = drm_atomic_get_plane_state(drm_state, plane);
>  				if (IS_ERR(state)) {
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
  2019-09-20 11:42 ` [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid() Maarten Lankhorst
@ 2019-09-25  5:30   ` Matt Roper
  2019-09-25  5:56     ` Matt Roper
  2019-09-25 22:09     ` Manasi Navare
  0 siblings, 2 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-25  5:30 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:22PM +0200, Maarten Lankhorst wrote:
> Small changes to intel_dp_mode_valid(), allow listing modes that
> can only be supported in the bigjoiner configuration, which is
> not supported yet.
> 
> Also unexport a few functions only used internally in intel_dp.c
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 98 +++++++++++++++++++------
>  1 file changed, 75 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 2fceb71f7f70..046e1662d1e3 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -247,7 +247,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>  }
>  
>  static int
> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> +intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
>  {
>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>  	struct intel_encoder *encoder = &intel_dig_port->base;
> @@ -257,6 +257,9 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
>  
>  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
>  
> +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11)
> +		max_dotclk *= 2;
> +

Should we be checking if the specific pipe can do big joiner on the
platform (gen11 vs gen12 differences) and also omitting eDP from
consideration?


>  	if (type != DP_DS_PORT_TYPE_VGA)
>  		return max_dotclk;
>  
> @@ -505,8 +508,10 @@ u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
>  		       1000000U);
>  }
>  
> -static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> -				       u32 mode_clock, u32 mode_hdisplay)
> +static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *dev_priv,
> +				       u32 link_clock, u32 lane_count,
> +				       u32 mode_clock, u32 mode_hdisplay,
> +				       bool bigjoiner)
>  {
>  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
>  	int i;
> @@ -523,6 +528,10 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>  
>  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
>  	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> +
> +	if (bigjoiner)
> +		max_bpp_small_joiner_ram *= 2;
> +

This change is correct, but while confirming in the bspec I noticed that
we may have the wrong DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER value for
gen11+.  It indicates 6144 for GLK, CNL, but 7680 for ICL+ (and double
that to 15360 when using big joiner).

Bspec: 20388
Bspec: 49259

>  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
>  
>  	/*
> @@ -531,6 +540,15 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>  	 */
>  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
>  
> +	if (bigjoiner) {
> +		u32 max_bpp_bigjoiner =
> +			dev_priv->max_cdclk_freq * 48 /
> +			intel_dp_mode_to_fec_clock(mode_clock);

Minor nitpick, but just to match the bspec (PPC * CDCLK * 24 bits /
pixel clock), I'd keep the 2 PPC and 24 bit factors separate here.

> +
> +		DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
> +		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
> +	}
> +
>  	/* Error out if the max bpp is less than smallest allowed valid bpp */
>  	if (bits_per_pixel < valid_dsc_bpp[0]) {
>  		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> @@ -553,7 +571,8 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>  }
>  
>  static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> -				       int mode_clock, int mode_hdisplay)
> +				       int mode_clock, int mode_hdisplay,
> +				       bool bigjoiner)
>  {
>  	u8 min_slice_count, i;
>  	int max_slice_width;
> @@ -578,12 +597,20 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
>  
>  	/* Find the closest match to the valid slice count values */
>  	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> -		if (valid_dsc_slicecount[i] >
> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> -						    false))
> +		u8 test_slice_count = bigjoiner ?
> +			2 * valid_dsc_slicecount[i] :
> +			valid_dsc_slicecount[i];
> +
> +		if (test_slice_count >
> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
>  			break;
> -		if (min_slice_count  <= valid_dsc_slicecount[i])
> -			return valid_dsc_slicecount[i];
> +
> +		/* big joiner needs small joiner to be enabled */
> +		if (bigjoiner && test_slice_count < 4)
> +			continue;
> +
> +		if (min_slice_count <= test_slice_count)
> +			return test_slice_count;
>  	}
>  
>  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> @@ -603,11 +630,15 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	int max_dotclk;
>  	u16 dsc_max_output_bpp = 0;
>  	u8 dsc_slice_count = 0;
> +	bool dsc = false, bigjoiner = false;
>  
>  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return MODE_NO_DBLESCAN;
>  
> -	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> +		return MODE_H_ILLEGAL;
> +
> +	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, false);
>  
>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>  		if (mode->hdisplay > fixed_mode->hdisplay)
> @@ -619,6 +650,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  		target_clock = fixed_mode->clock;
>  	}
>  
> +	if (mode->clock < 10000)
> +		return MODE_CLOCK_LOW;
> +
> +	if (target_clock > max_dotclk) {
> +		max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, true);
> +
> +		if (target_clock > max_dotclk)
> +			return MODE_CLOCK_HIGH;
> +
> +		bigjoiner = true;
> +	}
> +
>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>  
> @@ -639,26 +682,32 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  								true);
>  		} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
>  			dsc_max_output_bpp =
> -				intel_dp_dsc_get_output_bpp(max_link_clock,
> +				intel_dp_dsc_get_output_bpp(dev_priv,
> +							    max_link_clock,
>  							    max_lanes,
>  							    target_clock,
> -							    mode->hdisplay) >> 4;
> +							    mode->hdisplay,
> +							    bigjoiner) >> 4;
>  			dsc_slice_count =
>  				intel_dp_dsc_get_slice_count(intel_dp,
>  							     target_clock,
> -							     mode->hdisplay);
> +							     mode->hdisplay,
> +							     bigjoiner);
>  		}
> +
> +		dsc = dsc_max_output_bpp && dsc_slice_count;
>  	}
>  
> -	if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
> -	    target_clock > max_dotclk)
> +	/* big joiner configuration needs DSC */
> +	if (bigjoiner && !dsc) {
> +		DRM_DEBUG_KMS("Link clock needs bigjoiner, but DSC or FEC not available\n");
>  		return MODE_CLOCK_HIGH;
> +	}

Somewhere in this function we probably also need to make sure that the
big joiner is available on the pipe and that we're not using eDP.


Matt

>  
> -	if (mode->clock < 10000)
> -		return MODE_CLOCK_LOW;
> -
> -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> -		return MODE_H_ILLEGAL;
> +	if (mode_rate > max_rate && !dsc) {
> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> +		return MODE_CLOCK_HIGH;
> +	}
>  
>  	return intel_mode_valid_max_plane_size(dev_priv, mode);
>  }
> @@ -2068,14 +2117,17 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  		u8 dsc_dp_slice_count;
>  
>  		dsc_max_output_bpp =
> -			intel_dp_dsc_get_output_bpp(pipe_config->port_clock,
> +			intel_dp_dsc_get_output_bpp(dev_priv,
> +						    pipe_config->port_clock,
>  						    pipe_config->lane_count,
>  						    adjusted_mode->crtc_clock,
> -						    adjusted_mode->crtc_hdisplay);
> +						    adjusted_mode->crtc_hdisplay,
> +						    false);
>  		dsc_dp_slice_count =
>  			intel_dp_dsc_get_slice_count(intel_dp,
>  						     adjusted_mode->crtc_clock,
> -						     adjusted_mode->crtc_hdisplay);
> +						     adjusted_mode->crtc_hdisplay,
> +						     false);
>  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
>  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
>  			return -EINVAL;
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
  2019-09-25  5:30   ` Matt Roper
@ 2019-09-25  5:56     ` Matt Roper
  2019-09-25 22:09     ` Manasi Navare
  1 sibling, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-25  5:56 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Tue, Sep 24, 2019 at 10:30:39PM -0700, Matt Roper wrote:
> On Fri, Sep 20, 2019 at 01:42:22PM +0200, Maarten Lankhorst wrote:
> > Small changes to intel_dp_mode_valid(), allow listing modes that
> > can only be supported in the bigjoiner configuration, which is
> > not supported yet.
> > 
> > Also unexport a few functions only used internally in intel_dp.c
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp.c | 98 +++++++++++++++++++------
> >  1 file changed, 75 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 2fceb71f7f70..046e1662d1e3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -247,7 +247,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> >  }
> >  
> >  static int
> > -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> > +intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> >  {
> >  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> >  	struct intel_encoder *encoder = &intel_dig_port->base;
> > @@ -257,6 +257,9 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> >  
> >  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
> >  
> > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11)
> > +		max_dotclk *= 2;
> > +
> 
> Should we be checking if the specific pipe can do big joiner on the
> platform (gen11 vs gen12 differences) and also omitting eDP from
> consideration?
> 
> 
> >  	if (type != DP_DS_PORT_TYPE_VGA)
> >  		return max_dotclk;
> >  
> > @@ -505,8 +508,10 @@ u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> >  		       1000000U);
> >  }
> >  
> > -static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> > -				       u32 mode_clock, u32 mode_hdisplay)
> > +static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *dev_priv,
> > +				       u32 link_clock, u32 lane_count,
> > +				       u32 mode_clock, u32 mode_hdisplay,
> > +				       bool bigjoiner)
> >  {
> >  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> >  	int i;
> > @@ -523,6 +528,10 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  
> >  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> >  	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> > +
> > +	if (bigjoiner)
> > +		max_bpp_small_joiner_ram *= 2;
> > +
> 
> This change is correct, but while confirming in the bspec I noticed that
> we may have the wrong DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER value for
> gen11+.  It indicates 6144 for GLK, CNL, but 7680 for ICL+ (and double
> that to 15360 when using big joiner).

Sorry, meant to say wrong value for < gen11.  The current 61440 value we
use is 8 bits * 7680, so it's correct for gen11+, but too big for
GLK/CNL.

I just sent a simple patch to make the value platform-specific:
        https://patchwork.freedesktop.org/series/67195/


Matt

> 
> Bspec: 20388
> Bspec: 49259
> 
> >  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> >  
> >  	/*
> > @@ -531,6 +540,15 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  	 */
> >  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> >  
> > +	if (bigjoiner) {
> > +		u32 max_bpp_bigjoiner =
> > +			dev_priv->max_cdclk_freq * 48 /
> > +			intel_dp_mode_to_fec_clock(mode_clock);
> 
> Minor nitpick, but just to match the bspec (PPC * CDCLK * 24 bits /
> pixel clock), I'd keep the 2 PPC and 24 bit factors separate here.
> 
> > +
> > +		DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
> > +		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
> > +	}
> > +
> >  	/* Error out if the max bpp is less than smallest allowed valid bpp */
> >  	if (bits_per_pixel < valid_dsc_bpp[0]) {
> >  		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> > @@ -553,7 +571,8 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  }
> >  
> >  static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > -				       int mode_clock, int mode_hdisplay)
> > +				       int mode_clock, int mode_hdisplay,
> > +				       bool bigjoiner)
> >  {
> >  	u8 min_slice_count, i;
> >  	int max_slice_width;
> > @@ -578,12 +597,20 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> >  
> >  	/* Find the closest match to the valid slice count values */
> >  	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > -		if (valid_dsc_slicecount[i] >
> > -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > -						    false))
> > +		u8 test_slice_count = bigjoiner ?
> > +			2 * valid_dsc_slicecount[i] :
> > +			valid_dsc_slicecount[i];
> > +
> > +		if (test_slice_count >
> > +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
> >  			break;
> > -		if (min_slice_count  <= valid_dsc_slicecount[i])
> > -			return valid_dsc_slicecount[i];
> > +
> > +		/* big joiner needs small joiner to be enabled */
> > +		if (bigjoiner && test_slice_count < 4)
> > +			continue;
> > +
> > +		if (min_slice_count <= test_slice_count)
> > +			return test_slice_count;
> >  	}
> >  
> >  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > @@ -603,11 +630,15 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  	int max_dotclk;
> >  	u16 dsc_max_output_bpp = 0;
> >  	u8 dsc_slice_count = 0;
> > +	bool dsc = false, bigjoiner = false;
> >  
> >  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> >  		return MODE_NO_DBLESCAN;
> >  
> > -	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
> > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> > +		return MODE_H_ILLEGAL;
> > +
> > +	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, false);
> >  
> >  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
> >  		if (mode->hdisplay > fixed_mode->hdisplay)
> > @@ -619,6 +650,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  		target_clock = fixed_mode->clock;
> >  	}
> >  
> > +	if (mode->clock < 10000)
> > +		return MODE_CLOCK_LOW;
> > +
> > +	if (target_clock > max_dotclk) {
> > +		max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, true);
> > +
> > +		if (target_clock > max_dotclk)
> > +			return MODE_CLOCK_HIGH;
> > +
> > +		bigjoiner = true;
> > +	}
> > +
> >  	max_link_clock = intel_dp_max_link_rate(intel_dp);
> >  	max_lanes = intel_dp_max_lane_count(intel_dp);
> >  
> > @@ -639,26 +682,32 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  								true);
> >  		} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
> >  			dsc_max_output_bpp =
> > -				intel_dp_dsc_get_output_bpp(max_link_clock,
> > +				intel_dp_dsc_get_output_bpp(dev_priv,
> > +							    max_link_clock,
> >  							    max_lanes,
> >  							    target_clock,
> > -							    mode->hdisplay) >> 4;
> > +							    mode->hdisplay,
> > +							    bigjoiner) >> 4;
> >  			dsc_slice_count =
> >  				intel_dp_dsc_get_slice_count(intel_dp,
> >  							     target_clock,
> > -							     mode->hdisplay);
> > +							     mode->hdisplay,
> > +							     bigjoiner);
> >  		}
> > +
> > +		dsc = dsc_max_output_bpp && dsc_slice_count;
> >  	}
> >  
> > -	if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
> > -	    target_clock > max_dotclk)
> > +	/* big joiner configuration needs DSC */
> > +	if (bigjoiner && !dsc) {
> > +		DRM_DEBUG_KMS("Link clock needs bigjoiner, but DSC or FEC not available\n");
> >  		return MODE_CLOCK_HIGH;
> > +	}
> 
> Somewhere in this function we probably also need to make sure that the
> big joiner is available on the pipe and that we're not using eDP.
> 
> 
> Matt
> 
> >  
> > -	if (mode->clock < 10000)
> > -		return MODE_CLOCK_LOW;
> > -
> > -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> > -		return MODE_H_ILLEGAL;
> > +	if (mode_rate > max_rate && !dsc) {
> > +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> > +		return MODE_CLOCK_HIGH;
> > +	}
> >  
> >  	return intel_mode_valid_max_plane_size(dev_priv, mode);
> >  }
> > @@ -2068,14 +2117,17 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
> >  		u8 dsc_dp_slice_count;
> >  
> >  		dsc_max_output_bpp =
> > -			intel_dp_dsc_get_output_bpp(pipe_config->port_clock,
> > +			intel_dp_dsc_get_output_bpp(dev_priv,
> > +						    pipe_config->port_clock,
> >  						    pipe_config->lane_count,
> >  						    adjusted_mode->crtc_clock,
> > -						    adjusted_mode->crtc_hdisplay);
> > +						    adjusted_mode->crtc_hdisplay,
> > +						    false);
> >  		dsc_dp_slice_count =
> >  			intel_dp_dsc_get_slice_count(intel_dp,
> >  						     adjusted_mode->crtc_clock,
> > -						     adjusted_mode->crtc_hdisplay);
> > +						     adjusted_mode->crtc_hdisplay,
> > +						     false);
> >  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
> >  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
> >  			return -EINVAL;
> > -- 
> > 2.20.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state
  2019-09-24 23:40   ` Matt Roper
@ 2019-09-25  9:09     ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25  9:09 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 25-09-2019 om 01:40 schreef Matt Roper:
> On Fri, Sep 20, 2019 at 01:42:15PM +0200, Maarten Lankhorst wrote:
>> We want to split drm_crtc_state into the user visible state
>> and actual hardware state. To prepare for this, we need some
>> ground rules what should be in each state:
>>
>> In uapi we use:
>> - crtc, *_changed flags, event, commit, state, mode_blob, (plane/connector/encoder)_mask.
>>
>> In hw state we use what's displayed in hardware:
>> - enable, active, (adjusted) mode, color property blobs.
> I'd suggest elaborating a bit that the union we add in this patch is
> just an intermediate step and that the end goal is that we'll eventually
> be maintaining two separate copies of some of the data.
Yeah ok, will clear up commit message.
>> clear_intel_crtc_state and hw readout need to be updated for these rules,
>> which will allow us to enable 2 joined pipes.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> It might be worth providing some Coccinelle rules to apply these changes
> in a semi-automated manner; otherwise it's going to be a hassle to
> constantly resolve conflicts with pretty much any other display patches
> that land upstream.
>
> Otherwise,
>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

I tried, but it has to be resolved manually, spatch won't help.

For example when enabling a crtc, you have to set crtc_state->uapi.active,
which in atomic check gets copied to hw.active. If you set hw.active directly,
it will be ignored or cleared.

So before atomic_check() -> use uapi.
During atomic_check() and commit() -> use hw.

~Maarten



>> ---
>>  drivers/gpu/drm/i915/display/icl_dsi.c        |  18 +-
>>  drivers/gpu/drm/i915/display/intel_atomic.c   |  14 +-
>>  .../gpu/drm/i915/display/intel_atomic_plane.c |   6 +-
>>  drivers/gpu/drm/i915/display/intel_audio.c    |  12 +-
>>  drivers/gpu/drm/i915/display/intel_bw.c       |   4 +-
>>  drivers/gpu/drm/i915/display/intel_cdclk.c    |  16 +-
>>  drivers/gpu/drm/i915/display/intel_color.c    | 180 +++---
>>  drivers/gpu/drm/i915/display/intel_crt.c      |  24 +-
>>  drivers/gpu/drm/i915/display/intel_ddi.c      |  34 +-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 540 +++++++++---------
>>  .../drm/i915/display/intel_display_types.h    |  28 +-
>>  drivers/gpu/drm/i915/display/intel_dp.c       |  42 +-
>>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   6 +-
>>  drivers/gpu/drm/i915/display/intel_dpio_phy.c |  14 +-
>>  drivers/gpu/drm/i915/display/intel_dpll_mgr.c |  20 +-
>>  drivers/gpu/drm/i915/display/intel_dvo.c      |  14 +-
>>  drivers/gpu/drm/i915/display/intel_fbc.c      |   2 +-
>>  drivers/gpu/drm/i915/display/intel_hdmi.c     |  62 +-
>>  drivers/gpu/drm/i915/display/intel_lspcon.c   |   4 +-
>>  drivers/gpu/drm/i915/display/intel_lvds.c     |  12 +-
>>  drivers/gpu/drm/i915/display/intel_panel.c    |  14 +-
>>  drivers/gpu/drm/i915/display/intel_pipe_crc.c |   6 +-
>>  drivers/gpu/drm/i915/display/intel_psr.c      |  10 +-
>>  drivers/gpu/drm/i915/display/intel_sdvo.c     |  22 +-
>>  drivers/gpu/drm/i915/display/intel_sprite.c   |  25 +-
>>  drivers/gpu/drm/i915/display/intel_tv.c       |   8 +-
>>  drivers/gpu/drm/i915/display/intel_vdsc.c     |  12 +-
>>  drivers/gpu/drm/i915/display/vlv_dsi.c        |  20 +-
>>  drivers/gpu/drm/i915/i915_debugfs.c           |  14 +-
>>  drivers/gpu/drm/i915/intel_pm.c               | 180 +++---
>>  30 files changed, 699 insertions(+), 664 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
>> index 6e398c33a524..0e24b8e257e5 100644
>> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
>> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
>> @@ -276,7 +276,7 @@ static void configure_dual_link_mode(struct intel_encoder *encoder,
>>  
>>  	if (intel_dsi->dual_link == DSI_DUAL_LINK_FRONT_BACK) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -					&pipe_config->base.adjusted_mode;
>> +					&pipe_config->hw.adjusted_mode;
>>  		u32 dss_ctl2;
>>  		u16 hactive = adjusted_mode->crtc_hdisplay;
>>  		u16 dl_buffer_depth;
>> @@ -625,7 +625,7 @@ gen11_dsi_configure_transcoder(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	enum pipe pipe = intel_crtc->pipe;
>>  	u32 tmp;
>>  	enum port port;
>> @@ -768,7 +768,7 @@ gen11_dsi_set_transcoder_timings(struct intel_encoder *encoder,
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>>  	const struct drm_display_mode *adjusted_mode =
>> -					&pipe_config->base.adjusted_mode;
>> +					&pipe_config->hw.adjusted_mode;
>>  	enum port port;
>>  	enum transcoder dsi_trans;
>>  	/* horizontal timings */
>> @@ -1216,7 +1216,7 @@ static void gen11_dsi_get_timings(struct intel_encoder *encoder,
>>  {
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>>  	struct drm_display_mode *adjusted_mode =
>> -					&pipe_config->base.adjusted_mode;
>> +					&pipe_config->hw.adjusted_mode;
>>  
>>  	if (intel_dsi->dual_link) {
>>  		adjusted_mode->crtc_hdisplay *= 2;
>> @@ -1242,16 +1242,16 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>>  				 struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>>  
>>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>>  	pipe_config->port_clock =
>>  		cnl_calc_wrpll_link(dev_priv, &pipe_config->dpll_hw_state);
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = intel_dsi->pclk;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = intel_dsi->pclk;
>>  	if (intel_dsi->dual_link)
>> -		pipe_config->base.adjusted_mode.crtc_clock *= 2;
>> +		pipe_config->hw.adjusted_mode.crtc_clock *= 2;
>>  
>>  	gen11_dsi_get_timings(encoder, pipe_config);
>>  	pipe_config->output_types |= BIT(INTEL_OUTPUT_DSI);
>> @@ -1265,11 +1265,11 @@ static int gen11_dsi_compute_config(struct intel_encoder *encoder,
>>  	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
>>  						   base);
>>  	struct intel_connector *intel_connector = intel_dsi->attached_connector;
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	const struct drm_display_mode *fixed_mode =
>>  					intel_connector->panel.fixed_mode;
>>  	struct drm_display_mode *adjusted_mode =
>> -					&pipe_config->base.adjusted_mode;
>> +					&pipe_config->hw.adjusted_mode;
>>  
>>  	pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
>>  	intel_fixed_panel_mode(fixed_mode, adjusted_mode);
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index 698802da07b7..f4440ede95c5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -186,13 +186,14 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector)
>>  struct drm_crtc_state *
>>  intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  {
>> +	const struct intel_crtc_state *old_crtc_state = to_intel_crtc_state(crtc->state);
>>  	struct intel_crtc_state *crtc_state;
>>  
>> -	crtc_state = kmemdup(crtc->state, sizeof(*crtc_state), GFP_KERNEL);
>> +	crtc_state = kmemdup(old_crtc_state, sizeof(*crtc_state), GFP_KERNEL);
>>  	if (!crtc_state)
>>  		return NULL;
>>  
>> -	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->base);
>> +	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>>  
>>  	crtc_state->update_pipe = false;
>>  	crtc_state->disable_lp_wm = false;
>> @@ -205,7 +206,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  	crtc_state->fb_bits = 0;
>>  	crtc_state->update_planes = 0;
>>  
>> -	return &crtc_state->base;
>> +	return &crtc_state->uapi;
>>  }
>>  
>>  /**
>> @@ -220,7 +221,10 @@ void
>>  intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  			 struct drm_crtc_state *state)
>>  {
>> -	drm_atomic_helper_crtc_destroy_state(crtc, state);
>> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
>> +
>> +	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>> +	kfree(crtc_state);
>>  }
>>  
>>  static void intel_atomic_setup_scaler(struct intel_crtc_scaler_state *scaler_state,
>> @@ -316,7 +320,7 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
>>  	struct intel_plane_state *plane_state = NULL;
>>  	struct intel_crtc_scaler_state *scaler_state =
>>  		&crtc_state->scaler_state;
>> -	struct drm_atomic_state *drm_state = crtc_state->base.state;
>> +	struct drm_atomic_state *drm_state = crtc_state->uapi.state;
>>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
>>  	int num_scalers_need;
>>  	int i;
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> index 476ef0906ba0..1f50b15ec704 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> @@ -271,7 +271,7 @@ void intel_update_plane(struct intel_plane *plane,
>>  			const struct intel_crtc_state *crtc_state,
>>  			const struct intel_plane_state *plane_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	trace_intel_update_plane(&plane->base, crtc);
>>  	plane->update_plane(plane, crtc_state, plane_state);
>> @@ -281,7 +281,7 @@ void intel_update_slave(struct intel_plane *plane,
>>  			const struct intel_crtc_state *crtc_state,
>>  			const struct intel_plane_state *plane_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	trace_intel_update_plane(&plane->base, crtc);
>>  	plane->update_slave(plane, crtc_state, plane_state);
>> @@ -290,7 +290,7 @@ void intel_update_slave(struct intel_plane *plane,
>>  void intel_disable_plane(struct intel_plane *plane,
>>  			 const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	trace_intel_disable_plane(&plane->base, crtc);
>>  	plane->disable_plane(plane, crtc_state);
>> diff --git a/drivers/gpu/drm/i915/display/intel_audio.c b/drivers/gpu/drm/i915/display/intel_audio.c
>> index aac089c79ceb..2ecf1df0eeda 100644
>> --- a/drivers/gpu/drm/i915/display/intel_audio.c
>> +++ b/drivers/gpu/drm/i915/display/intel_audio.c
>> @@ -233,7 +233,7 @@ static const struct hdmi_aud_ncts hdmi_aud_ncts_36bpp[] = {
>>  static u32 audio_config_hdmi_pixel_clock(const struct intel_crtc_state *crtc_state)
>>  {
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	int i;
>>  
>>  	for (i = 0; i < ARRAY_SIZE(hdmi_audio_clock); i++) {
>> @@ -554,7 +554,7 @@ static void ilk_audio_codec_disable(struct intel_encoder *encoder,
>>  				    const struct drm_connector_state *old_conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	enum pipe pipe = crtc->pipe;
>>  	enum port port = encoder->port;
>>  	u32 tmp, eldv;
>> @@ -601,7 +601,7 @@ static void ilk_audio_codec_enable(struct intel_encoder *encoder,
>>  				   const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_connector *connector = conn_state->connector;
>>  	enum pipe pipe = crtc->pipe;
>>  	enum port port = encoder->port;
>> @@ -691,10 +691,10 @@ void intel_audio_codec_enable(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_connector *connector = conn_state->connector;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	enum port port = encoder->port;
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -752,7 +752,7 @@ void intel_audio_codec_disable(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct i915_audio_component *acomp = dev_priv->audio_component;
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	enum port port = encoder->port;
>>  	enum pipe pipe = crtc->pipe;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c
>> index 688858ebe4d0..a83a297be9a4 100644
>> --- a/drivers/gpu/drm/i915/display/intel_bw.c
>> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
>> @@ -264,7 +264,7 @@ static unsigned int intel_bw_crtc_num_active_planes(const struct intel_crtc_stat
>>  
>>  static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	unsigned int data_rate = 0;
>>  	enum plane_id plane_id;
>>  
>> @@ -285,7 +285,7 @@ static unsigned int intel_bw_crtc_data_rate(const struct intel_crtc_state *crtc_
>>  void intel_bw_crtc_update(struct intel_bw_state *bw_state,
>>  			  const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	bw_state->data_rate[crtc->pipe] =
>>  		intel_bw_crtc_data_rate(crtc_state);
>> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
>> index 43564295b864..17ffe7fbaa21 100644
>> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
>> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
>> @@ -1917,10 +1917,10 @@ static int intel_pixel_rate_to_cdclk(struct drm_i915_private *dev_priv,
>>  int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv =
>> -		to_i915(crtc_state->base.crtc->dev);
>> +		to_i915(crtc_state->uapi.crtc->dev);
>>  	int min_cdclk;
>>  
>> -	if (!crtc_state->base.enable)
>> +	if (!crtc_state->hw.enable)
>>  		return 0;
>>  
>>  	min_cdclk = intel_pixel_rate_to_cdclk(dev_priv, crtc_state->pixel_rate);
>> @@ -2043,7 +2043,7 @@ static u8 bxt_compute_min_voltage_level(struct intel_atomic_state *state)
>>  	       sizeof(state->min_voltage_level));
>>  
>>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
>> -		if (crtc_state->base.enable)
>> +		if (crtc_state->hw.enable)
>>  			state->min_voltage_level[i] =
>>  				crtc_state->min_voltage_level;
>>  		else
>> @@ -2129,7 +2129,7 @@ static int skl_dpll0_vco(struct intel_atomic_state *state)
>>  		vco = dev_priv->skl_preferred_vco_freq;
>>  
>>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
>> -		if (!crtc_state->base.enable)
>> +		if (!crtc_state->hw.enable)
>>  			continue;
>>  
>>  		if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP))
>> @@ -2255,11 +2255,11 @@ static int intel_modeset_all_pipes(struct intel_atomic_state *state)
>>  		if (IS_ERR(crtc_state))
>>  			return PTR_ERR(crtc_state);
>>  
>> -		if (!crtc_state->base.active ||
>> -		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
>> +		if (!crtc_state->hw.active ||
>> +		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
>>  			continue;
>>  
>> -		crtc_state->base.mode_changed = true;
>> +		crtc_state->uapi.mode_changed = true;
>>  
>>  		ret = drm_atomic_add_affected_connectors(&state->base,
>>  							 &crtc->base);
>> @@ -2310,7 +2310,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state *state)
>>  		crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
>>  		crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>>  		if (crtc_state &&
>> -		    drm_atomic_crtc_needs_modeset(&crtc_state->base))
>> +		    drm_atomic_crtc_needs_modeset(&crtc_state->uapi))
>>  			pipe = INVALID_PIPE;
>>  	} else {
>>  		pipe = INVALID_PIPE;
>> diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
>> index 318308dc136c..9b058907ef4e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_color.c
>> +++ b/drivers/gpu/drm/i915/display/intel_color.c
>> @@ -101,10 +101,10 @@ static bool lut_is_legacy(const struct drm_property_blob *lut)
>>  
>>  static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
>>  {
>> -	return !crtc_state->base.degamma_lut &&
>> -		!crtc_state->base.ctm &&
>> -		crtc_state->base.gamma_lut &&
>> -		lut_is_legacy(crtc_state->base.gamma_lut);
>> +	return !crtc_state->hw.degamma_lut &&
>> +		!crtc_state->hw.ctm &&
>> +		crtc_state->hw.gamma_lut &&
>> +		lut_is_legacy(crtc_state->hw.gamma_lut);
>>  }
>>  
>>  /*
>> @@ -189,7 +189,7 @@ static void icl_update_output_csc(struct intel_crtc *crtc,
>>  
>>  static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	/*
>>  	 * FIXME if there's a gamma LUT after the CSC, we should
>> @@ -203,7 +203,7 @@ static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
>>  static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
>>  				u16 coeffs[9])
>>  {
>> -	const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
>> +	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
>>  	const u64 *input;
>>  	u64 temp[9];
>>  	int i;
>> @@ -254,11 +254,11 @@ static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
>>  
>>  static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	bool limited_color_range = ilk_csc_limited_range(crtc_state);
>>  
>> -	if (crtc_state->base.ctm) {
>> +	if (crtc_state->hw.ctm) {
>>  		u16 coeff[9];
>>  
>>  		ilk_csc_convert_ctm(crtc_state, coeff);
>> @@ -293,10 +293,10 @@ static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>>  
>>  static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>> -	if (crtc_state->base.ctm) {
>> +	if (crtc_state->hw.ctm) {
>>  		u16 coeff[9];
>>  
>>  		ilk_csc_convert_ctm(crtc_state, coeff);
>> @@ -322,12 +322,12 @@ static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>>   */
>>  static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> -	if (crtc_state->base.ctm) {
>> -		const struct drm_color_ctm *ctm = crtc_state->base.ctm->data;
>> +	if (crtc_state->hw.ctm) {
>> +		const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
>>  		u16 coeffs[9] = {};
>>  		int i;
>>  
>> @@ -388,7 +388,7 @@ static u32 ilk_lut_10(const struct drm_color_lut *color)
>>  static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
>>  				    const struct drm_property_blob *blob)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	int i;
>> @@ -419,12 +419,12 @@ static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
>>  
>>  static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	i9xx_load_luts_internal(crtc_state, crtc_state->base.gamma_lut);
>> +	i9xx_load_luts_internal(crtc_state, crtc_state->hw.gamma_lut);
>>  }
>>  
>>  static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val;
>> @@ -437,7 +437,7 @@ static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
>>  
>>  static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val;
>> @@ -452,7 +452,7 @@ static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
>>  
>>  static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
>> @@ -462,7 +462,7 @@ static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
>>  
>>  static void skl_color_commit(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val = 0;
>> @@ -508,8 +508,8 @@ static void i965_load_lut_10p6(struct intel_crtc *crtc,
>>  
>>  static void i965_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>>  
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>>  		i9xx_load_luts(crtc_state);
>> @@ -531,8 +531,8 @@ static void ilk_load_lut_10(struct intel_crtc *crtc,
>>  
>>  static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>>  
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>>  		i9xx_load_luts(crtc_state);
>> @@ -632,9 +632,9 @@ static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
>>  
>>  static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>>  
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
>>  		i9xx_load_luts(crtc_state);
>> @@ -655,9 +655,9 @@ static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
>>  
>>  static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>>  
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
>>  		i9xx_load_luts(crtc_state);
>> @@ -678,11 +678,11 @@ static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
>>  
>>  static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
>> -	const struct drm_color_lut *lut = crtc_state->base.degamma_lut->data;
>> +	const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
>>  	u32 i;
>>  
>>  	/*
>> @@ -717,7 +717,7 @@ static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
>>  
>>  static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
>> @@ -744,8 +744,8 @@ static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_stat
>>  
>>  static void glk_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	/*
>>  	 * On GLK+ both pipe CSC and degamma LUT are controlled
>> @@ -755,7 +755,7 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
>>  	 * the degama LUT so that we don't have to reload
>>  	 * it every time the pipe CSC is being enabled.
>>  	 */
>> -	if (crtc_state->base.degamma_lut)
>> +	if (crtc_state->hw.degamma_lut)
>>  		glk_load_degamma_lut(crtc_state);
>>  	else
>>  		glk_load_degamma_lut_linear(crtc_state);
>> @@ -786,7 +786,7 @@ static void
>>  icl_load_gcmax(const struct intel_crtc_state *crtc_state,
>>  	       const struct drm_color_lut *color)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -799,9 +799,9 @@ icl_load_gcmax(const struct intel_crtc_state *crtc_state,
>>  static void
>>  icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
>> +	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
>>  	const struct drm_color_lut *lut = blob->data;
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 i;
>> @@ -828,9 +828,9 @@ icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
>>  static void
>>  icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	const struct drm_property_blob *blob = crtc_state->base.gamma_lut;
>> +	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
>>  	const struct drm_color_lut *lut = blob->data;
>>  	const struct drm_color_lut *entry;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -880,10 +880,10 @@ icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
>>  
>>  static void icl_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>> -	if (crtc_state->base.degamma_lut)
>> +	if (crtc_state->hw.degamma_lut)
>>  		glk_load_degamma_lut(crtc_state);
>>  
>>  	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
>> @@ -958,9 +958,9 @@ static void chv_load_cgm_gamma(struct intel_crtc *crtc,
>>  
>>  static void chv_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>>  
>>  	cherryview_load_csc_matrix(crtc_state);
>>  
>> @@ -978,28 +978,28 @@ static void chv_load_luts(const struct intel_crtc_state *crtc_state)
>>  
>>  void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	dev_priv->display.load_luts(crtc_state);
>>  }
>>  
>>  void intel_color_commit(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	dev_priv->display.color_commit(crtc_state);
>>  }
>>  
>>  int intel_color_check(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	return dev_priv->display.color_check(crtc_state);
>>  }
>>  
>>  void intel_color_get_config(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	if (dev_priv->display.read_luts)
>>  		dev_priv->display.read_luts(crtc_state);
>> @@ -1023,16 +1023,16 @@ static bool need_plane_update(struct intel_plane *plane,
>>  static int
>>  intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(new_crtc_state->base.state);
>> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>>  	const struct intel_crtc_state *old_crtc_state =
>>  		intel_atomic_get_old_crtc_state(state, crtc);
>>  	struct intel_plane *plane;
>>  
>> -	if (!new_crtc_state->base.active ||
>> -	    drm_atomic_crtc_needs_modeset(&new_crtc_state->base))
>> +	if (!new_crtc_state->hw.active ||
>> +	    drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
>>  		return 0;
>>  
>>  	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
>> @@ -1074,9 +1074,9 @@ static int check_lut_size(const struct drm_property_blob *lut, int expected)
>>  
>>  static int check_luts(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut;
>> -	const struct drm_property_blob *degamma_lut = crtc_state->base.degamma_lut;
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
>> +	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
>>  	int gamma_length, degamma_length;
>>  	u32 gamma_tests, degamma_tests;
>>  
>> @@ -1124,7 +1124,7 @@ static int i9xx_color_check(struct intel_crtc_state *crtc_state)
>>  		return ret;
>>  
>>  	crtc_state->gamma_enable =
>> -		crtc_state->base.gamma_lut &&
>> +		crtc_state->hw.gamma_lut &&
>>  		!crtc_state->c8_planes;
>>  
>>  	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
>> @@ -1143,11 +1143,11 @@ static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
>>  	if (crtc_state_is_legacy_gamma(crtc_state))
>>  		return 0;
>>  
>> -	if (crtc_state->base.degamma_lut)
>> +	if (crtc_state->hw.degamma_lut)
>>  		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
>> -	if (crtc_state->base.ctm)
>> +	if (crtc_state->hw.ctm)
>>  		cgm_mode |= CGM_PIPE_MODE_CSC;
>> -	if (crtc_state->base.gamma_lut)
>> +	if (crtc_state->hw.gamma_lut)
>>  		cgm_mode |= CGM_PIPE_MODE_GAMMA;
>>  
>>  	return cgm_mode;
>> @@ -1206,7 +1206,7 @@ static int ilk_color_check(struct intel_crtc_state *crtc_state)
>>  		return ret;
>>  
>>  	crtc_state->gamma_enable =
>> -		crtc_state->base.gamma_lut &&
>> +		crtc_state->hw.gamma_lut &&
>>  		!crtc_state->c8_planes;
>>  
>>  	/*
>> @@ -1232,8 +1232,8 @@ static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
>>  	if (!crtc_state->gamma_enable ||
>>  	    crtc_state_is_legacy_gamma(crtc_state))
>>  		return GAMMA_MODE_MODE_8BIT;
>> -	else if (crtc_state->base.gamma_lut &&
>> -		 crtc_state->base.degamma_lut)
>> +	else if (crtc_state->hw.gamma_lut &&
>> +		 crtc_state->hw.degamma_lut)
>>  		return GAMMA_MODE_MODE_SPLIT;
>>  	else
>>  		return GAMMA_MODE_MODE_10BIT;
>> @@ -1247,7 +1247,7 @@ static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
>>  	 * CSC comes after the LUT in degamma, RGB->YCbCr,
>>  	 * and RGB full->limited range mode.
>>  	 */
>> -	if (crtc_state->base.degamma_lut ||
>> +	if (crtc_state->hw.degamma_lut ||
>>  	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
>>  	    limited_color_range)
>>  		return 0;
>> @@ -1265,13 +1265,13 @@ static int ivb_color_check(struct intel_crtc_state *crtc_state)
>>  		return ret;
>>  
>>  	crtc_state->gamma_enable =
>> -		(crtc_state->base.gamma_lut ||
>> -		 crtc_state->base.degamma_lut) &&
>> +		(crtc_state->hw.gamma_lut ||
>> +		 crtc_state->hw.degamma_lut) &&
>>  		!crtc_state->c8_planes;
>>  
>>  	crtc_state->csc_enable =
>>  		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
>> -		crtc_state->base.ctm || limited_color_range;
>> +		crtc_state->hw.ctm || limited_color_range;
>>  
>>  	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
>>  
>> @@ -1302,14 +1302,14 @@ static int glk_color_check(struct intel_crtc_state *crtc_state)
>>  		return ret;
>>  
>>  	crtc_state->gamma_enable =
>> -		crtc_state->base.gamma_lut &&
>> +		crtc_state->hw.gamma_lut &&
>>  		!crtc_state->c8_planes;
>>  
>>  	/* On GLK+ degamma LUT is controlled by csc_enable */
>>  	crtc_state->csc_enable =
>> -		crtc_state->base.degamma_lut ||
>> +		crtc_state->hw.degamma_lut ||
>>  		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
>> -		crtc_state->base.ctm || crtc_state->limited_color_range;
>> +		crtc_state->hw.ctm || crtc_state->limited_color_range;
>>  
>>  	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
>>  
>> @@ -1326,14 +1326,14 @@ static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
>>  {
>>  	u32 gamma_mode = 0;
>>  
>> -	if (crtc_state->base.degamma_lut)
>> +	if (crtc_state->hw.degamma_lut)
>>  		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
>>  
>> -	if (crtc_state->base.gamma_lut &&
>> +	if (crtc_state->hw.gamma_lut &&
>>  	    !crtc_state->c8_planes)
>>  		gamma_mode |= POST_CSC_GAMMA_ENABLE;
>>  
>> -	if (!crtc_state->base.gamma_lut ||
>> +	if (!crtc_state->hw.gamma_lut ||
>>  	    crtc_state_is_legacy_gamma(crtc_state))
>>  		gamma_mode |= GAMMA_MODE_MODE_8BIT;
>>  	else
>> @@ -1346,7 +1346,7 @@ static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
>>  {
>>  	u32 csc_mode = 0;
>>  
>> -	if (crtc_state->base.ctm)
>> +	if (crtc_state->hw.ctm)
>>  		csc_mode |= ICL_CSC_ENABLE;
>>  
>>  	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
>> @@ -1423,7 +1423,7 @@ static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
>>  
>>  int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!crtc_state->gamma_enable)
>> @@ -1532,7 +1532,7 @@ static u32 intel_color_lut_pack(u32 val, u32 bit_precision)
>>  static struct drm_property_blob *
>>  i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	struct drm_property_blob *blob;
>> @@ -1566,13 +1566,13 @@ i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
>>  
>>  static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
>>  {
>> -	crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
>> +	crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>>  }
>>  
>>  static struct drm_property_blob *
>>  i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1613,15 +1613,15 @@ i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
>>  static void i965_read_luts(struct intel_crtc_state *crtc_state)
>>  {
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
>> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>>  	else
>> -		crtc_state->base.gamma_lut = i965_read_lut_10p6(crtc_state);
>> +		crtc_state->uapi.gamma_lut = i965_read_lut_10p6(crtc_state);
>>  }
>>  
>>  static struct drm_property_blob *
>>  chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1655,15 +1655,15 @@ chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
>>  static void chv_read_luts(struct intel_crtc_state *crtc_state)
>>  {
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
>> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>>  	else
>> -		crtc_state->base.gamma_lut = chv_read_cgm_lut(crtc_state);
>> +		crtc_state->uapi.gamma_lut = chv_read_cgm_lut(crtc_state);
>>  }
>>  
>>  static struct drm_property_blob *
>>  ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1696,15 +1696,15 @@ ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
>>  static void ilk_read_luts(struct intel_crtc_state *crtc_state)
>>  {
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
>> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>>  	else
>> -		crtc_state->base.gamma_lut = ilk_read_lut_10(crtc_state);
>> +		crtc_state->uapi.gamma_lut = ilk_read_lut_10(crtc_state);
>>  }
>>  
>>  static struct drm_property_blob *
>>  glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	int hw_lut_size = ivb_lut_10_size(prec_index);
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1742,9 +1742,9 @@ glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
>>  static void glk_read_luts(struct intel_crtc_state *crtc_state)
>>  {
>>  	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
>> -		crtc_state->base.gamma_lut = i9xx_read_lut_8(crtc_state);
>> +		crtc_state->uapi.gamma_lut = i9xx_read_lut_8(crtc_state);
>>  	else
>> -		crtc_state->base.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
>> +		crtc_state->uapi.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
>>  }
>>  
>>  void intel_color_init(struct intel_crtc *crtc)
>> diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c
>> index e6e8d4a82044..35a25172b269 100644
>> --- a/drivers/gpu/drm/i915/display/intel_crt.c
>> +++ b/drivers/gpu/drm/i915/display/intel_crt.c
>> @@ -132,9 +132,9 @@ static void intel_crt_get_config(struct intel_encoder *encoder,
>>  {
>>  	pipe_config->output_types |= BIT(INTEL_OUTPUT_ANALOG);
>>  
>> -	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>> +	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>>  }
>>  
>>  static void hsw_crt_get_config(struct intel_encoder *encoder,
>> @@ -144,13 +144,13 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,
>>  
>>  	intel_ddi_get_config(encoder, pipe_config);
>>  
>> -	pipe_config->base.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
>> +	pipe_config->hw.adjusted_mode.flags &= ~(DRM_MODE_FLAG_PHSYNC |
>>  					      DRM_MODE_FLAG_NHSYNC |
>>  					      DRM_MODE_FLAG_PVSYNC |
>>  					      DRM_MODE_FLAG_NVSYNC);
>> -	pipe_config->base.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>> +	pipe_config->hw.adjusted_mode.flags |= intel_crt_get_flags(encoder);
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
>> +	pipe_config->hw.adjusted_mode.crtc_clock = lpt_get_iclkip(dev_priv);
>>  }
>>  
>>  /* Note: The caller is required to filter out dpms modes not supported by the
>> @@ -161,8 +161,8 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_crt *crt = intel_encoder_to_crt(encoder);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  	u32 adpa;
>>  
>>  	if (INTEL_GEN(dev_priv) >= 5)
>> @@ -271,7 +271,7 @@ static void hsw_pre_enable_crt(struct intel_encoder *encoder,
>>  			       const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum pipe pipe = crtc->pipe;
>>  
>>  	WARN_ON(!crtc_state->has_pch_encoder);
>> @@ -288,7 +288,7 @@ static void hsw_enable_crt(struct intel_encoder *encoder,
>>  			   const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum pipe pipe = crtc->pipe;
>>  
>>  	WARN_ON(!crtc_state->has_pch_encoder);
>> @@ -358,7 +358,7 @@ static int intel_crt_compute_config(struct intel_encoder *encoder,
>>  				    struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  
>>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>>  		return -EINVAL;
>> @@ -373,7 +373,7 @@ static int pch_crt_compute_config(struct intel_encoder *encoder,
>>  				  struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  
>>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>>  		return -EINVAL;
>> @@ -390,7 +390,7 @@ static int hsw_crt_compute_config(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  
>>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
>>  		return -EINVAL;
>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>> index 1b59b852874b..c775fd205915 100644
>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>> @@ -1483,7 +1483,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config)
>>  	if (pipe_config->fec_enable)
>>  		dotclock = intel_dp_fec_to_mode_clock(dotclock);
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>>  }
>>  
>>  static void icl_ddi_clock_get(struct intel_encoder *encoder,
>> @@ -1698,7 +1698,7 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
>>  
>>  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	u32 temp;
>> @@ -1752,7 +1752,7 @@ void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
>>  void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>>  				    bool state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	u32 temp;
>> @@ -1774,7 +1774,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
>>  static u32
>>  intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1806,9 +1806,9 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>>  		BUG();
>>  	}
>>  
>> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PVSYNC)
>>  		temp |= TRANS_DDI_PVSYNC;
>> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_PHSYNC)
>>  		temp |= TRANS_DDI_PHSYNC;
>>  
>>  	if (cpu_transcoder == TRANSCODER_EDP) {
>> @@ -1861,7 +1861,7 @@ intel_ddi_transcoder_func_reg_val_get(const struct intel_crtc_state *crtc_state)
>>  
>>  void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	u32 temp;
>> @@ -1877,7 +1877,7 @@ void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
>>  static void
>>  intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	u32 temp;
>> @@ -1889,7 +1889,7 @@ intel_ddi_config_transcoder_func(const struct intel_crtc_state *crtc_state)
>>  
>>  void intel_ddi_disable_transcoder_func(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	i915_reg_t reg = TRANS_DDI_FUNC_CTL(cpu_transcoder);
>> @@ -2187,7 +2187,7 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>>  
>>  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
>>  	enum port port = encoder->port;
>> @@ -2205,7 +2205,7 @@ void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
>>  
>>  void intel_ddi_disable_pipe_clock(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  
>>  	if (cpu_transcoder != TRANSCODER_EDP) {
>> @@ -3421,7 +3421,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *encoder,
>>  				 const struct intel_crtc_state *crtc_state,
>>  				 const struct drm_connector_state *conn_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -3846,7 +3846,7 @@ intel_ddi_update_prepare(struct intel_atomic_state *state,
>>  	WARN_ON(crtc && crtc->active);
>>  
>>  	intel_tc_port_get_link(enc_to_dig_port(&encoder->base), required_lanes);
>> -	if (crtc_state && crtc_state->base.active)
>> +	if (crtc_state && crtc_state->hw.active)
>>  		intel_update_active_dpll(state, crtc, encoder);
>>  }
>>  
>> @@ -3976,7 +3976,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  			  struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>>  	u32 temp, flags = 0;
>>  
>> @@ -3994,7 +3994,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  	else
>>  		flags |= DRM_MODE_FLAG_NVSYNC;
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>>  	switch (temp & TRANS_DDI_BPC_MASK) {
>>  	case TRANS_DDI_BPC_6:
>> @@ -4136,7 +4136,7 @@ static int intel_ddi_compute_config(struct intel_encoder *encoder,
>>  				    struct intel_crtc_state *pipe_config,
>>  				    struct drm_connector_state *conn_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	enum port port = encoder->port;
>>  	int ret;
>> @@ -4267,7 +4267,7 @@ static int intel_hdmi_reset_link(struct intel_encoder *encoder,
>>  
>>  	WARN_ON(!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI));
>>  
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return 0;
>>  
>>  	if (!crtc_state->hdmi_high_tmds_clock_ratio &&
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index 7996864e6f7c..6818cbd00ac2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -518,7 +518,7 @@ icl_wa_scalerclkgating(struct drm_i915_private *dev_priv, enum pipe pipe,
>>  static bool
>>  needs_modeset(const struct intel_crtc_state *state)
>>  {
>> -	return drm_atomic_crtc_needs_modeset(&state->base);
>> +	return drm_atomic_crtc_needs_modeset(&state->uapi);
>>  }
>>  
>>  /*
>> @@ -632,7 +632,7 @@ i9xx_select_p2_div(const struct intel_limit *limit,
>>  		   const struct intel_crtc_state *crtc_state,
>>  		   int target)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
>>  		/*
>> @@ -668,7 +668,7 @@ i9xx_find_best_dpll(const struct intel_limit *limit,
>>  		    int target, int refclk, struct dpll *match_clock,
>>  		    struct dpll *best_clock)
>>  {
>> -	struct drm_device *dev = crtc_state->base.crtc->dev;
>> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>>  	struct dpll clock;
>>  	int err = target;
>>  
>> @@ -726,7 +726,7 @@ pnv_find_best_dpll(const struct intel_limit *limit,
>>  		   int target, int refclk, struct dpll *match_clock,
>>  		   struct dpll *best_clock)
>>  {
>> -	struct drm_device *dev = crtc_state->base.crtc->dev;
>> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>>  	struct dpll clock;
>>  	int err = target;
>>  
>> @@ -782,7 +782,7 @@ g4x_find_best_dpll(const struct intel_limit *limit,
>>  		   int target, int refclk, struct dpll *match_clock,
>>  		   struct dpll *best_clock)
>>  {
>> -	struct drm_device *dev = crtc_state->base.crtc->dev;
>> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>>  	struct dpll clock;
>>  	int max_n;
>>  	bool found = false;
>> @@ -876,7 +876,7 @@ vlv_find_best_dpll(const struct intel_limit *limit,
>>  		   int target, int refclk, struct dpll *match_clock,
>>  		   struct dpll *best_clock)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct dpll clock;
>>  	unsigned int bestppm = 1000000;
>> @@ -936,7 +936,7 @@ chv_find_best_dpll(const struct intel_limit *limit,
>>  		   int target, int refclk, struct dpll *match_clock,
>>  		   struct dpll *best_clock)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	unsigned int best_error_ppm;
>>  	struct dpll clock;
>> @@ -1015,7 +1015,7 @@ bool intel_crtc_active(struct intel_crtc *crtc)
>>  	 * for atomic.
>>  	 */
>>  	return crtc->active && crtc->base.primary->state->fb &&
>> -		crtc->config->base.adjusted_mode.crtc_clock;
>> +		crtc->config->hw.adjusted_mode.crtc_clock;
>>  }
>>  
>>  enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
>> @@ -1069,7 +1069,7 @@ static void intel_wait_for_pipe_scanline_moving(struct intel_crtc *crtc)
>>  static void
>>  intel_wait_for_pipe_off(const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (INTEL_GEN(dev_priv) >= 4) {
>> @@ -1528,7 +1528,7 @@ static void i9xx_enable_pll(struct intel_crtc *crtc,
>>  
>>  static void i9xx_disable_pll(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -1619,7 +1619,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
>>  
>>  static void ironlake_enable_pch_transcoder(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	i915_reg_t reg;
>> @@ -1763,7 +1763,7 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
>>  
>>  static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	/*
>>  	 * On i965gm the hardware frame counter reads
>> @@ -1783,7 +1783,7 @@ static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state
>>  
>>  static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	drm_crtc_set_max_vblank_count(&crtc->base,
>>  				      intel_crtc_max_vblank_count(crtc_state));
>> @@ -1792,7 +1792,7 @@ static void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
>>  
>>  static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -1850,7 +1850,7 @@ static void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
>>  
>>  static void intel_disable_pipe(const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -3116,14 +3116,14 @@ intel_set_plane_visible(struct intel_crtc_state *crtc_state,
>>  	plane_state->base.visible = visible;
>>  
>>  	if (visible)
>> -		crtc_state->base.plane_mask |= drm_plane_mask(&plane->base);
>> +		crtc_state->uapi.plane_mask |= drm_plane_mask(&plane->base);
>>  	else
>> -		crtc_state->base.plane_mask &= ~drm_plane_mask(&plane->base);
>> +		crtc_state->uapi.plane_mask &= ~drm_plane_mask(&plane->base);
>>  }
>>  
>>  static void fixup_active_planes(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	struct drm_plane *plane;
>>  
>>  	/*
>> @@ -3134,7 +3134,7 @@ static void fixup_active_planes(struct intel_crtc_state *crtc_state)
>>  	crtc_state->active_planes = 0;
>>  
>>  	drm_for_each_plane_mask(plane, &dev_priv->drm,
>> -				crtc_state->base.plane_mask)
>> +				crtc_state->uapi.plane_mask)
>>  		crtc_state->active_planes |= BIT(to_intel_plane(plane)->id);
>>  }
>>  
>> @@ -3608,7 +3608,7 @@ i9xx_plane_max_stride(struct intel_plane *plane,
>>  
>>  static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 dspcntr = 0;
>>  
>> @@ -3762,7 +3762,7 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
>>  		return ret;
>>  
>>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
>> -						  &crtc_state->base,
>> +						  &crtc_state->uapi,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  i9xx_plane_has_windowing(plane),
>> @@ -3938,7 +3938,7 @@ static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
>>   */
>>  static void skl_detach_scalers(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	const struct intel_crtc_scaler_state *scaler_state =
>>  		&crtc_state->scaler_state;
>>  	int i;
>> @@ -4133,7 +4133,7 @@ static u32 cnl_plane_ctl_flip(unsigned int reflect)
>>  
>>  u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	u32 plane_ctl = 0;
>>  
>>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
>> @@ -4189,7 +4189,7 @@ u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
>>  
>>  u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	u32 plane_color_ctl = 0;
>>  
>>  	if (INTEL_GEN(dev_priv) >= 11)
>> @@ -4411,11 +4411,11 @@ static void icl_set_pipe_chicken(struct intel_crtc *crtc)
>>  static void intel_update_pipe_config(const struct intel_crtc_state *old_crtc_state,
>>  				     const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	/* drm_atomic_helper_update_legacy_modeset_state might not be called. */
>> -	crtc->base.mode = new_crtc_state->base.mode;
>> +	crtc->base.mode = new_crtc_state->uapi.mode;
>>  
>>  	/*
>>  	 * Update pipe size and adjust fitter if needed: the reason for this is
>> @@ -4844,7 +4844,7 @@ static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
>>  
>>  static void ironlake_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>>  	enum pipe pipe = intel_crtc->pipe;
>>  	i915_reg_t reg;
>> @@ -5005,9 +5005,9 @@ void lpt_disable_iclkip(struct drm_i915_private *dev_priv)
>>  /* Program iCLKIP clock to the desired frequency */
>>  static void lpt_program_iclkip(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	int clock = crtc_state->base.adjusted_mode.crtc_clock;
>> +	int clock = crtc_state->hw.adjusted_mode.crtc_clock;
>>  	u32 divsel, phaseinc, auxdiv, phasedir = 0;
>>  	u32 temp;
>>  
>> @@ -5121,7 +5121,7 @@ int lpt_get_iclkip(struct drm_i915_private *dev_priv)
>>  static void ironlake_pch_transcoder_set_timings(const struct intel_crtc_state *crtc_state,
>>  						enum pipe pch_transcoder)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  
>> @@ -5164,7 +5164,7 @@ static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool e
>>  
>>  static void ivybridge_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	switch (crtc->pipe) {
>> @@ -5194,7 +5194,7 @@ static struct intel_encoder *
>>  intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>>  			   const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	const struct drm_connector_state *connector_state;
>>  	const struct drm_connector *connector;
>>  	struct intel_encoder *encoder = NULL;
>> @@ -5226,7 +5226,7 @@ intel_get_crtc_new_encoder(const struct intel_atomic_state *state,
>>  static void ironlake_pch_enable(const struct intel_atomic_state *state,
>>  				const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	enum pipe pipe = crtc->pipe;
>> @@ -5280,7 +5280,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
>>  	if (HAS_PCH_CPT(dev_priv) &&
>>  	    intel_crtc_has_dp_encoder(crtc_state)) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc_state->base.adjusted_mode;
>> +			&crtc_state->hw.adjusted_mode;
>>  		u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPECONF_BPC_MASK) >> 5;
>>  		i915_reg_t reg = TRANS_DP_CTL(pipe);
>>  		enum port port;
>> @@ -5310,7 +5310,7 @@ static void ironlake_pch_enable(const struct intel_atomic_state *state,
>>  static void lpt_pch_enable(const struct intel_atomic_state *state,
>>  			   const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  
>> @@ -5427,10 +5427,10 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>>  	struct intel_crtc_scaler_state *scaler_state =
>>  		&crtc_state->scaler_state;
>>  	struct intel_crtc *intel_crtc =
>> -		to_intel_crtc(crtc_state->base.crtc);
>> +		to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  
>>  	/*
>>  	 * Src coordinates are already rotated by 270 degrees for
>> @@ -5446,7 +5446,7 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>>  	 * Once NV12 is enabled, handle it here while allocating scaler
>>  	 * for NV12.
>>  	 */
>> -	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->base.enable &&
>> +	if (INTEL_GEN(dev_priv) >= 9 && crtc_state->hw.enable &&
>>  	    need_scaler && adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>>  		DRM_DEBUG_KMS("Pipe/Plane scaling not supported with IF-ID mode\n");
>>  		return -EINVAL;
>> @@ -5518,13 +5518,13 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>>   */
>>  int skl_update_scaler_crtc(struct intel_crtc_state *state)
>>  {
>> -	const struct drm_display_mode *adjusted_mode = &state->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &state->hw.adjusted_mode;
>>  	bool need_scaler = false;
>>  
>>  	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
>>  		need_scaler = true;
>>  
>> -	return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
>> +	return skl_update_scaler(state, !state->hw.active, SKL_CRTC_INDEX,
>>  				 &state->scaler_state.scaler_id,
>>  				 state->pipe_src_w, state->pipe_src_h,
>>  				 adjusted_mode->crtc_hdisplay,
>> @@ -5624,7 +5624,7 @@ static void skylake_scaler_disable(struct intel_crtc *crtc)
>>  
>>  static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	const struct intel_crtc_scaler_state *scaler_state =
>> @@ -5661,7 +5661,7 @@ static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state)
>>  
>>  static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -5682,7 +5682,7 @@ static void ironlake_pfit_enable(const struct intel_crtc_state *crtc_state)
>>  
>>  void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  
>> @@ -5718,7 +5718,7 @@ void hsw_enable_ips(const struct intel_crtc_state *crtc_state)
>>  
>>  void hsw_disable_ips(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  
>> @@ -5828,7 +5828,7 @@ intel_pre_disable_primary_noatomic(struct drm_crtc *crtc)
>>  static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_state,
>>  				       const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!old_crtc_state->ips_enabled)
>> @@ -5844,7 +5844,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
>>  	 * Disable IPS before we program the LUT.
>>  	 */
>>  	if (IS_HASWELL(dev_priv) &&
>> -	    (new_crtc_state->base.color_mgmt_changed ||
>> +	    (new_crtc_state->uapi.color_mgmt_changed ||
>>  	     new_crtc_state->update_pipe) &&
>>  	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
>>  		return true;
>> @@ -5855,7 +5855,7 @@ static bool hsw_pre_update_disable_ips(const struct intel_crtc_state *old_crtc_s
>>  static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_state,
>>  				       const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!new_crtc_state->ips_enabled)
>> @@ -5871,7 +5871,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
>>  	 * Re-enable IPS after the LUT has been programmed.
>>  	 */
>>  	if (IS_HASWELL(dev_priv) &&
>> -	    (new_crtc_state->base.color_mgmt_changed ||
>> +	    (new_crtc_state->uapi.color_mgmt_changed ||
>>  	     new_crtc_state->update_pipe) &&
>>  	    new_crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
>>  		return true;
>> @@ -5881,7 +5881,7 @@ static bool hsw_post_update_enable_ips(const struct intel_crtc_state *old_crtc_s
>>  	 * forcibly enable IPS on the first fastset.
>>  	 */
>>  	if (new_crtc_state->update_pipe &&
>> -	    old_crtc_state->base.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>>  		return true;
>>  
>>  	return !old_crtc_state->ips_enabled;
>> @@ -5912,10 +5912,10 @@ static bool needs_scalerclk_wa(struct drm_i915_private *dev_priv,
>>  
>>  static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct drm_atomic_state *state = old_crtc_state->base.state;
>> +	struct drm_atomic_state *state = old_crtc_state->uapi.state;
>>  	struct intel_crtc_state *pipe_config =
>>  		intel_atomic_get_new_crtc_state(to_intel_atomic_state(state),
>>  						crtc);
>> @@ -5925,7 +5925,7 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>>  
>>  	intel_frontbuffer_flip(to_i915(crtc->base.dev), pipe_config->fb_bits);
>>  
>> -	if (pipe_config->update_wm_post && pipe_config->base.active)
>> +	if (pipe_config->update_wm_post && pipe_config->hw.active)
>>  		intel_update_watermarks(crtc);
>>  
>>  	if (hsw_post_update_enable_ips(old_crtc_state, pipe_config))
>> @@ -5955,10 +5955,10 @@ static void intel_post_plane_update(struct intel_crtc_state *old_crtc_state)
>>  static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>>  				   struct intel_crtc_state *pipe_config)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_device *dev = crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct drm_atomic_state *state = old_crtc_state->base.state;
>> +	struct drm_atomic_state *state = old_crtc_state->uapi.state;
>>  	struct drm_plane *primary = crtc->base.primary;
>>  	struct drm_plane_state *old_primary_state =
>>  		drm_atomic_get_old_plane_state(state, primary);
>> @@ -6003,7 +6003,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>>  	 * event which is after the vblank start event, so we need to have a
>>  	 * wait-for-vblank between disabling the plane and the pipe.
>>  	 */
>> -	if (HAS_GMCH(dev_priv) && old_crtc_state->base.active &&
>> +	if (HAS_GMCH(dev_priv) && old_crtc_state->hw.active &&
>>  	    pipe_config->disable_cxsr && intel_set_memory_cxsr(dev_priv, false))
>>  		intel_wait_for_vblank(dev_priv, crtc->pipe);
>>  
>> @@ -6015,7 +6015,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state,
>>  	 * WaCxSRDisabledForSpriteScaling:ivb
>>  	 */
>>  	if (pipe_config->disable_lp_wm && ilk_disable_lp_wm(dev) &&
>> -	    old_crtc_state->base.active)
>> +	    old_crtc_state->hw.active)
>>  		intel_wait_for_vblank(dev_priv, crtc->pipe);
>>  
>>  	/*
>> @@ -6310,7 +6310,7 @@ static void intel_encoders_update_pipe(struct intel_crtc *crtc,
>>  
>>  static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
>>  
>>  	plane->disable_plane(plane, crtc_state);
>> @@ -6319,7 +6319,7 @@ static void intel_disable_primary_plane(const struct intel_crtc_state *crtc_stat
>>  static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
>>  				 struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -6453,7 +6453,7 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
>>  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>  				struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  	enum pipe pipe = intel_crtc->pipe, hsw_workaround_pipe;
>> @@ -6562,7 +6562,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>  
>>  static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -6578,7 +6578,7 @@ static void ironlake_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>>  static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>  				  struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
>> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -6637,7 +6637,7 @@ static void ironlake_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>  static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>  				 struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
>> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  	enum transcoder cpu_transcoder = old_crtc_state->cpu_transcoder;
>> @@ -6671,7 +6671,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>  
>>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!crtc_state->gmch_pfit.control)
>> @@ -6801,14 +6801,14 @@ intel_aux_power_domain(struct intel_digital_port *dig_port)
>>  
>>  static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct drm_encoder *encoder;
>>  	enum pipe pipe = crtc->pipe;
>>  	u64 mask;
>>  	enum transcoder transcoder = crtc_state->cpu_transcoder;
>>  
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return 0;
>>  
>>  	mask = BIT_ULL(POWER_DOMAIN_PIPE(pipe));
>> @@ -6818,7 +6818,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>>  		mask |= BIT_ULL(POWER_DOMAIN_PIPE_PANEL_FITTER(pipe));
>>  
>>  	drm_for_each_encoder_mask(encoder, &dev_priv->drm,
>> -				  crtc_state->base.encoder_mask) {
>> +				  crtc_state->uapi.encoder_mask) {
>>  		struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
>>  
>>  		mask |= BIT_ULL(intel_encoder->power_domain);
>> @@ -6836,7 +6836,7 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>>  static u64
>>  modeset_get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum intel_display_power_domain domain;
>>  	u64 domains, new_domains, old_domains;
>> @@ -6865,7 +6865,7 @@ static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
>>  static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
>>  				   struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -6921,7 +6921,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
>>  
>>  static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	I915_WRITE(FP0(crtc->pipe), crtc_state->dpll_hw_state.fp0);
>> @@ -6931,7 +6931,7 @@ static void i9xx_set_pll_dividers(const struct intel_crtc_state *crtc_state)
>>  static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
>>  			     struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -6981,7 +6981,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
>>  
>>  static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!old_crtc_state->gmch_pfit.control)
>> @@ -6997,7 +6997,7 @@ static void i9xx_pfit_disable(const struct intel_crtc_state *old_crtc_state)
>>  static void i9xx_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>  			      struct intel_atomic_state *state)
>>  {
>> -	struct drm_crtc *crtc = old_crtc_state->base.crtc;
>> +	struct drm_crtc *crtc = old_crtc_state->uapi.crtc;
>>  	struct drm_device *dev = crtc->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>> @@ -7165,8 +7165,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>>  		if (!crtc_state)
>>  			return;
>>  
>> -		I915_STATE_WARN(!crtc_state->base.active,
>> -		      "connector is active, but attached crtc isn't\n");
>> +		I915_STATE_WARN(!crtc_state->hw.active,
>> +				"connector is active, but attached crtc isn't\n");
>>  
>>  		if (!encoder || encoder->type == INTEL_OUTPUT_DP_MST)
>>  			return;
>> @@ -7177,8 +7177,8 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>>  		I915_STATE_WARN(conn_state->crtc != encoder->base.crtc,
>>  			"attached encoder crtc differs from connector crtc\n");
>>  	} else {
>> -		I915_STATE_WARN(crtc_state && crtc_state->base.active,
>> -			"attached crtc is active, but connector isn't\n");
>> +		I915_STATE_WARN(crtc_state && crtc_state->hw.active,
>> +				"attached crtc is active, but connector isn't\n");
>>  		I915_STATE_WARN(!crtc_state && conn_state->best_encoder,
>>  			"best encoder set without crtc!\n");
>>  	}
>> @@ -7186,7 +7186,7 @@ static void intel_connector_verify_state(struct intel_crtc_state *crtc_state,
>>  
>>  static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
>>  {
>> -	if (crtc_state->base.enable && crtc_state->has_pch_encoder)
>> +	if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
>>  		return crtc_state->fdi_lanes;
>>  
>>  	return 0;
>> @@ -7196,7 +7196,7 @@ static int ironlake_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
>>  				     struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct drm_atomic_state *state = pipe_config->base.state;
>> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>>  	struct intel_crtc *other_crtc;
>>  	struct intel_crtc_state *other_crtc_state;
>>  
>> @@ -7269,7 +7269,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>>  				       struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_device *dev = intel_crtc->base.dev;
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int lane, link_bw, fdi_dotclock, ret;
>>  	bool needs_recompute = false;
>>  
>> @@ -7315,7 +7315,7 @@ static int ironlake_fdi_compute_config(struct intel_crtc *intel_crtc,
>>  
>>  bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	/* IPS only exists on ULT machines and is tied to pipe A. */
>> @@ -7345,9 +7345,9 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state)
>>  static bool hsw_compute_ips_config(struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv =
>> -		to_i915(crtc_state->base.crtc->dev);
>> +		to_i915(crtc_state->uapi.crtc->dev);
>>  	struct intel_atomic_state *intel_state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  
>>  	if (!hsw_crtc_state_ips_capable(crtc_state))
>>  		return false;
>> @@ -7386,7 +7386,7 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>>  {
>>  	u32 pixel_rate;
>>  
>> -	pixel_rate = pipe_config->base.adjusted_mode.crtc_clock;
>> +	pixel_rate = pipe_config->hw.adjusted_mode.crtc_clock;
>>  
>>  	/*
>>  	 * We only use IF-ID interlacing. If we ever use
>> @@ -7419,12 +7419,12 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>>  
>>  static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	if (HAS_GMCH(dev_priv))
>>  		/* FIXME calculate proper pipe pixel rate for GMCH pfit */
>>  		crtc_state->pixel_rate =
>> -			crtc_state->base.adjusted_mode.crtc_clock;
>> +			crtc_state->hw.adjusted_mode.crtc_clock;
>>  	else
>>  		crtc_state->pixel_rate =
>>  			ilk_pipe_pixel_rate(crtc_state);
>> @@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>>  				     struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int clock_limit = dev_priv->max_dotclk_freq;
>>  
>>  	if (INTEL_GEN(dev_priv) < 4) {
>> @@ -7460,7 +7460,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>>  
>>  	if ((pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420 ||
>>  	     pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) &&
>> -	     pipe_config->base.ctm) {
>> +	     pipe_config->hw.ctm) {
>>  		/*
>>  		 * There is only one pipe CSC unit per pipe, and we need that
>>  		 * for output conversion from RGB->YCBCR. So if CTM is already
>> @@ -7629,7 +7629,7 @@ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
>>  static void intel_pch_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
>>  					 const struct intel_link_m_n *m_n)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -7656,7 +7656,7 @@ static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_sta
>>  					 const struct intel_link_m_n *m_n,
>>  					 const struct intel_link_m_n *m2_n2)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	enum transcoder transcoder = crtc_state->cpu_transcoder;
>> @@ -7969,7 +7969,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
>>  	if (!pipe_config)
>>  		return -ENOMEM;
>>  
>> -	pipe_config->base.crtc = &crtc->base;
>> +	pipe_config->uapi.crtc = &crtc->base;
>>  	pipe_config->pixel_multiplier = 1;
>>  	pipe_config->dpll = *dpll;
>>  
>> @@ -8129,11 +8129,11 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc,
>>  
>>  static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  	u32 crtc_vtotal, crtc_vblank_end;
>>  	int vsyncshift = 0;
>>  
>> @@ -8191,7 +8191,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
>>  
>>  static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -8212,39 +8212,39 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
>>  	u32 tmp;
>>  
>>  	tmp = I915_READ(HTOTAL(cpu_transcoder));
>> -	pipe_config->base.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
>> -	pipe_config->base.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_hdisplay = (tmp & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_htotal = ((tmp >> 16) & 0xffff) + 1;
>>  
>>  	if (!transcoder_is_dsi(cpu_transcoder)) {
>>  		tmp = I915_READ(HBLANK(cpu_transcoder));
>> -		pipe_config->base.adjusted_mode.crtc_hblank_start =
>> +		pipe_config->hw.adjusted_mode.crtc_hblank_start =
>>  							(tmp & 0xffff) + 1;
>> -		pipe_config->base.adjusted_mode.crtc_hblank_end =
>> +		pipe_config->hw.adjusted_mode.crtc_hblank_end =
>>  						((tmp >> 16) & 0xffff) + 1;
>>  	}
>>  	tmp = I915_READ(HSYNC(cpu_transcoder));
>> -	pipe_config->base.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
>> -	pipe_config->base.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_hsync_start = (tmp & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_hsync_end = ((tmp >> 16) & 0xffff) + 1;
>>  
>>  	tmp = I915_READ(VTOTAL(cpu_transcoder));
>> -	pipe_config->base.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
>> -	pipe_config->base.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_vdisplay = (tmp & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_vtotal = ((tmp >> 16) & 0xffff) + 1;
>>  
>>  	if (!transcoder_is_dsi(cpu_transcoder)) {
>>  		tmp = I915_READ(VBLANK(cpu_transcoder));
>> -		pipe_config->base.adjusted_mode.crtc_vblank_start =
>> +		pipe_config->hw.adjusted_mode.crtc_vblank_start =
>>  							(tmp & 0xffff) + 1;
>> -		pipe_config->base.adjusted_mode.crtc_vblank_end =
>> +		pipe_config->hw.adjusted_mode.crtc_vblank_end =
>>  						((tmp >> 16) & 0xffff) + 1;
>>  	}
>>  	tmp = I915_READ(VSYNC(cpu_transcoder));
>> -	pipe_config->base.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
>> -	pipe_config->base.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_vsync_start = (tmp & 0xffff) + 1;
>> +	pipe_config->hw.adjusted_mode.crtc_vsync_end = ((tmp >> 16) & 0xffff) + 1;
>>  
>>  	if (I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK) {
>> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
>> -		pipe_config->base.adjusted_mode.crtc_vtotal += 1;
>> -		pipe_config->base.adjusted_mode.crtc_vblank_end += 1;
>> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_INTERLACE;
>> +		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
>> +		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
>>  	}
>>  }
>>  
>> @@ -8259,27 +8259,27 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
>>  
>> -	pipe_config->base.mode.vdisplay = pipe_config->pipe_src_h;
>> -	pipe_config->base.mode.hdisplay = pipe_config->pipe_src_w;
>> +	pipe_config->hw.mode.vdisplay = pipe_config->pipe_src_h;
>> +	pipe_config->hw.mode.hdisplay = pipe_config->pipe_src_w;
>>  }
>>  
>>  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>>  				 struct intel_crtc_state *pipe_config)
>>  {
>> -	mode->hdisplay = pipe_config->base.adjusted_mode.crtc_hdisplay;
>> -	mode->htotal = pipe_config->base.adjusted_mode.crtc_htotal;
>> -	mode->hsync_start = pipe_config->base.adjusted_mode.crtc_hsync_start;
>> -	mode->hsync_end = pipe_config->base.adjusted_mode.crtc_hsync_end;
>> +	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
>> +	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
>> +	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
>> +	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
>>  
>> -	mode->vdisplay = pipe_config->base.adjusted_mode.crtc_vdisplay;
>> -	mode->vtotal = pipe_config->base.adjusted_mode.crtc_vtotal;
>> -	mode->vsync_start = pipe_config->base.adjusted_mode.crtc_vsync_start;
>> -	mode->vsync_end = pipe_config->base.adjusted_mode.crtc_vsync_end;
>> +	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
>> +	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
>> +	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
>> +	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
>>  
>> -	mode->flags = pipe_config->base.adjusted_mode.flags;
>> +	mode->flags = pipe_config->hw.adjusted_mode.flags;
>>  	mode->type = DRM_MODE_TYPE_DRIVER;
>>  
>> -	mode->clock = pipe_config->base.adjusted_mode.crtc_clock;
>> +	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
>>  
>>  	mode->hsync = drm_mode_hsync(mode);
>>  	mode->vrefresh = drm_mode_vrefresh(mode);
>> @@ -8288,7 +8288,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>>  
>>  static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 pipeconf;
>>  
>> @@ -8325,7 +8325,7 @@ static void i9xx_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  		}
>>  	}
>>  
>> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
>>  		if (INTEL_GEN(dev_priv) < 4 ||
>>  		    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_SDVO))
>>  			pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
>> @@ -8757,7 +8757,7 @@ static void intel_get_crtc_ycbcr_config(struct intel_crtc *crtc,
>>  
>>  static void i9xx_get_pipe_color_config(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
>> @@ -8880,7 +8880,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
>>  	 * but in case the pipe is enabled w/o any ports we need a sane
>>  	 * default.
>>  	 */
>> -	pipe_config->base.adjusted_mode.crtc_clock =
>> +	pipe_config->hw.adjusted_mode.crtc_clock =
>>  		pipe_config->port_clock / pipe_config->pixel_multiplier;
>>  
>>  	ret = true;
>> @@ -9395,7 +9395,7 @@ void intel_init_pch_refclk(struct drm_i915_private *dev_priv)
>>  
>>  static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val;
>> @@ -9423,7 +9423,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  	if (crtc_state->dither)
>>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>>  
>> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>>  		val |= PIPECONF_INTERLACED_ILK;
>>  	else
>>  		val |= PIPECONF_PROGRESSIVE;
>> @@ -9439,7 +9439,7 @@ static void ironlake_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  
>>  static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	u32 val = 0;
>> @@ -9447,7 +9447,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  	if (IS_HASWELL(dev_priv) && crtc_state->dither)
>>  		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
>>  
>> -	if (crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>>  		val |= PIPECONF_INTERLACED_ILK;
>>  	else
>>  		val |= PIPECONF_PROGRESSIVE;
>> @@ -9458,7 +9458,7 @@ static void haswell_set_pipeconf(const struct intel_crtc_state *crtc_state)
>>  
>>  static void bdw_set_pipemisc(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 val = 0;
>>  
>> @@ -9644,7 +9644,7 @@ static int ironlake_crtc_compute_clock(struct intel_crtc *crtc,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  	const struct intel_limit *limit;
>>  	int refclk = 120000;
>>  
>> @@ -10060,7 +10060,7 @@ static int haswell_crtc_compute_clock(struct intel_crtc *crtc,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  
>>  	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI) ||
>>  	    INTEL_GEN(dev_priv) >= 11) {
>> @@ -10608,7 +10608,7 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
>>  	}
>>  
>>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
>> -						  &crtc_state->base,
>> +						  &crtc_state->uapi,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  true, true);
>> @@ -10791,7 +10791,7 @@ i9xx_cursor_max_stride(struct intel_plane *plane,
>>  
>>  static u32 i9xx_cursor_ctl_crtc(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 cntl = 0;
>>  
>> @@ -11198,12 +11198,12 @@ int intel_get_load_detect_pipe(struct drm_connector *connector,
>>  		goto fail;
>>  	}
>>  
>> -	crtc_state->base.active = crtc_state->base.enable = true;
>> +	crtc_state->uapi.active = crtc_state->uapi.enable = true;
>>  
>>  	if (!mode)
>>  		mode = &load_detect_mode;
>>  
>> -	ret = drm_atomic_set_mode_for_crtc(&crtc_state->base, mode);
>> +	ret = drm_atomic_set_mode_for_crtc(&crtc_state->uapi, mode);
>>  	if (ret)
>>  		goto fail;
>>  
>> @@ -11411,7 +11411,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
>>  	 * we may need some idea for the dotclock anyway.
>>  	 * Calculate one based on the FDI configuration.
>>  	 */
>> -	pipe_config->base.adjusted_mode.crtc_clock =
>> +	pipe_config->hw.adjusted_mode.crtc_clock =
>>  		intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
>>  					 &pipe_config->fdi_m_n);
>>  }
>> @@ -11441,7 +11441,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
>>  		return NULL;
>>  	}
>>  
>> -	crtc_state->base.crtc = &crtc->base;
>> +	crtc_state->uapi.crtc = &crtc->base;
>>  
>>  	if (!dev_priv->display.get_pipe_config(crtc, crtc_state)) {
>>  		kfree(crtc_state);
>> @@ -11512,12 +11512,12 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
>>  				    const struct intel_plane_state *old_plane_state,
>>  				    struct intel_plane_state *plane_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	bool mode_changed = needs_modeset(crtc_state);
>> -	bool was_crtc_enabled = old_crtc_state->base.active;
>> -	bool is_crtc_enabled = crtc_state->base.active;
>> +	bool was_crtc_enabled = old_crtc_state->hw.active;
>> +	bool is_crtc_enabled = crtc_state->hw.active;
>>  	bool turn_off, turn_on, visible, was_visible;
>>  	struct drm_framebuffer *fb = plane_state->base.fb;
>>  	int ret;
>> @@ -11692,9 +11692,9 @@ static int icl_add_linked_planes(struct intel_atomic_state *state)
>>  
>>  static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->base.state);
>> +	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
>>  	struct intel_plane *plane, *linked;
>>  	struct intel_plane_state *plane_state;
>>  	int i;
>> @@ -11764,9 +11764,9 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>>  
>>  static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(new_crtc_state->base.state);
>> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>>  	const struct intel_crtc_state *old_crtc_state =
>>  		intel_atomic_get_old_crtc_state(state, crtc);
>>  
>> @@ -11784,10 +11784,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  	bool mode_changed = needs_modeset(crtc_state);
>>  
>>  	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
>> -	    mode_changed && !crtc_state->base.active)
>> +	    mode_changed && !crtc_state->hw.active)
>>  		crtc_state->update_wm_post = true;
>>  
>> -	if (mode_changed && crtc_state->base.enable &&
>> +	if (mode_changed && crtc_state->hw.enable &&
>>  	    dev_priv->display.crtc_compute_clock &&
>>  	    !WARN_ON(crtc_state->shared_dpll)) {
>>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>> @@ -11800,10 +11800,10 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  	 * when C8 planes are getting enabled/disabled.
>>  	 */
>>  	if (c8_planes_changed(crtc_state))
>> -		crtc_state->base.color_mgmt_changed = true;
>> +		crtc_state->uapi.color_mgmt_changed = true;
>>  
>>  	if (mode_changed || crtc_state->update_pipe ||
>> -	    crtc_state->base.color_mgmt_changed) {
>> +	    crtc_state->uapi.color_mgmt_changed) {
>>  		ret = intel_color_check(crtc_state);
>>  		if (ret)
>>  			return ret;
>> @@ -11925,7 +11925,7 @@ compute_baseline_pipe_bpp(struct intel_crtc *crtc,
>>  			  struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	struct drm_atomic_state *state = pipe_config->base.state;
>> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>>  	struct drm_connector *connector;
>>  	struct drm_connector_state *connector_state;
>>  	int bpp, i;
>> @@ -12078,7 +12078,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>>  				   struct intel_atomic_state *state,
>>  				   const char *context)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	const struct intel_plane_state *plane_state;
>>  	struct intel_plane *plane;
>> @@ -12087,14 +12087,14 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>>  
>>  	DRM_DEBUG_KMS("[CRTC:%d:%s] enable: %s %s\n",
>>  		      crtc->base.base.id, crtc->base.name,
>> -		      yesno(pipe_config->base.enable), context);
>> +		      yesno(pipe_config->hw.enable), context);
>>  
>> -	if (!pipe_config->base.enable)
>> +	if (!pipe_config->hw.enable)
>>  		goto dump_planes;
>>  
>>  	snprintf_output_types(buf, sizeof(buf), pipe_config->output_types);
>>  	DRM_DEBUG_KMS("active: %s, output_types: %s (0x%x), output format: %s\n",
>> -		      yesno(pipe_config->base.active),
>> +		      yesno(pipe_config->hw.active),
>>  		      buf, pipe_config->output_types,
>>  		      output_formats(pipe_config->output_format));
>>  
>> @@ -12134,10 +12134,10 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>>  		intel_dump_infoframe(dev_priv, &pipe_config->infoframes.hdmi);
>>  
>>  	DRM_DEBUG_KMS("requested mode:\n");
>> -	drm_mode_debug_printmodeline(&pipe_config->base.mode);
>> +	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
>>  	DRM_DEBUG_KMS("adjusted mode:\n");
>> -	drm_mode_debug_printmodeline(&pipe_config->base.adjusted_mode);
>> -	intel_dump_crtc_timings(&pipe_config->base.adjusted_mode);
>> +	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>> +	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
>>  	DRM_DEBUG_KMS("port clock: %d, pipe src size: %dx%d, pixel rate %d\n",
>>  		      pipe_config->port_clock,
>>  		      pipe_config->pipe_src_w, pipe_config->pipe_src_h,
>> @@ -12255,7 +12255,7 @@ static int
>>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv =
>> -		to_i915(crtc_state->base.crtc->dev);
>> +		to_i915(crtc_state->uapi.crtc->dev);
>>  	struct intel_crtc_state *saved_state;
>>  
>>  	saved_state = kzalloc(sizeof(*saved_state), GFP_KERNEL);
>> @@ -12278,9 +12278,10 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  		saved_state->wm = crtc_state->wm;
>>  
>>  	/* Keep base drm_crtc_state intact, only clear our extended struct */
>> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, base));
>> -	memcpy(&crtc_state->base + 1, &saved_state->base + 1,
>> -	       sizeof(*crtc_state) - sizeof(crtc_state->base));
>> +	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
>> +	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
>> +	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
>> +	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
>>  
>>  	kfree(saved_state);
>>  	return 0;
>> @@ -12289,8 +12290,8 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  static int
>>  intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  {
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> -	struct drm_atomic_state *state = pipe_config->base.state;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>> +	struct drm_atomic_state *state = pipe_config->uapi.state;
>>  	struct intel_encoder *encoder;
>>  	struct drm_connector *connector;
>>  	struct drm_connector_state *connector_state;
>> @@ -12310,13 +12311,13 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	 * positive or negative polarity is requested, treat this as meaning
>>  	 * negative polarity.
>>  	 */
>> -	if (!(pipe_config->base.adjusted_mode.flags &
>> +	if (!(pipe_config->hw.adjusted_mode.flags &
>>  	      (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC)))
>> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
>> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NHSYNC;
>>  
>> -	if (!(pipe_config->base.adjusted_mode.flags &
>> +	if (!(pipe_config->hw.adjusted_mode.flags &
>>  	      (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
>> -		pipe_config->base.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
>> +		pipe_config->hw.adjusted_mode.flags |= DRM_MODE_FLAG_NVSYNC;
>>  
>>  	ret = compute_baseline_pipe_bpp(to_intel_crtc(crtc),
>>  					pipe_config);
>> @@ -12333,7 +12334,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	 * computation to clearly distinguish it from the adjusted mode, which
>>  	 * can be changed by the connectors in the below retry loop.
>>  	 */
>> -	drm_mode_get_hv_timing(&pipe_config->base.mode,
>> +	drm_mode_get_hv_timing(&pipe_config->hw.mode,
>>  			       &pipe_config->pipe_src_w,
>>  			       &pipe_config->pipe_src_h);
>>  
>> @@ -12366,7 +12367,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	pipe_config->pixel_multiplier = 1;
>>  
>>  	/* Fill in default crtc timings, allow encoders to overwrite them. */
>> -	drm_mode_set_crtcinfo(&pipe_config->base.adjusted_mode,
>> +	drm_mode_set_crtcinfo(&pipe_config->hw.adjusted_mode,
>>  			      CRTC_STEREO_DOUBLE);
>>  
>>  	/* Pass our mode to the connectors and the CRTC to give them a chance to
>> @@ -12391,7 +12392,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	/* Set default port clock if not overwritten by the encoder. Needs to be
>>  	 * done afterwards in case the encoder adjusts the mode. */
>>  	if (!pipe_config->port_clock)
>> -		pipe_config->port_clock = pipe_config->base.adjusted_mode.crtc_clock
>> +		pipe_config->port_clock = pipe_config->hw.adjusted_mode.crtc_clock
>>  			* pipe_config->pixel_multiplier;
>>  
>>  	ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
>> @@ -12555,12 +12556,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  			  const struct intel_crtc_state *pipe_config,
>>  			  bool fastset)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(current_config->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc->dev);
>>  	bool ret = true;
>>  	u32 bp_gamma = 0;
>>  	bool fixup_inherited = fastset &&
>> -		(current_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
>> -		!(pipe_config->base.mode.private_flags & I915_MODE_FLAG_INHERITED);
>> +		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
>> +		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
>>  
>>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
>> @@ -12749,19 +12750,19 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  
>>  	PIPE_CONF_CHECK_X(output_types);
>>  
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hdisplay);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_htotal);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_start);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hblank_end);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_start);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_hsync_end);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
>>  
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vdisplay);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vtotal);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_start);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vblank_end);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_start);
>> -	PIPE_CONF_CHECK_I(base.adjusted_mode.crtc_vsync_end);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
>> +	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
>>  
>>  	PIPE_CONF_CHECK_I(pixel_multiplier);
>>  	PIPE_CONF_CHECK_I(output_format);
>> @@ -12777,17 +12778,17 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  
>>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>>  
>> -	PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
>> +	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>  			      DRM_MODE_FLAG_INTERLACE);
>>  
>>  	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
>> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
>> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>  				      DRM_MODE_FLAG_PHSYNC);
>> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
>> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>  				      DRM_MODE_FLAG_NHSYNC);
>> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
>> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>  				      DRM_MODE_FLAG_PVSYNC);
>> -		PIPE_CONF_CHECK_FLAGS(base.adjusted_mode.flags,
>> +		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>  				      DRM_MODE_FLAG_NVSYNC);
>>  	}
>>  
>> @@ -12826,7 +12827,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  
>>  		bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
>>  		if (bp_gamma)
>> -			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, base.gamma_lut, bp_gamma);
>> +			PIPE_CONF_CHECK_COLOR_LUT(gamma_mode, uapi.gamma_lut, bp_gamma);
>>  
>>  	}
>>  
>> @@ -12871,7 +12872,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
>>  		PIPE_CONF_CHECK_I(pipe_bpp);
>>  
>> -	PIPE_CONF_CHECK_CLOCK_FUZZY(base.adjusted_mode.crtc_clock);
>> +	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
>>  	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>>  
>>  	PIPE_CONF_CHECK_I(min_voltage_level);
>> @@ -12902,7 +12903,7 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
>>  	if (pipe_config->has_pch_encoder) {
>>  		int fdi_dotclock = intel_dotclock_calculate(intel_fdi_link_freq(dev_priv, pipe_config),
>>  							    &pipe_config->fdi_m_n);
>> -		int dotclock = pipe_config->base.adjusted_mode.crtc_clock;
>> +		int dotclock = pipe_config->hw.adjusted_mode.crtc_clock;
>>  
>>  		/*
>>  		 * FDI already provided one idea for the dotclock.
>> @@ -12930,7 +12931,7 @@ static void verify_wm_state(struct intel_crtc *crtc,
>>  	const enum pipe pipe = crtc->pipe;
>>  	int plane, level, max_level = ilk_wm_max_level(dev_priv);
>>  
>> -	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->base.active)
>> +	if (INTEL_GEN(dev_priv) < 9 || !new_crtc_state->hw.active)
>>  		return;
>>  
>>  	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
>> @@ -13139,12 +13140,12 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  	struct drm_atomic_state *state;
>>  	bool active;
>>  
>> -	state = old_crtc_state->base.state;
>> -	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->base);
>> +	state = old_crtc_state->uapi.state;
>> +	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>>  	pipe_config = old_crtc_state;
>>  	memset(pipe_config, 0, sizeof(*pipe_config));
>> -	pipe_config->base.crtc = &crtc->base;
>> -	pipe_config->base.state = state;
>> +	pipe_config->uapi.crtc = &crtc->base;
>> +	pipe_config->uapi.state = state;
>>  
>>  	DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.base.id, crtc->base.name);
>>  
>> @@ -13152,23 +13153,26 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  
>>  	/* we keep both pipes enabled on 830 */
>>  	if (IS_I830(dev_priv))
>> -		active = new_crtc_state->base.active;
>> +		active = new_crtc_state->hw.active;
>>  
>> -	I915_STATE_WARN(new_crtc_state->base.active != active,
>> -	     "crtc active state doesn't match with hw state "
>> -	     "(expected %i, found %i)\n", new_crtc_state->base.active, active);
>> +	I915_STATE_WARN(new_crtc_state->hw.active != active,
>> +			"crtc active state doesn't match with hw state "
>> +			"(expected %i, found %i)\n",
>> +			new_crtc_state->hw.active, active);
>>  
>> -	I915_STATE_WARN(crtc->active != new_crtc_state->base.active,
>> -	     "transitional active state does not match atomic hw state "
>> -	     "(expected %i, found %i)\n", new_crtc_state->base.active, crtc->active);
>> +	I915_STATE_WARN(crtc->active != new_crtc_state->hw.active,
>> +			"transitional active state does not match atomic hw state "
>> +			"(expected %i, found %i)\n",
>> +			new_crtc_state->hw.active, crtc->active);
>>  
>>  	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
>>  		enum pipe pipe;
>>  
>>  		active = encoder->get_hw_state(encoder, &pipe);
>> -		I915_STATE_WARN(active != new_crtc_state->base.active,
>> -			"[ENCODER:%i] active %i with crtc active %i\n",
>> -			encoder->base.base.id, active, new_crtc_state->base.active);
>> +		I915_STATE_WARN(active != new_crtc_state->hw.active,
>> +				"[ENCODER:%i] active %i with crtc active %i\n",
>> +				encoder->base.base.id, active,
>> +				new_crtc_state->hw.active);
>>  
>>  		I915_STATE_WARN(active && crtc->pipe != pipe,
>>  				"Encoder connected to wrong pipe %c\n",
>> @@ -13180,7 +13184,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  
>>  	intel_crtc_compute_pixel_rate(pipe_config);
>>  
>> -	if (!new_crtc_state->base.active)
>> +	if (!new_crtc_state->hw.active)
>>  		return;
>>  
>>  	intel_pipe_config_sanity_check(dev_priv, pipe_config);
>> @@ -13242,7 +13246,7 @@ verify_single_dpll_state(struct drm_i915_private *dev_priv,
>>  
>>  	crtc_mask = drm_crtc_mask(&crtc->base);
>>  
>> -	if (new_crtc_state->base.active)
>> +	if (new_crtc_state->hw.active)
>>  		I915_STATE_WARN(!(pll->active_mask & crtc_mask),
>>  				"pll active mismatch (expected pipe %c in active mask 0x%02x)\n",
>>  				pipe_name(drm_crtc_index(&crtc->base)), pll->active_mask);
>> @@ -13320,7 +13324,7 @@ intel_modeset_verify_disabled(struct drm_i915_private *dev_priv,
>>  
>>  static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	/*
>> @@ -13351,7 +13355,7 @@ static void update_scanline_offset(const struct intel_crtc_state *crtc_state)
>>  	 * answer that's slightly in the future.
>>  	 */
>>  	if (IS_GEN(dev_priv, 2)) {
>> -		const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
>> +		const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  		int vtotal;
>>  
>>  		vtotal = adjusted_mode->crtc_vtotal;
>> @@ -13401,7 +13405,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
>>  
>>  	/* look at all crtc's that are going to be enabled in during modeset */
>>  	for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
>> -		if (!crtc_state->base.active ||
>> +		if (!crtc_state->hw.active ||
>>  		    !needs_modeset(crtc_state))
>>  			continue;
>>  
>> @@ -13426,7 +13430,7 @@ static int haswell_mode_set_planes_workaround(struct intel_atomic_state *state)
>>  
>>  		crtc_state->hsw_workaround_pipe = INVALID_PIPE;
>>  
>> -		if (!crtc_state->base.active ||
>> +		if (!crtc_state->hw.active ||
>>  		    needs_modeset(crtc_state))
>>  			continue;
>>  
>> @@ -13469,12 +13473,12 @@ static int intel_modeset_checks(struct intel_atomic_state *state)
>>  
>>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>>  					    new_crtc_state, i) {
>> -		if (new_crtc_state->base.active)
>> +		if (new_crtc_state->hw.active)
>>  			state->active_pipes |= BIT(crtc->pipe);
>>  		else
>>  			state->active_pipes &= ~BIT(crtc->pipe);
>>  
>> -		if (old_crtc_state->base.active != new_crtc_state->base.active)
>> +		if (old_crtc_state->hw.active != new_crtc_state->hw.active)
>>  			state->active_pipe_changes |= BIT(crtc->pipe);
>>  	}
>>  
>> @@ -13513,7 +13517,7 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
>>  	if (!intel_pipe_config_compare(old_crtc_state, new_crtc_state, true))
>>  		return;
>>  
>> -	new_crtc_state->base.mode_changed = false;
>> +	new_crtc_state->uapi.mode_changed = false;
>>  	new_crtc_state->update_pipe = true;
>>  
>>  	/*
>> @@ -13548,9 +13552,9 @@ static int intel_atomic_check(struct drm_device *dev,
>>  	/* Catch I915_MODE_FLAG_INHERITED */
>>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>>  					    new_crtc_state, i) {
>> -		if (new_crtc_state->base.mode.private_flags !=
>> -		    old_crtc_state->base.mode.private_flags)
>> -			new_crtc_state->base.mode_changed = true;
>> +		if (new_crtc_state->hw.mode.private_flags !=
>> +		    old_crtc_state->hw.mode.private_flags)
>> +			new_crtc_state->uapi.mode_changed = true;
>>  	}
>>  
>>  	ret = drm_atomic_helper_check_modeset(dev, &state->base);
>> @@ -13562,7 +13566,7 @@ static int intel_atomic_check(struct drm_device *dev,
>>  		if (!needs_modeset(new_crtc_state))
>>  			continue;
>>  
>> -		if (!new_crtc_state->base.enable) {
>> +		if (!new_crtc_state->uapi.enable) {
>>  			any_ms = true;
>>  			continue;
>>  		}
>> @@ -13719,11 +13723,10 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>>  	intel_check_pch_fifo_underruns(dev_priv);
>>  
>>  	/* FIXME unify this for all platforms */
>> -	if (!new_crtc_state->base.active &&
>> +	if (!new_crtc_state->hw.active &&
>>  	    !HAS_GMCH(dev_priv) &&
>>  	    dev_priv->display.initial_watermarks)
>> -		dev_priv->display.initial_watermarks(state,
>> -						     new_crtc_state);
>> +		dev_priv->display.initial_watermarks(state, new_crtc_state);
>>  }
>>  
>>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>> @@ -13746,7 +13749,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>  
>>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>>  
>> -		if (old_crtc_state->base.active)
>> +		if (old_crtc_state->hw.active)
>>  			intel_old_crtc_state_disables(state,
>>  						      old_crtc_state,
>>  						      new_crtc_state,
>> @@ -13761,7 +13764,7 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
>>  	int i;
>>  
>>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
>> -		if (!new_crtc_state->base.active)
>> +		if (!new_crtc_state->hw.active)
>>  			continue;
>>  
>>  		intel_update_crtc(crtc, state, old_crtc_state,
>> @@ -13784,7 +13787,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>>  
>>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i)
>>  		/* ignore allocations for crtc's that have been turned off. */
>> -		if (new_crtc_state->base.active)
>> +		if (new_crtc_state->hw.active)
>>  			entries[i] = old_crtc_state->wm.skl.ddb;
>>  
>>  	/* If 2nd DBuf slice required, enable it here */
>> @@ -13806,7 +13809,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>>  
>>  			pipe = crtc->pipe;
>>  
>> -			if (updated & cmask || !new_crtc_state->base.active)
>> +			if (updated & cmask || !new_crtc_state->hw.active)
>>  				continue;
>>  
>>  			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
>> @@ -13825,7 +13828,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>>  			 */
>>  			if (!skl_ddb_entry_equal(&new_crtc_state->wm.skl.ddb,
>>  						 &old_crtc_state->wm.skl.ddb) &&
>> -			    !new_crtc_state->base.active_changed &&
>> +			    !new_crtc_state->uapi.active_changed &&
>>  			    state->wm_results.dirty_pipes != updated)
>>  				vbl_wait = true;
>>  
>> @@ -13958,12 +13961,13 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>>  		bool modeset = needs_modeset(new_crtc_state);
>>  
>>  		/* Complete events for now disable pipes here. */
>> -		if (modeset && !new_crtc_state->base.active && new_crtc_state->base.event) {
>> +		if (modeset && !new_crtc_state->hw.active && new_crtc_state->uapi.event) {
>>  			spin_lock_irq(&dev->event_lock);
>> -			drm_crtc_send_vblank_event(&crtc->base, new_crtc_state->base.event);
>> +			drm_crtc_send_vblank_event(&crtc->base,
>> +						   new_crtc_state->uapi.event);
>>  			spin_unlock_irq(&dev->event_lock);
>>  
>> -			new_crtc_state->base.event = NULL;
>> +			new_crtc_state->uapi.event = NULL;
>>  		}
>>  	}
>>  
>> @@ -13994,9 +13998,9 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state)
>>  	drm_atomic_helper_wait_for_flip_done(dev, &state->base);
>>  
>>  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
>> -		if (new_crtc_state->base.active &&
>> +		if (new_crtc_state->hw.active &&
>>  		    !needs_modeset(new_crtc_state) &&
>> -		    (new_crtc_state->base.color_mgmt_changed ||
>> +		    (new_crtc_state->uapi.color_mgmt_changed ||
>>  		     new_crtc_state->update_pipe))
>>  			intel_color_load_luts(new_crtc_state);
>>  	}
>> @@ -14451,16 +14455,16 @@ int
>>  skl_max_scale(const struct intel_crtc_state *crtc_state,
>>  	      const struct drm_format_info *format)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	int max_scale;
>>  	int crtc_clock, max_dotclk, tmpclk1, tmpclk2;
>>  
>> -	if (!crtc_state->base.enable)
>> +	if (!crtc_state->hw.enable)
>>  		return DRM_PLANE_HELPER_NO_SCALING;
>>  
>> -	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
>> -	max_dotclk = to_intel_atomic_state(crtc_state->base.state)->cdclk.logical.cdclk;
>> +	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
>> +	max_dotclk = to_intel_atomic_state(crtc_state->uapi.state)->cdclk.logical.cdclk;
>>  
>>  	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
>>  		max_dotclk *= 2;
>> @@ -14501,7 +14505,7 @@ static void intel_begin_crtc_commit(struct intel_atomic_state *state,
>>  	if (modeset)
>>  		goto out;
>>  
>> -	if (new_crtc_state->base.color_mgmt_changed ||
>> +	if (new_crtc_state->uapi.color_mgmt_changed ||
>>  	    new_crtc_state->update_pipe)
>>  		intel_color_commit(new_crtc_state);
>>  
>> @@ -14547,7 +14551,7 @@ static void intel_finish_crtc_commit(struct intel_atomic_state *state,
>>  
>>  	if (new_crtc_state->update_pipe &&
>>  	    !needs_modeset(new_crtc_state) &&
>> -	    old_crtc_state->base.mode.private_flags & I915_MODE_FLAG_INHERITED)
>> +	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
>>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>>  }
>>  
>> @@ -14659,7 +14663,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>>  	 * When crtc is inactive or there is a modeset pending,
>>  	 * wait for it to complete in the slowpath
>>  	 */
>> -	if (!crtc_state->base.active || needs_modeset(crtc_state) ||
>> +	if (!crtc_state->hw.active || needs_modeset(crtc_state) ||
>>  	    crtc_state->update_pipe)
>>  		goto slow;
>>  
>> @@ -14753,7 +14757,7 @@ intel_legacy_cursor_update(struct drm_plane *plane,
>>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>>  out_free:
>>  	if (new_crtc_state)
>> -		intel_crtc_destroy_state(crtc, &new_crtc_state->base);
>> +		intel_crtc_destroy_state(crtc, &new_crtc_state->uapi);
>>  	if (ret)
>>  		intel_plane_destroy_state(plane, new_plane_state);
>>  	else
>> @@ -15079,7 +15083,7 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
>>  		ret = -ENOMEM;
>>  		goto fail;
>>  	}
>> -	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->base);
>> +	__drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->uapi);
>>  	intel_crtc->config = crtc_state;
>>  
>>  	primary = intel_primary_plane_create(dev_priv, pipe);
>> @@ -16455,7 +16459,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>>  			   I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
>>  	}
>>  
>> -	if (crtc_state->base.active) {
>> +	if (crtc_state->hw.active) {
>>  		struct intel_plane *plane;
>>  
>>  		/* Disable everything but the primary plane */
>> @@ -16480,10 +16484,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>>  
>>  	/* Adjust the state of the output pipe according to whether we
>>  	 * have active connectors/encoders. */
>> -	if (crtc_state->base.active && !intel_crtc_has_encoders(crtc))
>> +	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc))
>>  		intel_crtc_disable_noatomic(&crtc->base, ctx);
>>  
>> -	if (crtc_state->base.active || HAS_GMCH(dev_priv)) {
>> +	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
>>  		/*
>>  		 * We start out with underrun reporting disabled to avoid races.
>>  		 * For correct bookkeeping mark this on active crtcs.
>> @@ -16514,7 +16518,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>>  
>>  static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	/*
>>  	 * Some SNB BIOSen (eg. ASUS K53SV) are known to misprogram
>> @@ -16527,7 +16531,7 @@ static bool has_bogus_dpll_config(const struct intel_crtc_state *crtc_state)
>>  	 * road.
>>  	 */
>>  	return IS_GEN(dev_priv, 6) &&
>> -		crtc_state->base.active &&
>> +		crtc_state->hw.active &&
>>  		crtc_state->shared_dpll &&
>>  		crtc_state->port_clock == 0;
>>  }
>> @@ -16544,7 +16548,7 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder)
>>  	 * encoder is active and trying to read from a pipe) and the
>>  	 * pipe itself being active. */
>>  	bool has_active_crtc = crtc_state &&
>> -		crtc_state->base.active;
>> +		crtc_state->hw.active;
>>  
>>  	if (crtc_state && has_bogus_dpll_config(crtc_state)) {
>>  		DRM_DEBUG_KMS("BIOS has misprogrammed the hardware. Disabling pipe %c\n",
>> @@ -16681,22 +16685,22 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  		struct intel_crtc_state *crtc_state =
>>  			to_intel_crtc_state(crtc->base.state);
>>  
>> -		__drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
>> +		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>>  		memset(crtc_state, 0, sizeof(*crtc_state));
>> -		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->base);
>> +		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>>  
>> -		crtc_state->base.active = crtc_state->base.enable =
>> +		crtc_state->hw.active = crtc_state->hw.enable =
>>  			dev_priv->display.get_pipe_config(crtc, crtc_state);
>>  
>> -		crtc->base.enabled = crtc_state->base.enable;
>> -		crtc->active = crtc_state->base.active;
>> +		crtc->base.enabled = crtc_state->hw.enable;
>> +		crtc->active = crtc_state->hw.active;
>>  
>> -		if (crtc_state->base.active)
>> +		if (crtc_state->hw.active)
>>  			dev_priv->active_pipes |= BIT(crtc->pipe);
>>  
>>  		DRM_DEBUG_KMS("[CRTC:%d:%s] hw state readout: %s\n",
>>  			      crtc->base.base.id, crtc->base.name,
>> -			      enableddisabled(crtc_state->base.active));
>> +			      enableddisabled(crtc_state->hw.active));
>>  	}
>>  
>>  	readout_plane_state(dev_priv);
>> @@ -16718,7 +16722,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			struct intel_crtc_state *crtc_state =
>>  				to_intel_crtc_state(crtc->base.state);
>>  
>> -			if (crtc_state->base.active &&
>> +			if (crtc_state->hw.active &&
>>  			    crtc_state->shared_dpll == pll)
>>  				pll->state.crtc_mask |= 1 << crtc->pipe;
>>  		}
>> @@ -16752,21 +16756,24 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  	drm_connector_list_iter_begin(dev, &conn_iter);
>>  	for_each_intel_connector_iter(connector, &conn_iter) {
>>  		if (connector->get_hw_state(connector)) {
>> -			connector->base.dpms = DRM_MODE_DPMS_ON;
>> +			struct intel_crtc_state *crtc_state = NULL;
>>  
>> +			connector->base.dpms = DRM_MODE_DPMS_ON;
>>  			encoder = connector->encoder;
>>  			connector->base.encoder = &encoder->base;
>>  
>> -			if (encoder->base.crtc &&
>> -			    encoder->base.crtc->state->active) {
>> +			if (encoder->base.crtc)
>> +				crtc_state = to_intel_crtc_state(encoder->base.crtc->state);
>> +
>> +			if (crtc_state && crtc_state->hw.active) {
>>  				/*
>>  				 * This has to be done during hardware readout
>>  				 * because anything calling .crtc_disable may
>>  				 * rely on the connector_mask being accurate.
>>  				 */
>> -				encoder->base.crtc->state->connector_mask |=
>> +				crtc_state->uapi.connector_mask |=
>>  					drm_connector_mask(&connector->base);
>> -				encoder->base.crtc->state->encoder_mask |=
>> +				crtc_state->uapi.encoder_mask |=
>>  					drm_encoder_mask(&encoder->base);
>>  			}
>>  
>> @@ -16789,11 +16796,12 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  		int min_cdclk = 0;
>>  
>>  		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
>> -		if (crtc_state->base.active) {
>> +		if (crtc_state->hw.active) {
>>  			intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
>>  			crtc->base.mode.hdisplay = crtc_state->pipe_src_w;
>>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
>> -			intel_mode_from_pipe_config(&crtc_state->base.adjusted_mode, crtc_state);
>> +			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>> +						    crtc_state);
>>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>>  
>>  			/*
>> @@ -16805,7 +16813,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			 * set a flag to indicate that a full recalculation is
>>  			 * needed on the next commit.
>>  			 */
>> -			crtc_state->base.mode.private_flags = I915_MODE_FLAG_INHERITED;
>> +			crtc_state->hw.mode.private_flags = I915_MODE_FLAG_INHERITED;
>>  
>>  			intel_crtc_compute_pixel_rate(crtc_state);
>>  
>> @@ -16816,7 +16824,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			}
>>  
>>  			drm_calc_timestamping_constants(&crtc->base,
>> -							&crtc_state->base.adjusted_mode);
>> +							&crtc_state->hw.adjusted_mode);
>>  			update_scanline_offset(crtc_state);
>>  		}
>>  
>> @@ -16987,7 +16995,7 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
>>  
>>  		drm_crtc_vblank_reset(&crtc->base);
>>  
>> -		if (crtc_state->base.active)
>> +		if (crtc_state->hw.active)
>>  			intel_crtc_vblank_on(crtc_state);
>>  	}
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index d5cc4b810d9e..2c3567081e16 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -749,7 +749,31 @@ enum intel_output_format {
>>  };
>>  
>>  struct intel_crtc_state {
>> -	struct drm_crtc_state base;
>> +	union {
>> +	/*
>> +	 * uapi (drm) state. This is the software state shown to userspace.
>> +	 * In particular, the following members are used for bookkeeping:
>> +	 * - crtc
>> +	 * - state
>> +	 * - *_changed
>> +	 * - event
>> +	 * - commit
>> +	 * - mode_blob
>> +	 */
>> +	struct drm_crtc_state uapi;
>> +
>> +	/*
>> +	 * actual hardware state, the state we program to the hardware.
>> +	 * The following members are used to verify the hardware state:
>> +	 * - enable
>> +	 * - active
>> +	 * - mode / adjusted_mode
>> +	 * - color property blobs.
>> +	 *
>> +	 * During initial hw readout, they need to be copied to uapi.
>> +	 */
>> +	struct drm_crtc_state hw;
>> +	};
>>  
>>  	/**
>>  	 * quirks - bitfield with hw state readout quirks
>> @@ -1091,7 +1115,7 @@ struct cxsr_latency {
>>  
>>  #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base)
>>  #define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
>> -#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, base)
>> +#define to_intel_crtc_state(x) container_of(x, struct intel_crtc_state, uapi)
>>  #define to_intel_connector(x) container_of(x, struct intel_connector, base)
>>  #define to_intel_encoder(x) container_of(x, struct intel_encoder, base)
>>  #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base)
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 02242a16640b..2fceb71f7f70 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -1966,7 +1966,7 @@ intel_dp_compute_link_config_wide(struct intel_dp *intel_dp,
>>  				  struct intel_crtc_state *pipe_config,
>>  				  const struct link_config_limits *limits)
>>  {
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int bpp, clock, lane_count;
>>  	int mode_rate, link_clock, link_avail;
>>  
>> @@ -2020,7 +2020,7 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>  {
>>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>>  	struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	u8 dsc_max_bpc;
>>  	int pipe_bpp;
>>  	int ret;
>> @@ -2131,7 +2131,7 @@ intel_dp_compute_link_config(struct intel_encoder *encoder,
>>  			     struct intel_crtc_state *pipe_config,
>>  			     struct drm_connector_state *conn_state)
>>  {
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	struct link_config_limits limits;
>>  	int common_len;
>> @@ -2219,8 +2219,8 @@ intel_dp_ycbcr420_config(struct intel_dp *intel_dp,
>>  {
>>  	const struct drm_display_info *info = &connector->display_info;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +		&crtc_state->hw.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	int ret;
>>  
>>  	if (!drm_mode_is_420_only(info, adjusted_mode) ||
>> @@ -2248,7 +2248,7 @@ bool intel_dp_limited_color_range(const struct intel_crtc_state *crtc_state,
>>  	const struct intel_digital_connector_state *intel_conn_state =
>>  		to_intel_digital_connector_state(conn_state);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  
>>  	if (intel_conn_state->broadcast_rgb == INTEL_BROADCAST_RGB_AUTO) {
>>  		/*
>> @@ -2271,11 +2271,11 @@ intel_dp_compute_config(struct intel_encoder *encoder,
>>  			struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	struct intel_lspcon *lspcon = enc_to_intel_lspcon(&encoder->base);
>>  	enum port port = encoder->port;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_connector *intel_connector = intel_dp->attached_connector;
>>  	struct intel_digital_connector_state *intel_conn_state =
>>  		to_intel_digital_connector_state(conn_state);
>> @@ -2395,8 +2395,8 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	enum port port = encoder->port;
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  
>>  	intel_dp_set_link_params(intel_dp, pipe_config->port_clock,
>>  				 pipe_config->lane_count,
>> @@ -2993,7 +2993,7 @@ static void assert_edp_pll(struct drm_i915_private *dev_priv, bool state)
>>  static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
>>  				const struct intel_crtc_state *pipe_config)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	assert_pipe_disabled(dev_priv, crtc->pipe);
>> @@ -3033,7 +3033,7 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp,
>>  static void ironlake_edp_pll_off(struct intel_dp *intel_dp,
>>  				 const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	assert_pipe_disabled(dev_priv, crtc->pipe);
>> @@ -3193,7 +3193,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	u32 tmp, flags = 0;
>>  	enum port port = encoder->port;
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  
>>  	if (encoder->type == INTEL_OUTPUT_EDP)
>>  		pipe_config->output_types |= BIT(INTEL_OUTPUT_EDP);
>> @@ -3228,7 +3228,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>>  			flags |= DRM_MODE_FLAG_NVSYNC;
>>  	}
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>>  	if (IS_G4X(dev_priv) && tmp & DP_COLOR_RANGE_16_235)
>>  		pipe_config->limited_color_range = true;
>> @@ -3245,7 +3245,7 @@ static void intel_dp_get_config(struct intel_encoder *encoder,
>>  			pipe_config->port_clock = 270000;
>>  	}
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock =
>> +	pipe_config->hw.adjusted_mode.crtc_clock =
>>  		intel_dotclock_calculate(pipe_config->port_clock,
>>  					 &pipe_config->dp_m_n);
>>  
>> @@ -3460,7 +3460,7 @@ static void intel_enable_dp(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	u32 dp_reg = I915_READ(intel_dp->output_reg);
>>  	enum pipe pipe = crtc->pipe;
>>  	intel_wakeref_t wakeref;
>> @@ -3593,7 +3593,7 @@ static void vlv_init_panel_power_sequencer(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	lockdep_assert_held(&dev_priv->pps_mutex);
>>  
>> @@ -4115,7 +4115,7 @@ intel_dp_link_down(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	enum port port = encoder->port;
>>  	u32 DP = intel_dp->DP;
>>  
>> @@ -4876,7 +4876,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
>>  
>>  	WARN_ON(!intel_crtc_has_dp_encoder(crtc_state));
>>  
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return 0;
>>  
>>  	if (conn_state->commit &&
>> @@ -6695,7 +6695,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
>>  				    int refresh_rate)
>>  {
>>  	struct intel_dp *intel_dp = dev_priv->drrs.dp;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum drrs_refresh_rate_type index = DRRS_HIGH_RR;
>>  
>>  	if (refresh_rate <= 0) {
>> @@ -6728,7 +6728,7 @@ static void intel_dp_set_drrs_state(struct drm_i915_private *dev_priv,
>>  		return;
>>  	}
>>  
>> -	if (!crtc_state->base.active) {
>> +	if (!crtc_state->hw.active) {
>>  		DRM_DEBUG_KMS("eDP encoder disabled. CRTC not Active\n");
>>  		return;
>>  	}
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> index eeeb3f933aa4..76f066b1dfe5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
>> @@ -42,13 +42,13 @@ static int intel_dp_mst_compute_link_config(struct intel_encoder *encoder,
>>  					    struct drm_connector_state *conn_state,
>>  					    struct link_config_limits *limits)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(&encoder->base);
>>  	struct intel_dp *intel_dp = &intel_mst->primary->dp;
>>  	struct intel_connector *connector =
>>  		to_intel_connector(conn_state->connector);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	void *port = connector->port;
>>  	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
>>  					   DP_DPCD_QUIRK_CONSTANT_N);
>> @@ -99,7 +99,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
>>  	struct intel_digital_connector_state *intel_conn_state =
>>  		to_intel_digital_connector_state(conn_state);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  	void *port = connector->port;
>>  	struct link_config_limits limits;
>>  	int ret;
>> diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
>> index 556d1b30f06a..704f38681c4b 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
>> @@ -739,7 +739,7 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base));
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val;
>>  
>> @@ -783,7 +783,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
>>  {
>>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>>  	enum pipe pipe = crtc->pipe;
>>  	unsigned int lane_mask =
>> @@ -864,7 +864,7 @@ void chv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum dpio_channel ch = vlv_dport_to_channel(dport);
>>  	enum pipe pipe = crtc->pipe;
>>  	int data, i, stagger;
>> @@ -953,7 +953,7 @@ void chv_phy_post_pll_disable(struct intel_encoder *encoder,
>>  			      const struct intel_crtc_state *old_crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	enum pipe pipe = to_intel_crtc(old_crtc_state->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
>>  	u32 val;
>>  
>>  	vlv_dpio_get(dev_priv);
>> @@ -1016,7 +1016,7 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
>>  {
>>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -1046,7 +1046,7 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder *encoder,
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
>>  	struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 val;
>> @@ -1075,7 +1075,7 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
>>  {
>>  	struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	enum dpio_channel port = vlv_dport_to_channel(dport);
>>  	enum pipe pipe = crtc->pipe;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
>> index 98288edf88f0..43c12bcfe3b2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
>> @@ -136,7 +136,7 @@ void assert_shared_dpll(struct drm_i915_private *dev_priv,
>>   */
>>  void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>>  
>> @@ -163,7 +163,7 @@ void intel_prepare_shared_dpll(const struct intel_crtc_state *crtc_state)
>>   */
>>  void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>>  	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
>> @@ -208,7 +208,7 @@ void intel_enable_shared_dpll(const struct intel_crtc_state *crtc_state)
>>   */
>>  void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_shared_dpll *pll = crtc_state->shared_dpll;
>>  	unsigned int crtc_mask = drm_crtc_mask(&crtc->base);
>> @@ -825,7 +825,7 @@ hsw_ddi_hdmi_get_dpll(struct intel_atomic_state *state,
>>  static struct intel_shared_dpll *
>>  hsw_ddi_dp_get_dpll(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	struct intel_shared_dpll *pll;
>>  	enum intel_dpll_id pll_id;
>>  	int clock = crtc_state->port_clock;
>> @@ -1734,7 +1734,7 @@ static bool
>>  bxt_ddi_hdmi_pll_dividers(struct intel_crtc_state *crtc_state,
>>  			  struct bxt_clk_div *clk_div)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct dpll best_clock;
>>  
>>  	/* Calculate HDMI div */
>> @@ -2257,7 +2257,7 @@ static bool
>>  cnl_ddi_calculate_wrpll(struct intel_crtc_state *crtc_state,
>>  			struct skl_wrpll_params *wrpll_params)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	u32 afe_clock = crtc_state->port_clock * 5;
>>  	u32 ref_clock;
>>  	u32 dco_min = 7998000;
>> @@ -2523,7 +2523,7 @@ static const struct skl_wrpll_params icl_tbt_pll_19_2MHz_values = {
>>  static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
>>  				  struct skl_wrpll_params *pll_params)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	const struct icl_combo_pll_params *params =
>>  		dev_priv->cdclk.hw.ref == 24000 ?
>>  		icl_dp_combo_pll_24MHz_values :
>> @@ -2545,7 +2545,7 @@ static bool icl_calc_dp_combo_pll(struct intel_crtc_state *crtc_state,
>>  static bool icl_calc_tbt_pll(struct intel_crtc_state *crtc_state,
>>  			     struct skl_wrpll_params *pll_params)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	*pll_params = dev_priv->cdclk.hw.ref == 24000 ?
>>  			icl_tbt_pll_24MHz_values : icl_tbt_pll_19_2MHz_values;
>> @@ -2556,7 +2556,7 @@ static bool icl_calc_dpll_state(struct intel_crtc_state *crtc_state,
>>  				struct intel_encoder *encoder,
>>  				struct intel_dpll_hw_state *pll_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	u32 cfgcr0, cfgcr1;
>>  	struct skl_wrpll_params pll_params = { 0 };
>>  	bool ret;
>> @@ -2682,7 +2682,7 @@ static bool icl_mg_pll_find_divisors(int clock_khz, bool is_dp, bool use_ssc,
>>  static bool icl_calc_mg_pll_state(struct intel_crtc_state *crtc_state,
>>  				  struct intel_dpll_hw_state *pll_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	int refclk_khz = dev_priv->cdclk.hw.ref;
>>  	int clock = crtc_state->port_clock;
>>  	u32 dco_khz, m1div, m2div_int, m2div_rem, m2div_frac;
>> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
>> index 34193d04597a..af0149e32bf4 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
>> @@ -178,9 +178,9 @@ static void intel_dvo_get_config(struct intel_encoder *encoder,
>>  	else
>>  		flags |= DRM_MODE_FLAG_NVSYNC;
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>>  }
>>  
>>  static void intel_disable_dvo(struct intel_encoder *encoder,
>> @@ -207,8 +207,8 @@ static void intel_enable_dvo(struct intel_encoder *encoder,
>>  	u32 temp = I915_READ(dvo_reg);
>>  
>>  	intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev,
>> -					 &pipe_config->base.mode,
>> -					 &pipe_config->base.adjusted_mode);
>> +					 &pipe_config->hw.mode,
>> +					 &pipe_config->hw.adjusted_mode);
>>  
>>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
>>  	I915_READ(dvo_reg);
>> @@ -253,7 +253,7 @@ static int intel_dvo_compute_config(struct intel_encoder *encoder,
>>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
>>  	const struct drm_display_mode *fixed_mode =
>>  		intel_dvo->attached_connector->panel.fixed_mode;
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  
>>  	/*
>>  	 * If we have timings from the BIOS for the panel, put them in
>> @@ -277,8 +277,8 @@ static void intel_dvo_pre_enable(struct intel_encoder *encoder,
>>  				 const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	struct intel_dvo *intel_dvo = enc_to_dvo(encoder);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 dvo_val;
>> diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
>> index 3111ecaeabd0..c6cc3775f3b8 100644
>> --- a/drivers/gpu/drm/i915/display/intel_fbc.c
>> +++ b/drivers/gpu/drm/i915/display/intel_fbc.c
>> @@ -667,7 +667,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
>>  	cache->vma = NULL;
>>  	cache->flags = 0;
>>  
>> -	cache->crtc.mode_flags = crtc_state->base.adjusted_mode.flags;
>> +	cache->crtc.mode_flags = crtc_state->hw.adjusted_mode.flags;
>>  	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
>>  		cache->crtc.hsw_bdw_pixel_rate = crtc_state->pixel_rate;
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
>> index 14e350f5ecc8..e1dbf641be79 100644
>> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
>> @@ -279,7 +279,7 @@ static void ibx_write_infoframe(struct intel_encoder *encoder,
>>  {
>>  	const u32 *data = frame;
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>>  	u32 val = I915_READ(reg);
>>  	int i;
>> @@ -315,7 +315,7 @@ static void ibx_read_infoframe(struct intel_encoder *encoder,
>>  			       void *frame, ssize_t len)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	u32 val, *data = frame;
>>  	int i;
>>  
>> @@ -334,7 +334,7 @@ static u32 ibx_infoframes_enabled(struct intel_encoder *encoder,
>>  				  const struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>>  	i915_reg_t reg = TVIDEO_DIP_CTL(pipe);
>>  	u32 val = I915_READ(reg);
>>  
>> @@ -356,7 +356,7 @@ static void cpt_write_infoframe(struct intel_encoder *encoder,
>>  {
>>  	const u32 *data = frame;
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>>  	u32 val = I915_READ(reg);
>>  	int i;
>> @@ -395,7 +395,7 @@ static void cpt_read_infoframe(struct intel_encoder *encoder,
>>  			       void *frame, ssize_t len)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	u32 val, *data = frame;
>>  	int i;
>>  
>> @@ -414,7 +414,7 @@ static u32 cpt_infoframes_enabled(struct intel_encoder *encoder,
>>  				  const struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>>  	u32 val = I915_READ(TVIDEO_DIP_CTL(pipe));
>>  
>>  	if ((val & VIDEO_DIP_ENABLE) == 0)
>> @@ -432,7 +432,7 @@ static void vlv_write_infoframe(struct intel_encoder *encoder,
>>  {
>>  	const u32 *data = frame;
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
>>  	u32 val = I915_READ(reg);
>>  	int i;
>> @@ -468,7 +468,7 @@ static void vlv_read_infoframe(struct intel_encoder *encoder,
>>  			       void *frame, ssize_t len)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	u32 val, *data = frame;
>>  	int i;
>>  
>> @@ -487,7 +487,7 @@ static u32 vlv_infoframes_enabled(struct intel_encoder *encoder,
>>  				  const struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	enum pipe pipe = to_intel_crtc(pipe_config->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(pipe_config->uapi.crtc)->pipe;
>>  	u32 val = I915_READ(VLV_TVIDEO_DIP_CTL(pipe));
>>  
>>  	if ((val & VIDEO_DIP_ENABLE) == 0)
>> @@ -700,7 +700,7 @@ intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder,
>>  {
>>  	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	struct drm_connector *connector = conn_state->connector;
>>  	int ret;
>>  
>> @@ -787,7 +787,7 @@ intel_hdmi_compute_hdmi_infoframe(struct intel_encoder *encoder,
>>  
>>  	ret = drm_hdmi_vendor_infoframe_from_display_mode(frame,
>>  							  conn_state->connector,
>> -							  &crtc_state->base.adjusted_mode);
>> +							  &crtc_state->hw.adjusted_mode);
>>  	if (WARN_ON(ret))
>>  		return false;
>>  
>> @@ -948,7 +948,7 @@ static bool intel_hdmi_set_gcp_infoframe(struct intel_encoder *encoder,
>>  					 const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	i915_reg_t reg;
>>  
>>  	if ((crtc_state->infoframes.enable &
>> @@ -973,7 +973,7 @@ void intel_hdmi_read_gcp_infoframe(struct intel_encoder *encoder,
>>  				   struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	i915_reg_t reg;
>>  
>>  	if ((crtc_state->infoframes.enable &
>> @@ -1010,7 +1010,7 @@ static void intel_hdmi_compute_gcp_infoframe(struct intel_encoder *encoder,
>>  
>>  	/* Enable default_phase whenever the display mode is suitably aligned */
>>  	if (gcp_default_phase_possible(crtc_state->pipe_bpp,
>> -				       &crtc_state->base.adjusted_mode))
>> +				       &crtc_state->hw.adjusted_mode))
>>  		crtc_state->infoframes.gcp |= GCP_DEFAULT_PHASE_ENABLE;
>>  }
>>  
>> @@ -1020,7 +1020,7 @@ static void ibx_set_infoframes(struct intel_encoder *encoder,
>>  			       const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
>>  	struct intel_hdmi *intel_hdmi = &intel_dig_port->hdmi;
>>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>> @@ -1079,7 +1079,7 @@ static void cpt_set_infoframes(struct intel_encoder *encoder,
>>  			       const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	i915_reg_t reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
>>  	u32 val = I915_READ(reg);
>> @@ -1128,7 +1128,7 @@ static void vlv_set_infoframes(struct intel_encoder *encoder,
>>  			       const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	i915_reg_t reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
>>  	u32 val = I915_READ(reg);
>> @@ -1724,9 +1724,9 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
>>  {
>>  	struct drm_device *dev = encoder->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  	u32 hdmi_val;
>>  
>>  	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
>> @@ -1817,7 +1817,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
>>  	    tmp & HDMI_COLOR_RANGE_16_235)
>>  		pipe_config->limited_color_range = true;
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>>  	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
>>  		dotclock = pipe_config->port_clock * 2 / 3;
>> @@ -1827,7 +1827,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
>>  	if (pipe_config->pixel_multiplier)
>>  		dotclock /= pipe_config->pixel_multiplier;
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>>  
>>  	pipe_config->lane_count = 4;
>>  
>> @@ -1848,7 +1848,7 @@ static void intel_enable_hdmi_audio(struct intel_encoder *encoder,
>>  				    const struct intel_crtc_state *pipe_config,
>>  				    const struct drm_connector_state *conn_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  
>>  	WARN_ON(!pipe_config->has_hdmi_sink);
>>  	DRM_DEBUG_DRIVER("Enabling HDMI audio on pipe %c\n",
>> @@ -1934,7 +1934,7 @@ static void cpt_enable_hdmi(struct intel_encoder *encoder,
>>  {
>>  	struct drm_device *dev = encoder->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 temp;
>> @@ -1998,7 +1998,7 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	struct intel_digital_port *intel_dig_port =
>>  		hdmi_to_dig_port(intel_hdmi);
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	u32 temp;
>>  
>>  	temp = I915_READ(intel_hdmi->hdmi_reg);
>> @@ -2198,12 +2198,12 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
>>  				     int bpc)
>>  {
>>  	struct drm_i915_private *dev_priv =
>> -		to_i915(crtc_state->base.crtc->dev);
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +		to_i915(crtc_state->uapi.crtc->dev);
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct drm_connector_state *connector_state;
>>  	struct drm_connector *connector;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	int i;
>>  
>>  	if (HAS_GMCH(dev_priv))
>> @@ -2228,7 +2228,7 @@ static bool hdmi_deep_color_possible(const struct intel_crtc_state *crtc_state,
>>  	for_each_new_connector_in_state(state, connector, connector_state, i) {
>>  		const struct drm_display_info *info = &connector->display_info;
>>  
>> -		if (connector_state->crtc != crtc_state->base.crtc)
>> +		if (connector_state->crtc != crtc_state->uapi.crtc)
>>  			continue;
>>  
>>  		if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
>> @@ -2269,7 +2269,7 @@ static bool
>>  intel_hdmi_ycbcr420_config(struct drm_connector *connector,
>>  			   struct intel_crtc_state *config)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(config->uapi.crtc);
>>  
>>  	if (!connector->ycbcr_420_allowed) {
>>  		DRM_ERROR("Platform doesn't support YCBCR420 output\n");
>> @@ -2324,7 +2324,7 @@ static int intel_hdmi_compute_clock(struct intel_encoder *encoder,
>>  {
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	int bpc, clock = adjusted_mode->crtc_clock;
>>  
>>  	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
>> @@ -2366,7 +2366,7 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
>>  {
>>  	struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	struct drm_connector *connector = conn_state->connector;
>>  	struct drm_scdc *scdc = &connector->display_info.hdmi.scdc;
>>  	struct intel_digital_connector_state *intel_conn_state =
>> diff --git a/drivers/gpu/drm/i915/display/intel_lspcon.c b/drivers/gpu/drm/i915/display/intel_lspcon.c
>> index f8f1308643a9..5145ff8b962b 100644
>> --- a/drivers/gpu/drm/i915/display/intel_lspcon.c
>> +++ b/drivers/gpu/drm/i915/display/intel_lspcon.c
>> @@ -189,7 +189,7 @@ void lspcon_ycbcr420_config(struct drm_connector *connector,
>>  {
>>  	const struct drm_display_info *info = &connector->display_info;
>>  	const struct drm_display_mode *adjusted_mode =
>> -					&crtc_state->base.adjusted_mode;
>> +					&crtc_state->hw.adjusted_mode;
>>  
>>  	if (drm_mode_is_420_only(info, adjusted_mode) &&
>>  	    connector->ycbcr_420_allowed) {
>> @@ -475,7 +475,7 @@ void lspcon_set_infoframes(struct intel_encoder *encoder,
>>  	struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
>>  	struct intel_lspcon *lspcon = &dig_port->lspcon;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  
>>  	if (!lspcon->active) {
>>  		DRM_ERROR("Writing infoframes while LSPCON disabled ?\n");
>> diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c
>> index c786abdc3336..0f77e5a8b7ff 100644
>> --- a/drivers/gpu/drm/i915/display/intel_lvds.c
>> +++ b/drivers/gpu/drm/i915/display/intel_lvds.c
>> @@ -135,7 +135,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
>>  	else
>>  		flags |= DRM_MODE_FLAG_PVSYNC;
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>>  	if (INTEL_GEN(dev_priv) < 5)
>>  		pipe_config->gmch_pfit.lvds_border_bits =
>> @@ -148,7 +148,7 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
>>  		pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE;
>>  	}
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = pipe_config->port_clock;
>>  }
>>  
>>  static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
>> @@ -230,8 +230,8 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder,
>>  {
>>  	struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	enum pipe pipe = crtc->pipe;
>>  	u32 temp;
>>  
>> @@ -392,8 +392,8 @@ static int intel_lvds_compute_config(struct intel_encoder *intel_encoder,
>>  		to_lvds_encoder(&intel_encoder->base);
>>  	struct intel_connector *intel_connector =
>>  		lvds_encoder->attached_connector;
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	unsigned int lvds_bpp;
>>  
>>  	/* Should never happen!! */
>> diff --git a/drivers/gpu/drm/i915/display/intel_panel.c b/drivers/gpu/drm/i915/display/intel_panel.c
>> index bc14e9c0285a..6f3eaae3761f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_panel.c
>> +++ b/drivers/gpu/drm/i915/display/intel_panel.c
>> @@ -178,7 +178,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
>>  			struct intel_crtc_state *pipe_config,
>>  			int fitting_mode)
>>  {
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int x = 0, y = 0, width = 0, height = 0;
>>  
>>  	/* Native modes don't need fitting */
>> @@ -300,7 +300,7 @@ static inline u32 panel_fitter_scaling(u32 source, u32 target)
>>  static void i965_scale_aspect(struct intel_crtc_state *pipe_config,
>>  			      u32 *pfit_control)
>>  {
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	u32 scaled_width = adjusted_mode->crtc_hdisplay *
>>  		pipe_config->pipe_src_h;
>>  	u32 scaled_height = pipe_config->pipe_src_w *
>> @@ -321,7 +321,7 @@ static void i9xx_scale_aspect(struct intel_crtc_state *pipe_config,
>>  			      u32 *pfit_control, u32 *pfit_pgm_ratios,
>>  			      u32 *border)
>>  {
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	u32 scaled_width = adjusted_mode->crtc_hdisplay *
>>  		pipe_config->pipe_src_h;
>>  	u32 scaled_height = pipe_config->pipe_src_w *
>> @@ -380,7 +380,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>>  	u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0;
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  
>>  	/* Native modes don't need fitting */
>>  	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
>> @@ -1047,7 +1047,7 @@ static void vlv_enable_backlight(const struct intel_crtc_state *crtc_state,
>>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>>  	struct intel_panel *panel = &connector->panel;
>> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>  	u32 ctl, ctl2;
>>  
>>  	ctl2 = I915_READ(VLV_BLC_PWM_CTL2(pipe));
>> @@ -1077,7 +1077,7 @@ static void bxt_enable_backlight(const struct intel_crtc_state *crtc_state,
>>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>>  	struct intel_panel *panel = &connector->panel;
>> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>  	u32 pwm_ctl, val;
>>  
>>  	/* Controller 1 uses the utility pin. */
>> @@ -1189,7 +1189,7 @@ void intel_panel_enable_backlight(const struct intel_crtc_state *crtc_state,
>>  	struct intel_connector *connector = to_intel_connector(conn_state->connector);
>>  	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
>>  	struct intel_panel *panel = &connector->panel;
>> -	enum pipe pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>  
>>  	if (!panel->backlight.present)
>>  		return;
>> diff --git a/drivers/gpu/drm/i915/display/intel_pipe_crc.c b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
>> index 6260a2082719..2746512f4466 100644
>> --- a/drivers/gpu/drm/i915/display/intel_pipe_crc.c
>> +++ b/drivers/gpu/drm/i915/display/intel_pipe_crc.c
>> @@ -309,13 +309,13 @@ intel_crtc_crc_setup_workarounds(struct intel_crtc *crtc, bool enable)
>>  		goto put_state;
>>  	}
>>  
>> -	pipe_config->base.mode_changed = pipe_config->has_psr;
>> +	pipe_config->uapi.mode_changed = pipe_config->has_psr;
>>  	pipe_config->crc_enabled = enable;
>>  
>>  	if (IS_HASWELL(dev_priv) &&
>> -	    pipe_config->base.active && crtc->pipe == PIPE_A &&
>> +	    pipe_config->hw.active && crtc->pipe == PIPE_A &&
>>  	    pipe_config->cpu_transcoder == TRANSCODER_EDP)
>> -		pipe_config->base.mode_changed = true;
>> +		pipe_config->uapi.mode_changed = true;
>>  
>>  	ret = drm_atomic_commit(state);
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
>> index b3c7eef53bf3..8988dbe8c19e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_psr.c
>> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
>> @@ -538,8 +538,8 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
>>  				    struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>> -	int crtc_hdisplay = crtc_state->base.adjusted_mode.crtc_hdisplay;
>> -	int crtc_vdisplay = crtc_state->base.adjusted_mode.crtc_vdisplay;
>> +	int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
>> +	int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
>>  	int psr_max_h = 0, psr_max_v = 0;
>>  
>>  	if (!dev_priv->psr.sink_psr2_support)
>> @@ -605,7 +605,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
>>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>>  	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	int psr_setup_time;
>>  
>>  	if (!CAN_PSR(dev_priv))
>> @@ -745,7 +745,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv,
>>  
>>  	dev_priv->psr.psr2_enabled = intel_psr2_enabled(dev_priv, crtc_state);
>>  	dev_priv->psr.busy_frontbuffer_bits = 0;
>> -	dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)->pipe;
>> +	dev_priv->psr.pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>  	dev_priv->psr.transcoder = crtc_state->cpu_transcoder;
>>  
>>  	/*
>> @@ -988,7 +988,7 @@ void intel_psr_update(struct intel_dp *intel_dp,
>>  int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
>>  			    u32 *out_value)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  
>>  	if (!dev_priv->psr.enabled || !new_crtc_state->has_psr)
>> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
>> index adeb1c840976..f74c528d5d68 100644
>> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
>> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
>> @@ -1087,7 +1087,7 @@ static bool intel_sdvo_compute_avi_infoframe(struct intel_sdvo *intel_sdvo,
>>  {
>>  	struct hdmi_avi_infoframe *frame = &crtc_state->infoframes.avi.avi;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	int ret;
>>  
>>  	if (!crtc_state->has_hdmi_sink)
>> @@ -1276,8 +1276,8 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>>  		to_intel_sdvo_connector_state(conn_state);
>>  	struct intel_sdvo_connector *intel_sdvo_connector =
>>  		to_intel_sdvo_connector(conn_state->connector);
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> -	struct drm_display_mode *mode = &pipe_config->base.mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>> +	struct drm_display_mode *mode = &pipe_config->hw.mode;
>>  
>>  	DRM_DEBUG_KMS("forcing bpc to 8 for SDVO\n");
>>  	pipe_config->pipe_bpp = 8*3;
>> @@ -1429,13 +1429,13 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>>  				  const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> -	const struct drm_display_mode *adjusted_mode = &crtc_state->base.adjusted_mode;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  	const struct intel_sdvo_connector_state *sdvo_state =
>>  		to_intel_sdvo_connector_state(conn_state);
>>  	const struct intel_sdvo_connector *intel_sdvo_connector =
>>  		to_intel_sdvo_connector(conn_state->connector);
>> -	const struct drm_display_mode *mode = &crtc_state->base.mode;
>> +	const struct drm_display_mode *mode = &crtc_state->hw.mode;
>>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>>  	u32 sdvox;
>>  	struct intel_sdvo_in_out_map in_out;
>> @@ -1629,7 +1629,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>>  			flags |= DRM_MODE_FLAG_NVSYNC;
>>  	}
>>  
>> -	pipe_config->base.adjusted_mode.flags |= flags;
>> +	pipe_config->hw.adjusted_mode.flags |= flags;
>>  
>>  	/*
>>  	 * pixel multiplier readout is tricky: Only on i915g/gm it is stored in
>> @@ -1649,7 +1649,7 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
>>  	if (pipe_config->pixel_multiplier)
>>  		dotclock /= pipe_config->pixel_multiplier;
>>  
>> -	pipe_config->base.adjusted_mode.crtc_clock = dotclock;
>> +	pipe_config->hw.adjusted_mode.crtc_clock = dotclock;
>>  
>>  	/* Cross check the port pixel multiplier with the sdvo encoder state. */
>>  	if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_CLOCK_RATE_MULT,
>> @@ -1701,7 +1701,7 @@ static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo,
>>  				    const struct drm_connector_state *conn_state)
>>  {
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	struct drm_connector *connector = conn_state->connector;
>>  	u8 *eld = connector->eld;
>>  
>> @@ -1723,7 +1723,7 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	u32 temp;
>>  
>>  	if (old_crtc_state->has_audio)
>> @@ -1785,7 +1785,7 @@ static void intel_enable_sdvo(struct intel_encoder *encoder,
>>  	struct drm_device *dev = encoder->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	u32 temp;
>>  	bool input1, input2;
>>  	int i;
>> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
>> index 7a7078d0ba23..a602e21c5fd5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
>> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
>> @@ -81,9 +81,9 @@ int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
>>   */
>>  void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
>>  	long timeout = msecs_to_jiffies_timeout(1);
>>  	int scanline, min, max, vblank_start;
>>  	wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
>> @@ -190,7 +190,7 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
>>   */
>>  void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	enum pipe pipe = crtc->pipe;
>>  	int scanline_end = intel_get_crtc_scanline(crtc);
>>  	u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
>> @@ -203,14 +203,15 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
>>  	 * Would be slightly nice to just grab the vblank count and arm the
>>  	 * event outside of the critical section - the spinlock might spin for a
>>  	 * while ... */
>> -	if (new_crtc_state->base.event) {
>> +	if (new_crtc_state->uapi.event) {
>>  		WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
>>  
>>  		spin_lock(&crtc->base.dev->event_lock);
>> -		drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
>> +		drm_crtc_arm_vblank_event(&crtc->base,
>> +				          new_crtc_state->uapi.event);
>>  		spin_unlock(&crtc->base.dev->event_lock);
>>  
>> -		new_crtc_state->base.event = NULL;
>> +		new_crtc_state->uapi.event = NULL;
>>  	}
>>  
>>  	local_irq_enable();
>> @@ -1515,7 +1516,7 @@ g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
>>  	const struct drm_rect *dst = &plane_state->base.dst;
>>  	int src_x, src_w, src_h, crtc_w, crtc_h;
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	unsigned int cpp = fb->format->cpp[0];
>>  	unsigned int width_bytes;
>>  	int min_width, min_height;
>> @@ -1587,7 +1588,7 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
>>  	}
>>  
>>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
>> -						  &crtc_state->base,
>> +						  &crtc_state->uapi,
>>  						  min_scale, max_scale,
>>  						  true, true);
>>  	if (ret)
>> @@ -1644,7 +1645,7 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
>>  		return ret;
>>  
>>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
>> -						  &crtc_state->base,
>> +						  &crtc_state->uapi,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  DRM_PLANE_HELPER_NO_SCALING,
>>  						  true, true);
>> @@ -1728,8 +1729,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
>>  	}
>>  
>>  	/* Y-tiling is not supported in IF-ID Interlace mode */
>> -	if (crtc_state->base.enable &&
>> -	    crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
>> +	if (crtc_state->hw.enable &&
>> +	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
>>  	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
>>  	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
>>  	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
>> @@ -1809,7 +1810,7 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
>>  	}
>>  
>>  	ret = drm_atomic_helper_check_plane_state(&plane_state->base,
>> -						  &crtc_state->base,
>> +						  &crtc_state->uapi,
>>  						  min_scale, max_scale,
>>  						  true, true);
>>  	if (ret)
>> diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c
>> index b70221f5112a..96a3d9348471 100644
>> --- a/drivers/gpu/drm/i915/display/intel_tv.c
>> +++ b/drivers/gpu/drm/i915/display/intel_tv.c
>> @@ -924,7 +924,7 @@ intel_enable_tv(struct intel_encoder *encoder,
>>  
>>  	/* Prevents vblank waits from timing out in intel_tv_detect_type() */
>>  	intel_wait_for_vblank(dev_priv,
>> -			      to_intel_crtc(pipe_config->base.crtc)->pipe);
>> +			      to_intel_crtc(pipe_config->uapi.crtc)->pipe);
>>  
>>  	I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE);
>>  }
>> @@ -1086,7 +1086,7 @@ intel_tv_get_config(struct intel_encoder *encoder,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  	struct drm_display_mode mode = {};
>>  	u32 tv_ctl, hctl1, hctl3, vctl1, vctl2, tmp;
>>  	struct tv_mode tv_mode = {};
>> @@ -1189,7 +1189,7 @@ intel_tv_compute_config(struct intel_encoder *encoder,
>>  		to_intel_tv_connector_state(conn_state);
>>  	const struct tv_mode *tv_mode = intel_tv_mode_find(conn_state);
>>  	struct drm_display_mode *adjusted_mode =
>> -		&pipe_config->base.adjusted_mode;
>> +		&pipe_config->hw.adjusted_mode;
>>  	int hdisplay = adjusted_mode->crtc_hdisplay;
>>  	int vdisplay = adjusted_mode->crtc_vdisplay;
>>  
>> @@ -1418,7 +1418,7 @@ static void intel_tv_pre_enable(struct intel_encoder *encoder,
>>  				const struct drm_connector_state *conn_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_tv *intel_tv = enc_to_tv(encoder);
>>  	const struct intel_tv_connector_state *tv_conn_state =
>>  		to_intel_tv_connector_state(conn_state);
>> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
>> index d4fb7f16f9f6..38c181499505 100644
>> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
>> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
>> @@ -329,8 +329,8 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>>  	int column_index = 0;
>>  	u8 line_buf_depth = 0;
>>  
>> -	vdsc_cfg->pic_width = pipe_config->base.adjusted_mode.crtc_hdisplay;
>> -	vdsc_cfg->pic_height = pipe_config->base.adjusted_mode.crtc_vdisplay;
>> +	vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
>> +	vdsc_cfg->pic_height = pipe_config->hw.adjusted_mode.crtc_vdisplay;
>>  	vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
>>  					     pipe_config->dsc_params.slice_count);
>>  	/*
>> @@ -459,7 +459,7 @@ int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>>  enum intel_display_power_domain
>>  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *i915 = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  
>>  	/*
>> @@ -483,7 +483,7 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>>  static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
>>  						const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -902,7 +902,7 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
>>  void intel_dsc_enable(struct intel_encoder *encoder,
>>  		      const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
>> @@ -938,7 +938,7 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>>  
>>  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
>> diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c
>> index 50064cde0724..16f93d1e71e5 100644
>> --- a/drivers/gpu/drm/i915/display/vlv_dsi.c
>> +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c
>> @@ -261,9 +261,9 @@ static int intel_dsi_compute_config(struct intel_encoder *encoder,
>>  	struct intel_dsi *intel_dsi = container_of(encoder, struct intel_dsi,
>>  						   base);
>>  	struct intel_connector *intel_connector = intel_dsi->attached_connector;
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
>> -	struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int ret;
>>  
>>  	DRM_DEBUG_KMS("\n");
>> @@ -624,7 +624,7 @@ static void intel_dsi_port_enable(struct intel_encoder *encoder,
>>  				  const struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>>  	enum port port;
>>  
>> @@ -746,7 +746,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
>>  				 const struct drm_connector_state *conn_state)
>>  {
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>> -	struct drm_crtc *crtc = pipe_config->base.crtc;
>> +	struct drm_crtc *crtc = pipe_config->uapi.crtc;
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  	enum pipe pipe = intel_crtc->pipe;
>> @@ -1032,9 +1032,9 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
>>  	struct drm_device *dev = encoder->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct drm_display_mode *adjusted_mode =
>> -					&pipe_config->base.adjusted_mode;
>> +					&pipe_config->hw.adjusted_mode;
>>  	struct drm_display_mode *adjusted_mode_sw;
>> -	struct intel_crtc *crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base);
>>  	unsigned int lane_count = intel_dsi->lane_count;
>>  	unsigned int bpp, fmt;
>> @@ -1045,7 +1045,7 @@ static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
>>  				crtc_hblank_start_sw, crtc_hblank_end_sw;
>>  
>>  	/* FIXME: hw readout should not depend on SW state */
>> -	adjusted_mode_sw = &crtc->config->base.adjusted_mode;
>> +	adjusted_mode_sw = &crtc->config->hw.adjusted_mode;
>>  
>>  	/*
>>  	 * Atleast one port is active as encoder->get_config called only if
>> @@ -1204,7 +1204,7 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
>>  	}
>>  
>>  	if (pclk) {
>> -		pipe_config->base.adjusted_mode.crtc_clock = pclk;
>> +		pipe_config->hw.adjusted_mode.crtc_clock = pclk;
>>  		pipe_config->port_clock = pclk;
>>  	}
>>  }
>> @@ -1315,9 +1315,9 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
>>  	struct drm_encoder *encoder = &intel_encoder->base;
>>  	struct drm_device *dev = encoder->dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	enum port port;
>>  	unsigned int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format);
>>  	u32 val, tmp;
>> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
>> index 43db50095257..1c4c3972fd23 100644
>> --- a/drivers/gpu/drm/i915/i915_debugfs.c
>> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
>> @@ -2749,11 +2749,11 @@ static int i915_display_info(struct seq_file *m, void *unused)
>>  
>>  		seq_printf(m, "CRTC %d: pipe: %c, active=%s, (size=%dx%d), dither=%s, bpp=%d\n",
>>  			   crtc->base.base.id, pipe_name(crtc->pipe),
>> -			   yesno(pipe_config->base.active),
>> +			   yesno(pipe_config->hw.active),
>>  			   pipe_config->pipe_src_w, pipe_config->pipe_src_h,
>>  			   yesno(pipe_config->dither), pipe_config->pipe_bpp);
>>  
>> -		if (pipe_config->base.active) {
>> +		if (pipe_config->hw.active) {
>>  			struct intel_plane *cursor =
>>  				to_intel_plane(crtc->base.cursor);
>>  
>> @@ -4204,11 +4204,11 @@ static int i915_drrs_ctl_set(void *data, u64 val)
>>  
>>  		crtc_state = to_intel_crtc_state(crtc->base.state);
>>  
>> -		if (!crtc_state->base.active ||
>> +		if (!crtc_state->hw.active ||
>>  		    !crtc_state->has_drrs)
>>  			goto out;
>>  
>> -		commit = crtc_state->base.commit;
>> +		commit = crtc_state->uapi.commit;
>>  		if (commit) {
>>  			ret = wait_for_completion_interruptible(&commit->hw_done);
>>  			if (ret)
>> @@ -4220,7 +4220,7 @@ static int i915_drrs_ctl_set(void *data, u64 val)
>>  			struct intel_encoder *encoder;
>>  			struct intel_dp *intel_dp;
>>  
>> -			if (!(crtc_state->base.connector_mask &
>> +			if (!(crtc_state->uapi.connector_mask &
>>  			      drm_connector_mask(connector)))
>>  				continue;
>>  
>> @@ -4279,14 +4279,14 @@ i915_fifo_underrun_reset_write(struct file *filp,
>>  			return ret;
>>  
>>  		crtc_state = to_intel_crtc_state(intel_crtc->base.state);
>> -		commit = crtc_state->base.commit;
>> +		commit = crtc_state->uapi.commit;
>>  		if (commit) {
>>  			ret = wait_for_completion_interruptible(&commit->hw_done);
>>  			if (!ret)
>>  				ret = wait_for_completion_interruptible(&commit->flip_done);
>>  		}
>>  
>> -		if (!ret && crtc_state->base.active) {
>> +		if (!ret && crtc_state->hw.active) {
>>  			DRM_DEBUG_KMS("Re-arming FIFO underruns on pipe %c\n",
>>  				      pipe_name(intel_crtc->pipe));
>>  
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index 6aa40f546226..edabf2cf4440 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -484,7 +484,7 @@ static const int pessimal_latency_ns = 5000;
>>  
>>  static void vlv_get_fifo_size(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -818,7 +818,7 @@ static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
>>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>  
>>  	/* FIXME check the 'enable' instead */
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return false;
>>  
>>  	/*
>> @@ -871,7 +871,7 @@ static void pineview_update_wm(struct intel_crtc *unused_crtc)
>>  	crtc = single_enabled_crtc(dev_priv);
>>  	if (crtc) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc->config->base.adjusted_mode;
>> +			&crtc->config->hw.adjusted_mode;
>>  		const struct drm_framebuffer *fb =
>>  			crtc->base.primary->state->fb;
>>  		int cpp = fb->format->cpp[0];
>> @@ -1107,7 +1107,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
>>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
>>  	unsigned int clock, htotal, cpp, width, wm;
>>  
>> @@ -1167,7 +1167,7 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
>>  static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>>  				 int level, enum plane_id plane_id, u16 value)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	bool dirty = false;
>>  
>>  	for (; level < intel_wm_num_levels(dev_priv); level++) {
>> @@ -1183,7 +1183,7 @@ static bool g4x_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>>  static bool g4x_raw_fbc_wm_set(struct intel_crtc_state *crtc_state,
>>  			       int level, u16 value)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	bool dirty = false;
>>  
>>  	/* NORMAL level doesn't have an FBC watermark */
>> @@ -1285,7 +1285,7 @@ static bool g4x_raw_plane_wm_is_valid(const struct intel_crtc_state *crtc_state,
>>  static bool g4x_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
>>  				     int level)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  
>>  	if (level > dev_priv->wm.max_level)
>>  		return false;
>> @@ -1323,9 +1323,9 @@ static void g4x_invalidate_wms(struct intel_crtc *crtc,
>>  
>>  static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  	struct g4x_wm_state *wm_state = &crtc_state->wm.g4x.optimal;
>>  	int num_active_planes = hweight8(crtc_state->active_planes &
>>  					 ~BIT(PLANE_CURSOR));
>> @@ -1412,17 +1412,17 @@ static int g4x_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  
>>  static int g4x_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct g4x_wm_state *intermediate = &new_crtc_state->wm.g4x.intermediate;
>>  	const struct g4x_wm_state *optimal = &new_crtc_state->wm.g4x.optimal;
>>  	struct intel_atomic_state *intel_state =
>> -		to_intel_atomic_state(new_crtc_state->base.state);
>> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>>  	const struct intel_crtc_state *old_crtc_state =
>>  		intel_atomic_get_old_crtc_state(intel_state, crtc);
>>  	const struct g4x_wm_state *active = &old_crtc_state->wm.g4x.optimal;
>>  	enum plane_id plane_id;
>>  
>> -	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
>> +	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
>>  		*intermediate = *optimal;
>>  
>>  		intermediate->cxsr = false;
>> @@ -1554,8 +1554,8 @@ static void g4x_program_watermarks(struct drm_i915_private *dev_priv)
>>  static void g4x_initial_watermarks(struct intel_atomic_state *state,
>>  				   struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	mutex_lock(&dev_priv->wm.wm_mutex);
>>  	crtc->wm.active.g4x = crtc_state->wm.g4x.intermediate;
>> @@ -1566,8 +1566,8 @@ static void g4x_initial_watermarks(struct intel_atomic_state *state,
>>  static void g4x_optimize_watermarks(struct intel_atomic_state *state,
>>  				    struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	if (!crtc_state->wm.need_postvbl_update)
>>  		return;
>> @@ -1616,7 +1616,7 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
>>  	struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
>>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	unsigned int clock, htotal, cpp, width, wm;
>>  
>>  	if (dev_priv->wm.pri_latency[level] == 0)
>> @@ -1654,7 +1654,7 @@ static bool vlv_need_sprite0_fifo_workaround(unsigned int active_planes)
>>  
>>  static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	const struct g4x_pipe_wm *raw =
>>  		&crtc_state->wm.vlv.raw[VLV_WM_LEVEL_PM2];
>>  	struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
>> @@ -1766,7 +1766,7 @@ static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
>>  static bool vlv_raw_plane_wm_set(struct intel_crtc_state *crtc_state,
>>  				 int level, enum plane_id plane_id, u16 value)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	int num_levels = intel_wm_num_levels(dev_priv);
>>  	bool dirty = false;
>>  
>> @@ -1841,16 +1841,16 @@ static bool vlv_raw_crtc_wm_is_valid(const struct intel_crtc_state *crtc_state,
>>  
>>  static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_atomic_state *state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  	struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
>>  	const struct vlv_fifo_state *fifo_state =
>>  		&crtc_state->wm.vlv.fifo_state;
>>  	int num_active_planes = hweight8(crtc_state->active_planes &
>>  					 ~BIT(PLANE_CURSOR));
>> -	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->base);
>> +	bool needs_modeset = drm_atomic_crtc_needs_modeset(&crtc_state->uapi);
>>  	const struct intel_plane_state *old_plane_state;
>>  	const struct intel_plane_state *new_plane_state;
>>  	struct intel_plane *plane;
>> @@ -1949,7 +1949,7 @@ static int vlv_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
>>  				   struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_uncore *uncore = &dev_priv->uncore;
>>  	const struct vlv_fifo_state *fifo_state =
>> @@ -2045,17 +2045,17 @@ static void vlv_atomic_update_fifo(struct intel_atomic_state *state,
>>  
>>  static int vlv_compute_intermediate_wm(struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct vlv_wm_state *intermediate = &new_crtc_state->wm.vlv.intermediate;
>>  	const struct vlv_wm_state *optimal = &new_crtc_state->wm.vlv.optimal;
>>  	struct intel_atomic_state *intel_state =
>> -		to_intel_atomic_state(new_crtc_state->base.state);
>> +		to_intel_atomic_state(new_crtc_state->uapi.state);
>>  	const struct intel_crtc_state *old_crtc_state =
>>  		intel_atomic_get_old_crtc_state(intel_state, crtc);
>>  	const struct vlv_wm_state *active = &old_crtc_state->wm.vlv.optimal;
>>  	int level;
>>  
>> -	if (!new_crtc_state->base.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->base)) {
>> +	if (!new_crtc_state->hw.active || drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi)) {
>>  		*intermediate = *optimal;
>>  
>>  		intermediate->cxsr = false;
>> @@ -2173,8 +2173,8 @@ static void vlv_program_watermarks(struct drm_i915_private *dev_priv)
>>  static void vlv_initial_watermarks(struct intel_atomic_state *state,
>>  				   struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	mutex_lock(&dev_priv->wm.wm_mutex);
>>  	crtc->wm.active.vlv = crtc_state->wm.vlv.intermediate;
>> @@ -2185,8 +2185,8 @@ static void vlv_initial_watermarks(struct intel_atomic_state *state,
>>  static void vlv_optimize_watermarks(struct intel_atomic_state *state,
>>  				    struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	if (!crtc_state->wm.need_postvbl_update)
>>  		return;
>> @@ -2211,7 +2211,7 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
>>  		/* self-refresh has much higher latency */
>>  		static const int sr_latency_ns = 12000;
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc->config->base.adjusted_mode;
>> +			&crtc->config->hw.adjusted_mode;
>>  		const struct drm_framebuffer *fb =
>>  			crtc->base.primary->state->fb;
>>  		int clock = adjusted_mode->crtc_clock;
>> @@ -2292,7 +2292,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>>  	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
>>  	if (intel_crtc_active(crtc)) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc->config->base.adjusted_mode;
>> +			&crtc->config->hw.adjusted_mode;
>>  		const struct drm_framebuffer *fb =
>>  			crtc->base.primary->state->fb;
>>  		int cpp;
>> @@ -2319,7 +2319,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>>  	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
>>  	if (intel_crtc_active(crtc)) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc->config->base.adjusted_mode;
>> +			&crtc->config->hw.adjusted_mode;
>>  		const struct drm_framebuffer *fb =
>>  			crtc->base.primary->state->fb;
>>  		int cpp;
>> @@ -2367,7 +2367,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
>>  		/* self-refresh has much higher latency */
>>  		static const int sr_latency_ns = 6000;
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&enabled->config->base.adjusted_mode;
>> +			&enabled->config->hw.adjusted_mode;
>>  		const struct drm_framebuffer *fb =
>>  			enabled->base.primary->state->fb;
>>  		int clock = adjusted_mode->crtc_clock;
>> @@ -2425,7 +2425,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
>>  	if (crtc == NULL)
>>  		return;
>>  
>> -	adjusted_mode = &crtc->config->base.adjusted_mode;
>> +	adjusted_mode = &crtc->config->hw.adjusted_mode;
>>  	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
>>  				       &i845_wm_info,
>>  				       dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
>> @@ -2515,7 +2515,7 @@ static u32 ilk_compute_pri_wm(const struct intel_crtc_state *crtc_state,
>>  		return method1;
>>  
>>  	method2 = ilk_wm_method2(crtc_state->pixel_rate,
>> -				 crtc_state->base.adjusted_mode.crtc_htotal,
>> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>>  				 drm_rect_width(&plane_state->base.dst),
>>  				 cpp, mem_value);
>>  
>> @@ -2543,7 +2543,7 @@ static u32 ilk_compute_spr_wm(const struct intel_crtc_state *crtc_state,
>>  
>>  	method1 = ilk_wm_method1(crtc_state->pixel_rate, cpp, mem_value);
>>  	method2 = ilk_wm_method2(crtc_state->pixel_rate,
>> -				 crtc_state->base.adjusted_mode.crtc_htotal,
>> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>>  				 drm_rect_width(&plane_state->base.dst),
>>  				 cpp, mem_value);
>>  	return min(method1, method2);
>> @@ -2568,7 +2568,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
>>  	cpp = plane_state->base.fb->format->cpp[0];
>>  
>>  	return ilk_wm_method2(crtc_state->pixel_rate,
>> -			      crtc_state->base.adjusted_mode.crtc_htotal,
>> +			      crtc_state->hw.adjusted_mode.crtc_htotal,
>>  			      plane_state->base.crtc_w, cpp, mem_value);
>>  }
>>  
>> @@ -2789,12 +2789,12 @@ static u32
>>  hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
>>  {
>>  	const struct intel_atomic_state *intel_state =
>> -		to_intel_atomic_state(crtc_state->base.state);
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  	const struct drm_display_mode *adjusted_mode =
>> -		&crtc_state->base.adjusted_mode;
>> +		&crtc_state->hw.adjusted_mode;
>>  	u32 linetime, ips_linetime;
>>  
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return 0;
>>  	if (WARN_ON(adjusted_mode->crtc_clock == 0))
>>  		return 0;
>> @@ -3104,11 +3104,9 @@ static bool ilk_validate_pipe_wm(const struct drm_i915_private *dev_priv,
>>  /* Compute new watermarks for the pipe */
>>  static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct intel_pipe_wm *pipe_wm;
>> -	struct drm_device *dev = state->dev;
>> -	const struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *plane_state;
>>  	const struct intel_plane_state *pristate = NULL;
>> @@ -3119,7 +3117,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  
>>  	pipe_wm = &crtc_state->wm.ilk.optimal;
>>  
>> -	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->base) {
>> +	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &crtc_state->uapi) {
>>  		const struct intel_plane_state *ps = to_intel_plane_state(plane_state);
>>  
>>  		if (plane->type == DRM_PLANE_TYPE_PRIMARY)
>> @@ -3130,7 +3128,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>  			curstate = ps;
>>  	}
>>  
>> -	pipe_wm->pipe_enabled = crtc_state->base.active;
>> +	pipe_wm->pipe_enabled = crtc_state->hw.active;
>>  	if (sprstate) {
>>  		pipe_wm->sprites_enabled = sprstate->base.visible;
>>  		pipe_wm->sprites_scaled = sprstate->base.visible &&
>> @@ -3187,11 +3185,11 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
>>   */
>>  static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(newstate->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>>  	struct intel_pipe_wm *a = &newstate->wm.ilk.intermediate;
>>  	struct intel_atomic_state *intel_state =
>> -		to_intel_atomic_state(newstate->base.state);
>> +		to_intel_atomic_state(newstate->uapi.state);
>>  	const struct intel_crtc_state *oldstate =
>>  		intel_atomic_get_old_crtc_state(intel_state, intel_crtc);
>>  	const struct intel_pipe_wm *b = &oldstate->wm.ilk.optimal;
>> @@ -3203,7 +3201,7 @@ static int ilk_compute_intermediate_wm(struct intel_crtc_state *newstate)
>>  	 * and after the vblank.
>>  	 */
>>  	*a = newstate->wm.ilk.optimal;
>> -	if (!newstate->base.active || drm_atomic_crtc_needs_modeset(&newstate->base) ||
>> +	if (!newstate->hw.active || drm_atomic_crtc_needs_modeset(&newstate->uapi) ||
>>  	    intel_state->skip_intermediate_wm)
>>  		return 0;
>>  
>> @@ -3780,7 +3778,7 @@ bool intel_can_enable_sagv(struct intel_atomic_state *state)
>>  	crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
>>  	crtc_state = to_intel_crtc_state(crtc->base.state);
>>  
>> -	if (crtc->base.state->adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>> +	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
>>  		return false;
>>  
>>  	for_each_intel_plane_on_crtc(dev, crtc, plane) {
>> @@ -3830,7 +3828,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
>>  	if (INTEL_GEN(dev_priv) < 11)
>>  		return ddb_size - 4; /* 4 blocks for bypass path allocation */
>>  
>> -	adjusted_mode = &crtc_state->base.adjusted_mode;
>> +	adjusted_mode = &crtc_state->hw.adjusted_mode;
>>  	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
>>  
>>  	/*
>> @@ -3859,16 +3857,16 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>>  				   struct skl_ddb_entry *alloc, /* out */
>>  				   int *num_active /* out */)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
>> -	struct drm_crtc *for_crtc = crtc_state->base.crtc;
>> +	struct drm_crtc *for_crtc = crtc_state->uapi.crtc;
>>  	const struct intel_crtc *crtc;
>>  	u32 pipe_width = 0, total_width = 0, width_before_pipe = 0;
>>  	enum pipe for_pipe = to_intel_crtc(for_crtc)->pipe;
>>  	u16 ddb_size;
>>  	u32 i;
>>  
>> -	if (WARN_ON(!state) || !crtc_state->base.active) {
>> +	if (WARN_ON(!state) || !crtc_state->hw.active) {
>>  		alloc->start = 0;
>>  		alloc->end = 0;
>>  		*num_active = hweight8(dev_priv->active_pipes);
>> @@ -3907,11 +3905,11 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>>  	 */
>>  	for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
>>  		const struct drm_display_mode *adjusted_mode =
>> -			&crtc_state->base.adjusted_mode;
>> +			&crtc_state->hw.adjusted_mode;
>>  		enum pipe pipe = crtc->pipe;
>>  		int hdisplay, vdisplay;
>>  
>> -		if (!crtc_state->base.enable)
>> +		if (!crtc_state->hw.enable)
>>  			continue;
>>  
>>  		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
>> @@ -3942,7 +3940,7 @@ static unsigned int
>>  skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
>>  		      int num_active)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	int level, max_level = ilk_wm_max_level(dev_priv);
>>  	struct skl_wm_level wm = {};
>>  	int ret, min_ddb_alloc = 0;
>> @@ -4111,7 +4109,7 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
>>  {
>>  	uint_fixed_16_16_t pipe_downscale = u32_to_fixed16(1);
>>  
>> -	if (!crtc_state->base.enable)
>> +	if (!crtc_state->hw.enable)
>>  		return pipe_downscale;
>>  
>>  	if (crtc_state->pch_pfit.enabled) {
>> @@ -4143,7 +4141,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>  				  struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev);
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *drm_plane_state;
>>  	int crtc_clock, dotclk;
>> @@ -4151,10 +4149,10 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>  	uint_fixed_16_16_t pipe_downscale;
>>  	uint_fixed_16_16_t max_downscale = u32_to_fixed16(1);
>>  
>> -	if (!crtc_state->base.enable)
>> +	if (!crtc_state->hw.enable)
>>  		return 0;
>>  
>> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
>> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>>  		uint_fixed_16_16_t plane_downscale;
>>  		uint_fixed_16_16_t fp_9_div_8 = div_fixed16(9, 8);
>>  		int bpp;
>> @@ -4179,7 +4177,7 @@ int skl_check_pipe_max_pixel_rate(struct intel_crtc *intel_crtc,
>>  
>>  	pipe_downscale = mul_fixed16(pipe_downscale, max_downscale);
>>  
>> -	crtc_clock = crtc_state->base.adjusted_mode.crtc_clock;
>> +	crtc_clock = crtc_state->hw.adjusted_mode.crtc_clock;
>>  	dotclk = to_intel_atomic_state(state)->cdclk.logical.cdclk;
>>  
>>  	if (IS_GEMINILAKE(dev_priv) || INTEL_GEN(dev_priv) >= 10)
>> @@ -4246,7 +4244,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>>  				 u64 *plane_data_rate,
>>  				 u64 *uv_plane_data_rate)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *drm_plane_state;
>>  	u64 total_data_rate = 0;
>> @@ -4255,7 +4253,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>>  		return 0;
>>  
>>  	/* Calculate and cache data rate for each plane */
>> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
>> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>>  		const struct intel_plane_state *plane_state =
>>  			to_intel_plane_state(drm_plane_state);
>> @@ -4283,11 +4281,11 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>>  	const struct drm_plane_state *drm_plane_state;
>>  	u64 total_data_rate = 0;
>>  
>> -	if (WARN_ON(!crtc_state->base.state))
>> +	if (WARN_ON(!crtc_state->uapi.state))
>>  		return 0;
>>  
>>  	/* Calculate and cache data rate for each plane */
>> -	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->base) {
>> +	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state, &crtc_state->uapi) {
>>  		const struct intel_plane_state *plane_state =
>>  			to_intel_plane_state(drm_plane_state);
>>  		enum plane_id plane_id = to_intel_plane(plane)->id;
>> @@ -4329,8 +4327,8 @@ static int
>>  skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
>>  		      struct skl_ddb_allocation *ddb /* out */)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> -	struct drm_crtc *crtc = crtc_state->base.crtc;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>> +	struct drm_crtc *crtc = crtc_state->uapi.crtc;
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
>>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>>  	struct skl_ddb_entry *alloc = &crtc_state->wm.skl.ddb;
>> @@ -4352,7 +4350,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *crtc_state,
>>  	if (WARN_ON(!state))
>>  		return 0;
>>  
>> -	if (!crtc_state->base.active) {
>> +	if (!crtc_state->hw.active) {
>>  		alloc->start = alloc->end = 0;
>>  		return 0;
>>  	}
>> @@ -4594,7 +4592,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>>  	u32 crtc_htotal;
>>  	uint_fixed_16_16_t linetime_us;
>>  
>> -	if (!crtc_state->base.active)
>> +	if (!crtc_state->hw.active)
>>  		return u32_to_fixed16(0);
>>  
>>  	pixel_rate = crtc_state->pixel_rate;
>> @@ -4602,7 +4600,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>>  	if (WARN_ON(pixel_rate == 0))
>>  		return u32_to_fixed16(0);
>>  
>> -	crtc_htotal = crtc_state->base.adjusted_mode.crtc_htotal;
>> +	crtc_htotal = crtc_state->hw.adjusted_mode.crtc_htotal;
>>  	linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
>>  
>>  	return linetime_us;
>> @@ -4637,7 +4635,7 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
>>  		      u32 plane_pixel_rate, struct skl_wm_params *wp,
>>  		      int color_plane)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	u32 interm_pbpl;
>>  
>> @@ -4763,7 +4761,7 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>>  				 const struct skl_wm_level *result_prev,
>>  				 struct skl_wm_level *result /* out */)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	u32 latency = dev_priv->wm.skl_latency[level];
>>  	uint_fixed_16_16_t method1, method2;
>>  	uint_fixed_16_16_t selected_result;
>> @@ -4789,14 +4787,14 @@ static void skl_compute_plane_wm(const struct intel_crtc_state *crtc_state,
>>  	method1 = skl_wm_method1(dev_priv, wp->plane_pixel_rate,
>>  				 wp->cpp, latency, wp->dbuf_block_size);
>>  	method2 = skl_wm_method2(wp->plane_pixel_rate,
>> -				 crtc_state->base.adjusted_mode.crtc_htotal,
>> +				 crtc_state->hw.adjusted_mode.crtc_htotal,
>>  				 latency,
>>  				 wp->plane_blocks_per_line);
>>  
>>  	if (wp->y_tiled) {
>>  		selected_result = max_fixed16(method2, wp->y_tile_minimum);
>>  	} else {
>> -		if ((wp->cpp * crtc_state->base.adjusted_mode.crtc_htotal /
>> +		if ((wp->cpp * crtc_state->hw.adjusted_mode.crtc_htotal /
>>  		     wp->dbuf_block_size < 1) &&
>>  		     (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
>>  			selected_result = method2;
>> @@ -4887,7 +4885,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>>  		      const struct skl_wm_params *wm_params,
>>  		      struct skl_wm_level *levels)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	int level, max_level = ilk_wm_max_level(dev_priv);
>>  	struct skl_wm_level *result_prev = &levels[0];
>>  
>> @@ -4904,7 +4902,7 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
>>  static u32
>>  skl_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_atomic_state *state = crtc_state->base.state;
>> +	struct drm_atomic_state *state = crtc_state->uapi.state;
>>  	struct drm_i915_private *dev_priv = to_i915(state->dev);
>>  	uint_fixed_16_16_t linetime_us;
>>  	u32 linetime_wm;
>> @@ -4923,7 +4921,7 @@ static void skl_compute_transition_wm(const struct intel_crtc_state *crtc_state,
>>  				      const struct skl_wm_params *wp,
>>  				      struct skl_plane_wm *wm)
>>  {
>> -	struct drm_device *dev = crtc_state->base.crtc->dev;
>> +	struct drm_device *dev = crtc_state->uapi.crtc->dev;
>>  	const struct drm_i915_private *dev_priv = to_i915(dev);
>>  	u16 trans_min, trans_y_tile_min;
>>  	const u16 trans_amount = 10; /* This is configurable amount */
>> @@ -5083,7 +5081,7 @@ static int icl_build_plane_wm(struct intel_crtc_state *crtc_state,
>>  
>>  static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>  	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
>>  	struct drm_plane *plane;
>>  	const struct drm_plane_state *drm_plane_state;
>> @@ -5096,7 +5094,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
>>  	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
>>  
>>  	drm_atomic_crtc_state_for_each_plane_state(plane, drm_plane_state,
>> -						   &crtc_state->base) {
>> +						   &crtc_state->uapi) {
>>  		const struct intel_plane_state *plane_state =
>>  			to_intel_plane_state(drm_plane_state);
>>  
>> @@ -5275,8 +5273,8 @@ static int
>>  skl_ddb_add_affected_planes(const struct intel_crtc_state *old_crtc_state,
>>  			    struct intel_crtc_state *new_crtc_state)
>>  {
>> -	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->base.state);
>> -	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
>> +	struct intel_atomic_state *state = to_intel_atomic_state(new_crtc_state->uapi.state);
>> +	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	struct intel_plane *plane;
>>  
>> @@ -5576,7 +5574,7 @@ static int skl_wm_add_affected_planes(struct intel_atomic_state *state,
>>  		 * power well the hardware state will go out of sync
>>  		 * with the software state.
>>  		 */
>> -		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->base) &&
>> +		if (!drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi) &&
>>  		    skl_plane_wm_equals(dev_priv,
>>  					&old_crtc_state->wm.skl.optimal.planes[plane_id],
>>  					&new_crtc_state->wm.skl.optimal.planes[plane_id]))
>> @@ -5643,7 +5641,7 @@ skl_compute_wm(struct intel_atomic_state *state)
>>  static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
>>  				      struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>>  	struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
>>  	enum pipe pipe = crtc->pipe;
>> @@ -5657,7 +5655,7 @@ static void skl_atomic_update_crtc_wm(struct intel_atomic_state *state,
>>  static void skl_initial_wm(struct intel_atomic_state *state,
>>  			   struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  	struct drm_device *dev = intel_crtc->base.dev;
>>  	struct drm_i915_private *dev_priv = to_i915(dev);
>>  	struct skl_ddb_values *results = &state->wm_results;
>> @@ -5667,7 +5665,7 @@ static void skl_initial_wm(struct intel_atomic_state *state,
>>  
>>  	mutex_lock(&dev_priv->wm.wm_mutex);
>>  
>> -	if (crtc_state->base.active_changed)
>> +	if (crtc_state->uapi.active_changed)
>>  		skl_atomic_update_crtc_wm(state, crtc_state);
>>  
>>  	mutex_unlock(&dev_priv->wm.wm_mutex);
>> @@ -5726,8 +5724,8 @@ static void ilk_program_watermarks(struct drm_i915_private *dev_priv)
>>  static void ilk_initial_watermarks(struct intel_atomic_state *state,
>>  				   struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	mutex_lock(&dev_priv->wm.wm_mutex);
>>  	crtc->wm.active.ilk = crtc_state->wm.ilk.intermediate;
>> @@ -5738,8 +5736,8 @@ static void ilk_initial_watermarks(struct intel_atomic_state *state,
>>  static void ilk_optimize_watermarks(struct intel_atomic_state *state,
>>  				    struct intel_crtc_state *crtc_state)
>>  {
>> -	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
>> +	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>  
>>  	if (!crtc_state->wm.need_postvbl_update)
>>  		return;
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-24 23:41   ` Matt Roper
@ 2019-09-25  9:29     ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25  9:29 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 25-09-2019 om 01:41 schreef Matt Roper:
> On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
>> Now that we separated everything into uapi and hw, it's
>> time to make the split definitive. Remove the union and
>> make a copy of the hw state on modeset and fastset.
>>
>> Color blobs are copied in crtc atomic_check(), right
>> before color management is checked.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
>>  drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
>>  drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
>>  .../drm/i915/display/intel_display_types.h    |  8 ++--
>>  4 files changed, 85 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index f4440ede95c5..fb550d3cea7f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  
>>  	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>>  
>> +	/* copy color blobs */
>> +	if (crtc_state->hw.degamma_lut)
>> +		drm_property_blob_get(crtc_state->hw.degamma_lut);
>> +	if (crtc_state->hw.ctm)
>> +		drm_property_blob_get(crtc_state->hw.ctm);
>> +	if (crtc_state->hw.gamma_lut)
>> +		drm_property_blob_get(crtc_state->hw.gamma_lut);
>> +
>>  	crtc_state->update_pipe = false;
>>  	crtc_state->disable_lp_wm = false;
>>  	crtc_state->disable_cxsr = false;
>> @@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  	return &crtc_state->uapi;
>>  }
>>  
>> +static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
>> +{
>> +	drm_property_blob_put(crtc_state->hw.degamma_lut);
>> +	drm_property_blob_put(crtc_state->hw.gamma_lut);
>> +	drm_property_blob_put(crtc_state->hw.ctm);
>> +}
>> +
>> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	intel_crtc_put_color_blobs(crtc_state);
>> +}
>> +
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
>> +{
>> +	intel_crtc_put_color_blobs(crtc_state);
>> +
>> +	if (crtc_state->uapi.degamma_lut)
>> +		crtc_state->hw.degamma_lut =
>> +			drm_property_blob_get(crtc_state->uapi.degamma_lut);
>> +	else
>> +		crtc_state->hw.degamma_lut = NULL;
>> +
>> +	if (crtc_state->uapi.gamma_lut)
>> +		crtc_state->hw.gamma_lut =
>> +			drm_property_blob_get(crtc_state->uapi.gamma_lut);
>> +	else
>> +		crtc_state->hw.gamma_lut = NULL;
>> +
>> +	if (crtc_state->uapi.ctm)
>> +		crtc_state->hw.ctm =
>> +			drm_property_blob_get(crtc_state->uapi.ctm);
>> +	else
>> +		crtc_state->hw.ctm = NULL;
>> +}
>> +
>>  /**
>>   * intel_crtc_destroy_state - destroy crtc state
>>   * @crtc: drm crtc
>> @@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
>>  
>>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>> +	intel_crtc_free_hw_state(crtc_state);
>>  	kfree(crtc_state);
>>  }
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
>> index 58065d3161a3..42be91e0772a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
>> @@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
>>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  			       struct drm_crtc_state *state);
>> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
>>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index 32bbb5bf48f3..e40485a1e503 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
>>  	DRM_FORMAT_MOD_INVALID
>>  };
>>  
>> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
>>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
>>  				struct intel_crtc_state *pipe_config);
>>  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
>> @@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>>  	crtc->enabled = false;
>>  	crtc->state->connector_mask = 0;
>>  	crtc->state->encoder_mask = 0;
>> +	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
>>  
> Do we actually have any valid uapi state to copy at this point?  I
> thought intel_crtc_disable_noatomic was only called during initial
> hardware readout (which only updates hw state and then does a hw->uapi
> copy at the end)?
>
>
>>  	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
>>  		encoder->base.crtc = NULL;
>> @@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  
>>  	if (mode_changed || crtc_state->updatenoughe_pipe ||
>>  	    crtc_state->uapi.color_mgmt_changed) {
>> +		/* Copy color blobs to hw state */
>> +		intel_crtc_copy_color_blobs(crtc_state);
> The copy only matters if crtc_state->uapi.color_mgmt_changed, right?  I
> guess it doesn't really matter if we call this more often than we need
> to since we're not actually copying the blobs themselves, just
> dropping/taking extra references.

Yes, exactly. :)

intel_color_commit is only called when color_mgmt_changed is set, so that's sufficient.

>
>> +
>>  		ret = intel_color_check(crtc_state);
>>  		if (ret)
>>  			return ret;
>> @@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>>  	return ret;
>>  }
>>  
>> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	crtc_state->hw.enable = crtc_state->uapi.enable;
>> +	crtc_state->hw.active = crtc_state->uapi.active;
>> +	crtc_state->hw.mode = crtc_state->uapi.mode;
>> +	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
>> +}
>> +
>> +static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	crtc_state->uapi.enable = crtc_state->hw.enable;
>> +	crtc_state->uapi.active = crtc_state->hw.active;
>> +	crtc_state->uapi.mode = crtc_state->hw.mode;
>> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>> +}
>> +
>>  static int
>>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  {
>> @@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  	 * fixed, so that the crtc_state can be safely duplicated. For now,
>>  	 * only fields that are know to not cause problems are preserved. */
>>  
>> +	saved_state->uapi = crtc_state->uapi;
>>  	saved_state->scaler_state = crtc_state->scaler_state;
>>  	saved_state->shared_dpll = crtc_state->shared_dpll;
>>  	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
>> @@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>>  		saved_state->wm = crtc_state->wm;
>>  
>> -	/* Keep base drm_crtc_state intact, only clear our extended struct */
>> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
>> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
>> -	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
>> -	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
>> +	intel_crtc_free_hw_state(crtc_state);
>> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>> +	copy_uapi_to_hw_state(crtc_state);
>>  
>>  	kfree(saved_state);
>>  	return 0;
>> @@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
>>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>>  
>> +	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
>> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>> +
>>  	return 0;
>>  }
>>  
>> @@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  
>>  	state = old_crtc_state->uapi.state;
>>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>> +	intel_crtc_free_hw_state(old_crtc_state);
>> +
>>  	pipe_config = old_crtc_state;
>>  	memset(pipe_config, 0, sizeof(*pipe_config));
>>  	pipe_config->uapi.crtc = &crtc->base;
>> @@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
>>  
>>  		if (!new_crtc_state->uapi.enable) {
>>  			any_ms = true;
>> +			clear_intel_crtc_state(new_crtc_state);
> Why do we need this call?  uapi is preserved during this call (and then
> re-copied to hw), so it doesn't seem like this has any effect on the
> uapi/hw split we're dealing with in this patch?

We want to clear crtc_state->hw, it can be replaced with a intel_crtc_free_hw_state() + memset on crtc_state->hw.

I wanted to clear the entire state, so when dumping crtc_state you don't see any old state.

Although we're missing error checking here, so that needs fixing.


>
>>  			continue;
>>  		}
>>  
>> @@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			to_intel_crtc_state(crtc->base.state);
>>  
>>  		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>> +		intel_crtc_free_hw_state(crtc_state);
>>  		memset(crtc_state, 0, sizeof(*crtc_state));
>>  		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>>  
>> @@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
>>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>>  						    crtc_state);
>> +			crtc_state->hw.mode = crtc->base.mode;
>>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>>  
>>  			/*
>> @@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  
>>  		intel_bw_crtc_update(bw_state, crtc_state);
>>  
>> +		copy_hw_to_uapi_state(crtc_state);
>>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>>  	}
>>  }
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 2c3567081e16..e81b785cc8f2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -749,7 +749,6 @@ enum intel_output_format {
>>  };
>>  
>>  struct intel_crtc_state {
>> -	union {
>>  	/*
>>  	 * uapi (drm) state. This is the software state shown to userspace.
>>  	 * In particular, the following members are used for bookkeeping:
>> @@ -772,8 +771,11 @@ struct intel_crtc_state {
>>  	 *
>>  	 * During initial hw readout, they need to be copied to uapi.
>>  	 */
>> -	struct drm_crtc_state hw;
>> -	};
>> +	struct {
>> +		bool active, enable;
>> +		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
>> +		struct drm_display_mode mode, adjusted_mode;
>> +	} hw;
>>  
>>  	/**
>>  	 * quirks - bitfield with hw state readout quirks
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+
  2019-09-25  4:55   ` Matt Roper
@ 2019-09-25 12:45     ` Maarten Lankhorst
  2019-09-25 13:02     ` Ville Syrjälä
  1 sibling, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25 12:45 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 25-09-2019 om 06:55 schreef Matt Roper:
> On Fri, Sep 20, 2019 at 01:42:21PM +0200, Maarten Lankhorst wrote:
>> We cannot switch between HQ and normal mode on GLK+, so only
>> add planes on platforms where it makes sense.
>>
>> We could probably restrict it even more to only add when scaler
>> users toggles between 1 and 2, but lets just leave it for now.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_atomic.c | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index 158594e64bb9..c50e0b218bd6 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -421,6 +421,11 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
>>  			 */
>>  			if (!plane) {
>>  				struct drm_plane_state *state;
>> +
>> +				/* No need to reprogram, we're not changing scaling mode */
>> +				if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
>> +					continue;
>> +
> We could probably just combine this into the existing !plane condition
> and enhance the comment above that to say "Note that GLK+ scalers don't
> have a HQ mode so this isn't necessary on those platforms."
>
> Either way,
>
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>

I changed the coment slightly, but we need the continue or we get a null pointer deref.

Thanks for review, pushed 6, 8, 9 and the first patch (although newer v5 version with Ville's R-B).

>
>>  				plane = drm_plane_from_index(&dev_priv->drm, i);
>>  				state = drm_atomic_get_plane_state(drm_state, plane);
>>  				if (IS_ERR(state)) {
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-20 11:42 ` [PATCH 05/23] drm/i915: Complete sw/hw split Maarten Lankhorst
  2019-09-24 23:41   ` Matt Roper
@ 2019-09-25 13:01   ` Ville Syrjälä
  2019-09-25 14:12     ` Maarten Lankhorst
  2019-09-25 14:18     ` Maarten Lankhorst
  1 sibling, 2 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-25 13:01 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
> Now that we separated everything into uapi and hw, it's
> time to make the split definitive. Remove the union and
> make a copy of the hw state on modeset and fastset.
> 
> Color blobs are copied in crtc atomic_check(), right
> before color management is checked.

Don't like. IMO there should be one and only one place where copy over
the uapi state into the hw state. Otherwise it's a mess because you
constantly have to remind yourself which bits of state already got
copied and which didn't.

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
>  drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
>  .../drm/i915/display/intel_display_types.h    |  8 ++--
>  4 files changed, 85 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index f4440ede95c5..fb550d3cea7f 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  
>  	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>  
> +	/* copy color blobs */
> +	if (crtc_state->hw.degamma_lut)
> +		drm_property_blob_get(crtc_state->hw.degamma_lut);
> +	if (crtc_state->hw.ctm)
> +		drm_property_blob_get(crtc_state->hw.ctm);
> +	if (crtc_state->hw.gamma_lut)
> +		drm_property_blob_get(crtc_state->hw.gamma_lut);
> +
>  	crtc_state->update_pipe = false;
>  	crtc_state->disable_lp_wm = false;
>  	crtc_state->disable_cxsr = false;
> @@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>  	return &crtc_state->uapi;
>  }
>  
> +static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
> +{
> +	drm_property_blob_put(crtc_state->hw.degamma_lut);
> +	drm_property_blob_put(crtc_state->hw.gamma_lut);
> +	drm_property_blob_put(crtc_state->hw.ctm);
> +}
> +
> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
> +{
> +	intel_crtc_put_color_blobs(crtc_state);
> +}
> +
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
> +{
> +	intel_crtc_put_color_blobs(crtc_state);
> +
> +	if (crtc_state->uapi.degamma_lut)
> +		crtc_state->hw.degamma_lut =
> +			drm_property_blob_get(crtc_state->uapi.degamma_lut);
> +	else
> +		crtc_state->hw.degamma_lut = NULL;
> +
> +	if (crtc_state->uapi.gamma_lut)
> +		crtc_state->hw.gamma_lut =
> +			drm_property_blob_get(crtc_state->uapi.gamma_lut);
> +	else
> +		crtc_state->hw.gamma_lut = NULL;
> +
> +	if (crtc_state->uapi.ctm)
> +		crtc_state->hw.ctm =
> +			drm_property_blob_get(crtc_state->uapi.ctm);
> +	else
> +		crtc_state->hw.ctm = NULL;
> +}
> +
>  /**
>   * intel_crtc_destroy_state - destroy crtc state
>   * @crtc: drm crtc
> @@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
>  	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
>  
>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> +	intel_crtc_free_hw_state(crtc_state);
>  	kfree(crtc_state);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> index 58065d3161a3..42be91e0772a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>  			       struct drm_crtc_state *state);
> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 32bbb5bf48f3..e40485a1e503 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
>  	DRM_FORMAT_MOD_INVALID
>  };
>  
> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
>  				struct intel_crtc_state *pipe_config);
>  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
> @@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>  	crtc->enabled = false;
>  	crtc->state->connector_mask = 0;
>  	crtc->state->encoder_mask = 0;
> +	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
>  
>  	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
>  		encoder->base.crtc = NULL;
> @@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  
>  	if (mode_changed || crtc_state->update_pipe ||
>  	    crtc_state->uapi.color_mgmt_changed) {
> +		/* Copy color blobs to hw state */
> +		intel_crtc_copy_color_blobs(crtc_state);
> +
>  		ret = intel_color_check(crtc_state);
>  		if (ret)
>  			return ret;
> @@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>  	return ret;
>  }
>  
> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> +{
> +	crtc_state->hw.enable = crtc_state->uapi.enable;
> +	crtc_state->hw.active = crtc_state->uapi.active;
> +	crtc_state->hw.mode = crtc_state->uapi.mode;
> +	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
> +}
> +
> +static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +{
> +	crtc_state->uapi.enable = crtc_state->hw.enable;
> +	crtc_state->uapi.active = crtc_state->hw.active;
> +	crtc_state->uapi.mode = crtc_state->hw.mode;
> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> +}
> +
>  static int
>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  {
> @@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  	 * fixed, so that the crtc_state can be safely duplicated. For now,
>  	 * only fields that are know to not cause problems are preserved. */
>  
> +	saved_state->uapi = crtc_state->uapi;
>  	saved_state->scaler_state = crtc_state->scaler_state;
>  	saved_state->shared_dpll = crtc_state->shared_dpll;
>  	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> @@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>  	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>  		saved_state->wm = crtc_state->wm;
>  
> -	/* Keep base drm_crtc_state intact, only clear our extended struct */
> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
> -	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
> -	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
> +	intel_crtc_free_hw_state(crtc_state);
> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> +	copy_uapi_to_hw_state(crtc_state);
>  
>  	kfree(saved_state);
>  	return 0;
> @@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>  
> +	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
> +
>  	return 0;
>  }
>  
> @@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
>  
>  	state = old_crtc_state->uapi.state;
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> +	intel_crtc_free_hw_state(old_crtc_state);
> +
>  	pipe_config = old_crtc_state;
>  	memset(pipe_config, 0, sizeof(*pipe_config));
>  	pipe_config->uapi.crtc = &crtc->base;
> @@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
>  
>  		if (!new_crtc_state->uapi.enable) {
>  			any_ms = true;
> +			clear_intel_crtc_state(new_crtc_state);
>  			continue;
>  		}
>  
> @@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			to_intel_crtc_state(crtc->base.state);
>  
>  		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> +		intel_crtc_free_hw_state(crtc_state);
>  		memset(crtc_state, 0, sizeof(*crtc_state));
>  		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>  
> @@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
> +			crtc_state->hw.mode = crtc->base.mode;
>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>  
>  			/*
> @@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  
>  		intel_bw_crtc_update(bw_state, crtc_state);
>  
> +		copy_hw_to_uapi_state(crtc_state);
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>  	}
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 2c3567081e16..e81b785cc8f2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -749,7 +749,6 @@ enum intel_output_format {
>  };
>  
>  struct intel_crtc_state {
> -	union {
>  	/*
>  	 * uapi (drm) state. This is the software state shown to userspace.
>  	 * In particular, the following members are used for bookkeeping:
> @@ -772,8 +771,11 @@ struct intel_crtc_state {
>  	 *
>  	 * During initial hw readout, they need to be copied to uapi.
>  	 */
> -	struct drm_crtc_state hw;
> -	};
> +	struct {
> +		bool active, enable;
> +		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
> +		struct drm_display_mode mode, adjusted_mode;
> +	} hw;
>  
>  	/**
>  	 * quirks - bitfield with hw state readout quirks
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+
  2019-09-25  4:55   ` Matt Roper
  2019-09-25 12:45     ` Maarten Lankhorst
@ 2019-09-25 13:02     ` Ville Syrjälä
  1 sibling, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-25 13:02 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Sep 24, 2019 at 09:55:31PM -0700, Matt Roper wrote:
> On Fri, Sep 20, 2019 at 01:42:21PM +0200, Maarten Lankhorst wrote:
> > We cannot switch between HQ and normal mode on GLK+, so only
> > add planes on platforms where it makes sense.
> > 
> > We could probably restrict it even more to only add when scaler
> > users toggles between 1 and 2, but lets just leave it for now.
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_atomic.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> > index 158594e64bb9..c50e0b218bd6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> > @@ -421,6 +421,11 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
> >  			 */
> >  			if (!plane) {
> >  				struct drm_plane_state *state;
> > +
> > +				/* No need to reprogram, we're not changing scaling mode */
> > +				if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > +					continue;
> > +
> 
> We could probably just combine this into the existing !plane condition
> and enhance the comment above that to say "Note that GLK+ scalers don't
> have a HQ mode so this isn't necessary on those platforms."

I'm rewriting this whole scaler mess.

> 
> Either way,
> 
> Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
> 
> 
> >  				plane = drm_plane_from_index(&dev_priv->drm, i);
> >  				state = drm_atomic_get_plane_state(drm_state, plane);
> >  				if (IS_ERR(state)) {
> > -- 
> > 2.20.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-25 13:01   ` Ville Syrjälä
@ 2019-09-25 14:12     ` Maarten Lankhorst
  2019-09-25 14:18     ` Maarten Lankhorst
  1 sibling, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25 14:12 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 25-09-2019 om 15:01 schreef Ville Syrjälä:
> On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
>> Now that we separated everything into uapi and hw, it's
>> time to make the split definitive. Remove the union and
>> make a copy of the hw state on modeset and fastset.
>>
>> Color blobs are copied in crtc atomic_check(), right
>> before color management is checked.
> Don't like. IMO there should be one and only one place where copy over
> the uapi state into the hw state. Otherwise it's a mess because you
> constantly have to remind yourself which bits of state already got
> copied and which didn't.

Yeah it's a tad annoying, can always just do it in this loop. We either copy full state on modeset or just the blobs..

Will send a new version.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit.
  2019-09-25  4:17   ` Matt Roper
@ 2019-09-25 14:14     ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25 14:14 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 25-09-2019 om 06:17 schreef Matt Roper:
> On Fri, Sep 20, 2019 at 01:42:19PM +0200, Maarten Lankhorst wrote:
>> This can all be done from the intel_update_crtc function. Split out the
>> pipe update into a separate function, just like is done for the planes.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> The code here all looks logically correct, but I think our various
> pipe functions are still somewhat confusing.  E.g.,
> intel_update_pipe_config() and commit_pipe_config() have names that
> make it sound like they're doing the same thing.  At the moment
> intel_update_pipe_config() is basically the fastset-specific stuff, but
> is there any reason most of those operations can't just be done on all
> commits?  Re-writing the pfit/scaler registers or pipe chicken seems
> like a pretty small number of registers to try to avoid.
>
> If we want to keep them separate, I'd suggest renaming
> intel_update_pipe_config() (and probably the 'update_pipe' flag too) to
> make it more clear that it's meant for the fastset special case.
>

I'm sending a new version with intel_update_pipe_config inlined.

It makes sense to avoid, especially the chicken bits because that function performs a read as well.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-25 13:01   ` Ville Syrjälä
  2019-09-25 14:12     ` Maarten Lankhorst
@ 2019-09-25 14:18     ` Maarten Lankhorst
  2019-09-25 14:54       ` Ville Syrjälä
  1 sibling, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-25 14:18 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 25-09-2019 om 15:01 schreef Ville Syrjälä:
> On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
>> Now that we separated everything into uapi and hw, it's
>> time to make the split definitive. Remove the union and
>> make a copy of the hw state on modeset and fastset.
>>
>> Color blobs are copied in crtc atomic_check(), right
>> before color management is checked.
> Don't like. IMO there should be one and only one place where copy over
> the uapi state into the hw state. Otherwise it's a mess because you
> constantly have to remind yourself which bits of state already got
> copied and which didn't.

Oh now I remember, because bigjoiner is assigned later on we can't copy blobs yet

and bigjoiner was the whole reaon we wanted separate blobs so it didn't have to look at the other crtc_state..

Would it help if I copy the blobs in intel_color_check() instead?

>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
>>  drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
>>  drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
>>  .../drm/i915/display/intel_display_types.h    |  8 ++--
>>  4 files changed, 85 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index f4440ede95c5..fb550d3cea7f 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  
>>  	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
>>  
>> +	/* copy color blobs */
>> +	if (crtc_state->hw.degamma_lut)
>> +		drm_property_blob_get(crtc_state->hw.degamma_lut);
>> +	if (crtc_state->hw.ctm)
>> +		drm_property_blob_get(crtc_state->hw.ctm);
>> +	if (crtc_state->hw.gamma_lut)
>> +		drm_property_blob_get(crtc_state->hw.gamma_lut);
>> +
>>  	crtc_state->update_pipe = false;
>>  	crtc_state->disable_lp_wm = false;
>>  	crtc_state->disable_cxsr = false;
>> @@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
>>  	return &crtc_state->uapi;
>>  }
>>  
>> +static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
>> +{
>> +	drm_property_blob_put(crtc_state->hw.degamma_lut);
>> +	drm_property_blob_put(crtc_state->hw.gamma_lut);
>> +	drm_property_blob_put(crtc_state->hw.ctm);
>> +}
>> +
>> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	intel_crtc_put_color_blobs(crtc_state);
>> +}
>> +
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
>> +{
>> +	intel_crtc_put_color_blobs(crtc_state);
>> +
>> +	if (crtc_state->uapi.degamma_lut)
>> +		crtc_state->hw.degamma_lut =
>> +			drm_property_blob_get(crtc_state->uapi.degamma_lut);
>> +	else
>> +		crtc_state->hw.degamma_lut = NULL;
>> +
>> +	if (crtc_state->uapi.gamma_lut)
>> +		crtc_state->hw.gamma_lut =
>> +			drm_property_blob_get(crtc_state->uapi.gamma_lut);
>> +	else
>> +		crtc_state->hw.gamma_lut = NULL;
>> +
>> +	if (crtc_state->uapi.ctm)
>> +		crtc_state->hw.ctm =
>> +			drm_property_blob_get(crtc_state->uapi.ctm);
>> +	else
>> +		crtc_state->hw.ctm = NULL;
>> +}
>> +
>>  /**
>>   * intel_crtc_destroy_state - destroy crtc state
>>   * @crtc: drm crtc
>> @@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
>>  
>>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>> +	intel_crtc_free_hw_state(crtc_state);
>>  	kfree(crtc_state);
>>  }
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
>> index 58065d3161a3..42be91e0772a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
>> @@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
>>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  			       struct drm_crtc_state *state);
>> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
>>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index 32bbb5bf48f3..e40485a1e503 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
>>  	DRM_FORMAT_MOD_INVALID
>>  };
>>  
>> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
>>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
>>  				struct intel_crtc_state *pipe_config);
>>  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
>> @@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
>>  	crtc->enabled = false;
>>  	crtc->state->connector_mask = 0;
>>  	crtc->state->encoder_mask = 0;
>> +	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
>>  
>>  	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
>>  		encoder->base.crtc = NULL;
>> @@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  
>>  	if (mode_changed || crtc_state->update_pipe ||
>>  	    crtc_state->uapi.color_mgmt_changed) {
>> +		/* Copy color blobs to hw state */
>> +		intel_crtc_copy_color_blobs(crtc_state);
>> +
>>  		ret = intel_color_check(crtc_state);
>>  		if (ret)
>>  			return ret;
>> @@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>>  	return ret;
>>  }
>>  
>> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	crtc_state->hw.enable = crtc_state->uapi.enable;
>> +	crtc_state->hw.active = crtc_state->uapi.active;
>> +	crtc_state->hw.mode = crtc_state->uapi.mode;
>> +	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
>> +}
>> +
>> +static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>> +{
>> +	crtc_state->uapi.enable = crtc_state->hw.enable;
>> +	crtc_state->uapi.active = crtc_state->hw.active;
>> +	crtc_state->uapi.mode = crtc_state->hw.mode;
>> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>> +}
>> +
>>  static int
>>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  {
>> @@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  	 * fixed, so that the crtc_state can be safely duplicated. For now,
>>  	 * only fields that are know to not cause problems are preserved. */
>>  
>> +	saved_state->uapi = crtc_state->uapi;
>>  	saved_state->scaler_state = crtc_state->scaler_state;
>>  	saved_state->shared_dpll = crtc_state->shared_dpll;
>>  	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
>> @@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
>>  	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
>>  		saved_state->wm = crtc_state->wm;
>>  
>> -	/* Keep base drm_crtc_state intact, only clear our extended struct */
>> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
>> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
>> -	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
>> -	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
>> +	intel_crtc_free_hw_state(crtc_state);
>> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>> +	copy_uapi_to_hw_state(crtc_state);
>>  
>>  	kfree(saved_state);
>>  	return 0;
>> @@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
>>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>>  
>> +	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
>> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>> +
>>  	return 0;
>>  }
>>  
>> @@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  
>>  	state = old_crtc_state->uapi.state;
>>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>> +	intel_crtc_free_hw_state(old_crtc_state);
>> +
>>  	pipe_config = old_crtc_state;
>>  	memset(pipe_config, 0, sizeof(*pipe_config));
>>  	pipe_config->uapi.crtc = &crtc->base;
>> @@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
>>  
>>  		if (!new_crtc_state->uapi.enable) {
>>  			any_ms = true;
>> +			clear_intel_crtc_state(new_crtc_state);
>>  			continue;
>>  		}
>>  
>> @@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			to_intel_crtc_state(crtc->base.state);
>>  
>>  		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
>> +		intel_crtc_free_hw_state(crtc_state);
>>  		memset(crtc_state, 0, sizeof(*crtc_state));
>>  		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
>>  
>> @@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
>>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>>  						    crtc_state);
>> +			crtc_state->hw.mode = crtc->base.mode;
>>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>>  
>>  			/*
>> @@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  
>>  		intel_bw_crtc_update(bw_state, crtc_state);
>>  
>> +		copy_hw_to_uapi_state(crtc_state);
>>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>>  	}
>>  }
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 2c3567081e16..e81b785cc8f2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -749,7 +749,6 @@ enum intel_output_format {
>>  };
>>  
>>  struct intel_crtc_state {
>> -	union {
>>  	/*
>>  	 * uapi (drm) state. This is the software state shown to userspace.
>>  	 * In particular, the following members are used for bookkeeping:
>> @@ -772,8 +771,11 @@ struct intel_crtc_state {
>>  	 *
>>  	 * During initial hw readout, they need to be copied to uapi.
>>  	 */
>> -	struct drm_crtc_state hw;
>> -	};
>> +	struct {
>> +		bool active, enable;
>> +		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
>> +		struct drm_display_mode mode, adjusted_mode;
>> +	} hw;
>>  
>>  	/**
>>  	 * quirks - bitfield with hw state readout quirks
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 05/23] drm/i915: Complete sw/hw split
  2019-09-25 14:18     ` Maarten Lankhorst
@ 2019-09-25 14:54       ` Ville Syrjälä
  0 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-25 14:54 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Wed, Sep 25, 2019 at 04:18:09PM +0200, Maarten Lankhorst wrote:
> Op 25-09-2019 om 15:01 schreef Ville Syrjälä:
> > On Fri, Sep 20, 2019 at 01:42:17PM +0200, Maarten Lankhorst wrote:
> >> Now that we separated everything into uapi and hw, it's
> >> time to make the split definitive. Remove the union and
> >> make a copy of the hw state on modeset and fastset.
> >>
> >> Color blobs are copied in crtc atomic_check(), right
> >> before color management is checked.
> > Don't like. IMO there should be one and only one place where copy over
> > the uapi state into the hw state. Otherwise it's a mess because you
> > constantly have to remind yourself which bits of state already got
> > copied and which didn't.
> 
> Oh now I remember, because bigjoiner is assigned later on we can't copy blobs yet
> 
> and bigjoiner was the whole reaon we wanted separate blobs so it didn't have to look at the other crtc_state..
> 
> Would it help if I copy the blobs in intel_color_check() instead?

Can't we just do something like:

drm_atomic_helper_check_modeset();
for_each_crtc_in_state() {
	if (crtc_state->enable)
		copy_uapi_to_hw();
}

compute_config() {
	if (need_bigjoiner) {
		get_other_crtc_state();
		if (other_crtc_state->uapi.enable)
			fail;
		other_hw = current_hw;
		adjust_hw_state_for_bigjoiner(other_hw);
	}
}

?

> 
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/display/intel_atomic.c   | 44 +++++++++++++++++++
> >>  drivers/gpu/drm/i915/display/intel_atomic.h   |  2 +
> >>  drivers/gpu/drm/i915/display/intel_display.c  | 39 +++++++++++++---
> >>  .../drm/i915/display/intel_display_types.h    |  8 ++--
> >>  4 files changed, 85 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> >> index f4440ede95c5..fb550d3cea7f 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> >> @@ -195,6 +195,14 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
> >>  
> >>  	__drm_atomic_helper_crtc_duplicate_state(crtc, &crtc_state->uapi);
> >>  
> >> +	/* copy color blobs */
> >> +	if (crtc_state->hw.degamma_lut)
> >> +		drm_property_blob_get(crtc_state->hw.degamma_lut);
> >> +	if (crtc_state->hw.ctm)
> >> +		drm_property_blob_get(crtc_state->hw.ctm);
> >> +	if (crtc_state->hw.gamma_lut)
> >> +		drm_property_blob_get(crtc_state->hw.gamma_lut);
> >> +
> >>  	crtc_state->update_pipe = false;
> >>  	crtc_state->disable_lp_wm = false;
> >>  	crtc_state->disable_cxsr = false;
> >> @@ -209,6 +217,41 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
> >>  	return &crtc_state->uapi;
> >>  }
> >>  
> >> +static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state)
> >> +{
> >> +	drm_property_blob_put(crtc_state->hw.degamma_lut);
> >> +	drm_property_blob_put(crtc_state->hw.gamma_lut);
> >> +	drm_property_blob_put(crtc_state->hw.ctm);
> >> +}
> >> +
> >> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
> >> +{
> >> +	intel_crtc_put_color_blobs(crtc_state);
> >> +}
> >> +
> >> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
> >> +{
> >> +	intel_crtc_put_color_blobs(crtc_state);
> >> +
> >> +	if (crtc_state->uapi.degamma_lut)
> >> +		crtc_state->hw.degamma_lut =
> >> +			drm_property_blob_get(crtc_state->uapi.degamma_lut);
> >> +	else
> >> +		crtc_state->hw.degamma_lut = NULL;
> >> +
> >> +	if (crtc_state->uapi.gamma_lut)
> >> +		crtc_state->hw.gamma_lut =
> >> +			drm_property_blob_get(crtc_state->uapi.gamma_lut);
> >> +	else
> >> +		crtc_state->hw.gamma_lut = NULL;
> >> +
> >> +	if (crtc_state->uapi.ctm)
> >> +		crtc_state->hw.ctm =
> >> +			drm_property_blob_get(crtc_state->uapi.ctm);
> >> +	else
> >> +		crtc_state->hw.ctm = NULL;
> >> +}
> >> +
> >>  /**
> >>   * intel_crtc_destroy_state - destroy crtc state
> >>   * @crtc: drm crtc
> >> @@ -224,6 +267,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc,
> >>  	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
> >>  
> >>  	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> >> +	intel_crtc_free_hw_state(crtc_state);
> >>  	kfree(crtc_state);
> >>  }
> >>  
> >> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> >> index 58065d3161a3..42be91e0772a 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> >> @@ -35,6 +35,8 @@ intel_digital_connector_duplicate_state(struct drm_connector *connector);
> >>  struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
> >>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
> >>  			       struct drm_crtc_state *state);
> >> +void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
> >> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
> >>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
> >>  void intel_atomic_state_clear(struct drm_atomic_state *state);
> >>  
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> >> index 32bbb5bf48f3..e40485a1e503 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> >> @@ -114,6 +114,7 @@ static const u64 cursor_format_modifiers[] = {
> >>  	DRM_FORMAT_MOD_INVALID
> >>  };
> >>  
> >> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state);
> >>  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
> >>  				struct intel_crtc_state *pipe_config);
> >>  static void ironlake_pch_clock_get(struct intel_crtc *crtc,
> >> @@ -7097,6 +7098,7 @@ static void intel_crtc_disable_noatomic(struct drm_crtc *crtc,
> >>  	crtc->enabled = false;
> >>  	crtc->state->connector_mask = 0;
> >>  	crtc->state->encoder_mask = 0;
> >> +	copy_uapi_to_hw_state(to_intel_crtc_state(crtc->state));
> >>  
> >>  	for_each_encoder_on_crtc(crtc->dev, crtc, encoder)
> >>  		encoder->base.crtc = NULL;
> >> @@ -11804,6 +11806,9 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
> >>  
> >>  	if (mode_changed || crtc_state->update_pipe ||
> >>  	    crtc_state->uapi.color_mgmt_changed) {
> >> +		/* Copy color blobs to hw state */
> >> +		intel_crtc_copy_color_blobs(crtc_state);
> >> +
> >>  		ret = intel_color_check(crtc_state);
> >>  		if (ret)
> >>  			return ret;
> >> @@ -12251,6 +12256,22 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
> >>  	return ret;
> >>  }
> >>  
> >> +static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> >> +{
> >> +	crtc_state->hw.enable = crtc_state->uapi.enable;
> >> +	crtc_state->hw.active = crtc_state->uapi.active;
> >> +	crtc_state->hw.mode = crtc_state->uapi.mode;
> >> +	crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
> >> +}
> >> +
> >> +static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> >> +{
> >> +	crtc_state->uapi.enable = crtc_state->hw.enable;
> >> +	crtc_state->uapi.active = crtc_state->hw.active;
> >> +	crtc_state->uapi.mode = crtc_state->hw.mode;
> >> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> >> +}
> >> +
> >>  static int
> >>  clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
> >>  {
> >> @@ -12267,6 +12288,7 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
> >>  	 * fixed, so that the crtc_state can be safely duplicated. For now,
> >>  	 * only fields that are know to not cause problems are preserved. */
> >>  
> >> +	saved_state->uapi = crtc_state->uapi;
> >>  	saved_state->scaler_state = crtc_state->scaler_state;
> >>  	saved_state->shared_dpll = crtc_state->shared_dpll;
> >>  	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> >> @@ -12277,11 +12299,9 @@ clear_intel_crtc_state(struct intel_crtc_state *crtc_state)
> >>  	    IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> >>  		saved_state->wm = crtc_state->wm;
> >>  
> >> -	/* Keep base drm_crtc_state intact, only clear our extended struct */
> >> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, uapi));
> >> -	BUILD_BUG_ON(offsetof(struct intel_crtc_state, hw));
> >> -	memcpy(&crtc_state->uapi + 1, &saved_state->uapi + 1,
> >> -	       sizeof(*crtc_state) - sizeof(crtc_state->uapi));
> >> +	intel_crtc_free_hw_state(crtc_state);
> >> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> >> +	copy_uapi_to_hw_state(crtc_state);
> >>  
> >>  	kfree(saved_state);
> >>  	return 0;
> >> @@ -12421,6 +12441,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> >>  	DRM_DEBUG_KMS("hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
> >>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> >>  
> >> +	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
> >> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
> >> +
> >>  	return 0;
> >>  }
> >>  
> >> @@ -13142,6 +13165,8 @@ verify_crtc_state(struct intel_crtc *crtc,
> >>  
> >>  	state = old_crtc_state->uapi.state;
> >>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> >> +	intel_crtc_free_hw_state(old_crtc_state);
> >> +
> >>  	pipe_config = old_crtc_state;
> >>  	memset(pipe_config, 0, sizeof(*pipe_config));
> >>  	pipe_config->uapi.crtc = &crtc->base;
> >> @@ -13568,6 +13593,7 @@ static int intel_atomic_check(struct drm_device *dev,
> >>  
> >>  		if (!new_crtc_state->uapi.enable) {
> >>  			any_ms = true;
> >> +			clear_intel_crtc_state(new_crtc_state);
> >>  			continue;
> >>  		}
> >>  
> >> @@ -16686,6 +16712,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >>  			to_intel_crtc_state(crtc->base.state);
> >>  
> >>  		__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
> >> +		intel_crtc_free_hw_state(crtc_state);
> >>  		memset(crtc_state, 0, sizeof(*crtc_state));
> >>  		__drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->uapi);
> >>  
> >> @@ -16802,6 +16829,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >>  			crtc->base.mode.vdisplay = crtc_state->pipe_src_h;
> >>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
> >>  						    crtc_state);
> >> +			crtc_state->hw.mode = crtc->base.mode;
> >>  			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
> >>  
> >>  			/*
> >> @@ -16847,6 +16875,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >>  
> >>  		intel_bw_crtc_update(bw_state, crtc_state);
> >>  
> >> +		copy_hw_to_uapi_state(crtc_state);
> >>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
> >>  	}
> >>  }
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> >> index 2c3567081e16..e81b785cc8f2 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> >> @@ -749,7 +749,6 @@ enum intel_output_format {
> >>  };
> >>  
> >>  struct intel_crtc_state {
> >> -	union {
> >>  	/*
> >>  	 * uapi (drm) state. This is the software state shown to userspace.
> >>  	 * In particular, the following members are used for bookkeeping:
> >> @@ -772,8 +771,11 @@ struct intel_crtc_state {
> >>  	 *
> >>  	 * During initial hw readout, they need to be copied to uapi.
> >>  	 */
> >> -	struct drm_crtc_state hw;
> >> -	};
> >> +	struct {
> >> +		bool active, enable;
> >> +		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
> >> +		struct drm_display_mode mode, adjusted_mode;
> >> +	} hw;
> >>  
> >>  	/**
> >>  	 * quirks - bitfield with hw state readout quirks
> >> -- 
> >> 2.20.1
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
  2019-09-25  5:30   ` Matt Roper
  2019-09-25  5:56     ` Matt Roper
@ 2019-09-25 22:09     ` Manasi Navare
  2019-09-26 16:00       ` Maarten Lankhorst
  1 sibling, 1 reply; 82+ messages in thread
From: Manasi Navare @ 2019-09-25 22:09 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Sep 24, 2019 at 10:30:39PM -0700, Matt Roper wrote:
> On Fri, Sep 20, 2019 at 01:42:22PM +0200, Maarten Lankhorst wrote:
> > Small changes to intel_dp_mode_valid(), allow listing modes that
> > can only be supported in the bigjoiner configuration, which is
> > not supported yet.
> > 
> > Also unexport a few functions only used internally in intel_dp.c
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp.c | 98 +++++++++++++++++++------
> >  1 file changed, 75 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 2fceb71f7f70..046e1662d1e3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -247,7 +247,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> >  }
> >  
> >  static int
> > -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> > +intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> >  {
> >  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> >  	struct intel_encoder *encoder = &intel_dig_port->base;
> > @@ -257,6 +257,9 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> >  
> >  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
> >  
> > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11)
> > +		max_dotclk *= 2;
> > +

Since here we allow the big joiner for >=11 (ICL+), we need to update the
plane_mode_valid check to ensure that we allow the 8K mode only for TGL+
else with big joiner enabled on ICL we will enable it on ICL which is not permitted (not POR)


> 
> Should we be checking if the specific pipe can do big joiner on the
> platform (gen11 vs gen12 differences) and also omitting eDP from
> consideration?
> 
> 
> >  	if (type != DP_DS_PORT_TYPE_VGA)
> >  		return max_dotclk;
> >  
> > @@ -505,8 +508,10 @@ u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
> >  		       1000000U);
> >  }
> >  
> > -static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> > -				       u32 mode_clock, u32 mode_hdisplay)
> > +static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *dev_priv,
> > +				       u32 link_clock, u32 lane_count,
> > +				       u32 mode_clock, u32 mode_hdisplay,
> > +				       bool bigjoiner)
> >  {
> >  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
> >  	int i;
> > @@ -523,6 +528,10 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  
> >  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
> >  	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
> > +
> > +	if (bigjoiner)
> > +		max_bpp_small_joiner_ram *= 2;
> > +
> 
> This change is correct, but while confirming in the bspec I noticed that
> we may have the wrong DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER value for
> gen11+.  It indicates 6144 for GLK, CNL, but 7680 for ICL+ (and double
> that to 15360 when using big joiner).
> 
> Bspec: 20388
> Bspec: 49259

@Matt, the 7680 is in bytes which translates to 61440 bits and thats what
we are using, see the #DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER

and then its double for big joiner, so this is correct

> 
> >  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
> >  
> >  	/*
> > @@ -531,6 +540,15 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  	 */
> >  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
> >  
> > +	if (bigjoiner) {
> > +		u32 max_bpp_bigjoiner =
> > +			dev_priv->max_cdclk_freq * 48 /
> > +			intel_dp_mode_to_fec_clock(mode_clock);
> 
> Minor nitpick, but just to match the bspec (PPC * CDCLK * 24 bits /
> pixel clock), I'd keep the 2 PPC and 24 bit factors separate here.
>

Yes I agree her with Matt that we shd keep the 2ppc separate just to match bspec
 
> > +
> > +		DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
> > +		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
> > +	}
> > +
> >  	/* Error out if the max bpp is less than smallest allowed valid bpp */
> >  	if (bits_per_pixel < valid_dsc_bpp[0]) {
> >  		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
> > @@ -553,7 +571,8 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
> >  }
> >  
> >  static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> > -				       int mode_clock, int mode_hdisplay)
> > +				       int mode_clock, int mode_hdisplay,
> > +				       bool bigjoiner)
> >  {
> >  	u8 min_slice_count, i;
> >  	int max_slice_width;
> > @@ -578,12 +597,20 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
> >  
> >  	/* Find the closest match to the valid slice count values */
> >  	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
> > -		if (valid_dsc_slicecount[i] >
> > -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
> > -						    false))
> > +		u8 test_slice_count = bigjoiner ?
> > +			2 * valid_dsc_slicecount[i] :
> > +			valid_dsc_slicecount[i];
> > +
> > +		if (test_slice_count >
> > +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
> >  			break;
> > -		if (min_slice_count  <= valid_dsc_slicecount[i])
> > -			return valid_dsc_slicecount[i];
> > +
> > +		/* big joiner needs small joiner to be enabled */
> > +		if (bigjoiner && test_slice_count < 4)
> > +			continue;
> > +
> > +		if (min_slice_count <= test_slice_count)
> > +			return test_slice_count;
> >  	}
> >  
> >  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> > @@ -603,11 +630,15 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  	int max_dotclk;
> >  	u16 dsc_max_output_bpp = 0;
> >  	u8 dsc_slice_count = 0;
> > +	bool dsc = false, bigjoiner = false;
> >  
> >  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> >  		return MODE_NO_DBLESCAN;
> >  
> > -	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
> > +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> > +		return MODE_H_ILLEGAL;
> > +
> > +	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, false);
> >  
> >  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
> >  		if (mode->hdisplay > fixed_mode->hdisplay)
> > @@ -619,6 +650,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  		target_clock = fixed_mode->clock;
> >  	}
> >  
> > +	if (mode->clock < 10000)
> > +		return MODE_CLOCK_LOW;
> > +
> > +	if (target_clock > max_dotclk) {
> > +		max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, true);
> > +
> > +		if (target_clock > max_dotclk)
> > +			return MODE_CLOCK_HIGH;
> > +
> > +		bigjoiner = true;
> > +	}
> > +
> >  	max_link_clock = intel_dp_max_link_rate(intel_dp);
> >  	max_lanes = intel_dp_max_lane_count(intel_dp);
> >  
> > @@ -639,26 +682,32 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  								true);
> >  		} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
> >  			dsc_max_output_bpp =
> > -				intel_dp_dsc_get_output_bpp(max_link_clock,
> > +				intel_dp_dsc_get_output_bpp(dev_priv,
> > +							    max_link_clock,
> >  							    max_lanes,
> >  							    target_clock,
> > -							    mode->hdisplay) >> 4;
> > +							    mode->hdisplay,
> > +							    bigjoiner) >> 4;
> >  			dsc_slice_count =
> >  				intel_dp_dsc_get_slice_count(intel_dp,
> >  							     target_clock,
> > -							     mode->hdisplay);
> > +							     mode->hdisplay,
> > +							     bigjoiner);
> >  		}
> > +
> > +		dsc = dsc_max_output_bpp && dsc_slice_count;
> >  	}
> >  
> > -	if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
> > -	    target_clock > max_dotclk)
> > +	/* big joiner configuration needs DSC */
> > +	if (bigjoiner && !dsc) {
> > +		DRM_DEBUG_KMS("Link clock needs bigjoiner, but DSC or FEC not available\n");
> >  		return MODE_CLOCK_HIGH;
> > +	}
> 
> Somewhere in this function we probably also need to make sure that the
> big joiner is available on the pipe and that we're not using eDP.
>

Yes I agree we need to check that we allow big joine only for B and C for ICL and then
all pipes for TGL+ and not allow for eDP

Manasi
  
> 
> Matt
> 
> >  
> > -	if (mode->clock < 10000)
> > -		return MODE_CLOCK_LOW;
> > -
> > -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> > -		return MODE_H_ILLEGAL;
> > +	if (mode_rate > max_rate && !dsc) {
> > +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> > +		return MODE_CLOCK_HIGH;
> > +	}
> >  
> >  	return intel_mode_valid_max_plane_size(dev_priv, mode);
> >  }
> > @@ -2068,14 +2117,17 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
> >  		u8 dsc_dp_slice_count;
> >  
> >  		dsc_max_output_bpp =
> > -			intel_dp_dsc_get_output_bpp(pipe_config->port_clock,
> > +			intel_dp_dsc_get_output_bpp(dev_priv,
> > +						    pipe_config->port_clock,
> >  						    pipe_config->lane_count,
> >  						    adjusted_mode->crtc_clock,
> > -						    adjusted_mode->crtc_hdisplay);
> > +						    adjusted_mode->crtc_hdisplay,
> > +						    false);
> >  		dsc_dp_slice_count =
> >  			intel_dp_dsc_get_slice_count(intel_dp,
> >  						     adjusted_mode->crtc_clock,
> > -						     adjusted_mode->crtc_hdisplay);
> > +						     adjusted_mode->crtc_hdisplay,
> > +						     false);
> >  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
> >  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
> >  			return -EINVAL;
> > -- 
> > 2.20.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit.
  2019-09-20 11:42 ` [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit Maarten Lankhorst
  2019-09-25  4:17   ` Matt Roper
@ 2019-09-25 22:14   ` Manasi Navare
  1 sibling, 0 replies; 82+ messages in thread
From: Manasi Navare @ 2019-09-25 22:14 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

Hi Maarten,

Could you hold off on merging this patch and big joiner enabling patch else
my 2p2p series which is almost ready to merge except for the final r-b from you
on the HW state patch will need to rebased and that will delay the landing of the
series.

Manasi


On Fri, Sep 20, 2019 at 01:42:19PM +0200, Maarten Lankhorst wrote:
> This can all be done from the intel_update_crtc function. Split out the
> pipe update into a separate function, just like is done for the planes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 124 ++++++++-----------
>  1 file changed, 52 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 520c66071e67..fd8b398733b8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -136,8 +136,6 @@ static void vlv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
>  static void chv_prepare_pll(struct intel_crtc *crtc,
>  			    const struct intel_crtc_state *pipe_config);
> -static void intel_begin_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
> -static void intel_finish_crtc_commit(struct intel_atomic_state *, struct intel_crtc *);
>  static void intel_crtc_init_scalers(struct intel_crtc *crtc,
>  				    struct intel_crtc_state *crtc_state);
>  static void skylake_pfit_enable(const struct intel_crtc_state *crtc_state);
> @@ -13673,13 +13671,54 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
>  	return crtc->base.funcs->get_vblank_counter(&crtc->base);
>  }
>  
> +void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
> +				  struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +
> +	if (!IS_GEN(dev_priv, 2))
> +		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
> +
> +	if (crtc_state->has_pch_encoder) {
> +		enum pipe pch_transcoder =
> +			intel_crtc_pch_transcoder(crtc);
> +
> +		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
> +	}
> +}
> +
> +static void commit_pipe_config(struct intel_atomic_state *state,
> +			       struct intel_crtc_state *old_crtc_state,
> +			       struct intel_crtc_state *new_crtc_state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	bool modeset = needs_modeset(new_crtc_state);
> +
> +	if (!modeset) {
> +		if (new_crtc_state->uapi.color_mgmt_changed ||
> +		    new_crtc_state->update_pipe)
> +			intel_color_commit(new_crtc_state);
> +
> +		if (new_crtc_state->update_pipe)
> +			intel_update_pipe_config(old_crtc_state, new_crtc_state);
> +		else if (INTEL_GEN(dev_priv) >= 9)
> +			skl_detach_scalers(new_crtc_state);
> +
> +		if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> +			bdw_set_pipemisc(new_crtc_state);
> +	}
> +
> +	if (dev_priv->display.atomic_update_watermarks)
> +		dev_priv->display.atomic_update_watermarks(state,
> +							   new_crtc_state);
> +}
> +
>  static void intel_update_crtc(struct intel_crtc *crtc,
>  			      struct intel_atomic_state *state,
>  			      struct intel_crtc_state *old_crtc_state,
>  			      struct intel_crtc_state *new_crtc_state)
>  {
> -	struct drm_device *dev = state->base.dev;
> -	struct drm_i915_private *dev_priv = to_i915(dev);
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	bool modeset = needs_modeset(new_crtc_state);
>  	struct intel_plane_state *new_plane_state =
>  		intel_atomic_get_new_plane_state(state,
> @@ -13703,14 +13742,21 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	else if (new_plane_state)
>  		intel_fbc_enable(crtc, new_crtc_state, new_plane_state);
>  
> -	intel_begin_crtc_commit(state, crtc);
> +	/* Perform vblank evasion around commit operation */
> +	intel_pipe_update_start(new_crtc_state);
> +
> +	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>  
>  	if (INTEL_GEN(dev_priv) >= 9)
>  		skl_update_planes_on_crtc(state, crtc);
>  	else
>  		i9xx_update_planes_on_crtc(state, crtc);
>  
> -	intel_finish_crtc_commit(state, crtc);
> +	intel_pipe_update_end(new_crtc_state);
> +
> +	if (new_crtc_state->update_pipe && !modeset &&
> +	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> @@ -14507,72 +14553,6 @@ skl_max_scale(const struct intel_crtc_state *crtc_state,
>  	return max_scale;
>  }
>  
> -static void intel_begin_crtc_commit(struct intel_atomic_state *state,
> -				    struct intel_crtc *crtc)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_crtc_state *old_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, crtc);
> -	struct intel_crtc_state *new_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, crtc);
> -	bool modeset = needs_modeset(new_crtc_state);
> -
> -	/* Perform vblank evasion around commit operation */
> -	intel_pipe_update_start(new_crtc_state);
> -
> -	if (modeset)
> -		goto out;
> -
> -	if (new_crtc_state->uapi.color_mgmt_changed ||
> -	    new_crtc_state->update_pipe)
> -		intel_color_commit(new_crtc_state);
> -
> -	if (new_crtc_state->update_pipe)
> -		intel_update_pipe_config(old_crtc_state, new_crtc_state);
> -	else if (INTEL_GEN(dev_priv) >= 9)
> -		skl_detach_scalers(new_crtc_state);
> -
> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> -		bdw_set_pipemisc(new_crtc_state);
> -
> -out:
> -	if (dev_priv->display.atomic_update_watermarks)
> -		dev_priv->display.atomic_update_watermarks(state,
> -							   new_crtc_state);
> -}
> -
> -void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
> -				  struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -
> -	if (!IS_GEN(dev_priv, 2))
> -		intel_set_cpu_fifo_underrun_reporting(dev_priv, crtc->pipe, true);
> -
> -	if (crtc_state->has_pch_encoder) {
> -		enum pipe pch_transcoder =
> -			intel_crtc_pch_transcoder(crtc);
> -
> -		intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, true);
> -	}
> -}
> -
> -static void intel_finish_crtc_commit(struct intel_atomic_state *state,
> -				     struct intel_crtc *crtc)
> -{
> -	struct intel_crtc_state *old_crtc_state =
> -		intel_atomic_get_old_crtc_state(state, crtc);
> -	struct intel_crtc_state *new_crtc_state =
> -		intel_atomic_get_new_crtc_state(state, crtc);
> -
> -	intel_pipe_update_end(new_crtc_state);
> -
> -	if (new_crtc_state->update_pipe &&
> -	    !needs_modeset(new_crtc_state) &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> -		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
> -}
> -
>  /**
>   * intel_plane_destroy - destroy a plane
>   * @plane: plane to destroy
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check.
  2019-09-20 11:42 ` [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check Maarten Lankhorst
@ 2019-09-26  3:48   ` Matt Roper
  2019-09-30 14:12     ` Maarten Lankhorst
  0 siblings, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-26  3:48 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:23PM +0200, Maarten Lankhorst wrote:
> When the clock is higher than the dotclock, try with 2 pipes enabled.
> If we can enable 2, then we will go into big joiner mode, and steal
> the adjacent crtc.
> 
> This only links the crtc's in software, no hardware or plane
> programming is done yet. Blobs are also copied from the master's
> crtc_state, so it doesn't depend at commit time on the other
> crtc_state.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   |  15 +-
>  drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 197 +++++++++++++++++-
>  .../drm/i915/display/intel_display_types.h    |  11 +-
>  drivers/gpu/drm/i915/display/intel_dp.c       |  25 ++-
>  5 files changed, 228 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index c50e0b218bd6..0db04064c86e 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -228,25 +228,26 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
>  	intel_crtc_put_color_blobs(crtc_state);
>  }
>  
> -void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
> +				 const struct intel_crtc_state *from_crtc_state)
>  {
>  	intel_crtc_put_color_blobs(crtc_state);
>  
> -	if (crtc_state->uapi.degamma_lut)
> +	if (from_crtc_state->uapi.degamma_lut)
>  		crtc_state->hw.degamma_lut =
> -			drm_property_blob_get(crtc_state->uapi.degamma_lut);
> +			drm_property_blob_get(from_crtc_state->uapi.degamma_lut);
>  	else
>  		crtc_state->hw.degamma_lut = NULL;
>  
> -	if (crtc_state->uapi.gamma_lut)
> +	if (from_crtc_state->uapi.gamma_lut)
>  		crtc_state->hw.gamma_lut =
> -			drm_property_blob_get(crtc_state->uapi.gamma_lut);
> +			drm_property_blob_get(from_crtc_state->uapi.gamma_lut);
>  	else
>  		crtc_state->hw.gamma_lut = NULL;
>  
> -	if (crtc_state->uapi.ctm)
> +	if (from_crtc_state->uapi.ctm)
>  		crtc_state->hw.ctm =
> -			drm_property_blob_get(crtc_state->uapi.ctm);
> +			drm_property_blob_get(from_crtc_state->uapi.ctm);
>  	else
>  		crtc_state->hw.ctm = NULL;
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> index 42be91e0772a..8da84d64aa04 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -36,7 +36,8 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>  			       struct drm_crtc_state *state);
>  void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
> -void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
> +				 const struct intel_crtc_state *from_crtc_state);
>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index ba52a70840fd..143d531c4c81 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  				     struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>  	int clock_limit = dev_priv->max_dotclk_freq;
>  
>  	if (INTEL_GEN(dev_priv) < 4) {
> @@ -7451,6 +7451,25 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> +	/*
> +	 * copy hw mode to transcoder mode.
> +	 * This matters mostly for big joiner, which splits the mode in half.
> +	 */
> +	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
> +	if (pipe_config->bigjoiner) {
> +		/* Make sure the crtc config is halved horizontally */
> +		adjusted_mode->crtc_clock /= 2;
> +		adjusted_mode->crtc_hdisplay /= 2;
> +		adjusted_mode->crtc_hblank_start /= 2;
> +		adjusted_mode->crtc_hblank_end /= 2;
> +		adjusted_mode->crtc_hsync_start /= 2;
> +		adjusted_mode->crtc_hsync_end /= 2;
> +		adjusted_mode->crtc_htotal /= 2;
> +		adjusted_mode->crtc_hskew /= 2;

If adjusted_mode is the "pipe mode," does anything other than the size
have meaning or matter at that level?  Not that halving the rest of
these hurts anything, it just seems strange to consider them at the pipe
level.

> +
> +		pipe_config->pipe_src_w /= 2;
> +	}
> +
>  	if (adjusted_mode->crtc_clock > clock_limit) {
>  		DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
>  			      adjusted_mode->crtc_clock, clock_limit,
> @@ -8133,7 +8152,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)

We may want to rename this function to intel_set_transcoder_timings
now that pipe and transcoder are starting to be different.


>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> -	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.transcoder_mode;
>  	u32 crtc_vtotal, crtc_vblank_end;
>  	int vsyncshift = 0;
>  
> @@ -11774,6 +11793,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  		to_intel_crtc_state(_crtc_state);
>  	int ret;
>  	bool mode_changed = needs_modeset(crtc_state);
> +	struct intel_atomic_state *state =
> +		to_intel_atomic_state(crtc_state->uapi.state);
>  
>  	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
>  	    mode_changed && !crtc_state->hw.active)
> @@ -11781,6 +11802,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  
>  	if (mode_changed && crtc_state->hw.enable &&
>  	    dev_priv->display.crtc_compute_clock &&
> +	    !crtc_state->bigjoiner_slave &&
>  	    !WARN_ON(crtc_state->shared_dpll)) {
>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>  		if (ret)
> @@ -11796,8 +11818,15 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>  
>  	if (mode_changed || crtc_state->update_pipe ||
>  	    crtc_state->uapi.color_mgmt_changed) {
> +		const struct intel_crtc_state *master_crtc_state = crtc_state;
> +
> +		if (crtc_state->bigjoiner_slave)
> +			master_crtc_state =
> +				intel_atomic_get_new_crtc_state(state,
> +					crtc_state->bigjoiner_linked_crtc);
> +
>  		/* Copy color blobs to hw state */
> -		intel_crtc_copy_color_blobs(crtc_state);
> +		intel_crtc_copy_color_blobs(crtc_state, master_crtc_state);
>  
>  		ret = intel_color_check(crtc_state);
>  		if (ret)
> @@ -12259,7 +12288,48 @@ static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>  	crtc_state->uapi.active = crtc_state->hw.active;
>  	crtc_state->uapi.mode = crtc_state->hw.mode;
> -	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
> +}
> +
> +static int
> +copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
> +			  const struct intel_crtc_state *from_crtc_state)
> +{
> +	struct intel_crtc_state *saved_state;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
> +	if (!saved_state)
> +		return -ENOMEM;
> +
> +	saved_state->uapi = crtc_state->uapi;
> +	saved_state->scaler_state = crtc_state->scaler_state;
> +	saved_state->shared_dpll = crtc_state->shared_dpll;
> +	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> +	saved_state->crc_enabled = crtc_state->crc_enabled;
> +
> +	intel_crtc_free_hw_state(crtc_state);
> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> +	kfree(saved_state);
> +
> +	/* Re-init hw state */
> +	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
> +	crtc_state->hw.enable = from_crtc_state->hw.enable;
> +	crtc_state->hw.active = from_crtc_state->hw.active;
> +	crtc_state->hw.mode = from_crtc_state->hw.mode;
> +	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
> +
> +	/* Some fixups */
> +	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
> +	crtc_state->uapi.connectors_changed = from_crtc_state->uapi.connectors_changed;
> +	crtc_state->uapi.active_changed = from_crtc_state->uapi.active_changed;
> +	crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;
> +	crtc_state->bigjoiner_linked_crtc = to_intel_crtc(from_crtc_state->uapi.crtc);
> +	crtc_state->bigjoiner_slave = true;
> +	crtc_state->cpu_transcoder = (enum transcoder)crtc->pipe;
> +	crtc_state->has_audio = false;
> +
> +	return 0;
>  }
>  
>  static int
> @@ -12432,7 +12502,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>  
>  	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
> -	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.transcoder_mode;
>  
>  	return 0;
>  }
> @@ -13549,6 +13619,109 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
>  	new_crtc_state->has_drrs = old_crtc_state->has_drrs;
>  }
>  
> +static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
> +	struct intel_crtc *crtc, *slave, *master;
> +	int i, ret = 0;
> +
> +	if (INTEL_GEN(dev_priv) < 11)
> +		return 0;
> +
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!old_crtc_state->bigjoiner_slave)
> +			continue;
> +
> +		if (crtc->pipe == PIPE_A) {

Rather than a hardcoded PIPE_A check, should we have a bitmask of pipes
that can be big joiner masters somewhere?  mask = 0b111 for gen12, but
mask = 0b010 for gen11.  Then the allowable slaves
would be mask << 1, which would also ensure gen11 doesn't allow a slave on pipe B.

> +			DRM_ERROR("Bigjoiner slave on pipe A?\n");

We should probably just use a WARN_ON() in the condition above since
this shouldn't happen unless we screwed up somewhere in the driver.

> +			return -EINVAL;
> +		}
> +
> +		/* crtc staying in slave mode? */
> +		if (!new_crtc_state->uapi.enable)
> +			continue;
> +
> +		if (needs_modeset(new_crtc_state) || new_crtc_state->update_pipe) {

Won't needs_modeset() always return true here?  I.e., if we were a slave
previously but didn't bail on the uapi.enable check above, then
uapi.enable is flipping from false to true.

Given that enabling the previously-slave CRTC is only possible if the
previously-master CRTC is also modesetting in a way that won't need a
slave anymore, it seems like the next step would be

        master_crtc_state = intel_get_existing_crtc_state()
        if (!master_crtc_state || !needs_modeset(master_crtc_state))
                fail
                
otherwise we've now overcommitted our slave CRTC.

> +			master = old_crtc_state->bigjoiner_linked_crtc;
> +			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
> +			if (IS_ERR(master_crtc_state))
> +				return PTR_ERR(master_crtc_state);
> +
> +			/*
> +			 * Force modeset on master, to recalculate bigjoiner
> +			 * state.
> +			 *
> +			 * If master_crtc_state was not part of the atomic commit,
> +			 * we will fail because the master was not deconfigured,
> +			 * but at least fail below to unify the checks.
> +			 */
> +			master_crtc_state->uapi.mode_changed = true;

Should we instead update intel_pipe_config_compare to check bigjoiner
fields and prevent fastsets on states currently using the bigjoiner? 

> +
> +			ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
> +			if (ret)
> +				return ret;
> +
> +			ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +					    new_crtc_state, i) {
> +		if (!new_crtc_state->uapi.enable || !new_crtc_state->bigjoiner) {
> +			if (!old_crtc_state->bigjoiner)
> +				continue;
> +		}
> +
> +		if (!needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe)
> +			continue;
> +
> +		if (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave) {
> +			if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
> +				DRM_DEBUG_KMS("Big joiner configuration requires CRTC + 1 to be used, doesn't exist\n");
> +				return -EINVAL;
> +			}
> +
> +			slave = new_crtc_state->bigjoiner_linked_crtc =
> +				intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
> +			slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave);
> +			if (IS_ERR(slave_crtc_state))
> +				return PTR_ERR(slave_crtc_state);
> +
> +			if (slave_crtc_state->uapi.enable) {
> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires this CRTC to be unconfigured\n",
> +					      slave->base.base.id, slave->base.name);
> +				return -EINVAL;
> +			} else {
> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
> +					      slave->base.base.id, slave->base.name);
> +				ret = copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
> +			}
> +		} else {
> +			master = new_crtc_state->bigjoiner_linked_crtc;
> +			if (!master)
> +				continue;
> +

What about the case of a CRTC that previously needed the bigjoiner but
is performing a modeset such that it no longer does?  In that case
new_crtc_state->bigjoiner will be false so we'll end up in this branch.
But then we seem to be trying to grab the ex-master's master which
doesn't make sense for this case since we actually want to grab the
slave and clear it out.

The code in this branch seems to be trying to operate on a CRTC that was
previously a slave, but assuming an ex-slave is staying disabled
(!new_crtc_state->uapi.enable), then I think we took the 'continue' at
the top of the loop and never make it down here.

> +			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
> +			if (IS_ERR(master_crtc_state))
> +				return PTR_ERR(master_crtc_state);
> +
> +			if (!master_crtc_state->uapi.enable && !new_crtc_state->uapi.enable) {
> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Disabling slave from big joiner\n",
> +					      crtc->base.base.id, crtc->base.name);
> +				ret = clear_intel_crtc_state(new_crtc_state);
> +			}
> +		}
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  /**
>   * intel_atomic_check - validate state object
>   * @dev: drm device
> @@ -13583,7 +13756,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  
>  		if (!new_crtc_state->uapi.enable) {
>  			any_ms = true;
> -			clear_intel_crtc_state(new_crtc_state);
> +
> +			/* big joiner slave is cleared in intel_atomic_check_bigjoiner() */
> +			if (!new_crtc_state->bigjoiner_slave)
> +				clear_intel_crtc_state(new_crtc_state);
>  			continue;
>  		}
>  
> @@ -13597,6 +13773,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  			any_ms = true;
>  	}
>  
> +	ret = intel_atomic_check_bigjoiner(state);
> +	if (ret)
> +		return ret;
> +
>  	ret = drm_dp_mst_atomic_check(&state->base);
>  	if (ret)
>  		goto fail;
> @@ -13747,7 +13927,9 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  
>  	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>  
> -	if (INTEL_GEN(dev_priv) >= 9)
> +	if (new_crtc_state->bigjoiner)
> +		{/* Not supported yet */}
> +	else if (INTEL_GEN(dev_priv) >= 9)
>  		skl_update_planes_on_crtc(state, crtc);
>  	else
>  		i9xx_update_planes_on_crtc(state, crtc);
> @@ -16846,7 +17028,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		}
>  
>  		intel_bw_crtc_update(bw_state, crtc_state);
> -
>  		copy_hw_to_uapi_state(crtc_state);
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>  	}

Strap whitespace change.

> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 394f84e5d583..dd0329a4b9ff 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -774,7 +774,7 @@ struct intel_crtc_state {
>  	struct {
>  		bool active, enable;
>  		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
> -		struct drm_display_mode mode, adjusted_mode;
> +		struct drm_display_mode mode, adjusted_mode, transcoder_mode;
>  	} hw;
>  
>  	/**
> @@ -1005,6 +1005,15 @@ struct intel_crtc_state {
>  	/* enable pipe csc? */
>  	bool csc_enable;
>  
> +	/* enable pipe big joiner? */
> +	bool bigjoiner;
> +
> +	/* big joiner slave crtc? */
> +	bool bigjoiner_slave;
> +
> +	/* linked crtc for bigjoiner, either slave or master */
> +	struct intel_crtc *bigjoiner_linked_crtc;
> +
>  	/* Display Stream compression state */
>  	struct {
>  		bool compression_enable;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 046e1662d1e3..3d487ce16151 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2105,6 +2105,19 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  	pipe_config->port_clock = intel_dp->common_rates[limits->max_clock];
>  	pipe_config->lane_count = limits->max_lane_count;
>  
> +	if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, false)) {
> +		if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, true)) {
> +			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
> +			return -EINVAL;
> +		}
> +		if (intel_dp_is_edp(intel_dp)) {
> +			DRM_DEBUG_KMS("Cannot split eDP stream in bigjoiner configuration.\n");
> +			return -EINVAL;
> +		}
> +		pipe_config->bigjoiner = true;
> +		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
> +	}
> +
>  	if (intel_dp_is_edp(intel_dp)) {
>  		pipe_config->dsc_params.compressed_bpp =
>  			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
> @@ -2122,12 +2135,12 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  						    pipe_config->lane_count,
>  						    adjusted_mode->crtc_clock,
>  						    adjusted_mode->crtc_hdisplay,
> -						    false);
> +						    pipe_config->bigjoiner);
>  		dsc_dp_slice_count =
>  			intel_dp_dsc_get_slice_count(intel_dp,
>  						     adjusted_mode->crtc_clock,
>  						     adjusted_mode->crtc_hdisplay,
> -						     false);
> +						     pipe_config->bigjoiner);
>  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
>  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
>  			return -EINVAL;
> @@ -2142,13 +2155,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  	 * is greater than the maximum Cdclock and if slice count is even
>  	 * then we need to use 2 VDSC instances.
>  	 */
> -	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) {
> -		if (pipe_config->dsc_params.slice_count > 1) {
> -			pipe_config->dsc_params.dsc_split = true;
> -		} else {
> +	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq || pipe_config->bigjoiner) {
> +		if (pipe_config->dsc_params.slice_count < 2) {
>  			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
>  			return -EINVAL;
>  		}
> +
> +		pipe_config->dsc_params.dsc_split = true;
>  	}
>  
>  	ret = intel_dp_compute_dsc_params(intel_dp, pipe_config);
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences.
  2019-09-20 11:42 ` [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences Maarten Lankhorst
@ 2019-09-26  5:18   ` Matt Roper
  2019-09-26 23:54     ` Matt Roper
  0 siblings, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-26  5:18 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:24PM +0200, Maarten Lankhorst wrote:
> Make vdsc work when no output is enabled. The big joiner needs VDSC
> on the slave, so enable it and set the appropriate bits.
> Also update timestamping constants, because slave crtc's are not
> updated in drm_atomic_helper_update_legacy_modeset_state().
> 
> This should be enough to bring up CRTC's in a big joiner configuration,
> without any plane configuration on the second pipe yet.
> 
> HOWEVER, we bring up the crtc's in the wrong order. We need to make
> sure that the master crtc is brought up after the slave crtc, we
> don't do that yet. This is done correctly later in this series.
> 
> The next steps are to add atomic commit, and make sure we enable and
> update both master and slave in the correct order.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

A couple minor comments inline below, but I didn't see any clear
problems with this patch so

Acked-by: Matt Roper <matthew.d.roper@intel.com>

However there's a lot of pretty complicated changes here in areas that
I'm only vaguely familiar with, so I think it would be good if someone
like Manasi who's more familiar with this area of the code could look it
over.


Matt


> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  55 ++-
>  drivers/gpu/drm/i915/display/intel_display.c  | 402 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |  17 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  18 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
>  6 files changed, 418 insertions(+), 198 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index c775fd205915..a26155f90261 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -1694,6 +1694,13 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
>  		skl_ddi_clock_get(encoder, pipe_config);
>  	else if (INTEL_GEN(dev_priv) <= 8)
>  		hsw_ddi_clock_get(encoder, pipe_config);
> +
> +	if (pipe_config->bigjoiner) {
> +		pipe_config->hw.transcoder_mode.crtc_clock =
> +			pipe_config->hw.adjusted_mode.crtc_clock;
> +
> +		pipe_config->hw.adjusted_mode.crtc_clock /= 2;
> +	}
>  }
>  
>  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
> @@ -2176,13 +2183,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>  	    intel_phy_is_tc(dev_priv, phy))
>  		intel_display_power_get(dev_priv,
>  					intel_ddi_main_link_aux_domain(dig_port));
> -
> -	/*
> -	 * VDSC power is needed when DSC is enabled
> -	 */
> -	if (crtc_state->dsc_params.compression_enable)
> -		intel_display_power_get(dev_priv,
> -					intel_dsc_power_domain(crtc_state));
>  }
>  
>  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
> @@ -3290,7 +3290,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	/* 7.l */
>  	intel_ddi_enable_fec(encoder, crtc_state);
> -	intel_dsc_enable(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner)
> +		intel_dsc_enable(encoder, crtc_state);
>  }
>  
>  static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
> @@ -3361,7 +3362,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  	if (!is_mst)
>  		intel_ddi_enable_pipe_clock(crtc_state);
>  
> -	intel_dsc_enable(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner)
> +		intel_dsc_enable(encoder, crtc_state);
>  }
>  
>  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> @@ -3972,19 +3974,18 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
>  		crtc_state->min_voltage_level = 2;
>  }
>  
> -void intel_ddi_get_config(struct intel_encoder *encoder,
> -			  struct intel_crtc_state *pipe_config)
> +static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
> +				    struct intel_crtc_state *pipe_config)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	u32 temp, flags = 0;
>  
> -	/* XXX: DSI transcoder paranoia */
> -	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> +	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>  		return;
>  
> -	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
>  		flags |= DRM_MODE_FLAG_PHSYNC;
>  	else
> @@ -4066,6 +4067,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	default:
>  		break;
>  	}
> +}
> +
> +void intel_ddi_get_config(struct intel_encoder *encoder,
> +			  struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +
> +	/* XXX: DSI transcoder paranoia */
> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> +		return;
> +
> +	intel_ddi_read_func_ctl(encoder, pipe_config);
> +	if (pipe_config->bigjoiner_slave) {
> +		/* read out pipe settings from master */
> +		enum transcoder save = pipe_config->cpu_transcoder;
> +
> +		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
> +		WARN_ON(pipe_config->output_types);
> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> +		pipe_config->cpu_transcoder = save;
> +	}
>  
>  	pipe_config->has_audio =
>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
> @@ -4090,7 +4114,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
>  	}
>  
> -	intel_ddi_clock_get(encoder, pipe_config);
> +	if (!pipe_config->bigjoiner_slave)
> +		intel_ddi_clock_get(encoder, pipe_config);
>  
>  	if (IS_GEN9_LP(dev_priv))
>  		pipe_config->lane_lat_optim_mask =
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 143d531c4c81..8c08c4914c9b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6449,6 +6449,45 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
>  	I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);
>  }
>  
> +static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
> +					 struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *master = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct intel_crtc_state *master_crtc_state;
> +	struct drm_connector_state *conn_state;
> +	struct drm_connector *conn;
> +	struct intel_encoder *encoder = NULL;
> +	int i;
> +
> +	if (crtc_state->bigjoiner_slave)
> +		master = crtc_state->bigjoiner_linked_crtc;
> +
> +	master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
> +
> +	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
> +		if (conn_state->crtc != &master->base)
> +			continue;
> +
> +		encoder = to_intel_encoder(conn_state->best_encoder);
> +		break;
> +	}
> +
> +	if (!crtc_state->bigjoiner_slave) {
> +		/* need to enable VDSC, which we skipped in pre-enable */
> +		intel_dsc_enable(encoder, crtc_state);
> +	} else {
> +		/*
> +		 * Enable sequence steps 1-7 on bigjoiner master
> +		 */

I'd extend this comment to indicate that we do this on the slave (using
the master's state, transcoder, and DDI) because the [will] program the
slave CRTC before the master.

> +		intel_encoders_pre_pll_enable(master, master_crtc_state, state);
> +		intel_enable_shared_dpll(master_crtc_state);
> +		intel_encoders_pre_enable(master, master_crtc_state, state);
> +
> +		/* and DSC on slave */
> +		intel_dsc_enable(NULL, crtc_state);
> +	}
> +}
> +
>  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  				struct intel_atomic_state *state)
>  {
> @@ -6462,37 +6501,38 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (WARN_ON(intel_crtc->active))
>  		return;
>  
> -	intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
> +	if (!pipe_config->bigjoiner) {
> +		intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
>  
> -	if (pipe_config->shared_dpll)
> -		intel_enable_shared_dpll(pipe_config);
> +		if (pipe_config->shared_dpll)
> +			intel_enable_shared_dpll(pipe_config);
>  
> -	intel_encoders_pre_enable(intel_crtc, pipe_config, state);
> +		intel_encoders_pre_enable(intel_crtc, pipe_config, state);
> +	} else {
> +		icl_ddi_bigjoiner_pre_enable(state, pipe_config);
> +	}
>  
> -	if (intel_crtc_has_dp_encoder(pipe_config))
> -		intel_dp_set_m_n(pipe_config, M1_N1);
> +	intel_set_pipe_src_size(pipe_config);
> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> +		bdw_set_pipemisc(pipe_config);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_pipe_timings(pipe_config);
> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> +		if (intel_crtc_has_dp_encoder(pipe_config))
> +			intel_dp_set_m_n(pipe_config, M1_N1);
>  
> -	intel_set_pipe_src_size(pipe_config);
> +		intel_set_pipe_timings(pipe_config);
>  
> -	if (cpu_transcoder != TRANSCODER_EDP &&
> -	    !transcoder_is_dsi(cpu_transcoder)) {
> -		I915_WRITE(PIPE_MULT(cpu_transcoder),
> -			   pipe_config->pixel_multiplier - 1);
> -	}
> +		if (cpu_transcoder != TRANSCODER_EDP)
> +			I915_WRITE(PIPE_MULT(cpu_transcoder),
> +				  pipe_config->pixel_multiplier - 1);
>  
> -	if (pipe_config->has_pch_encoder) {
> -		intel_cpu_transcoder_set_m_n(pipe_config,
> -					     &pipe_config->fdi_m_n, NULL);
> -	}
> +		if (pipe_config->has_pch_encoder) {
> +			intel_cpu_transcoder_set_m_n(pipe_config,
> +						    &pipe_config->fdi_m_n, NULL);
> +		}
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
>  		haswell_set_pipeconf(pipe_config);
> -
> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> -		bdw_set_pipemisc(pipe_config);
> +	}
>  
>  	intel_crtc->active = true;
>  
> @@ -6520,9 +6560,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (INTEL_GEN(dev_priv) >= 11)
>  		icl_set_pipe_chicken(intel_crtc);
>  
> -	intel_ddi_set_pipe_settings(pipe_config);
> -	if (!transcoder_is_dsi(cpu_transcoder))
> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> +		intel_ddi_set_pipe_settings(pipe_config);
> +
>  		intel_ddi_enable_transcoder_func(pipe_config);
> +	}
>  
>  	if (dev_priv->display.initial_watermarks != NULL)
>  		dev_priv->display.initial_watermarks(state, pipe_config);
> @@ -6531,8 +6573,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  		icl_pipe_mbus_enable(intel_crtc);
>  
>  	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
> -	if (!transcoder_is_dsi(cpu_transcoder))
> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
>  		intel_enable_pipe(pipe_config);
> +	else
> +		trace_intel_pipe_enable(intel_crtc);
>  
>  	if (pipe_config->has_pch_encoder)
>  		lpt_pch_enable(state, pipe_config);
> @@ -6663,9 +6707,27 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>  	else
>  		ironlake_pfit_disable(old_crtc_state);
>  
> -	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
> +	if (old_crtc_state->bigjoiner) {
> +		struct intel_crtc *master;
> +		struct intel_crtc_state *master_crtc_state;
>  
> -	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
> +		/* ports are disabled from the slave, after it deconfigures */
> +		if (!old_crtc_state->bigjoiner_slave)
> +			return;
> +
> +		master = old_crtc_state->bigjoiner_linked_crtc;
> +		master_crtc_state = intel_atomic_get_old_crtc_state(state, master);
> +
> +		intel_ddi_disable_pipe_clock(old_crtc_state);
> +
> +		/* disable ports on the master crtc */
> +		intel_encoders_post_disable(master, master_crtc_state, state);
> +		intel_encoders_post_pll_disable(master, master_crtc_state, state);
> +	} else {
> +		intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
> +
> +		intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
> +	}
>  }
>  
>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
> @@ -6829,6 +6891,9 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>  	if (crtc_state->shared_dpll)
>  		mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE);
>  
> +	if (crtc_state->dsc_params.compression_enable)
> +		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
> +
>  	return mask;
>  }
>  
> @@ -7417,6 +7482,19 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>  	return pixel_rate;
>  }
>  
> +static void intel_encoder_get_config(struct intel_encoder *encoder,
> +				     struct intel_crtc_state *crtc_state)
> +{
> +	encoder->get_config(encoder, crtc_state);
> +
> +	crtc_state->hw.transcoder_mode.flags = crtc_state->hw.adjusted_mode.flags;
> +
> +	/* if transcoder clock is not set, assume same as adjusted_mode clock */
> +	if (!crtc_state->hw.transcoder_mode.crtc_clock)
> +		crtc_state->hw.transcoder_mode.crtc_clock =
> +			crtc_state->hw.adjusted_mode.crtc_clock;
> +}
> +
>  static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> @@ -8265,6 +8343,24 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
>  		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
>  		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
>  	}
> +
> +	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
> +	if (pipe_config->bigjoiner) {
> +		struct drm_display_mode *adjusted_mode =
> +			&pipe_config->hw.adjusted_mode;
> +
> +		/*
> +		  * transcoder is programmed to the full mode,
> +		  * but pipje timings are half of the transcoder mode
> +		  */
> +		adjusted_mode->crtc_hdisplay /= 2;
> +		adjusted_mode->crtc_hblank_start /= 2;
> +		adjusted_mode->crtc_hblank_end /= 2;
> +		adjusted_mode->crtc_hsync_start /= 2;
> +		adjusted_mode->crtc_hsync_end /= 2;
> +		adjusted_mode->crtc_htotal /= 2;
> +		adjusted_mode->crtc_hskew /= 2;
> +	}
>  }
>  
>  static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> @@ -8285,20 +8381,22 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>  				 struct intel_crtc_state *pipe_config)
>  {
> -	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
> -	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
> -	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
> -	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
> +	struct drm_display_mode *hw_mode = &pipe_config->hw.transcoder_mode;
>  
> -	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
> +	mode->hdisplay = hw_mode->crtc_hdisplay;
> +	mode->htotal = hw_mode->crtc_htotal;
> +	mode->hsync_start = hw_mode->crtc_hsync_start;
> +	mode->hsync_end = hw_mode->crtc_hsync_end;
>  
> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
> +	mode->vdisplay = hw_mode->crtc_vdisplay;
> +	mode->vtotal = hw_mode->crtc_vtotal;
> +	mode->vsync_start = hw_mode->crtc_vsync_start;
> +	mode->vsync_end = hw_mode->crtc_vsync_end;
> +
> +	mode->flags = hw_mode->flags;
>  	mode->type = DRM_MODE_TYPE_DRIVER;
>  
> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
> +	mode->clock = hw_mode->crtc_clock;
>  
>  	mode->hsync = drm_mode_hsync(mode);
>  	mode->vrefresh = drm_mode_vrefresh(mode);
> @@ -10385,6 +10483,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>  	u32 tmp;
>  
>  	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
> +	if (!(tmp & TRANS_DDI_FUNC_ENABLE))
> +		return;
>  
>  	if (INTEL_GEN(dev_priv) >= 12)
>  		port = TGL_TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp);
> @@ -10455,11 +10555,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>  		WARN_ON(active);
>  		active = true;
>  	}
> +	intel_dsc_get_config(pipe_config);
>  
> -	if (!active)
> -		goto out;
> +	if (!active) {
> +		/* bigjoiner slave doesn't enable transcoder */
> +		if (!pipe_config->bigjoiner_slave)
> +			goto out;
> +
> +		active = true;
> +		pipe_config->pixel_multiplier = 1;
>  
> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> +		/* we cannot read out most state, so don't bother.. */
> +		pipe_config->quirks |= PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE;
> +	} else if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>  	    INTEL_GEN(dev_priv) >= 11) {
>  		haswell_get_ddi_port_state(crtc, pipe_config);
>  		intel_get_pipe_timings(crtc, pipe_config);
> @@ -10513,7 +10621,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> +	if (pipe_config->bigjoiner_slave) {
> +		/* Cannot be read out as a slave, set to 0. */
> +		pipe_config->pixel_multiplier = 0;
> +	} else if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
>  		pipe_config->pixel_multiplier =
>  			I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> @@ -11468,7 +11579,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
>  		return NULL;
>  	}
>  
> -	encoder->get_config(encoder, crtc_state);
> +	intel_encoder_get_config(encoder, crtc_state);
>  
>  	intel_mode_from_pipe_config(mode, crtc_state);
>  
> @@ -12285,9 +12396,11 @@ static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
>  
>  static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>  {
> -	crtc_state->uapi.enable = crtc_state->hw.enable;
> -	crtc_state->uapi.active = crtc_state->hw.active;
> -	crtc_state->uapi.mode = crtc_state->hw.mode;
> +	if (!crtc_state->bigjoiner_slave) {
> +		crtc_state->uapi.enable = crtc_state->hw.enable;
> +		crtc_state->uapi.active = crtc_state->hw.active;
> +		crtc_state->uapi.mode = crtc_state->hw.mode;
> +	}
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
>  }
>  
> @@ -12318,6 +12431,7 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
>  	crtc_state->hw.active = from_crtc_state->hw.active;
>  	crtc_state->hw.mode = from_crtc_state->hw.mode;
>  	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
> +	crtc_state->hw.transcoder_mode = from_crtc_state->hw.transcoder_mode;
>  
>  	/* Some fixups */
>  	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
> @@ -12833,19 +12947,41 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_X(output_types);
>  
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
> -
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
> +		/* bigjoiner mode = transcoder mode / 2, for calculations */
> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
> +
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hdisplay);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_htotal);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_start);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_end);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_start);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_end);
> +
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vdisplay);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vtotal);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_start);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_end);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_start);
> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_end);
> +
> +		PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> +				      DRM_MODE_FLAG_INTERLACE);
> +
> +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> +					      DRM_MODE_FLAG_PHSYNC);
> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> +					      DRM_MODE_FLAG_NHSYNC);
> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> +					      DRM_MODE_FLAG_PVSYNC);
> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> +					      DRM_MODE_FLAG_NVSYNC);
> +		}
> +	}
>  
>  	PIPE_CONF_CHECK_I(pixel_multiplier);
>  	PIPE_CONF_CHECK_I(output_format);
> @@ -12857,24 +12993,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> -	PIPE_CONF_CHECK_BOOL(fec_enable);
> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
> +		PIPE_CONF_CHECK_BOOL(fec_enable);
>  
>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>  
> -	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> -			      DRM_MODE_FLAG_INTERLACE);
> -
> -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> -				      DRM_MODE_FLAG_PHSYNC);
> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> -				      DRM_MODE_FLAG_NHSYNC);
> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> -				      DRM_MODE_FLAG_PVSYNC);
> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> -				      DRM_MODE_FLAG_NVSYNC);
> -	}
> -
>  	PIPE_CONF_CHECK_X(gmch_pfit.control);
>  	/* pfit ratios are autocomputed by the hw on gen4+ */
>  	if (INTEL_GEN(dev_priv) < 4)
> @@ -12898,7 +13021,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  		}
>  
>  		PIPE_CONF_CHECK_I(scaler_state.scaler_id);
> -		PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
> +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
> +			PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
>  
>  		PIPE_CONF_CHECK_X(gamma_mode);
>  		if (IS_CHERRYVIEW(dev_priv))
> @@ -12917,48 +13041,50 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(double_wide);
>  
>  	PIPE_CONF_CHECK_P(shared_dpll);
> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
>  	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);

Missing indent on this line?

> -	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.spll);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
> -
> -	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
> -	PIPE_CONF_CHECK_X(dsi_pll.div);
> -
> -	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
> -		PIPE_CONF_CHECK_I(pipe_bpp);
> -
> -	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
> -	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> -
> -	PIPE_CONF_CHECK_I(min_voltage_level);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.spll);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
> +
> +		PIPE_CONF_CHECK_X(dsi_pll.ctrl);
> +		PIPE_CONF_CHECK_X(dsi_pll.div);
> +
> +		if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
> +			PIPE_CONF_CHECK_I(pipe_bpp);
> +
> +		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
> +		PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> +
> +		PIPE_CONF_CHECK_I(min_voltage_level);
> +	}
>  
>  	PIPE_CONF_CHECK_X(infoframes.enable);
>  	PIPE_CONF_CHECK_X(infoframes.gcp);
> @@ -12967,6 +13093,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_INFOFRAME(hdmi);
>  	PIPE_CONF_CHECK_INFOFRAME(drm);
>  
> +	PIPE_CONF_CHECK_BOOL(bigjoiner);
> +	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
> +	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
> +	PIPE_CONF_CHECK_BOOL(dsc_params.compression_enable);
> +	PIPE_CONF_CHECK_BOOL(dsc_params.dsc_split);
> +
>  #undef PIPE_CONF_CHECK_X
>  #undef PIPE_CONF_CHECK_I
>  #undef PIPE_CONF_CHECK_BOOL
> @@ -13221,6 +13353,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>  	struct intel_encoder *encoder;
>  	struct intel_crtc_state *pipe_config;
>  	struct drm_atomic_state *state;
> +	struct intel_crtc *master = crtc;
>  	bool active;
>  
>  	state = old_crtc_state->uapi.state;
> @@ -13250,7 +13383,10 @@ verify_crtc_state(struct intel_crtc *crtc,
>  			"(expected %i, found %i)\n",
>  			new_crtc_state->hw.active, crtc->active);
>  
> -	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
> +	if (new_crtc_state->bigjoiner_slave)
> +		master = new_crtc_state->bigjoiner_linked_crtc;
> +
> +	for_each_encoder_on_crtc(dev, &master->base, encoder) {
>  		enum pipe pipe;
>  
>  		active = encoder->get_hw_state(encoder, &pipe);
> @@ -13259,12 +13395,12 @@ verify_crtc_state(struct intel_crtc *crtc,
>  				encoder->base.base.id, active,
>  				new_crtc_state->hw.active);
>  
> -		I915_STATE_WARN(active && crtc->pipe != pipe,
> +		I915_STATE_WARN(active && master->pipe != pipe,
>  				"Encoder connected to wrong pipe %c\n",
>  				pipe_name(pipe));
>  
>  		if (active)
> -			encoder->get_config(encoder, pipe_config);
> +			intel_encoder_get_config(encoder, pipe_config);
>  	}
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -13906,6 +14042,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  
>  	if (modeset) {
>  		update_scanline_offset(new_crtc_state);
> +		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.transcoder_mode);
>  		dev_priv->display.crtc_enable(new_crtc_state, state);
>  
>  		/* vblanks work again, re-enable pipe CRC. */
> @@ -13990,7 +14127,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	 */
>  	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
>  						    new_crtc_state, i) {
> -		if (!needs_modeset(new_crtc_state))
> +		if (!needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner_slave)
>  			continue;
>  
>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> @@ -14000,6 +14137,19 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  						      old_crtc_state,
>  						      new_crtc_state,
>  						      crtc);
> +
> +		if (old_crtc_state->bigjoiner) {
> +			struct intel_crtc *slave = old_crtc_state->bigjoiner_linked_crtc;
> +			struct intel_crtc_state *old_slave_crtc_state =
> +				intel_atomic_get_crtc_state(&state->base, slave);
> +			struct intel_crtc_state *new_slave_crtc_state =
> +				intel_atomic_get_crtc_state(&state->base, slave);
> +
> +			intel_old_crtc_state_disables(state,
> +						      old_slave_crtc_state,
> +						      new_slave_crtc_state,
> +						      slave);
> +		}
>  	}
>  }
>  
> @@ -16433,7 +16583,7 @@ int intel_modeset_init(struct drm_device *dev)
>  	for_each_intel_crtc(dev, crtc) {
>  		struct intel_initial_plane_config plane_config = {};
>  
> -		if (!crtc->active)
> +		if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
>  			continue;
>  
>  		/*
> @@ -16923,7 +17073,17 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			crtc_state = to_intel_crtc_state(crtc->base.state);
>  
>  			encoder->base.crtc = &crtc->base;
> -			encoder->get_config(encoder, crtc_state);
> +			intel_encoder_get_config(encoder, crtc_state);
> +
> +			/* read out to slave crtc as well for bigjoiner */
> +			if (crtc_state->bigjoiner) {
> +				/* encoder should read be linked to bigjoiner master */
> +				WARN_ON(crtc_state->bigjoiner_slave);
> +
> +				crtc = crtc_state->bigjoiner_linked_crtc;
> +				crtc_state = to_intel_crtc_state(crtc->base.state);
> +				intel_encoder_get_config(encoder, crtc_state);
> +			}
>  		} else {
>  			encoder->base.crtc = NULL;
>  		}
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index dd0329a4b9ff..7e06c61447e6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -786,6 +786,7 @@ struct intel_crtc_state {
>  	 * accordingly.
>  	 */
>  #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS	(1<<0) /* unreliable sync mode.flags */
> +#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE	(1<<1) /* bigjoiner slave, partial readout */
>  	unsigned long quirks;
>  
>  	unsigned fb_bits; /* framebuffers to flip */
> @@ -1572,4 +1573,20 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>  	return i915_ggtt_offset(state->vma);
>  }
>  
> +static inline bool
> +intel_crtc_supports_dsc(const struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);
> +
> +	/* On TGL, DSC is supported on all Pipes */
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		return true;
> +
> +	if (INTEL_GEN(dev_priv) >= 10 &&
> +	    pipe_config->cpu_transcoder != TRANSCODER_A)
> +		return true;
> +
> +	return false;
> +}
> +
>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3d487ce16151..234be1c31958 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1907,22 +1907,6 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
>  		drm_dp_sink_supports_fec(intel_dp->fec_capable);
>  }
>  
> -static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
> -					 const struct intel_crtc_state *pipe_config)
> -{
> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> -
> -	/* On TGL, DSC is supported on all Pipes */
> -	if (INTEL_GEN(dev_priv) >= 12)
> -		return true;
> -
> -	if (INTEL_GEN(dev_priv) >= 10 &&
> -	    pipe_config->cpu_transcoder != TRANSCODER_A)
> -		return true;
> -
> -	return false;
> -}
> -
>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>  				  const struct intel_crtc_state *pipe_config)
>  {
> @@ -1930,7 +1914,7 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>  	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
>  		return false;
>  
> -	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
> +	return intel_crtc_supports_dsc(pipe_config) &&
>  		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
> index 38c181499505..11d4da9734a0 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -480,11 +480,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
>  }
>  
> -static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
> -						const struct intel_crtc_state *crtc_state)
> +static void intel_configure_pps_for_dsc_encoder(const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> @@ -494,6 +493,9 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
>  	u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1;
>  	int i = 0;
>  
> +	if (crtc_state->bigjoiner)
> +		num_vdsc_instances *= 2;
> +
>  	/* Populate PICTURE_PARAMETER_SET_0 registers */
>  	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
>  		DSC_VER_MIN_SHIFT |
> @@ -899,74 +901,104 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
>  					sizeof(dp_dsc_pps_sdp));
>  }
>  
> +static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
> +{
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +
> +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
> +		return DSS_CTL1;
> +
> +	return ICL_PIPE_DSS_CTL1(pipe);
> +}
> +
> +static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
> +{
> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> +
> +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
> +		return DSS_CTL2;
> +
> +	return ICL_PIPE_DSS_CTL2(pipe);
> +}
> +
>  void intel_dsc_enable(struct intel_encoder *encoder,
>  		      const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>  	u32 dss_ctl1_val = 0;
>  	u32 dss_ctl2_val = 0;
>  
>  	if (!crtc_state->dsc_params.compression_enable)
>  		return;
>  
> -	/* Enable Power wells for VDSC/joining */
> -	intel_display_power_get(dev_priv,
> -				intel_dsc_power_domain(crtc_state));
> +	intel_configure_pps_for_dsc_encoder(crtc_state);
>  
> -	intel_configure_pps_for_dsc_encoder(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner_slave)
> +		intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
>  
> -	intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
> -
> -	if (crtc_state->cpu_transcoder == TRANSCODER_EDP) {
> -		dss_ctl1_reg = DSS_CTL1;
> -		dss_ctl2_reg = DSS_CTL2;
> -	} else {
> -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
> -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
> -	}
>  	dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
>  	if (crtc_state->dsc_params.dsc_split) {
>  		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
>  		dss_ctl1_val |= JOINER_ENABLE;
>  	}
> -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
> -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
> +	if (crtc_state->bigjoiner) {
> +		dss_ctl1_val |= BIG_JOINER_ENABLE;
> +		if (!crtc_state->bigjoiner_slave)
> +			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
> +	}
> +	I915_WRITE(dss_ctl1_reg(crtc_state), dss_ctl1_val);
> +	I915_WRITE(dss_ctl2_reg(crtc_state), dss_ctl2_val);
>  }
>  
>  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	enum pipe pipe = crtc->pipe;
> -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> -	u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
>  
>  	if (!old_crtc_state->dsc_params.compression_enable)
>  		return;
>  
> -	if (old_crtc_state->cpu_transcoder == TRANSCODER_EDP) {
> -		dss_ctl1_reg = DSS_CTL1;
> -		dss_ctl2_reg = DSS_CTL2;
> -	} else {
> -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
> -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
> +	I915_WRITE(dss_ctl1_reg(old_crtc_state), 0);
> +	I915_WRITE(dss_ctl2_reg(old_crtc_state), 0);
> +}
> +
> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
> +{
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	u32 dss_ctl1_val, dss_ctl2_val;
> +	intel_wakeref_t wakeref;
> +
> +	if (!intel_crtc_supports_dsc(crtc_state))
> +		return;
> +
> +	wakeref = intel_display_power_get_if_enabled(dev_priv, intel_dsc_power_domain(crtc_state));
> +	if (!wakeref)
> +		return;
> +
> +	dss_ctl1_val = I915_READ(dss_ctl1_reg(crtc_state));
> +	dss_ctl2_val = I915_READ(dss_ctl2_reg(crtc_state));
> +	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE)
> +		crtc_state->dsc_params.compression_enable = true;
> +
> +	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
> +		crtc_state->dsc_params.dsc_split = true;
> +
> +	if (dss_ctl1_val & BIG_JOINER_ENABLE) {
> +		crtc_state->bigjoiner = true;
> +
> +		if (!(dss_ctl1_val & MASTER_BIG_JOINER_ENABLE)) {
> +			crtc_state->bigjoiner_slave = true;
> +			if (!WARN_ON(crtc->pipe == PIPE_A))
> +				crtc_state->bigjoiner_linked_crtc =
> +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
> +		} else {
> +			if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
> +				crtc_state->bigjoiner_linked_crtc =
> +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
> +		}
>  	}
> -	dss_ctl1_val = I915_READ(dss_ctl1_reg);
> -	if (dss_ctl1_val & JOINER_ENABLE)
> -		dss_ctl1_val &= ~JOINER_ENABLE;
> -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
> -
> -	dss_ctl2_val = I915_READ(dss_ctl2_reg);
> -	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
> -	    dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
> -		dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
> -				  RIGHT_BRANCH_VDSC_ENABLE);
> -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
> -
> -	/* Disable Power wells for VDSC/joining */
> -	intel_display_power_put_unchecked(dev_priv,
> -					  intel_dsc_power_domain(old_crtc_state));
> +
> +	intel_display_power_put(dev_priv, intel_dsc_power_domain(crtc_state), wakeref);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
> index 90d3f6017fcb..569cf17402ba 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -15,6 +15,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
>  int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>  				struct intel_crtc_state *pipe_config);
> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
> +
>  enum intel_display_power_domain
>  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-20 11:42 ` [PATCH 16/23] drm/i915: Program planes in bigjoiner mode Maarten Lankhorst
@ 2019-09-26 13:06   ` Ville Syrjälä
  2019-09-26 15:50     ` Maarten Lankhorst
  0 siblings, 1 reply; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-26 13:06 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> Now that we can program planes from the update_slave callback, and
> we have done all fb pinning correctly, it's time to program those
> planes as well.
> 
> We use the update_slave callback as it allows us to use the
> separate states correctly.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
>  3 files changed, 57 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index cc088676f0a2..5db091e4ad6a 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>  	}
>  }
>  
> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> +					 struct intel_crtc *crtc)

This plane stuff is where things go very much off the rails IMO.
Planes should not have to know anything about bigjoiner. They should
just have their appropriate hw state and blindly bash it into the
hardware.

> +{
> +	struct intel_crtc_state *old_crtc_state =
> +		intel_atomic_get_old_crtc_state(state, crtc);
> +	struct intel_crtc_state *new_crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +	struct skl_ddb_entry entries_y[I915_MAX_PLANES];
> +	struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
> +	u32 update_mask = new_crtc_state->update_planes;
> +	struct intel_plane *plane;
> +
> +	memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_y));
> +	memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
> +
> +	while ((plane = skl_next_plane_to_commit(state, crtc,
> +						 entries_y, entries_uv,
> +						 &update_mask))) {
> +		struct intel_plane_state *new_plane_state =
> +			intel_atomic_get_new_plane_state(state, plane);
> +		const struct intel_plane_state *master_plane_state;
> +
> +		if (new_plane_state->base.visible) {
> +			master_plane_state =
> +				intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
> +
> +			intel_update_slave(plane, new_crtc_state,
> +					   master_plane_state, new_plane_state);
> +		} else if (new_plane_state->slave) {
> +			/*
> +			 * bigjoiner slave + planar slave.
> +			 * The correct sequence is to get from the planar slave to planar master,
> +			 * then to the master plane state for the master_plane_state.
> +			 */
> +
> +			struct intel_plane *linked = new_plane_state->linked_plane;
> +			const struct intel_plane_state *uv_plane_state =
> +				intel_atomic_get_new_plane_state(state, linked);
> +
> +			linked = uv_plane_state->bigjoiner_plane;
> +			master_plane_state =
> +				intel_atomic_get_new_plane_state(state, linked);
> +
> +			intel_update_slave(plane, new_crtc_state,
> +					   master_plane_state, new_plane_state);
> +		} else {
> +			intel_disable_plane(plane, new_crtc_state);
> +		}
> +	}
> +}
> +
>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
>  				struct intel_crtc *crtc)
>  {
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index 901a50e6e2d3..1cffda2b50b5 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -30,6 +30,8 @@ void intel_plane_free(struct intel_plane *plane);
>  struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
>  void intel_plane_destroy_state(struct drm_plane *plane,
>  			       struct drm_plane_state *state);
> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> +					 struct intel_crtc *crtc);
>  void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>  			       struct intel_crtc *crtc);
>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 06ceac4f1436..acb3c5974e99 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -14223,8 +14223,8 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  
>  	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>  
> -	if (new_crtc_state->bigjoiner)
> -		{/* Not supported yet */}
> +	if (new_crtc_state->bigjoiner_slave)
> +		icl_update_bigjoiner_planes_on_crtc(state, crtc);
>  	else if (INTEL_GEN(dev_priv) >= 9)
>  		skl_update_planes_on_crtc(state, crtc);
>  	else
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 13:06   ` Ville Syrjälä
@ 2019-09-26 15:50     ` Maarten Lankhorst
  2019-09-26 16:09       ` Ville Syrjälä
  0 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-26 15:50 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
>> Now that we can program planes from the update_slave callback, and
>> we have done all fb pinning correctly, it's time to program those
>> planes as well.
>>
>> We use the update_slave callback as it allows us to use the
>> separate states correctly.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
>>  3 files changed, 57 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> index cc088676f0a2..5db091e4ad6a 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>>  	}
>>  }
>>  
>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
>> +					 struct intel_crtc *crtc)
> This plane stuff is where things go very much off the rails IMO.
> Planes should not have to know anything about bigjoiner. They should
> just have their appropriate hw state and blindly bash it into the
> hardware.

We already need this for planar slave/master, what's the issue exactly?

We're using master_plane_state for all plane properties (fb/rotation/props) and plane_state for writing all state.

>> +{
>> +	struct intel_crtc_state *old_crtc_state =
>> +		intel_atomic_get_old_crtc_state(state, crtc);
>> +	struct intel_crtc_state *new_crtc_state =
>> +		intel_atomic_get_new_crtc_state(state, crtc);
>> +	struct skl_ddb_entry entries_y[I915_MAX_PLANES];
>> +	struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
>> +	u32 update_mask = new_crtc_state->update_planes;
>> +	struct intel_plane *plane;
>> +
>> +	memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
>> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_y));
>> +	memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
>> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
>> +
>> +	while ((plane = skl_next_plane_to_commit(state, crtc,
>> +						 entries_y, entries_uv,
>> +						 &update_mask))) {
>> +		struct intel_plane_state *new_plane_state =
>> +			intel_atomic_get_new_plane_state(state, plane);
>> +		const struct intel_plane_state *master_plane_state;
>> +
>> +		if (new_plane_state->base.visible) {
>> +			master_plane_state =
>> +				intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
>> +
>> +			intel_update_slave(plane, new_crtc_state,
>> +					   master_plane_state, new_plane_state);
>> +		} else if (new_plane_state->slave) {
>> +			/*
>> +			 * bigjoiner slave + planar slave.
>> +			 * The correct sequence is to get from the planar slave to planar master,
>> +			 * then to the master plane state for the master_plane_state.
>> +			 */
>> +
>> +			struct intel_plane *linked = new_plane_state->linked_plane;
>> +			const struct intel_plane_state *uv_plane_state =
>> +				intel_atomic_get_new_plane_state(state, linked);
>> +
>> +			linked = uv_plane_state->bigjoiner_plane;
>> +			master_plane_state =
>> +				intel_atomic_get_new_plane_state(state, linked);
>> +
>> +			intel_update_slave(plane, new_crtc_state,
>> +					   master_plane_state, new_plane_state);
>> +		} else {
>> +			intel_disable_plane(plane, new_crtc_state);
>> +		}
>> +	}
>> +}
>> +
>>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
>>  				struct intel_crtc *crtc)
>>  {
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
>> index 901a50e6e2d3..1cffda2b50b5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
>> @@ -30,6 +30,8 @@ void intel_plane_free(struct intel_plane *plane);
>>  struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
>>  void intel_plane_destroy_state(struct drm_plane *plane,
>>  			       struct drm_plane_state *state);
>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
>> +					 struct intel_crtc *crtc);
>>  void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>>  			       struct intel_crtc *crtc);
>>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index 06ceac4f1436..acb3c5974e99 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -14223,8 +14223,8 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>>  
>>  	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>>  
>> -	if (new_crtc_state->bigjoiner)
>> -		{/* Not supported yet */}
>> +	if (new_crtc_state->bigjoiner_slave)
>> +		icl_update_bigjoiner_planes_on_crtc(state, crtc);
>>  	else if (INTEL_GEN(dev_priv) >= 9)
>>  		skl_update_planes_on_crtc(state, crtc);
>>  	else
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid()
  2019-09-25 22:09     ` Manasi Navare
@ 2019-09-26 16:00       ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-26 16:00 UTC (permalink / raw)
  To: Manasi Navare, Matt Roper; +Cc: intel-gfx

Op 26-09-2019 om 00:09 schreef Manasi Navare:
> On Tue, Sep 24, 2019 at 10:30:39PM -0700, Matt Roper wrote:
>> On Fri, Sep 20, 2019 at 01:42:22PM +0200, Maarten Lankhorst wrote:
>>> Small changes to intel_dp_mode_valid(), allow listing modes that
>>> can only be supported in the bigjoiner configuration, which is
>>> not supported yet.
>>>
>>> Also unexport a few functions only used internally in intel_dp.c
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>> ---
>>>  drivers/gpu/drm/i915/display/intel_dp.c | 98 +++++++++++++++++++------
>>>  1 file changed, 75 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>>> index 2fceb71f7f70..046e1662d1e3 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>>> @@ -247,7 +247,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>>>  }
>>>  
>>>  static int
>>> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
>>> +intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
>>>  {
>>>  	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>>>  	struct intel_encoder *encoder = &intel_dig_port->base;
>>> @@ -257,6 +257,9 @@ intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
>>>  
>>>  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
>>>  
>>> +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11)
>>> +		max_dotclk *= 2;
>>> +
> Since here we allow the big joiner for >=11 (ICL+), we need to update the
> plane_mode_valid check to ensure that we allow the 8K mode only for TGL+
> else with big joiner enabled on ICL we will enable it on ICL which is not permitted (not POR)

Should we decrease hdisplay_max to 5120 then for < gen12?

intel_mode_valid() currently allows the full mode.

>
>
>> Should we be checking if the specific pipe can do big joiner on the
>> platform (gen11 vs gen12 differences) and also omitting eDP from
>> consideration?
>>
>>
>>>  	if (type != DP_DS_PORT_TYPE_VGA)
>>>  		return max_dotclk;
>>>  
>>> @@ -505,8 +508,10 @@ u32 intel_dp_fec_to_mode_clock(u32 fec_clock)
>>>  		       1000000U);
>>>  }
>>>  
>>> -static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>>> -				       u32 mode_clock, u32 mode_hdisplay)
>>> +static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *dev_priv,
>>> +				       u32 link_clock, u32 lane_count,
>>> +				       u32 mode_clock, u32 mode_hdisplay,
>>> +				       bool bigjoiner)
>>>  {
>>>  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
>>>  	int i;
>>> @@ -523,6 +528,10 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>>>  
>>>  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
>>>  	max_bpp_small_joiner_ram = DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER / mode_hdisplay;
>>> +
>>> +	if (bigjoiner)
>>> +		max_bpp_small_joiner_ram *= 2;
>>> +
>> This change is correct, but while confirming in the bspec I noticed that
>> we may have the wrong DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER value for
>> gen11+.  It indicates 6144 for GLK, CNL, but 7680 for ICL+ (and double
>> that to 15360 when using big joiner).
>>
>> Bspec: 20388
>> Bspec: 49259
> @Matt, the 7680 is in bytes which translates to 61440 bits and thats what
> we are using, see the #DP_DSC_MAX_SMALL_JOINER_RAM_BUFFER
>
> and then its double for big joiner, so this is correct
>
>>>  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
>>>  
>>>  	/*
>>> @@ -531,6 +540,15 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>>>  	 */
>>>  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
>>>  
>>> +	if (bigjoiner) {
>>> +		u32 max_bpp_bigjoiner =
>>> +			dev_priv->max_cdclk_freq * 48 /
>>> +			intel_dp_mode_to_fec_clock(mode_clock);
>> Minor nitpick, but just to match the bspec (PPC * CDCLK * 24 bits /
>> pixel clock), I'd keep the 2 PPC and 24 bit factors separate here.
>>
> Yes I agree her with Matt that we shd keep the 2ppc separate just to match bspec
>  
>>> +
>>> +		DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner);
>>> +		bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner);
>>> +	}
>>> +
>>>  	/* Error out if the max bpp is less than smallest allowed valid bpp */
>>>  	if (bits_per_pixel < valid_dsc_bpp[0]) {
>>>  		DRM_DEBUG_KMS("Unsupported BPP %u, min %u\n",
>>> @@ -553,7 +571,8 @@ static u16 intel_dp_dsc_get_output_bpp(u32 link_clock, u32 lane_count,
>>>  }
>>>  
>>>  static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
>>> -				       int mode_clock, int mode_hdisplay)
>>> +				       int mode_clock, int mode_hdisplay,
>>> +				       bool bigjoiner)
>>>  {
>>>  	u8 min_slice_count, i;
>>>  	int max_slice_width;
>>> @@ -578,12 +597,20 @@ static u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
>>>  
>>>  	/* Find the closest match to the valid slice count values */
>>>  	for (i = 0; i < ARRAY_SIZE(valid_dsc_slicecount); i++) {
>>> -		if (valid_dsc_slicecount[i] >
>>> -		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
>>> -						    false))
>>> +		u8 test_slice_count = bigjoiner ?
>>> +			2 * valid_dsc_slicecount[i] :
>>> +			valid_dsc_slicecount[i];
>>> +
>>> +		if (test_slice_count >
>>> +		    drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
>>>  			break;
>>> -		if (min_slice_count  <= valid_dsc_slicecount[i])
>>> -			return valid_dsc_slicecount[i];
>>> +
>>> +		/* big joiner needs small joiner to be enabled */
>>> +		if (bigjoiner && test_slice_count < 4)
>>> +			continue;
>>> +
>>> +		if (min_slice_count <= test_slice_count)
>>> +			return test_slice_count;
>>>  	}
>>>  
>>>  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
>>> @@ -603,11 +630,15 @@ intel_dp_mode_valid(struct drm_connector *connector,
>>>  	int max_dotclk;
>>>  	u16 dsc_max_output_bpp = 0;
>>>  	u8 dsc_slice_count = 0;
>>> +	bool dsc = false, bigjoiner = false;
>>>  
>>>  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
>>>  		return MODE_NO_DBLESCAN;
>>>  
>>> -	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp);
>>> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
>>> +		return MODE_H_ILLEGAL;
>>> +
>>> +	max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, false);
>>>  
>>>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>>>  		if (mode->hdisplay > fixed_mode->hdisplay)
>>> @@ -619,6 +650,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
>>>  		target_clock = fixed_mode->clock;
>>>  	}
>>>  
>>> +	if (mode->clock < 10000)
>>> +		return MODE_CLOCK_LOW;
>>> +
>>> +	if (target_clock > max_dotclk) {
>>> +		max_dotclk = intel_dp_downstream_max_dotclock(intel_dp, true);
>>> +
>>> +		if (target_clock > max_dotclk)
>>> +			return MODE_CLOCK_HIGH;
>>> +
>>> +		bigjoiner = true;
>>> +	}
>>> +
>>>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>>>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>>>  
>>> @@ -639,26 +682,32 @@ intel_dp_mode_valid(struct drm_connector *connector,
>>>  								true);
>>>  		} else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
>>>  			dsc_max_output_bpp =
>>> -				intel_dp_dsc_get_output_bpp(max_link_clock,
>>> +				intel_dp_dsc_get_output_bpp(dev_priv,
>>> +							    max_link_clock,
>>>  							    max_lanes,
>>>  							    target_clock,
>>> -							    mode->hdisplay) >> 4;
>>> +							    mode->hdisplay,
>>> +							    bigjoiner) >> 4;
>>>  			dsc_slice_count =
>>>  				intel_dp_dsc_get_slice_count(intel_dp,
>>>  							     target_clock,
>>> -							     mode->hdisplay);
>>> +							     mode->hdisplay,
>>> +							     bigjoiner);
>>>  		}
>>> +
>>> +		dsc = dsc_max_output_bpp && dsc_slice_count;
>>>  	}
>>>  
>>> -	if ((mode_rate > max_rate && !(dsc_max_output_bpp && dsc_slice_count)) ||
>>> -	    target_clock > max_dotclk)
>>> +	/* big joiner configuration needs DSC */
>>> +	if (bigjoiner && !dsc) {
>>> +		DRM_DEBUG_KMS("Link clock needs bigjoiner, but DSC or FEC not available\n");
>>>  		return MODE_CLOCK_HIGH;
>>> +	}
>> Somewhere in this function we probably also need to make sure that the
>> big joiner is available on the pipe and that we're not using eDP.
>>
> Yes I agree we need to check that we allow big joine only for B and C for ICL and then
> all pipes for TGL+ and not allow for eDP

Yeah, I only allow for mode_valid() to succeed with eDP, will fix that with a check.

bigjoiner is not allowed on pipe A through intel_dp_source_supports_dsc, pipe A -> it didn't need an explicit check.

>> Matt
>>
>>>  
>>> -	if (mode->clock < 10000)
>>> -		return MODE_CLOCK_LOW;
>>> -
>>> -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
>>> -		return MODE_H_ILLEGAL;
>>> +	if (mode_rate > max_rate && !dsc) {
>>> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
>>> +		return MODE_CLOCK_HIGH;
>>> +	}
>>>  
>>>  	return intel_mode_valid_max_plane_size(dev_priv, mode);
>>>  }
>>> @@ -2068,14 +2117,17 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>>  		u8 dsc_dp_slice_count;
>>>  
>>>  		dsc_max_output_bpp =
>>> -			intel_dp_dsc_get_output_bpp(pipe_config->port_clock,
>>> +			intel_dp_dsc_get_output_bpp(dev_priv,
>>> +						    pipe_config->port_clock,
>>>  						    pipe_config->lane_count,
>>>  						    adjusted_mode->crtc_clock,
>>> -						    adjusted_mode->crtc_hdisplay);
>>> +						    adjusted_mode->crtc_hdisplay,
>>> +						    false);
>>>  		dsc_dp_slice_count =
>>>  			intel_dp_dsc_get_slice_count(intel_dp,
>>>  						     adjusted_mode->crtc_clock,
>>> -						     adjusted_mode->crtc_hdisplay);
>>> +						     adjusted_mode->crtc_hdisplay,
>>> +						     false);
>>>  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
>>>  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
>>>  			return -EINVAL;
>>> -- 
>>> 2.20.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> -- 
>> Matt Roper
>> Graphics Software Engineer
>> VTT-OSGC Platform Enablement
>> Intel Corporation
>> (916) 356-2795
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 15:50     ` Maarten Lankhorst
@ 2019-09-26 16:09       ` Ville Syrjälä
  2019-09-26 16:13         ` Maarten Lankhorst
  2019-09-26 19:11         ` Ville Syrjälä
  0 siblings, 2 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-26 16:09 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> > On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> >> Now that we can program planes from the update_slave callback, and
> >> we have done all fb pinning correctly, it's time to program those
> >> planes as well.
> >>
> >> We use the update_slave callback as it allows us to use the
> >> separate states correctly.
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
> >>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
> >>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
> >>  3 files changed, 57 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >> index cc088676f0a2..5db091e4ad6a 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> >>  	}
> >>  }
> >>  
> >> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> >> +					 struct intel_crtc *crtc)
> > This plane stuff is where things go very much off the rails IMO.
> > Planes should not have to know anything about bigjoiner. They should
> > just have their appropriate hw state and blindly bash it into the
> > hardware.
> 
> We already need this for planar slave/master, what's the issue exactly?

That already is too fragile. I don't want this spreading all over
the driver and coupling everything to the bigjoiner logic.

Here's a crude idea how I think we might avoid this:
git://github.com/vsyrjala/linux.git uapi_hw_state_split

But I didn't dare boot it yet...

> 
> We're using master_plane_state for all plane properties (fb/rotation/props) and plane_state for writing all state.
> 
> >> +{
> >> +	struct intel_crtc_state *old_crtc_state =
> >> +		intel_atomic_get_old_crtc_state(state, crtc);
> >> +	struct intel_crtc_state *new_crtc_state =
> >> +		intel_atomic_get_new_crtc_state(state, crtc);
> >> +	struct skl_ddb_entry entries_y[I915_MAX_PLANES];
> >> +	struct skl_ddb_entry entries_uv[I915_MAX_PLANES];
> >> +	u32 update_mask = new_crtc_state->update_planes;
> >> +	struct intel_plane *plane;
> >> +
> >> +	memcpy(entries_y, old_crtc_state->wm.skl.plane_ddb_y,
> >> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_y));
> >> +	memcpy(entries_uv, old_crtc_state->wm.skl.plane_ddb_uv,
> >> +	       sizeof(old_crtc_state->wm.skl.plane_ddb_uv));
> >> +
> >> +	while ((plane = skl_next_plane_to_commit(state, crtc,
> >> +						 entries_y, entries_uv,
> >> +						 &update_mask))) {
> >> +		struct intel_plane_state *new_plane_state =
> >> +			intel_atomic_get_new_plane_state(state, plane);
> >> +		const struct intel_plane_state *master_plane_state;
> >> +
> >> +		if (new_plane_state->base.visible) {
> >> +			master_plane_state =
> >> +				intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
> >> +
> >> +			intel_update_slave(plane, new_crtc_state,
> >> +					   master_plane_state, new_plane_state);
> >> +		} else if (new_plane_state->slave) {
> >> +			/*
> >> +			 * bigjoiner slave + planar slave.
> >> +			 * The correct sequence is to get from the planar slave to planar master,
> >> +			 * then to the master plane state for the master_plane_state.
> >> +			 */
> >> +
> >> +			struct intel_plane *linked = new_plane_state->linked_plane;
> >> +			const struct intel_plane_state *uv_plane_state =
> >> +				intel_atomic_get_new_plane_state(state, linked);
> >> +
> >> +			linked = uv_plane_state->bigjoiner_plane;
> >> +			master_plane_state =
> >> +				intel_atomic_get_new_plane_state(state, linked);
> >> +
> >> +			intel_update_slave(plane, new_crtc_state,
> >> +					   master_plane_state, new_plane_state);
> >> +		} else {
> >> +			intel_disable_plane(plane, new_crtc_state);
> >> +		}
> >> +	}
> >> +}
> >> +
> >>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
> >>  				struct intel_crtc *crtc)
> >>  {
> >> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> >> index 901a50e6e2d3..1cffda2b50b5 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> >> @@ -30,6 +30,8 @@ void intel_plane_free(struct intel_plane *plane);
> >>  struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane);
> >>  void intel_plane_destroy_state(struct drm_plane *plane,
> >>  			       struct drm_plane_state *state);
> >> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> >> +					 struct intel_crtc *crtc);
> >>  void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> >>  			       struct intel_crtc *crtc);
> >>  void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
> >> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> >> index 06ceac4f1436..acb3c5974e99 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> >> @@ -14223,8 +14223,8 @@ static void intel_update_crtc(struct intel_crtc *crtc,
> >>  
> >>  	commit_pipe_config(state, old_crtc_state, new_crtc_state);
> >>  
> >> -	if (new_crtc_state->bigjoiner)
> >> -		{/* Not supported yet */}
> >> +	if (new_crtc_state->bigjoiner_slave)
> >> +		icl_update_bigjoiner_planes_on_crtc(state, crtc);
> >>  	else if (INTEL_GEN(dev_priv) >= 9)
> >>  		skl_update_planes_on_crtc(state, crtc);
> >>  	else
> >> -- 
> >> 2.20.1
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 16:09       ` Ville Syrjälä
@ 2019-09-26 16:13         ` Maarten Lankhorst
  2019-09-26 16:26           ` Ville Syrjälä
  2019-09-26 19:11         ` Ville Syrjälä
  1 sibling, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-26 16:13 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 26-09-2019 om 18:09 schreef Ville Syrjälä:
> On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
>> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
>>> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
>>>> Now that we can program planes from the update_slave callback, and
>>>> we have done all fb pinning correctly, it's time to program those
>>>> planes as well.
>>>>
>>>> We use the update_slave callback as it allows us to use the
>>>> separate states correctly.
>>>>
>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>> ---
>>>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
>>>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
>>>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
>>>>  3 files changed, 57 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>> index cc088676f0a2..5db091e4ad6a 100644
>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>>>>  	}
>>>>  }
>>>>  
>>>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
>>>> +					 struct intel_crtc *crtc)
>>> This plane stuff is where things go very much off the rails IMO.
>>> Planes should not have to know anything about bigjoiner. They should
>>> just have their appropriate hw state and blindly bash it into the
>>> hardware.
>> We already need this for planar slave/master, what's the issue exactly?
> That already is too fragile. I don't want this spreading all over
> the driver and coupling everything to the bigjoiner logic.
>
> Here's a crude idea how I think we might avoid this:
> git://github.com/vsyrjala/linux.git uapi_hw_state_split
>
> But I didn't dare boot it yet...

So you basically want the same uapi/hw split for planes as we did with crtc's above?

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 16:13         ` Maarten Lankhorst
@ 2019-09-26 16:26           ` Ville Syrjälä
  0 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-26 16:26 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Sep 26, 2019 at 06:13:53PM +0200, Maarten Lankhorst wrote:
> Op 26-09-2019 om 18:09 schreef Ville Syrjälä:
> > On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
> >> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> >>> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> >>>> Now that we can program planes from the update_slave callback, and
> >>>> we have done all fb pinning correctly, it's time to program those
> >>>> planes as well.
> >>>>
> >>>> We use the update_slave callback as it allows us to use the
> >>>> separate states correctly.
> >>>>
> >>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >>>> ---
> >>>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
> >>>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
> >>>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
> >>>>  3 files changed, 57 insertions(+), 2 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>> index cc088676f0a2..5db091e4ad6a 100644
> >>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> >>>>  	}
> >>>>  }
> >>>>  
> >>>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> >>>> +					 struct intel_crtc *crtc)
> >>> This plane stuff is where things go very much off the rails IMO.
> >>> Planes should not have to know anything about bigjoiner. They should
> >>> just have their appropriate hw state and blindly bash it into the
> >>> hardware.
> >> We already need this for planar slave/master, what's the issue exactly?
> > That already is too fragile. I don't want this spreading all over
> > the driver and coupling everything to the bigjoiner logic.
> >
> > Here's a crude idea how I think we might avoid this:
> > git://github.com/vsyrjala/linux.git uapi_hw_state_split
> >
> > But I didn't dare boot it yet...
> 
> So you basically want the same uapi/hw split for planes as we did with crtc's above?

Yes. And ideally doing the uapi->hw copy in one specific spot as early
as possible, so that the rest of the driver can remain blissfully
ignonarant about all of this.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 16:09       ` Ville Syrjälä
  2019-09-26 16:13         ` Maarten Lankhorst
@ 2019-09-26 19:11         ` Ville Syrjälä
  2019-09-27  8:56           ` Maarten Lankhorst
  1 sibling, 1 reply; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-26 19:11 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Sep 26, 2019 at 07:09:22PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
> > Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> > > On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> > >> Now that we can program planes from the update_slave callback, and
> > >> we have done all fb pinning correctly, it's time to program those
> > >> planes as well.
> > >>
> > >> We use the update_slave callback as it allows us to use the
> > >> separate states correctly.
> > >>
> > >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > >> ---
> > >>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
> > >>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
> > >>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
> > >>  3 files changed, 57 insertions(+), 2 deletions(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >> index cc088676f0a2..5db091e4ad6a 100644
> > >> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> > >>  	}
> > >>  }
> > >>  
> > >> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> > >> +					 struct intel_crtc *crtc)
> > > This plane stuff is where things go very much off the rails IMO.
> > > Planes should not have to know anything about bigjoiner. They should
> > > just have their appropriate hw state and blindly bash it into the
> > > hardware.
> > 
> > We already need this for planar slave/master, what's the issue exactly?
> 
> That already is too fragile. I don't want this spreading all over
> the driver and coupling everything to the bigjoiner logic.
> 
> Here's a crude idea how I think we might avoid this:
> git://github.com/vsyrjala/linux.git uapi_hw_state_split
> 
> But I didn't dare boot it yet...

It took a handful extra fixes to get that to boot. But now I at least
get a picture on the screen instead of oopses.

Fixes pushed to the same branch.

Looks like still something going wrong with the cursor ioctl though.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences.
  2019-09-26  5:18   ` Matt Roper
@ 2019-09-26 23:54     ` Matt Roper
  2019-09-27  8:25       ` Maarten Lankhorst
  0 siblings, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-09-26 23:54 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Wed, Sep 25, 2019 at 10:18:19PM -0700, Matt Roper wrote:
> On Fri, Sep 20, 2019 at 01:42:24PM +0200, Maarten Lankhorst wrote:
> > Make vdsc work when no output is enabled. The big joiner needs VDSC
> > on the slave, so enable it and set the appropriate bits.
> > Also update timestamping constants, because slave crtc's are not
> > updated in drm_atomic_helper_update_legacy_modeset_state().
> > 
> > This should be enough to bring up CRTC's in a big joiner configuration,
> > without any plane configuration on the second pipe yet.
> > 
> > HOWEVER, we bring up the crtc's in the wrong order. We need to make
> > sure that the master crtc is brought up after the slave crtc, we
> > don't do that yet. This is done correctly later in this series.
> > 
> > The next steps are to add atomic commit, and make sure we enable and
> > update both master and slave in the correct order.
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> A couple minor comments inline below, but I didn't see any clear
> problems with this patch so
> 
> Acked-by: Matt Roper <matthew.d.roper@intel.com>
> 
> However there's a lot of pretty complicated changes here in areas that
> I'm only vaguely familiar with, so I think it would be good if someone
> like Manasi who's more familiar with this area of the code could look it
> over.
> 
> 
> Matt
> 
> 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |  55 ++-
> >  drivers/gpu/drm/i915/display/intel_display.c  | 402 ++++++++++++------
> >  .../drm/i915/display/intel_display_types.h    |  17 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |  18 +-
> >  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
> >  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
> >  6 files changed, 418 insertions(+), 198 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index c775fd205915..a26155f90261 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -1694,6 +1694,13 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
> >  		skl_ddi_clock_get(encoder, pipe_config);
> >  	else if (INTEL_GEN(dev_priv) <= 8)
> >  		hsw_ddi_clock_get(encoder, pipe_config);
> > +
> > +	if (pipe_config->bigjoiner) {
> > +		pipe_config->hw.transcoder_mode.crtc_clock =
> > +			pipe_config->hw.adjusted_mode.crtc_clock;
> > +
> > +		pipe_config->hw.adjusted_mode.crtc_clock /= 2;
> > +	}
> >  }
> >  
> >  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
> > @@ -2176,13 +2183,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
> >  	    intel_phy_is_tc(dev_priv, phy))
> >  		intel_display_power_get(dev_priv,
> >  					intel_ddi_main_link_aux_domain(dig_port));
> > -
> > -	/*
> > -	 * VDSC power is needed when DSC is enabled
> > -	 */
> > -	if (crtc_state->dsc_params.compression_enable)
> > -		intel_display_power_get(dev_priv,
> > -					intel_dsc_power_domain(crtc_state));
> >  }
> >  
> >  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
> > @@ -3290,7 +3290,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
> >  
> >  	/* 7.l */
> >  	intel_ddi_enable_fec(encoder, crtc_state);
> > -	intel_dsc_enable(encoder, crtc_state);
> > +	if (!crtc_state->bigjoiner)
> > +		intel_dsc_enable(encoder, crtc_state);
> >  }
> >  
> >  static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
> > @@ -3361,7 +3362,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
> >  	if (!is_mst)
> >  		intel_ddi_enable_pipe_clock(crtc_state);
> >  
> > -	intel_dsc_enable(encoder, crtc_state);
> > +	if (!crtc_state->bigjoiner)
> > +		intel_dsc_enable(encoder, crtc_state);
> >  }
> >  
> >  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
> > @@ -3972,19 +3974,18 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
> >  		crtc_state->min_voltage_level = 2;
> >  }
> >  
> > -void intel_ddi_get_config(struct intel_encoder *encoder,
> > -			  struct intel_crtc_state *pipe_config)
> > +static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
> > +				    struct intel_crtc_state *pipe_config)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >  	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
> >  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> >  	u32 temp, flags = 0;
> >  
> > -	/* XXX: DSI transcoder paranoia */
> > -	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> > +	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> > +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
> >  		return;
> >  
> > -	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
> >  	if (temp & TRANS_DDI_PHSYNC)
> >  		flags |= DRM_MODE_FLAG_PHSYNC;
> >  	else
> > @@ -4066,6 +4067,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  	default:
> >  		break;
> >  	}
> > +}
> > +
> > +void intel_ddi_get_config(struct intel_encoder *encoder,
> > +			  struct intel_crtc_state *pipe_config)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > +
> > +	/* XXX: DSI transcoder paranoia */
> > +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> > +		return;
> > +
> > +	intel_ddi_read_func_ctl(encoder, pipe_config);
> > +	if (pipe_config->bigjoiner_slave) {
> > +		/* read out pipe settings from master */
> > +		enum transcoder save = pipe_config->cpu_transcoder;
> > +
> > +		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
> > +		WARN_ON(pipe_config->output_types);
> > +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
> > +		intel_ddi_read_func_ctl(encoder, pipe_config);
> > +		pipe_config->cpu_transcoder = save;
> > +	}
> >  
> >  	pipe_config->has_audio =
> >  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
> > @@ -4090,7 +4114,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
> >  	}
> >  
> > -	intel_ddi_clock_get(encoder, pipe_config);
> > +	if (!pipe_config->bigjoiner_slave)
> > +		intel_ddi_clock_get(encoder, pipe_config);
> >  
> >  	if (IS_GEN9_LP(dev_priv))
> >  		pipe_config->lane_lat_optim_mask =
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 143d531c4c81..8c08c4914c9b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -6449,6 +6449,45 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
> >  	I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);
> >  }
> >  
> > +static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
> > +					 struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_crtc *master = to_intel_crtc(crtc_state->uapi.crtc);
> > +	struct intel_crtc_state *master_crtc_state;
> > +	struct drm_connector_state *conn_state;
> > +	struct drm_connector *conn;
> > +	struct intel_encoder *encoder = NULL;
> > +	int i;
> > +
> > +	if (crtc_state->bigjoiner_slave)
> > +		master = crtc_state->bigjoiner_linked_crtc;
> > +
> > +	master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
> > +
> > +	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
> > +		if (conn_state->crtc != &master->base)
> > +			continue;
> > +
> > +		encoder = to_intel_encoder(conn_state->best_encoder);
> > +		break;
> > +	}
> > +
> > +	if (!crtc_state->bigjoiner_slave) {
> > +		/* need to enable VDSC, which we skipped in pre-enable */
> > +		intel_dsc_enable(encoder, crtc_state);
> > +	} else {
> > +		/*
> > +		 * Enable sequence steps 1-7 on bigjoiner master
> > +		 */
> 
> I'd extend this comment to indicate that we do this on the slave (using
> the master's state, transcoder, and DDI) because the [will] program the
> slave CRTC before the master.
> 
> > +		intel_encoders_pre_pll_enable(master, master_crtc_state, state);
> > +		intel_enable_shared_dpll(master_crtc_state);
> > +		intel_encoders_pre_enable(master, master_crtc_state, state);
> > +
> > +		/* and DSC on slave */
> > +		intel_dsc_enable(NULL, crtc_state);
> > +	}
> > +}
> > +
> >  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
> >  				struct intel_atomic_state *state)
> >  {
> > @@ -6462,37 +6501,38 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
> >  	if (WARN_ON(intel_crtc->active))
> >  		return;
> >  
> > -	intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
> > +	if (!pipe_config->bigjoiner) {
> > +		intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
> >  
> > -	if (pipe_config->shared_dpll)
> > -		intel_enable_shared_dpll(pipe_config);
> > +		if (pipe_config->shared_dpll)
> > +			intel_enable_shared_dpll(pipe_config);
> >  
> > -	intel_encoders_pre_enable(intel_crtc, pipe_config, state);
> > +		intel_encoders_pre_enable(intel_crtc, pipe_config, state);
> > +	} else {
> > +		icl_ddi_bigjoiner_pre_enable(state, pipe_config);
> > +	}
> >  
> > -	if (intel_crtc_has_dp_encoder(pipe_config))
> > -		intel_dp_set_m_n(pipe_config, M1_N1);
> > +	intel_set_pipe_src_size(pipe_config);
> > +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> > +		bdw_set_pipemisc(pipe_config);
> >  
> > -	if (!transcoder_is_dsi(cpu_transcoder))
> > -		intel_set_pipe_timings(pipe_config);
> > +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> > +		if (intel_crtc_has_dp_encoder(pipe_config))
> > +			intel_dp_set_m_n(pipe_config, M1_N1);
> >  
> > -	intel_set_pipe_src_size(pipe_config);
> > +		intel_set_pipe_timings(pipe_config);
> >  
> > -	if (cpu_transcoder != TRANSCODER_EDP &&
> > -	    !transcoder_is_dsi(cpu_transcoder)) {
> > -		I915_WRITE(PIPE_MULT(cpu_transcoder),
> > -			   pipe_config->pixel_multiplier - 1);
> > -	}
> > +		if (cpu_transcoder != TRANSCODER_EDP)
> > +			I915_WRITE(PIPE_MULT(cpu_transcoder),
> > +				  pipe_config->pixel_multiplier - 1);
> >  
> > -	if (pipe_config->has_pch_encoder) {
> > -		intel_cpu_transcoder_set_m_n(pipe_config,
> > -					     &pipe_config->fdi_m_n, NULL);
> > -	}
> > +		if (pipe_config->has_pch_encoder) {
> > +			intel_cpu_transcoder_set_m_n(pipe_config,
> > +						    &pipe_config->fdi_m_n, NULL);
> > +		}
> >  
> > -	if (!transcoder_is_dsi(cpu_transcoder))
> >  		haswell_set_pipeconf(pipe_config);
> > -
> > -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> > -		bdw_set_pipemisc(pipe_config);
> > +	}
> >  
> >  	intel_crtc->active = true;
> >  
> > @@ -6520,9 +6560,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
> >  	if (INTEL_GEN(dev_priv) >= 11)
> >  		icl_set_pipe_chicken(intel_crtc);
> >  
> > -	intel_ddi_set_pipe_settings(pipe_config);
> > -	if (!transcoder_is_dsi(cpu_transcoder))
> > +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> > +		intel_ddi_set_pipe_settings(pipe_config);
> > +
> >  		intel_ddi_enable_transcoder_func(pipe_config);
> > +	}
> >  
> >  	if (dev_priv->display.initial_watermarks != NULL)
> >  		dev_priv->display.initial_watermarks(state, pipe_config);
> > @@ -6531,8 +6573,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
> >  		icl_pipe_mbus_enable(intel_crtc);
> >  
> >  	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
> > -	if (!transcoder_is_dsi(cpu_transcoder))
> > +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
> >  		intel_enable_pipe(pipe_config);
> > +	else
> > +		trace_intel_pipe_enable(intel_crtc);
> >  
> >  	if (pipe_config->has_pch_encoder)
> >  		lpt_pch_enable(state, pipe_config);
> > @@ -6663,9 +6707,27 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
> >  	else
> >  		ironlake_pfit_disable(old_crtc_state);
> >  
> > -	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
> > +	if (old_crtc_state->bigjoiner) {
> > +		struct intel_crtc *master;
> > +		struct intel_crtc_state *master_crtc_state;
> >  
> > -	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
> > +		/* ports are disabled from the slave, after it deconfigures */
> > +		if (!old_crtc_state->bigjoiner_slave)
> > +			return;
> > +
> > +		master = old_crtc_state->bigjoiner_linked_crtc;
> > +		master_crtc_state = intel_atomic_get_old_crtc_state(state, master);
> > +
> > +		intel_ddi_disable_pipe_clock(old_crtc_state);
> > +
> > +		/* disable ports on the master crtc */
> > +		intel_encoders_post_disable(master, master_crtc_state, state);
> > +		intel_encoders_post_pll_disable(master, master_crtc_state, state);
> > +	} else {
> > +		intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
> > +
> > +		intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
> > +	}
> >  }
> >  
> >  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
> > @@ -6829,6 +6891,9 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
> >  	if (crtc_state->shared_dpll)
> >  		mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE);
> >  
> > +	if (crtc_state->dsc_params.compression_enable)
> > +		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
> > +
> >  	return mask;
> >  }
> >  
> > @@ -7417,6 +7482,19 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
> >  	return pixel_rate;
> >  }
> >  
> > +static void intel_encoder_get_config(struct intel_encoder *encoder,
> > +				     struct intel_crtc_state *crtc_state)
> > +{
> > +	encoder->get_config(encoder, crtc_state);
> > +
> > +	crtc_state->hw.transcoder_mode.flags = crtc_state->hw.adjusted_mode.flags;
> > +
> > +	/* if transcoder clock is not set, assume same as adjusted_mode clock */
> > +	if (!crtc_state->hw.transcoder_mode.crtc_clock)
> > +		crtc_state->hw.transcoder_mode.crtc_clock =
> > +			crtc_state->hw.adjusted_mode.crtc_clock;
> > +}
> > +
> >  static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> > @@ -8265,6 +8343,24 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
> >  		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
> >  		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
> >  	}
> > +
> > +	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
> > +	if (pipe_config->bigjoiner) {
> > +		struct drm_display_mode *adjusted_mode =
> > +			&pipe_config->hw.adjusted_mode;
> > +
> > +		/*
> > +		  * transcoder is programmed to the full mode,
> > +		  * but pipje timings are half of the transcoder mode
> > +		  */
> > +		adjusted_mode->crtc_hdisplay /= 2;
> > +		adjusted_mode->crtc_hblank_start /= 2;
> > +		adjusted_mode->crtc_hblank_end /= 2;
> > +		adjusted_mode->crtc_hsync_start /= 2;
> > +		adjusted_mode->crtc_hsync_end /= 2;
> > +		adjusted_mode->crtc_htotal /= 2;
> > +		adjusted_mode->crtc_hskew /= 2;
> > +	}
> >  }
> >  
> >  static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > @@ -8285,20 +8381,22 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> >  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
> >  				 struct intel_crtc_state *pipe_config)
> >  {
> > -	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
> > -	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
> > -	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
> > -	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
> > +	struct drm_display_mode *hw_mode = &pipe_config->hw.transcoder_mode;
> >  
> > -	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> > -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> > -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> > -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
> > +	mode->hdisplay = hw_mode->crtc_hdisplay;
> > +	mode->htotal = hw_mode->crtc_htotal;
> > +	mode->hsync_start = hw_mode->crtc_hsync_start;
> > +	mode->hsync_end = hw_mode->crtc_hsync_end;
> >  
> > -	mode->flags = pipe_config->hw.adjusted_mode.flags;
> > +	mode->vdisplay = hw_mode->crtc_vdisplay;
> > +	mode->vtotal = hw_mode->crtc_vtotal;
> > +	mode->vsync_start = hw_mode->crtc_vsync_start;
> > +	mode->vsync_end = hw_mode->crtc_vsync_end;
> > +
> > +	mode->flags = hw_mode->flags;
> >  	mode->type = DRM_MODE_TYPE_DRIVER;
> >  
> > -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
> > +	mode->clock = hw_mode->crtc_clock;
> >  
> >  	mode->hsync = drm_mode_hsync(mode);
> >  	mode->vrefresh = drm_mode_vrefresh(mode);
> > @@ -10385,6 +10483,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
> >  	u32 tmp;
> >  
> >  	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
> > +	if (!(tmp & TRANS_DDI_FUNC_ENABLE))
> > +		return;
> >  
> >  	if (INTEL_GEN(dev_priv) >= 12)
> >  		port = TGL_TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp);
> > @@ -10455,11 +10555,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> >  		WARN_ON(active);
> >  		active = true;
> >  	}
> > +	intel_dsc_get_config(pipe_config);
> >  
> > -	if (!active)
> > -		goto out;
> > +	if (!active) {
> > +		/* bigjoiner slave doesn't enable transcoder */
> > +		if (!pipe_config->bigjoiner_slave)
> > +			goto out;
> > +
> > +		active = true;
> > +		pipe_config->pixel_multiplier = 1;
> >  
> > -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > +		/* we cannot read out most state, so don't bother.. */
> > +		pipe_config->quirks |= PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE;
> > +	} else if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> >  	    INTEL_GEN(dev_priv) >= 11) {
> >  		haswell_get_ddi_port_state(crtc, pipe_config);
> >  		intel_get_pipe_timings(crtc, pipe_config);
> > @@ -10513,7 +10621,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
> >  		}
> >  	}
> >  
> > -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > +	if (pipe_config->bigjoiner_slave) {
> > +		/* Cannot be read out as a slave, set to 0. */
> > +		pipe_config->pixel_multiplier = 0;
> > +	} else if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> >  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> >  		pipe_config->pixel_multiplier =
> >  			I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> > @@ -11468,7 +11579,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
> >  		return NULL;
> >  	}
> >  
> > -	encoder->get_config(encoder, crtc_state);
> > +	intel_encoder_get_config(encoder, crtc_state);
> >  
> >  	intel_mode_from_pipe_config(mode, crtc_state);
> >  
> > @@ -12285,9 +12396,11 @@ static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> >  
> >  static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> >  {
> > -	crtc_state->uapi.enable = crtc_state->hw.enable;
> > -	crtc_state->uapi.active = crtc_state->hw.active;
> > -	crtc_state->uapi.mode = crtc_state->hw.mode;
> > +	if (!crtc_state->bigjoiner_slave) {
> > +		crtc_state->uapi.enable = crtc_state->hw.enable;
> > +		crtc_state->uapi.active = crtc_state->hw.active;
> > +		crtc_state->uapi.mode = crtc_state->hw.mode;
> > +	}
> >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
> >  }
> >  
> > @@ -12318,6 +12431,7 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
> >  	crtc_state->hw.active = from_crtc_state->hw.active;
> >  	crtc_state->hw.mode = from_crtc_state->hw.mode;
> >  	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
> > +	crtc_state->hw.transcoder_mode = from_crtc_state->hw.transcoder_mode;
> >  
> >  	/* Some fixups */
> >  	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
> > @@ -12833,19 +12947,41 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  
> >  	PIPE_CONF_CHECK_X(output_types);
> >  
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
> > -
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
> > -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
> > +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
> > +		/* bigjoiner mode = transcoder mode / 2, for calculations */
> > +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
> > +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
> > +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
> > +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
> > +
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hdisplay);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_htotal);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_start);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_end);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_start);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_end);
> > +
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vdisplay);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vtotal);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_start);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_end);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_start);
> > +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_end);
> > +
> > +		PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> > +				      DRM_MODE_FLAG_INTERLACE);
> > +
> > +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
> > +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> > +					      DRM_MODE_FLAG_PHSYNC);
> > +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> > +					      DRM_MODE_FLAG_NHSYNC);
> > +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> > +					      DRM_MODE_FLAG_PVSYNC);
> > +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
> > +					      DRM_MODE_FLAG_NVSYNC);
> > +		}
> > +	}
> >  
> >  	PIPE_CONF_CHECK_I(pixel_multiplier);
> >  	PIPE_CONF_CHECK_I(output_format);
> > @@ -12857,24 +12993,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
> >  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
> >  	PIPE_CONF_CHECK_BOOL(has_infoframe);
> > -	PIPE_CONF_CHECK_BOOL(fec_enable);
> > +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
> > +		PIPE_CONF_CHECK_BOOL(fec_enable);
> >  
> >  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
> >  
> > -	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> > -			      DRM_MODE_FLAG_INTERLACE);
> > -
> > -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
> > -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> > -				      DRM_MODE_FLAG_PHSYNC);
> > -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> > -				      DRM_MODE_FLAG_NHSYNC);
> > -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> > -				      DRM_MODE_FLAG_PVSYNC);
> > -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
> > -				      DRM_MODE_FLAG_NVSYNC);
> > -	}
> > -
> >  	PIPE_CONF_CHECK_X(gmch_pfit.control);
> >  	/* pfit ratios are autocomputed by the hw on gen4+ */
> >  	if (INTEL_GEN(dev_priv) < 4)
> > @@ -12898,7 +13021,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  		}
> >  
> >  		PIPE_CONF_CHECK_I(scaler_state.scaler_id);
> > -		PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
> > +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
> > +			PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
> >  
> >  		PIPE_CONF_CHECK_X(gamma_mode);
> >  		if (IS_CHERRYVIEW(dev_priv))
> > @@ -12917,48 +13041,50 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  	PIPE_CONF_CHECK_BOOL(double_wide);
> >  
> >  	PIPE_CONF_CHECK_P(shared_dpll);
> > +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
> >  	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
> 
> Missing indent on this line?
> 
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.spll);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
> > -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
> > -
> > -	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
> > -	PIPE_CONF_CHECK_X(dsi_pll.div);
> > -
> > -	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
> > -		PIPE_CONF_CHECK_I(pipe_bpp);
> > -
> > -	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
> > -	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> > -
> > -	PIPE_CONF_CHECK_I(min_voltage_level);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.spll);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
> > +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
> > +
> > +		PIPE_CONF_CHECK_X(dsi_pll.ctrl);
> > +		PIPE_CONF_CHECK_X(dsi_pll.div);
> > +
> > +		if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
> > +			PIPE_CONF_CHECK_I(pipe_bpp);
> > +
> > +		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
> > +		PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
> > +
> > +		PIPE_CONF_CHECK_I(min_voltage_level);
> > +	}
> >  
> >  	PIPE_CONF_CHECK_X(infoframes.enable);
> >  	PIPE_CONF_CHECK_X(infoframes.gcp);
> > @@ -12967,6 +13093,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >  	PIPE_CONF_CHECK_INFOFRAME(hdmi);
> >  	PIPE_CONF_CHECK_INFOFRAME(drm);
> >  
> > +	PIPE_CONF_CHECK_BOOL(bigjoiner);
> > +	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
> > +	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
> > +	PIPE_CONF_CHECK_BOOL(dsc_params.compression_enable);
> > +	PIPE_CONF_CHECK_BOOL(dsc_params.dsc_split);
> > +
> >  #undef PIPE_CONF_CHECK_X
> >  #undef PIPE_CONF_CHECK_I
> >  #undef PIPE_CONF_CHECK_BOOL
> > @@ -13221,6 +13353,7 @@ verify_crtc_state(struct intel_crtc *crtc,
> >  	struct intel_encoder *encoder;
> >  	struct intel_crtc_state *pipe_config;
> >  	struct drm_atomic_state *state;
> > +	struct intel_crtc *master = crtc;
> >  	bool active;
> >  
> >  	state = old_crtc_state->uapi.state;
> > @@ -13250,7 +13383,10 @@ verify_crtc_state(struct intel_crtc *crtc,
> >  			"(expected %i, found %i)\n",
> >  			new_crtc_state->hw.active, crtc->active);
> >  
> > -	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
> > +	if (new_crtc_state->bigjoiner_slave)
> > +		master = new_crtc_state->bigjoiner_linked_crtc;
> > +
> > +	for_each_encoder_on_crtc(dev, &master->base, encoder) {
> >  		enum pipe pipe;
> >  
> >  		active = encoder->get_hw_state(encoder, &pipe);
> > @@ -13259,12 +13395,12 @@ verify_crtc_state(struct intel_crtc *crtc,
> >  				encoder->base.base.id, active,
> >  				new_crtc_state->hw.active);
> >  
> > -		I915_STATE_WARN(active && crtc->pipe != pipe,
> > +		I915_STATE_WARN(active && master->pipe != pipe,
> >  				"Encoder connected to wrong pipe %c\n",
> >  				pipe_name(pipe));
> >  
> >  		if (active)
> > -			encoder->get_config(encoder, pipe_config);
> > +			intel_encoder_get_config(encoder, pipe_config);
> >  	}
> >  
> >  	intel_crtc_compute_pixel_rate(pipe_config);
> > @@ -13906,6 +14042,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
> >  
> >  	if (modeset) {
> >  		update_scanline_offset(new_crtc_state);
> > +		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.transcoder_mode);
> >  		dev_priv->display.crtc_enable(new_crtc_state, state);
> >  
> >  		/* vblanks work again, re-enable pipe CRC. */
> > @@ -13990,7 +14127,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  	 */
> >  	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
> >  						    new_crtc_state, i) {
> > -		if (!needs_modeset(new_crtc_state))
> > +		if (!needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner_slave)
> >  			continue;
> >  
> >  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
> > @@ -14000,6 +14137,19 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> >  						      old_crtc_state,
> >  						      new_crtc_state,
> >  						      crtc);
> > +
> > +		if (old_crtc_state->bigjoiner) {
> > +			struct intel_crtc *slave = old_crtc_state->bigjoiner_linked_crtc;
> > +			struct intel_crtc_state *old_slave_crtc_state =
> > +				intel_atomic_get_crtc_state(&state->base, slave);
> > +			struct intel_crtc_state *new_slave_crtc_state =
> > +				intel_atomic_get_crtc_state(&state->base, slave);
> > +
> > +			intel_old_crtc_state_disables(state,
> > +						      old_slave_crtc_state,
> > +						      new_slave_crtc_state,
> > +						      slave);
> > +		}
> >  	}
> >  }
> >  
> > @@ -16433,7 +16583,7 @@ int intel_modeset_init(struct drm_device *dev)
> >  	for_each_intel_crtc(dev, crtc) {
> >  		struct intel_initial_plane_config plane_config = {};
> >  
> > -		if (!crtc->active)
> > +		if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
> >  			continue;
> >  
> >  		/*
> > @@ -16923,7 +17073,17 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  			crtc_state = to_intel_crtc_state(crtc->base.state);
> >  
> >  			encoder->base.crtc = &crtc->base;
> > -			encoder->get_config(encoder, crtc_state);
> > +			intel_encoder_get_config(encoder, crtc_state);
> > +
> > +			/* read out to slave crtc as well for bigjoiner */
> > +			if (crtc_state->bigjoiner) {
> > +				/* encoder should read be linked to bigjoiner master */
> > +				WARN_ON(crtc_state->bigjoiner_slave);
> > +
> > +				crtc = crtc_state->bigjoiner_linked_crtc;
> > +				crtc_state = to_intel_crtc_state(crtc->base.state);
> > +				intel_encoder_get_config(encoder, crtc_state);
> > +			}
> >  		} else {
> >  			encoder->base.crtc = NULL;
> >  		}
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index dd0329a4b9ff..7e06c61447e6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -786,6 +786,7 @@ struct intel_crtc_state {
> >  	 * accordingly.
> >  	 */
> >  #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS	(1<<0) /* unreliable sync mode.flags */
> > +#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE	(1<<1) /* bigjoiner slave, partial readout */
> >  	unsigned long quirks;
> >  
> >  	unsigned fb_bits; /* framebuffers to flip */
> > @@ -1572,4 +1573,20 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
> >  	return i915_ggtt_offset(state->vma);
> >  }
> >  
> > +static inline bool
> > +intel_crtc_supports_dsc(const struct intel_crtc_state *pipe_config)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);
> > +
> > +	/* On TGL, DSC is supported on all Pipes */
> > +	if (INTEL_GEN(dev_priv) >= 12)
> > +		return true;
> > +
> > +	if (INTEL_GEN(dev_priv) >= 10 &&
> > +	    pipe_config->cpu_transcoder != TRANSCODER_A)
> > +		return true;
> > +
> > +	return false;
> > +}
> > +
> >  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 3d487ce16151..234be1c31958 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -1907,22 +1907,6 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> >  		drm_dp_sink_supports_fec(intel_dp->fec_capable);
> >  }
> >  
> > -static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
> > -					 const struct intel_crtc_state *pipe_config)
> > -{
> > -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
> > -
> > -	/* On TGL, DSC is supported on all Pipes */
> > -	if (INTEL_GEN(dev_priv) >= 12)
> > -		return true;
> > -
> > -	if (INTEL_GEN(dev_priv) >= 10 &&
> > -	    pipe_config->cpu_transcoder != TRANSCODER_A)
> > -		return true;
> > -
> > -	return false;
> > -}
> > -
> >  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
> >  				  const struct intel_crtc_state *pipe_config)
> >  {
> > @@ -1930,7 +1914,7 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
> >  	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
> >  		return false;
> >  
> > -	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
> > +	return intel_crtc_supports_dsc(pipe_config) &&
> >  		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
> > index 38c181499505..11d4da9734a0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> > +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> > @@ -480,11 +480,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
> >  		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
> >  }
> >  
> > -static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
> > -						const struct intel_crtc_state *crtc_state)
> > +static void intel_configure_pps_for_dsc_encoder(const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >  	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
> >  	enum pipe pipe = crtc->pipe;
> >  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> > @@ -494,6 +493,9 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
> >  	u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1;
> >  	int i = 0;
> >  
> > +	if (crtc_state->bigjoiner)
> > +		num_vdsc_instances *= 2;
> > +
> >  	/* Populate PICTURE_PARAMETER_SET_0 registers */
> >  	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
> >  		DSC_VER_MIN_SHIFT |
> > @@ -899,74 +901,104 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
> >  					sizeof(dp_dsc_pps_sdp));
> >  }
> >  
> > +static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
> > +{
> > +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> > +
> > +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
> > +		return DSS_CTL1;
> > +
> > +	return ICL_PIPE_DSS_CTL1(pipe);
> > +}
> > +
> > +static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
> > +{
> > +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
> > +
> > +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
> > +		return DSS_CTL2;
> > +
> > +	return ICL_PIPE_DSS_CTL2(pipe);
> > +}
> > +
> >  void intel_dsc_enable(struct intel_encoder *encoder,
> >  		      const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > -	enum pipe pipe = crtc->pipe;
> > -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >  	u32 dss_ctl1_val = 0;
> >  	u32 dss_ctl2_val = 0;
> >  
> >  	if (!crtc_state->dsc_params.compression_enable)
> >  		return;
> >  
> > -	/* Enable Power wells for VDSC/joining */
> > -	intel_display_power_get(dev_priv,
> > -				intel_dsc_power_domain(crtc_state));
> > +	intel_configure_pps_for_dsc_encoder(crtc_state);
> >  
> > -	intel_configure_pps_for_dsc_encoder(encoder, crtc_state);
> > +	if (!crtc_state->bigjoiner_slave)
> > +		intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
> >  
> > -	intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
> > -
> > -	if (crtc_state->cpu_transcoder == TRANSCODER_EDP) {
> > -		dss_ctl1_reg = DSS_CTL1;
> > -		dss_ctl2_reg = DSS_CTL2;
> > -	} else {
> > -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
> > -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
> > -	}
> >  	dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
> >  	if (crtc_state->dsc_params.dsc_split) {
> >  		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
> >  		dss_ctl1_val |= JOINER_ENABLE;
> >  	}
> > -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
> > -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
> > +	if (crtc_state->bigjoiner) {
> > +		dss_ctl1_val |= BIG_JOINER_ENABLE;
> > +		if (!crtc_state->bigjoiner_slave)
> > +			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
> > +	}
> > +	I915_WRITE(dss_ctl1_reg(crtc_state), dss_ctl1_val);
> > +	I915_WRITE(dss_ctl2_reg(crtc_state), dss_ctl2_val);
> >  }
> >  
> >  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
> >  {
> >  	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	enum pipe pipe = crtc->pipe;
> > -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
> > -	u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
> >  
> >  	if (!old_crtc_state->dsc_params.compression_enable)
> >  		return;
> >  
> > -	if (old_crtc_state->cpu_transcoder == TRANSCODER_EDP) {
> > -		dss_ctl1_reg = DSS_CTL1;
> > -		dss_ctl2_reg = DSS_CTL2;
> > -	} else {
> > -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
> > -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
> > +	I915_WRITE(dss_ctl1_reg(old_crtc_state), 0);
> > +	I915_WRITE(dss_ctl2_reg(old_crtc_state), 0);
> > +}
> > +
> > +void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
> > +{
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +	u32 dss_ctl1_val, dss_ctl2_val;
> > +	intel_wakeref_t wakeref;
> > +
> > +	if (!intel_crtc_supports_dsc(crtc_state))
> > +		return;
> > +
> > +	wakeref = intel_display_power_get_if_enabled(dev_priv, intel_dsc_power_domain(crtc_state));
> > +	if (!wakeref)
> > +		return;
> > +
> > +	dss_ctl1_val = I915_READ(dss_ctl1_reg(crtc_state));
> > +	dss_ctl2_val = I915_READ(dss_ctl2_reg(crtc_state));
> > +	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE)
> > +		crtc_state->dsc_params.compression_enable = true;
> > +
> > +	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
> > +		crtc_state->dsc_params.dsc_split = true;
> > +
> > +	if (dss_ctl1_val & BIG_JOINER_ENABLE) {
> > +		crtc_state->bigjoiner = true;

Is crtc_state->bigjoiner supposed to be set on both master and slave or
just on the master?  I thought we only set it for the master based on
what I see in intel_dp_dsc_compute_config, but this appears to set in on
both during readout (my interpretation of bspec #50174 is that bit 29 is
set on both master and slave, whereas bit 28 is only set on the master).
Should this be testing against MASTER_BIG_JOINER_ENABLE instead?


Matt

> > +
> > +		if (!(dss_ctl1_val & MASTER_BIG_JOINER_ENABLE)) {
> > +			crtc_state->bigjoiner_slave = true;
> > +			if (!WARN_ON(crtc->pipe == PIPE_A))
> > +				crtc_state->bigjoiner_linked_crtc =
> > +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
> > +		} else {
> > +			if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
> > +				crtc_state->bigjoiner_linked_crtc =
> > +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
> > +		}
> >  	}
> > -	dss_ctl1_val = I915_READ(dss_ctl1_reg);
> > -	if (dss_ctl1_val & JOINER_ENABLE)
> > -		dss_ctl1_val &= ~JOINER_ENABLE;
> > -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
> > -
> > -	dss_ctl2_val = I915_READ(dss_ctl2_reg);
> > -	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
> > -	    dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
> > -		dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
> > -				  RIGHT_BRANCH_VDSC_ENABLE);
> > -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
> > -
> > -	/* Disable Power wells for VDSC/joining */
> > -	intel_display_power_put_unchecked(dev_priv,
> > -					  intel_dsc_power_domain(old_crtc_state));
> > +
> > +	intel_display_power_put(dev_priv, intel_dsc_power_domain(crtc_state), wakeref);
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
> > index 90d3f6017fcb..569cf17402ba 100644
> > --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> > +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> > @@ -15,6 +15,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
> >  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
> >  int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
> >  				struct intel_crtc_state *pipe_config);
> > +void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
> > +
> >  enum intel_display_power_domain
> >  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
> >  
> > -- 
> > 2.20.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Matt Roper
> Graphics Software Engineer
> VTT-OSGC Platform Enablement
> Intel Corporation
> (916) 356-2795
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 13/23] drm/i915: Make hardware readout work on i915.
  2019-09-20 11:42 ` [PATCH 13/23] drm/i915: Make hardware readout work on i915 Maarten Lankhorst
@ 2019-09-27  0:49   ` Matt Roper
  0 siblings, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-27  0:49 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:25PM +0200, Maarten Lankhorst wrote:
> Unfortunately I have no way to test this, but it should be correct
> if the bios sets up bigjoiner in a sane way.
> 
> Skip iterating over bigjoiner slaves, only the master has the state we
> care about.
> 
> Add the width of the bigjoiner slave to the reconstructed fb.
> 
> Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> master.
> 
> And last, disable bigjoiner slave from primary if reconstruction fails.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 65 +++++++++++++++++++-
>  1 file changed, 62 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8c08c4914c9b..0424a378eb51 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3177,6 +3177,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  	struct intel_plane *intel_plane = to_intel_plane(primary);
>  	struct intel_plane_state *intel_state =
>  		to_intel_plane_state(plane_state);
> +	struct intel_crtc_state *crtc_state =
> +		to_intel_crtc_state(intel_crtc->base.state);
>  	struct drm_framebuffer *fb;
>  
>  	if (!plane_config->fb)
> @@ -3199,7 +3201,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  		if (c == &intel_crtc->base)
>  			continue;
>  
> -		if (!to_intel_crtc(c)->active)
> +		if (!to_intel_crtc_state(c->state)->uapi.active)
>  			continue;
>  
>  		state = to_intel_plane_state(c->primary->state);
> @@ -3221,6 +3223,12 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  	 * pretend the BIOS never had it enabled.
>  	 */
>  	intel_plane_disable_noatomic(intel_crtc, intel_plane);
> +	if (crtc_state->bigjoiner) {
> +		struct intel_crtc *slave =
> +			crtc_state->bigjoiner_linked_crtc;
> +
> +		intel_plane_disable_noatomic(slave, to_intel_plane(slave->base.primary));
> +	}
>  
>  	return;
>  
> @@ -9918,6 +9926,7 @@ static void
>  skylake_get_initial_plane_config(struct intel_crtc *crtc,
>  				 struct intel_initial_plane_config *plane_config)
>  {
> +	struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
>  	struct drm_device *dev = crtc->base.dev;
>  	struct drm_i915_private *dev_priv = to_i915(dev);
>  	struct intel_plane *plane = to_intel_plane(crtc->base.primary);
> @@ -10021,6 +10030,18 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
>  	fb->height = ((val >> 16) & 0xffff) + 1;
>  	fb->width = ((val >> 0) & 0xffff) + 1;
>  
> +	/* add bigjoiner slave as well, if the fb stretches both */
> +	if (crtc_state->bigjoiner) {
> +		enum pipe bigjoiner_pipe = crtc_state->bigjoiner_linked_crtc->pipe;
> +
> +		if (fb->width == crtc_state->pipe_src_w &&

I just noticed that we don't seem to readout PLANE_POS or scaler state
when the scalers are in plane mode rather than pfit.  I guess we haven't
found the BIOS to use plane scaling in the past, but I wonder if that
might become something we have to worry about in bigjoiner cases?  I
could definitely imagine BIOS centering a framebuffer in the middle of a
panel (so it doesn't cover either pipe completely).

> +		    (I915_READ(PLANE_SURF(bigjoiner_pipe, plane_id)) & 0xfffff000) == plane_config->base) {
> +			val = I915_READ(PLANE_SIZE(crtc_state->bigjoiner_linked_crtc->pipe, plane_id));
> +			fb->height += ((val >> 16) & 0xfff) + 1;

On gen10 and below there were only 12 bits for height, but that bumped
up to 13 on gen11 (which are the platforms that have bigjoiner), so this
should be 0x1fff like below.  Although we should probably just mask with
0xffff to be consistent with the regular height/width readout farther up
(the extra bits are MBZ so it should be harmless to include them).

> +			fb->width += ((val >> 0) & 0x1fff) + 1;
> +		}
> +	}
> +
>  	val = I915_READ(PLANE_STRIDE(pipe, plane_id));
>  	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
>  	fb->pitches[0] = (val & 0x3ff) * stride_mult;
> @@ -16814,7 +16835,8 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc,
>  
>  	/* Adjust the state of the output pipe according to whether we
>  	 * have active connectors/encoders. */
> -	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc))
> +	if (crtc_state->hw.active && !intel_crtc_has_encoders(crtc) &&
> +	    !crtc_state->bigjoiner_slave)
>  		intel_crtc_disable_noatomic(&crtc->base, ctx);
>  
>  	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
> @@ -17136,6 +17158,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		struct intel_plane *plane;
>  		int min_cdclk = 0;
>  
> +		if (crtc_state->bigjoiner_slave)
> +			continue;
> +
>  		memset(&crtc->base.mode, 0, sizeof(crtc->base.mode));
>  		if (crtc_state->hw.active) {
>  			intel_mode_from_pipe_config(&crtc->base.mode, crtc_state);
> @@ -17144,7 +17169,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
>  			crtc_state->hw.mode = crtc->base.mode;
> -			WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
> +			if (!crtc_state->bigjoiner_slave)

This is always true since we added the 'continue' just above for slave
crtc's.



Matt

> +				WARN_ON(drm_atomic_set_mode_for_crtc(crtc->base.state, &crtc->base.mode));
>  
>  			/*
>  			 * The initial mode needs to be set in order to keep
> @@ -17190,6 +17216,39 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		intel_bw_crtc_update(bw_state, crtc_state);
>  		copy_hw_to_uapi_state(crtc_state);
>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
> +
> +		/* discard our incomplete slave state, copy it from master */
> +		if (crtc_state->bigjoiner && crtc_state->hw.active) {
> +			struct intel_crtc *slave = crtc_state->bigjoiner_linked_crtc;
> +			struct intel_crtc_state *slave_crtc_state =
> +				to_intel_crtc_state(slave->base.state);
> +
> +			copy_bigjoiner_crtc_state(slave_crtc_state, crtc_state);
> +			slave->base.mode = crtc->base.mode;
> +
> +			dev_priv->min_cdclk[slave->pipe] = min_cdclk;
> +			dev_priv->min_voltage_level[slave->pipe] =
> +				crtc_state->min_voltage_level;
> +
> +			for_each_intel_plane_on_crtc(&dev_priv->drm, slave, plane) {
> +				const struct intel_plane_state *plane_state =
> +					to_intel_plane_state(plane->base.state);
> +
> +				/*
> +				* FIXME don't have the fb yet, so can't
> +				* use intel_plane_data_rate() :(
> +				*/
> +				if (plane_state->base.visible)
> +					crtc_state->data_rate[plane->id] =
> +						4 * crtc_state->pixel_rate;
> +				else
> +					crtc_state->data_rate[plane->id] = 0;
> +			}
> +
> +			intel_bw_crtc_update(bw_state, slave_crtc_state);
> +			drm_calc_timestamping_constants(&slave->base,
> +							&slave_crtc_state->hw.adjusted_mode);
> +		}
>  	}
>  }
>  
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates
  2019-09-20 11:42 ` [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates Maarten Lankhorst
@ 2019-09-27  3:18   ` Matt Roper
  0 siblings, 0 replies; 82+ messages in thread
From: Matt Roper @ 2019-09-27  3:18 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:26PM +0200, Maarten Lankhorst wrote:
> We want to program slave planes with the master plane_state for
> properties such as FB, rotation, coordinates, etc, but the
> slave plane_state for all programming parameters.
> 
> Instead of special casing NV12 Y-planes, we make the code more
> generic, Y planes are programmed with separate state from the UV
> plane.
> 
> This will allow us to program planes on a bigjoiner slave crtc in
> a similar way.
> 
> This also requires the VMA to be copied to the slave, which is
> done in prepare_plane_fb().
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

I'm not super wild about how complicated all the plane stuff is
becoming.  My hope originally was that we could completely virtualize
our planes and handle uapi and hw state independently for both bigjoiner
and nv12.  I.e., make the underlying hardware planes shared resources
that we grab as necessary and setup sort of like how we handle scalers
and dpll's and such elsewhere in the driver.  Of course that was just my
super high-level idea and I haven't gone off and done all the design and
implementation you have so I may be completely overlooking problems that
would make that kind of design unworkable.

It's an unfortunate outcome of the increasingly-complicated hardware
design, but I just worry about how hard it's going to be for us to
maintain some of this stuff going forward.  I keep confusing myself
while reviewing the patches here, so I imagine it will be even harder
for someone who isn't specifically focused on bigjoiner and nv12 to
unravel and understand the codeflow and state handling that's happening.

When we're all done with this work, I think we're going to need some
really extensive kerneldoc updates that lay out the overall flow of
how/where various bits of plane programming information get pulled from
and at what points in the display update sequence.


Matt

> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c | 21 +++---
>  .../gpu/drm/i915/display/intel_atomic_plane.h |  3 -
>  drivers/gpu/drm/i915/display/intel_display.c  | 56 ++++++++++++--
>  drivers/gpu/drm/i915/display/intel_display.h  |  3 +-
>  .../drm/i915/display/intel_display_types.h    |  6 +-
>  drivers/gpu/drm/i915/display/intel_sprite.c   | 75 ++++++++++---------
>  6 files changed, 106 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index a1a34b9981cc..964db7774d10 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -277,14 +277,15 @@ void intel_update_plane(struct intel_plane *plane,
>  	plane->update_plane(plane, crtc_state, plane_state);
>  }
>  
> -void intel_update_slave(struct intel_plane *plane,
> -			const struct intel_crtc_state *crtc_state,
> -			const struct intel_plane_state *plane_state)
> +static void intel_update_slave(struct intel_plane *plane,
> +			       const struct intel_crtc_state *crtc_state,
> +			       const struct intel_plane_state *master_plane_state,
> +			       const struct intel_plane_state *slave_plane_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  
>  	trace_intel_update_plane(&plane->base, crtc);
> -	plane->update_slave(plane, crtc_state, plane_state);
> +	plane->update_slave(plane, crtc_state, master_plane_state, slave_plane_state);
>  }
>  
>  void intel_disable_plane(struct intel_plane *plane,
> @@ -324,6 +325,8 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>  		} else if (new_plane_state->planar_slave) {
>  			struct intel_plane *master =
>  				new_plane_state->planar_linked_plane;
> +			struct intel_plane_state *master_plane_state =
> +				intel_atomic_get_new_plane_state(state, master);
>  
>  			/*
>  			 * We update the slave plane from this function because
> @@ -331,13 +334,11 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>  			 * callback runs into issues when the Y plane is
>  			 * reassigned, disabled or used by a different plane.
>  			 *
> -			 * The slave plane is updated with the master plane's
> -			 * plane_state.
> +			 * The slave plane is updated with the master's
> +			 * plane_state as extra argument.
>  			 */
> -			new_plane_state =
> -				intel_atomic_get_new_plane_state(state, master);
> -
> -			intel_update_slave(plane, new_crtc_state, new_plane_state);
> +			intel_update_slave(plane, new_crtc_state,
> +					   master_plane_state, new_plane_state);
>  		} else {
>  			intel_disable_plane(plane, new_crtc_state);
>  		}
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index cb7ef4f9eafd..33fb85cd3909 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -23,9 +23,6 @@ unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
>  void intel_update_plane(struct intel_plane *plane,
>  			const struct intel_crtc_state *crtc_state,
>  			const struct intel_plane_state *plane_state);
> -void intel_update_slave(struct intel_plane *plane,
> -			const struct intel_crtc_state *crtc_state,
> -			const struct intel_plane_state *plane_state);
>  void intel_disable_plane(struct intel_plane *plane,
>  			 const struct intel_crtc_state *crtc_state);
>  struct intel_plane *intel_plane_alloc(void);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 0424a378eb51..df588bf47559 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3972,11 +3972,12 @@ static unsigned int skl_plane_stride_mult(const struct drm_framebuffer *fb,
>  		return intel_tile_width_bytes(fb, color_plane);
>  }
>  
> -u32 skl_plane_stride(const struct intel_plane_state *plane_state,
> +u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
> +		     const struct intel_plane_state *plane_state,
>  		     int color_plane)
>  {
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
> -	unsigned int rotation = plane_state->base.rotation;
> +	const struct drm_framebuffer *fb = master_plane_state->base.fb;
> +	unsigned int rotation = master_plane_state->base.rotation;
>  	u32 stride = plane_state->color_plane[color_plane].stride;
>  
>  	if (color_plane >= fb->format->num_planes)
> @@ -11900,6 +11901,23 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  		crtc_state->active_planes |= BIT(linked->id);
>  		crtc_state->update_planes |= BIT(linked->id);
>  		DRM_DEBUG_KMS("Using %s as Y plane for %s\n", linked->base.name, plane->base.name);
> +
> +		/* Copy parameters to slave plane */
> +		linked_state->ctl = plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE;
> +		linked_state->color_ctl = plane_state->color_ctl;
> +		linked_state->color_plane[0] = plane_state->color_plane[0];
> +
> +		linked_state->base.src = plane_state->base.src;
> +		linked_state->base.dst = plane_state->base.dst;
> +
> +		if (icl_is_hdr_plane(dev_priv, plane->id)) {
> +			if (linked->id == PLANE_SPRITE5)
> +				plane_state->cus_ctl |= PLANE_CUS_PLANE_7;
> +			else if (linked->id == PLANE_SPRITE4)
> +				plane_state->cus_ctl |= PLANE_CUS_PLANE_6;
> +			else
> +				MISSING_CASE(linked->id);
> +		}
>  	}
>  
>  	return 0;
> @@ -14782,6 +14800,23 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>  			return ret;
>  	}
>  
> +	if (to_intel_plane_state(new_state)->planar_slave) {
> +		struct intel_plane_state *new_plane_state = to_intel_plane_state(new_state);
> +		const struct intel_plane_state *linked_plane_state =
> +			intel_atomic_get_new_plane_state(intel_state, new_plane_state->planar_linked_plane);
> +
> +		/*
> +		 * We are a planar slave, VMA is on our planar master,
> +		 * but may not be the same as the bigjoiner master plane.
> +		 *
> +		 * Copy the vma from our planar master and return.
> +		 */
> +		if (linked_plane_state->vma)
> +			new_plane_state->vma =
> +				i915_vma_get(linked_plane_state->vma);
> +		return 0;
> +	}
> +
>  	if (!obj)
>  		return 0;
>  
> @@ -14851,10 +14886,11 @@ intel_prepare_plane_fb(struct drm_plane *plane,
>   */
>  void
>  intel_cleanup_plane_fb(struct drm_plane *plane,
> -		       struct drm_plane_state *old_state)
> +		       struct drm_plane_state *_old_state)
>  {
> +	struct intel_plane_state *old_state = to_intel_plane_state(_old_state);
>  	struct intel_atomic_state *intel_state =
> -		to_intel_atomic_state(old_state->state);
> +		to_intel_atomic_state(old_state->base.state);
>  	struct drm_i915_private *dev_priv = to_i915(plane->dev);
>  
>  	if (intel_state->rps_interactive) {
> @@ -14862,9 +14898,17 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
>  		intel_state->rps_interactive = false;
>  	}
>  
> +	/* pin is handled in master plane_state for planar formats */
> +	if (old_state->planar_slave) {
> +		if (old_state->vma)
> +			i915_vma_put(old_state->vma);
> +		old_state->vma = NULL;
> +		return;
> +	}
> +
>  	/* Should only be called after a successful intel_prepare_plane_fb()! */
>  	mutex_lock(&dev_priv->drm.struct_mutex);
> -	intel_plane_unpin_fb(to_intel_plane_state(old_state));
> +	intel_plane_unpin_fb(old_state);
>  	mutex_unlock(&dev_priv->drm.struct_mutex);
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index b1ae0e59c715..764d05d13b9e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -560,7 +560,8 @@ u32 glk_plane_color_ctl_crtc(const struct intel_crtc_state *crtc_state);
>  u32 skl_plane_ctl(const struct intel_crtc_state *crtc_state,
>  		  const struct intel_plane_state *plane_state);
>  u32 skl_plane_ctl_crtc(const struct intel_crtc_state *crtc_state);
> -u32 skl_plane_stride(const struct intel_plane_state *plane_state,
> +u32 skl_plane_stride(const struct intel_plane_state *master_plane_state,
> +		     const struct intel_plane_state *plane_state,
>  		     int plane);
>  int skl_check_plane_surface(struct intel_plane_state *plane_state);
>  int i9xx_check_plane_surface(struct intel_plane_state *plane_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 7e06c61447e6..ace372a76330 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -538,6 +538,9 @@ struct intel_plane_state {
>  	/* plane color control register */
>  	u32 color_ctl;
>  
> +	/* chroma upsampler control register */
> +	u32 cus_ctl;
> +
>  	/*
>  	 * scaler_id
>  	 *    = -1 : not using a scaler
> @@ -1097,7 +1100,8 @@ struct intel_plane {
>  			     const struct intel_plane_state *plane_state);
>  	void (*update_slave)(struct intel_plane *plane,
>  			     const struct intel_crtc_state *crtc_state,
> -			     const struct intel_plane_state *plane_state);
> +			     const struct intel_plane_state *master_plane_state,
> +			     const struct intel_plane_state *slave_plane_state);
>  	void (*disable_plane)(struct intel_plane *plane,
>  			      const struct intel_crtc_state *crtc_state);
>  	bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index f0956fecdea4..bca7ff8a8907 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -346,10 +346,11 @@ skl_plane_max_stride(struct intel_plane *plane,
>  static void
>  skl_program_scaler(struct intel_plane *plane,
>  		   const struct intel_crtc_state *crtc_state,
> +		   const struct intel_plane_state *master_plane_state,
>  		   const struct intel_plane_state *plane_state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
> +	const struct drm_framebuffer *fb = master_plane_state->base.fb;
>  	enum pipe pipe = plane->pipe;
>  	int scaler_id = plane_state->scaler_id;
>  	const struct intel_scaler *scaler =
> @@ -527,28 +528,29 @@ icl_program_input_csc(struct intel_plane *plane,
>  static void
>  skl_program_plane(struct intel_plane *plane,
>  		  const struct intel_crtc_state *crtc_state,
> +		  const struct intel_plane_state *master_plane_state,
>  		  const struct intel_plane_state *plane_state,
> -		  int color_plane, bool slave, u32 plane_ctl)
> +		  int color_plane)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
>  	enum plane_id plane_id = plane->id;
>  	enum pipe pipe = plane->pipe;
> -	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
> +	const struct drm_intel_sprite_colorkey *key = &master_plane_state->ckey;
>  	u32 surf_addr = plane_state->color_plane[color_plane].offset;
> -	u32 stride = skl_plane_stride(plane_state, color_plane);
> -	u32 aux_stride = skl_plane_stride(plane_state, 1);
> +	u32 stride = skl_plane_stride(master_plane_state, plane_state, color_plane);
> +	u32 aux_stride = skl_plane_stride(master_plane_state, plane_state, 1);
>  	int crtc_x = plane_state->base.dst.x1;
>  	int crtc_y = plane_state->base.dst.y1;
>  	u32 x = plane_state->color_plane[color_plane].x;
>  	u32 y = plane_state->color_plane[color_plane].y;
>  	u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
>  	u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
> -	struct intel_plane *linked = plane_state->planar_linked_plane;
> -	const struct drm_framebuffer *fb = plane_state->base.fb;
> -	u8 alpha = plane_state->base.alpha >> 8;
> +	const struct drm_framebuffer *fb = master_plane_state->base.fb;
> +	u8 alpha = master_plane_state->base.alpha >> 8;
>  	u32 plane_color_ctl = 0;
>  	unsigned long irqflags;
>  	u32 keymsk, keymax;
> +	u32 plane_ctl = plane_state->ctl;
>  
>  	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
>  
> @@ -580,32 +582,14 @@ skl_program_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
>  		      (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
>  
> -	if (icl_is_hdr_plane(dev_priv, plane_id)) {
> -		u32 cus_ctl = 0;
> -
> -		if (linked) {
> -			/* Enable and use MPEG-2 chroma siting */
> -			cus_ctl = PLANE_CUS_ENABLE |
> -				PLANE_CUS_HPHASE_0 |
> -				PLANE_CUS_VPHASE_SIGN_NEGATIVE |
> -				PLANE_CUS_VPHASE_0_25;
> -
> -			if (linked->id == PLANE_SPRITE5)
> -				cus_ctl |= PLANE_CUS_PLANE_7;
> -			else if (linked->id == PLANE_SPRITE4)
> -				cus_ctl |= PLANE_CUS_PLANE_6;
> -			else
> -				MISSING_CASE(linked->id);
> -		}
> -
> -		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
> -	}
> +	if (icl_is_hdr_plane(dev_priv, plane_id))
> +		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl);
>  
>  	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
>  		I915_WRITE_FW(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);
> +		icl_program_input_csc(plane, crtc_state, master_plane_state);
>  
>  	skl_write_plane_wm(plane, crtc_state);
>  
> @@ -629,8 +613,8 @@ skl_program_plane(struct intel_plane *plane,
>  	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
>  		      intel_plane_ggtt_offset(plane_state) + surf_addr);
>  
> -	if (!slave && plane_state->scaler_id >= 0)
> -		skl_program_scaler(plane, crtc_state, plane_state);
> +	if (plane_state->scaler_id >= 0)
> +		skl_program_scaler(plane, crtc_state, master_plane_state, plane_state);
>  
>  	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
>  }
> @@ -647,17 +631,26 @@ skl_update_plane(struct intel_plane *plane,
>  		color_plane = 1;
>  	}
>  
> -	skl_program_plane(plane, crtc_state, plane_state,
> -			  color_plane, false, plane_state->ctl);
> +	skl_program_plane(plane, crtc_state, plane_state, plane_state, color_plane);
>  }
>  
>  static void
>  icl_update_slave(struct intel_plane *plane,
>  		 const struct intel_crtc_state *crtc_state,
> -		 const struct intel_plane_state *plane_state)
> +		 const struct intel_plane_state *master_plane_state,
> +		 const struct intel_plane_state *slave_plane_state)
>  {
> -	skl_program_plane(plane, crtc_state, plane_state, 0, true,
> -			  plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
> +	const struct drm_framebuffer *fb = master_plane_state->base.fb;
> +	int color_plane = 0;
> +
> +	if (drm_format_info_is_yuv_semiplanar(fb->format) &&
> +	    !slave_plane_state->planar_slave) {
> +		/* Program the UV plane, even as slave (Big joiner). */
> +		color_plane = 1;
> +	}
> +
> +	skl_program_plane(plane, crtc_state, master_plane_state,
> +			  slave_plane_state, color_plane);
>  }
>  
>  static void
> @@ -1845,6 +1838,14 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
>  		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
>  							     plane_state);
>  
> +	if (icl_is_hdr_plane(dev_priv, plane->id) && fb->format->is_yuv)
> +		/* Enable and use MPEG-2 chroma siting */
> +		plane_state->cus_ctl = PLANE_CUS_ENABLE |
> +			PLANE_CUS_HPHASE_0 |
> +			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
> +	else
> +		plane_state->cus_ctl = 0;
> +
>  	return 0;
>  }
>  
> @@ -2513,7 +2514,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
>  	plane->disable_plane = skl_disable_plane;
>  	plane->get_hw_state = skl_plane_get_hw_state;
>  	plane->check_plane = skl_plane_check;
> -	if (icl_is_nv12_y_plane(plane_id))
> +	if (INTEL_GEN(dev_priv) >= 11)
>  		plane->update_slave = icl_update_slave;
>  
>  	if (INTEL_GEN(dev_priv) >= 11)
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences.
  2019-09-26 23:54     ` Matt Roper
@ 2019-09-27  8:25       ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-27  8:25 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 27-09-2019 om 01:54 schreef Matt Roper:
> On Wed, Sep 25, 2019 at 10:18:19PM -0700, Matt Roper wrote:
>> On Fri, Sep 20, 2019 at 01:42:24PM +0200, Maarten Lankhorst wrote:
>>> Make vdsc work when no output is enabled. The big joiner needs VDSC
>>> on the slave, so enable it and set the appropriate bits.
>>> Also update timestamping constants, because slave crtc's are not
>>> updated in drm_atomic_helper_update_legacy_modeset_state().
>>>
>>> This should be enough to bring up CRTC's in a big joiner configuration,
>>> without any plane configuration on the second pipe yet.
>>>
>>> HOWEVER, we bring up the crtc's in the wrong order. We need to make
>>> sure that the master crtc is brought up after the slave crtc, we
>>> don't do that yet. This is done correctly later in this series.
>>>
>>> The next steps are to add atomic commit, and make sure we enable and
>>> update both master and slave in the correct order.
>>>
>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> A couple minor comments inline below, but I didn't see any clear
>> problems with this patch so
>>
>> Acked-by: Matt Roper <matthew.d.roper@intel.com>
>>
>> However there's a lot of pretty complicated changes here in areas that
>> I'm only vaguely familiar with, so I think it would be good if someone
>> like Manasi who's more familiar with this area of the code could look it
>> over.
>>
>>
>> Matt
>>
>>
>>> ---
>>>  drivers/gpu/drm/i915/display/intel_ddi.c      |  55 ++-
>>>  drivers/gpu/drm/i915/display/intel_display.c  | 402 ++++++++++++------
>>>  .../drm/i915/display/intel_display_types.h    |  17 +
>>>  drivers/gpu/drm/i915/display/intel_dp.c       |  18 +-
>>>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
>>>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
>>>  6 files changed, 418 insertions(+), 198 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>>> index c775fd205915..a26155f90261 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>>> @@ -1694,6 +1694,13 @@ static void intel_ddi_clock_get(struct intel_encoder *encoder,
>>>  		skl_ddi_clock_get(encoder, pipe_config);
>>>  	else if (INTEL_GEN(dev_priv) <= 8)
>>>  		hsw_ddi_clock_get(encoder, pipe_config);
>>> +
>>> +	if (pipe_config->bigjoiner) {
>>> +		pipe_config->hw.transcoder_mode.crtc_clock =
>>> +			pipe_config->hw.adjusted_mode.crtc_clock;
>>> +
>>> +		pipe_config->hw.adjusted_mode.crtc_clock /= 2;
>>> +	}
>>>  }
>>>  
>>>  void intel_ddi_set_pipe_settings(const struct intel_crtc_state *crtc_state)
>>> @@ -2176,13 +2183,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>>>  	    intel_phy_is_tc(dev_priv, phy))
>>>  		intel_display_power_get(dev_priv,
>>>  					intel_ddi_main_link_aux_domain(dig_port));
>>> -
>>> -	/*
>>> -	 * VDSC power is needed when DSC is enabled
>>> -	 */
>>> -	if (crtc_state->dsc_params.compression_enable)
>>> -		intel_display_power_get(dev_priv,
>>> -					intel_dsc_power_domain(crtc_state));
>>>  }
>>>  
>>>  void intel_ddi_enable_pipe_clock(const struct intel_crtc_state *crtc_state)
>>> @@ -3290,7 +3290,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
>>>  
>>>  	/* 7.l */
>>>  	intel_ddi_enable_fec(encoder, crtc_state);
>>> -	intel_dsc_enable(encoder, crtc_state);
>>> +	if (!crtc_state->bigjoiner)
>>> +		intel_dsc_enable(encoder, crtc_state);
>>>  }
>>>  
>>>  static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
>>> @@ -3361,7 +3362,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
>>>  	if (!is_mst)
>>>  		intel_ddi_enable_pipe_clock(crtc_state);
>>>  
>>> -	intel_dsc_enable(encoder, crtc_state);
>>> +	if (!crtc_state->bigjoiner)
>>> +		intel_dsc_enable(encoder, crtc_state);
>>>  }
>>>  
>>>  static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
>>> @@ -3972,19 +3974,18 @@ void intel_ddi_compute_min_voltage_level(struct drm_i915_private *dev_priv,
>>>  		crtc_state->min_voltage_level = 2;
>>>  }
>>>  
>>> -void intel_ddi_get_config(struct intel_encoder *encoder,
>>> -			  struct intel_crtc_state *pipe_config)
>>> +static void intel_ddi_read_func_ctl(struct intel_encoder *encoder,
>>> +				    struct intel_crtc_state *pipe_config)
>>>  {
>>>  	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>>  	struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>>>  	u32 temp, flags = 0;
>>>  
>>> -	/* XXX: DSI transcoder paranoia */
>>> -	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
>>> +	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>>>  		return;
>>>  
>>> -	temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>>  	if (temp & TRANS_DDI_PHSYNC)
>>>  		flags |= DRM_MODE_FLAG_PHSYNC;
>>>  	else
>>> @@ -4066,6 +4067,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>>  	default:
>>>  		break;
>>>  	}
>>> +}
>>> +
>>> +void intel_ddi_get_config(struct intel_encoder *encoder,
>>> +			  struct intel_crtc_state *pipe_config)
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>>> +
>>> +	/* XXX: DSI transcoder paranoia */
>>> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
>>> +		return;
>>> +
>>> +	intel_ddi_read_func_ctl(encoder, pipe_config);
>>> +	if (pipe_config->bigjoiner_slave) {
>>> +		/* read out pipe settings from master */
>>> +		enum transcoder save = pipe_config->cpu_transcoder;
>>> +
>>> +		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
>>> +		WARN_ON(pipe_config->output_types);
>>> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
>>> +		intel_ddi_read_func_ctl(encoder, pipe_config);
>>> +		pipe_config->cpu_transcoder = save;
>>> +	}
>>>  
>>>  	pipe_config->has_audio =
>>>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
>>> @@ -4090,7 +4114,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>>  		dev_priv->vbt.edp.bpp = pipe_config->pipe_bpp;
>>>  	}
>>>  
>>> -	intel_ddi_clock_get(encoder, pipe_config);
>>> +	if (!pipe_config->bigjoiner_slave)
>>> +		intel_ddi_clock_get(encoder, pipe_config);
>>>  
>>>  	if (IS_GEN9_LP(dev_priv))
>>>  		pipe_config->lane_lat_optim_mask =
>>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>>> index 143d531c4c81..8c08c4914c9b 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>>> @@ -6449,6 +6449,45 @@ static void icl_pipe_mbus_enable(struct intel_crtc *crtc)
>>>  	I915_WRITE(PIPE_MBUS_DBOX_CTL(pipe), val);
>>>  }
>>>  
>>> +static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
>>> +					 struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct intel_crtc *master = to_intel_crtc(crtc_state->uapi.crtc);
>>> +	struct intel_crtc_state *master_crtc_state;
>>> +	struct drm_connector_state *conn_state;
>>> +	struct drm_connector *conn;
>>> +	struct intel_encoder *encoder = NULL;
>>> +	int i;
>>> +
>>> +	if (crtc_state->bigjoiner_slave)
>>> +		master = crtc_state->bigjoiner_linked_crtc;
>>> +
>>> +	master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
>>> +
>>> +	for_each_new_connector_in_state(&state->base, conn, conn_state, i) {
>>> +		if (conn_state->crtc != &master->base)
>>> +			continue;
>>> +
>>> +		encoder = to_intel_encoder(conn_state->best_encoder);
>>> +		break;
>>> +	}
>>> +
>>> +	if (!crtc_state->bigjoiner_slave) {
>>> +		/* need to enable VDSC, which we skipped in pre-enable */
>>> +		intel_dsc_enable(encoder, crtc_state);
>>> +	} else {
>>> +		/*
>>> +		 * Enable sequence steps 1-7 on bigjoiner master
>>> +		 */
>> I'd extend this comment to indicate that we do this on the slave (using
>> the master's state, transcoder, and DDI) because the [will] program the
>> slave CRTC before the master.
>>
>>> +		intel_encoders_pre_pll_enable(master, master_crtc_state, state);
>>> +		intel_enable_shared_dpll(master_crtc_state);
>>> +		intel_encoders_pre_enable(master, master_crtc_state, state);
>>> +
>>> +		/* and DSC on slave */
>>> +		intel_dsc_enable(NULL, crtc_state);
>>> +	}
>>> +}
>>> +
>>>  static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>>  				struct intel_atomic_state *state)
>>>  {
>>> @@ -6462,37 +6501,38 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>>  	if (WARN_ON(intel_crtc->active))
>>>  		return;
>>>  
>>> -	intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
>>> +	if (!pipe_config->bigjoiner) {
>>> +		intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
>>>  
>>> -	if (pipe_config->shared_dpll)
>>> -		intel_enable_shared_dpll(pipe_config);
>>> +		if (pipe_config->shared_dpll)
>>> +			intel_enable_shared_dpll(pipe_config);
>>>  
>>> -	intel_encoders_pre_enable(intel_crtc, pipe_config, state);
>>> +		intel_encoders_pre_enable(intel_crtc, pipe_config, state);
>>> +	} else {
>>> +		icl_ddi_bigjoiner_pre_enable(state, pipe_config);
>>> +	}
>>>  
>>> -	if (intel_crtc_has_dp_encoder(pipe_config))
>>> -		intel_dp_set_m_n(pipe_config, M1_N1);
>>> +	intel_set_pipe_src_size(pipe_config);
>>> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
>>> +		bdw_set_pipemisc(pipe_config);
>>>  
>>> -	if (!transcoder_is_dsi(cpu_transcoder))
>>> -		intel_set_pipe_timings(pipe_config);
>>> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
>>> +		if (intel_crtc_has_dp_encoder(pipe_config))
>>> +			intel_dp_set_m_n(pipe_config, M1_N1);
>>>  
>>> -	intel_set_pipe_src_size(pipe_config);
>>> +		intel_set_pipe_timings(pipe_config);
>>>  
>>> -	if (cpu_transcoder != TRANSCODER_EDP &&
>>> -	    !transcoder_is_dsi(cpu_transcoder)) {
>>> -		I915_WRITE(PIPE_MULT(cpu_transcoder),
>>> -			   pipe_config->pixel_multiplier - 1);
>>> -	}
>>> +		if (cpu_transcoder != TRANSCODER_EDP)
>>> +			I915_WRITE(PIPE_MULT(cpu_transcoder),
>>> +				  pipe_config->pixel_multiplier - 1);
>>>  
>>> -	if (pipe_config->has_pch_encoder) {
>>> -		intel_cpu_transcoder_set_m_n(pipe_config,
>>> -					     &pipe_config->fdi_m_n, NULL);
>>> -	}
>>> +		if (pipe_config->has_pch_encoder) {
>>> +			intel_cpu_transcoder_set_m_n(pipe_config,
>>> +						    &pipe_config->fdi_m_n, NULL);
>>> +		}
>>>  
>>> -	if (!transcoder_is_dsi(cpu_transcoder))
>>>  		haswell_set_pipeconf(pipe_config);
>>> -
>>> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
>>> -		bdw_set_pipemisc(pipe_config);
>>> +	}
>>>  
>>>  	intel_crtc->active = true;
>>>  
>>> @@ -6520,9 +6560,11 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>>  	if (INTEL_GEN(dev_priv) >= 11)
>>>  		icl_set_pipe_chicken(intel_crtc);
>>>  
>>> -	intel_ddi_set_pipe_settings(pipe_config);
>>> -	if (!transcoder_is_dsi(cpu_transcoder))
>>> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
>>> +		intel_ddi_set_pipe_settings(pipe_config);
>>> +
>>>  		intel_ddi_enable_transcoder_func(pipe_config);
>>> +	}
>>>  
>>>  	if (dev_priv->display.initial_watermarks != NULL)
>>>  		dev_priv->display.initial_watermarks(state, pipe_config);
>>> @@ -6531,8 +6573,10 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>>>  		icl_pipe_mbus_enable(intel_crtc);
>>>  
>>>  	/* XXX: Do the pipe assertions at the right place for BXT DSI. */
>>> -	if (!transcoder_is_dsi(cpu_transcoder))
>>> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
>>>  		intel_enable_pipe(pipe_config);
>>> +	else
>>> +		trace_intel_pipe_enable(intel_crtc);
>>>  
>>>  	if (pipe_config->has_pch_encoder)
>>>  		lpt_pch_enable(state, pipe_config);
>>> @@ -6663,9 +6707,27 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
>>>  	else
>>>  		ironlake_pfit_disable(old_crtc_state);
>>>  
>>> -	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
>>> +	if (old_crtc_state->bigjoiner) {
>>> +		struct intel_crtc *master;
>>> +		struct intel_crtc_state *master_crtc_state;
>>>  
>>> -	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
>>> +		/* ports are disabled from the slave, after it deconfigures */
>>> +		if (!old_crtc_state->bigjoiner_slave)
>>> +			return;
>>> +
>>> +		master = old_crtc_state->bigjoiner_linked_crtc;
>>> +		master_crtc_state = intel_atomic_get_old_crtc_state(state, master);
>>> +
>>> +		intel_ddi_disable_pipe_clock(old_crtc_state);
>>> +
>>> +		/* disable ports on the master crtc */
>>> +		intel_encoders_post_disable(master, master_crtc_state, state);
>>> +		intel_encoders_post_pll_disable(master, master_crtc_state, state);
>>> +	} else {
>>> +		intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
>>> +
>>> +		intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
>>> +	}
>>>  }
>>>  
>>>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
>>> @@ -6829,6 +6891,9 @@ static u64 get_crtc_power_domains(struct intel_crtc_state *crtc_state)
>>>  	if (crtc_state->shared_dpll)
>>>  		mask |= BIT_ULL(POWER_DOMAIN_DISPLAY_CORE);
>>>  
>>> +	if (crtc_state->dsc_params.compression_enable)
>>> +		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
>>> +
>>>  	return mask;
>>>  }
>>>  
>>> @@ -7417,6 +7482,19 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
>>>  	return pixel_rate;
>>>  }
>>>  
>>> +static void intel_encoder_get_config(struct intel_encoder *encoder,
>>> +				     struct intel_crtc_state *crtc_state)
>>> +{
>>> +	encoder->get_config(encoder, crtc_state);
>>> +
>>> +	crtc_state->hw.transcoder_mode.flags = crtc_state->hw.adjusted_mode.flags;
>>> +
>>> +	/* if transcoder clock is not set, assume same as adjusted_mode clock */
>>> +	if (!crtc_state->hw.transcoder_mode.crtc_clock)
>>> +		crtc_state->hw.transcoder_mode.crtc_clock =
>>> +			crtc_state->hw.adjusted_mode.crtc_clock;
>>> +}
>>> +
>>>  static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
>>>  {
>>>  	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
>>> @@ -8265,6 +8343,24 @@ static void intel_get_pipe_timings(struct intel_crtc *crtc,
>>>  		pipe_config->hw.adjusted_mode.crtc_vtotal += 1;
>>>  		pipe_config->hw.adjusted_mode.crtc_vblank_end += 1;
>>>  	}
>>> +
>>> +	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
>>> +	if (pipe_config->bigjoiner) {
>>> +		struct drm_display_mode *adjusted_mode =
>>> +			&pipe_config->hw.adjusted_mode;
>>> +
>>> +		/*
>>> +		  * transcoder is programmed to the full mode,
>>> +		  * but pipje timings are half of the transcoder mode
>>> +		  */
>>> +		adjusted_mode->crtc_hdisplay /= 2;
>>> +		adjusted_mode->crtc_hblank_start /= 2;
>>> +		adjusted_mode->crtc_hblank_end /= 2;
>>> +		adjusted_mode->crtc_hsync_start /= 2;
>>> +		adjusted_mode->crtc_hsync_end /= 2;
>>> +		adjusted_mode->crtc_htotal /= 2;
>>> +		adjusted_mode->crtc_hskew /= 2;
>>> +	}
>>>  }
>>>  
>>>  static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>>> @@ -8285,20 +8381,22 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>>>  void intel_mode_from_pipe_config(struct drm_display_mode *mode,
>>>  				 struct intel_crtc_state *pipe_config)
>>>  {
>>> -	mode->hdisplay = pipe_config->hw.adjusted_mode.crtc_hdisplay;
>>> -	mode->htotal = pipe_config->hw.adjusted_mode.crtc_htotal;
>>> -	mode->hsync_start = pipe_config->hw.adjusted_mode.crtc_hsync_start;
>>> -	mode->hsync_end = pipe_config->hw.adjusted_mode.crtc_hsync_end;
>>> +	struct drm_display_mode *hw_mode = &pipe_config->hw.transcoder_mode;
>>>  
>>> -	mode->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
>>> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
>>> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
>>> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
>>> +	mode->hdisplay = hw_mode->crtc_hdisplay;
>>> +	mode->htotal = hw_mode->crtc_htotal;
>>> +	mode->hsync_start = hw_mode->crtc_hsync_start;
>>> +	mode->hsync_end = hw_mode->crtc_hsync_end;
>>>  
>>> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
>>> +	mode->vdisplay = hw_mode->crtc_vdisplay;
>>> +	mode->vtotal = hw_mode->crtc_vtotal;
>>> +	mode->vsync_start = hw_mode->crtc_vsync_start;
>>> +	mode->vsync_end = hw_mode->crtc_vsync_end;
>>> +
>>> +	mode->flags = hw_mode->flags;
>>>  	mode->type = DRM_MODE_TYPE_DRIVER;
>>>  
>>> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
>>> +	mode->clock = hw_mode->crtc_clock;
>>>  
>>>  	mode->hsync = drm_mode_hsync(mode);
>>>  	mode->vrefresh = drm_mode_vrefresh(mode);
>>> @@ -10385,6 +10483,8 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc,
>>>  	u32 tmp;
>>>  
>>>  	tmp = I915_READ(TRANS_DDI_FUNC_CTL(pipe_config->cpu_transcoder));
>>> +	if (!(tmp & TRANS_DDI_FUNC_ENABLE))
>>> +		return;
>>>  
>>>  	if (INTEL_GEN(dev_priv) >= 12)
>>>  		port = TGL_TRANS_DDI_FUNC_CTL_VAL_TO_PORT(tmp);
>>> @@ -10455,11 +10555,19 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>>>  		WARN_ON(active);
>>>  		active = true;
>>>  	}
>>> +	intel_dsc_get_config(pipe_config);
>>>  
>>> -	if (!active)
>>> -		goto out;
>>> +	if (!active) {
>>> +		/* bigjoiner slave doesn't enable transcoder */
>>> +		if (!pipe_config->bigjoiner_slave)
>>> +			goto out;
>>> +
>>> +		active = true;
>>> +		pipe_config->pixel_multiplier = 1;
>>>  
>>> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>>> +		/* we cannot read out most state, so don't bother.. */
>>> +		pipe_config->quirks |= PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE;
>>> +	} else if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>>>  	    INTEL_GEN(dev_priv) >= 11) {
>>>  		haswell_get_ddi_port_state(crtc, pipe_config);
>>>  		intel_get_pipe_timings(crtc, pipe_config);
>>> @@ -10513,7 +10621,10 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
>>>  		}
>>>  	}
>>>  
>>> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>>> +	if (pipe_config->bigjoiner_slave) {
>>> +		/* Cannot be read out as a slave, set to 0. */
>>> +		pipe_config->pixel_multiplier = 0;
>>> +	} else if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>>>  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
>>>  		pipe_config->pixel_multiplier =
>>>  			I915_READ(PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
>>> @@ -11468,7 +11579,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
>>>  		return NULL;
>>>  	}
>>>  
>>> -	encoder->get_config(encoder, crtc_state);
>>> +	intel_encoder_get_config(encoder, crtc_state);
>>>  
>>>  	intel_mode_from_pipe_config(mode, crtc_state);
>>>  
>>> @@ -12285,9 +12396,11 @@ static void copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
>>>  
>>>  static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>>>  {
>>> -	crtc_state->uapi.enable = crtc_state->hw.enable;
>>> -	crtc_state->uapi.active = crtc_state->hw.active;
>>> -	crtc_state->uapi.mode = crtc_state->hw.mode;
>>> +	if (!crtc_state->bigjoiner_slave) {
>>> +		crtc_state->uapi.enable = crtc_state->hw.enable;
>>> +		crtc_state->uapi.active = crtc_state->hw.active;
>>> +		crtc_state->uapi.mode = crtc_state->hw.mode;
>>> +	}
>>>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
>>>  }
>>>  
>>> @@ -12318,6 +12431,7 @@ copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
>>>  	crtc_state->hw.active = from_crtc_state->hw.active;
>>>  	crtc_state->hw.mode = from_crtc_state->hw.mode;
>>>  	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
>>> +	crtc_state->hw.transcoder_mode = from_crtc_state->hw.transcoder_mode;
>>>  
>>>  	/* Some fixups */
>>>  	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
>>> @@ -12833,19 +12947,41 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>>  
>>>  	PIPE_CONF_CHECK_X(output_types);
>>>  
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_start);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hblank_end);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_start);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hsync_end);
>>> -
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_start);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vblank_end);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_start);
>>> -	PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vsync_end);
>>> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
>>> +		/* bigjoiner mode = transcoder mode / 2, for calculations */
>>> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_hdisplay);
>>> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_htotal);
>>> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vdisplay);
>>> +		PIPE_CONF_CHECK_I(hw.adjusted_mode.crtc_vtotal);
>>> +
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hdisplay);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_htotal);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_start);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hblank_end);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_start);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_hsync_end);
>>> +
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vdisplay);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vtotal);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_start);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vblank_end);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_start);
>>> +		PIPE_CONF_CHECK_I(hw.transcoder_mode.crtc_vsync_end);
>>> +
>>> +		PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
>>> +				      DRM_MODE_FLAG_INTERLACE);
>>> +
>>> +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
>>> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
>>> +					      DRM_MODE_FLAG_PHSYNC);
>>> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
>>> +					      DRM_MODE_FLAG_NHSYNC);
>>> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
>>> +					      DRM_MODE_FLAG_PVSYNC);
>>> +			PIPE_CONF_CHECK_FLAGS(hw.transcoder_mode.flags,
>>> +					      DRM_MODE_FLAG_NVSYNC);
>>> +		}
>>> +	}
>>>  
>>>  	PIPE_CONF_CHECK_I(pixel_multiplier);
>>>  	PIPE_CONF_CHECK_I(output_format);
>>> @@ -12857,24 +12993,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>>  	PIPE_CONF_CHECK_BOOL(hdmi_scrambling);
>>>  	PIPE_CONF_CHECK_BOOL(hdmi_high_tmds_clock_ratio);
>>>  	PIPE_CONF_CHECK_BOOL(has_infoframe);
>>> -	PIPE_CONF_CHECK_BOOL(fec_enable);
>>> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
>>> +		PIPE_CONF_CHECK_BOOL(fec_enable);
>>>  
>>>  	PIPE_CONF_CHECK_BOOL_INCOMPLETE(has_audio);
>>>  
>>> -	PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>> -			      DRM_MODE_FLAG_INTERLACE);
>>> -
>>> -	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS)) {
>>> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>> -				      DRM_MODE_FLAG_PHSYNC);
>>> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>> -				      DRM_MODE_FLAG_NHSYNC);
>>> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>> -				      DRM_MODE_FLAG_PVSYNC);
>>> -		PIPE_CONF_CHECK_FLAGS(hw.adjusted_mode.flags,
>>> -				      DRM_MODE_FLAG_NVSYNC);
>>> -	}
>>> -
>>>  	PIPE_CONF_CHECK_X(gmch_pfit.control);
>>>  	/* pfit ratios are autocomputed by the hw on gen4+ */
>>>  	if (INTEL_GEN(dev_priv) < 4)
>>> @@ -12898,7 +13021,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>>  		}
>>>  
>>>  		PIPE_CONF_CHECK_I(scaler_state.scaler_id);
>>> -		PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
>>> +		if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE))
>>> +			PIPE_CONF_CHECK_CLOCK_FUZZY(pixel_rate);
>>>  
>>>  		PIPE_CONF_CHECK_X(gamma_mode);
>>>  		if (IS_CHERRYVIEW(dev_priv))
>>> @@ -12917,48 +13041,50 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>>  	PIPE_CONF_CHECK_BOOL(double_wide);
>>>  
>>>  	PIPE_CONF_CHECK_P(shared_dpll);
>>> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
>>>  	PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
>> Missing indent on this line?
>>
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.spll);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
>>> -	PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
>>> -
>>> -	PIPE_CONF_CHECK_X(dsi_pll.ctrl);
>>> -	PIPE_CONF_CHECK_X(dsi_pll.div);
>>> -
>>> -	if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
>>> -		PIPE_CONF_CHECK_I(pipe_bpp);
>>> -
>>> -	PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
>>> -	PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>>> -
>>> -	PIPE_CONF_CHECK_I(min_voltage_level);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.fp0);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.fp1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.wrpll);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.spll);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.ctrl1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr2);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.cfgcr0);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb0);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.ebb4);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll0);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll2);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll3);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll6);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll8);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll9);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pll10);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.pcsdw12);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_refclkin_ctl);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_coreclkctl1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_clktop2_hsclkctl);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div0);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_div1);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_lf);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_frac_lock);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_ssc);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_bias);
>>> +		PIPE_CONF_CHECK_X(dpll_hw_state.mg_pll_tdc_coldst_bias);
>>> +
>>> +		PIPE_CONF_CHECK_X(dsi_pll.ctrl);
>>> +		PIPE_CONF_CHECK_X(dsi_pll.div);
>>> +
>>> +		if (IS_G4X(dev_priv) || INTEL_GEN(dev_priv) >= 5)
>>> +			PIPE_CONF_CHECK_I(pipe_bpp);
>>> +
>>> +		PIPE_CONF_CHECK_CLOCK_FUZZY(hw.adjusted_mode.crtc_clock);
>>> +		PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
>>> +
>>> +		PIPE_CONF_CHECK_I(min_voltage_level);
>>> +	}
>>>  
>>>  	PIPE_CONF_CHECK_X(infoframes.enable);
>>>  	PIPE_CONF_CHECK_X(infoframes.gcp);
>>> @@ -12967,6 +13093,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>>  	PIPE_CONF_CHECK_INFOFRAME(hdmi);
>>>  	PIPE_CONF_CHECK_INFOFRAME(drm);
>>>  
>>> +	PIPE_CONF_CHECK_BOOL(bigjoiner);
>>> +	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
>>> +	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
>>> +	PIPE_CONF_CHECK_BOOL(dsc_params.compression_enable);
>>> +	PIPE_CONF_CHECK_BOOL(dsc_params.dsc_split);
>>> +
>>>  #undef PIPE_CONF_CHECK_X
>>>  #undef PIPE_CONF_CHECK_I
>>>  #undef PIPE_CONF_CHECK_BOOL
>>> @@ -13221,6 +13353,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>>>  	struct intel_encoder *encoder;
>>>  	struct intel_crtc_state *pipe_config;
>>>  	struct drm_atomic_state *state;
>>> +	struct intel_crtc *master = crtc;
>>>  	bool active;
>>>  
>>>  	state = old_crtc_state->uapi.state;
>>> @@ -13250,7 +13383,10 @@ verify_crtc_state(struct intel_crtc *crtc,
>>>  			"(expected %i, found %i)\n",
>>>  			new_crtc_state->hw.active, crtc->active);
>>>  
>>> -	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
>>> +	if (new_crtc_state->bigjoiner_slave)
>>> +		master = new_crtc_state->bigjoiner_linked_crtc;
>>> +
>>> +	for_each_encoder_on_crtc(dev, &master->base, encoder) {
>>>  		enum pipe pipe;
>>>  
>>>  		active = encoder->get_hw_state(encoder, &pipe);
>>> @@ -13259,12 +13395,12 @@ verify_crtc_state(struct intel_crtc *crtc,
>>>  				encoder->base.base.id, active,
>>>  				new_crtc_state->hw.active);
>>>  
>>> -		I915_STATE_WARN(active && crtc->pipe != pipe,
>>> +		I915_STATE_WARN(active && master->pipe != pipe,
>>>  				"Encoder connected to wrong pipe %c\n",
>>>  				pipe_name(pipe));
>>>  
>>>  		if (active)
>>> -			encoder->get_config(encoder, pipe_config);
>>> +			intel_encoder_get_config(encoder, pipe_config);
>>>  	}
>>>  
>>>  	intel_crtc_compute_pixel_rate(pipe_config);
>>> @@ -13906,6 +14042,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>>>  
>>>  	if (modeset) {
>>>  		update_scanline_offset(new_crtc_state);
>>> +		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.transcoder_mode);
>>>  		dev_priv->display.crtc_enable(new_crtc_state, state);
>>>  
>>>  		/* vblanks work again, re-enable pipe CRC. */
>>> @@ -13990,7 +14127,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>>  	 */
>>>  	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
>>>  						    new_crtc_state, i) {
>>> -		if (!needs_modeset(new_crtc_state))
>>> +		if (!needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner_slave)
>>>  			continue;
>>>  
>>>  		intel_pre_plane_update(old_crtc_state, new_crtc_state);
>>> @@ -14000,6 +14137,19 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>>  						      old_crtc_state,
>>>  						      new_crtc_state,
>>>  						      crtc);
>>> +
>>> +		if (old_crtc_state->bigjoiner) {
>>> +			struct intel_crtc *slave = old_crtc_state->bigjoiner_linked_crtc;
>>> +			struct intel_crtc_state *old_slave_crtc_state =
>>> +				intel_atomic_get_crtc_state(&state->base, slave);
>>> +			struct intel_crtc_state *new_slave_crtc_state =
>>> +				intel_atomic_get_crtc_state(&state->base, slave);
>>> +
>>> +			intel_old_crtc_state_disables(state,
>>> +						      old_slave_crtc_state,
>>> +						      new_slave_crtc_state,
>>> +						      slave);
>>> +		}
>>>  	}
>>>  }
>>>  
>>> @@ -16433,7 +16583,7 @@ int intel_modeset_init(struct drm_device *dev)
>>>  	for_each_intel_crtc(dev, crtc) {
>>>  		struct intel_initial_plane_config plane_config = {};
>>>  
>>> -		if (!crtc->active)
>>> +		if (!to_intel_crtc_state(crtc->base.state)->uapi.active)
>>>  			continue;
>>>  
>>>  		/*
>>> @@ -16923,7 +17073,17 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>>  			crtc_state = to_intel_crtc_state(crtc->base.state);
>>>  
>>>  			encoder->base.crtc = &crtc->base;
>>> -			encoder->get_config(encoder, crtc_state);
>>> +			intel_encoder_get_config(encoder, crtc_state);
>>> +
>>> +			/* read out to slave crtc as well for bigjoiner */
>>> +			if (crtc_state->bigjoiner) {
>>> +				/* encoder should read be linked to bigjoiner master */
>>> +				WARN_ON(crtc_state->bigjoiner_slave);
>>> +
>>> +				crtc = crtc_state->bigjoiner_linked_crtc;
>>> +				crtc_state = to_intel_crtc_state(crtc->base.state);
>>> +				intel_encoder_get_config(encoder, crtc_state);
>>> +			}
>>>  		} else {
>>>  			encoder->base.crtc = NULL;
>>>  		}
>>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>>> index dd0329a4b9ff..7e06c61447e6 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>>> @@ -786,6 +786,7 @@ struct intel_crtc_state {
>>>  	 * accordingly.
>>>  	 */
>>>  #define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS	(1<<0) /* unreliable sync mode.flags */
>>> +#define PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE	(1<<1) /* bigjoiner slave, partial readout */
>>>  	unsigned long quirks;
>>>  
>>>  	unsigned fb_bits; /* framebuffers to flip */
>>> @@ -1572,4 +1573,20 @@ static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state)
>>>  	return i915_ggtt_offset(state->vma);
>>>  }
>>>  
>>> +static inline bool
>>> +intel_crtc_supports_dsc(const struct intel_crtc_state *pipe_config)
>>> +{
>>> +	struct drm_i915_private *dev_priv = to_i915(pipe_config->uapi.crtc->dev);
>>> +
>>> +	/* On TGL, DSC is supported on all Pipes */
>>> +	if (INTEL_GEN(dev_priv) >= 12)
>>> +		return true;
>>> +
>>> +	if (INTEL_GEN(dev_priv) >= 10 &&
>>> +	    pipe_config->cpu_transcoder != TRANSCODER_A)
>>> +		return true;
>>> +
>>> +	return false;
>>> +}
>>> +
>>>  #endif /*  __INTEL_DISPLAY_TYPES_H__ */
>>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>>> index 3d487ce16151..234be1c31958 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>>> @@ -1907,22 +1907,6 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
>>>  		drm_dp_sink_supports_fec(intel_dp->fec_capable);
>>>  }
>>>  
>>> -static bool intel_dp_source_supports_dsc(struct intel_dp *intel_dp,
>>> -					 const struct intel_crtc_state *pipe_config)
>>> -{
>>> -	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
>>> -
>>> -	/* On TGL, DSC is supported on all Pipes */
>>> -	if (INTEL_GEN(dev_priv) >= 12)
>>> -		return true;
>>> -
>>> -	if (INTEL_GEN(dev_priv) >= 10 &&
>>> -	    pipe_config->cpu_transcoder != TRANSCODER_A)
>>> -		return true;
>>> -
>>> -	return false;
>>> -}
>>> -
>>>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>>>  				  const struct intel_crtc_state *pipe_config)
>>>  {
>>> @@ -1930,7 +1914,7 @@ static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>>>  	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable && 0)
>>>  		return false;
>>>  
>>> -	return intel_dp_source_supports_dsc(intel_dp, pipe_config) &&
>>> +	return intel_crtc_supports_dsc(pipe_config) &&
>>>  		drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
>>>  }
>>>  
>>> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
>>> index 38c181499505..11d4da9734a0 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
>>> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
>>> @@ -480,11 +480,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>>>  		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
>>>  }
>>>  
>>> -static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
>>> -						const struct intel_crtc_state *crtc_state)
>>> +static void intel_configure_pps_for_dsc_encoder(const struct intel_crtc_state *crtc_state)
>>>  {
>>>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>>  	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
>>>  	enum pipe pipe = crtc->pipe;
>>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>> @@ -494,6 +493,9 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
>>>  	u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1;
>>>  	int i = 0;
>>>  
>>> +	if (crtc_state->bigjoiner)
>>> +		num_vdsc_instances *= 2;
>>> +
>>>  	/* Populate PICTURE_PARAMETER_SET_0 registers */
>>>  	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
>>>  		DSC_VER_MIN_SHIFT |
>>> @@ -899,74 +901,104 @@ static void intel_dp_write_dsc_pps_sdp(struct intel_encoder *encoder,
>>>  					sizeof(dp_dsc_pps_sdp));
>>>  }
>>>  
>>> +static i915_reg_t dss_ctl1_reg(const struct intel_crtc_state *crtc_state)
>>> +{
>>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>> +
>>> +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
>>> +		return DSS_CTL1;
>>> +
>>> +	return ICL_PIPE_DSS_CTL1(pipe);
>>> +}
>>> +
>>> +static i915_reg_t dss_ctl2_reg(const struct intel_crtc_state *crtc_state)
>>> +{
>>> +	enum pipe pipe = to_intel_crtc(crtc_state->uapi.crtc)->pipe;
>>> +
>>> +	if (crtc_state->cpu_transcoder == TRANSCODER_EDP)
>>> +		return DSS_CTL2;
>>> +
>>> +	return ICL_PIPE_DSS_CTL2(pipe);
>>> +}
>>> +
>>>  void intel_dsc_enable(struct intel_encoder *encoder,
>>>  		      const struct intel_crtc_state *crtc_state)
>>>  {
>>>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>>> -	enum pipe pipe = crtc->pipe;
>>> -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>>  	u32 dss_ctl1_val = 0;
>>>  	u32 dss_ctl2_val = 0;
>>>  
>>>  	if (!crtc_state->dsc_params.compression_enable)
>>>  		return;
>>>  
>>> -	/* Enable Power wells for VDSC/joining */
>>> -	intel_display_power_get(dev_priv,
>>> -				intel_dsc_power_domain(crtc_state));
>>> +	intel_configure_pps_for_dsc_encoder(crtc_state);
>>>  
>>> -	intel_configure_pps_for_dsc_encoder(encoder, crtc_state);
>>> +	if (!crtc_state->bigjoiner_slave)
>>> +		intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
>>>  
>>> -	intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
>>> -
>>> -	if (crtc_state->cpu_transcoder == TRANSCODER_EDP) {
>>> -		dss_ctl1_reg = DSS_CTL1;
>>> -		dss_ctl2_reg = DSS_CTL2;
>>> -	} else {
>>> -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
>>> -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
>>> -	}
>>>  	dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
>>>  	if (crtc_state->dsc_params.dsc_split) {
>>>  		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
>>>  		dss_ctl1_val |= JOINER_ENABLE;
>>>  	}
>>> -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
>>> -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
>>> +	if (crtc_state->bigjoiner) {
>>> +		dss_ctl1_val |= BIG_JOINER_ENABLE;
>>> +		if (!crtc_state->bigjoiner_slave)
>>> +			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
>>> +	}
>>> +	I915_WRITE(dss_ctl1_reg(crtc_state), dss_ctl1_val);
>>> +	I915_WRITE(dss_ctl2_reg(crtc_state), dss_ctl2_val);
>>>  }
>>>  
>>>  void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
>>>  {
>>>  	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
>>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> -	enum pipe pipe = crtc->pipe;
>>> -	i915_reg_t dss_ctl1_reg, dss_ctl2_reg;
>>> -	u32 dss_ctl1_val = 0, dss_ctl2_val = 0;
>>>  
>>>  	if (!old_crtc_state->dsc_params.compression_enable)
>>>  		return;
>>>  
>>> -	if (old_crtc_state->cpu_transcoder == TRANSCODER_EDP) {
>>> -		dss_ctl1_reg = DSS_CTL1;
>>> -		dss_ctl2_reg = DSS_CTL2;
>>> -	} else {
>>> -		dss_ctl1_reg = ICL_PIPE_DSS_CTL1(pipe);
>>> -		dss_ctl2_reg = ICL_PIPE_DSS_CTL2(pipe);
>>> +	I915_WRITE(dss_ctl1_reg(old_crtc_state), 0);
>>> +	I915_WRITE(dss_ctl2_reg(old_crtc_state), 0);
>>> +}
>>> +
>>> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
>>> +{
>>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>>> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>> +	u32 dss_ctl1_val, dss_ctl2_val;
>>> +	intel_wakeref_t wakeref;
>>> +
>>> +	if (!intel_crtc_supports_dsc(crtc_state))
>>> +		return;
>>> +
>>> +	wakeref = intel_display_power_get_if_enabled(dev_priv, intel_dsc_power_domain(crtc_state));
>>> +	if (!wakeref)
>>> +		return;
>>> +
>>> +	dss_ctl1_val = I915_READ(dss_ctl1_reg(crtc_state));
>>> +	dss_ctl2_val = I915_READ(dss_ctl2_reg(crtc_state));
>>> +	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE)
>>> +		crtc_state->dsc_params.compression_enable = true;
>>> +
>>> +	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
>>> +		crtc_state->dsc_params.dsc_split = true;
>>> +
>>> +	if (dss_ctl1_val & BIG_JOINER_ENABLE) {
>>> +		crtc_state->bigjoiner = true;
> Is crtc_state->bigjoiner supposed to be set on both master and slave or
> just on the master?  I thought we only set it for the master based on
> what I see in intel_dp_dsc_compute_config, but this appears to set in on
> both during readout (my interpretation of bspec #50174 is that bit 29 is
> set on both master and slave, whereas bit 28 is only set on the master).
> Should this be testing against MASTER_BIG_JOINER_ENABLE instead?
This is correct, we copy the entire crtc_state to the slave, including the bigjoiner flag.
>
> Matt
>
>>> +
>>> +		if (!(dss_ctl1_val & MASTER_BIG_JOINER_ENABLE)) {
>>> +			crtc_state->bigjoiner_slave = true;
>>> +			if (!WARN_ON(crtc->pipe == PIPE_A))
>>> +				crtc_state->bigjoiner_linked_crtc =
>>> +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe - 1);
>>> +		} else {
>>> +			if (!WARN_ON(INTEL_NUM_PIPES(dev_priv) == crtc->pipe + 1))
>>> +				crtc_state->bigjoiner_linked_crtc =
>>> +					intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
>>> +		}
>>>  	}
>>> -	dss_ctl1_val = I915_READ(dss_ctl1_reg);
>>> -	if (dss_ctl1_val & JOINER_ENABLE)
>>> -		dss_ctl1_val &= ~JOINER_ENABLE;
>>> -	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
>>> -
>>> -	dss_ctl2_val = I915_READ(dss_ctl2_reg);
>>> -	if (dss_ctl2_val & LEFT_BRANCH_VDSC_ENABLE ||
>>> -	    dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE)
>>> -		dss_ctl2_val &= ~(LEFT_BRANCH_VDSC_ENABLE |
>>> -				  RIGHT_BRANCH_VDSC_ENABLE);
>>> -	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
>>> -
>>> -	/* Disable Power wells for VDSC/joining */
>>> -	intel_display_power_put_unchecked(dev_priv,
>>> -					  intel_dsc_power_domain(old_crtc_state));
>>> +
>>> +	intel_display_power_put(dev_priv, intel_dsc_power_domain(crtc_state), wakeref);
>>>  }
>>> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
>>> index 90d3f6017fcb..569cf17402ba 100644
>>> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
>>> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
>>> @@ -15,6 +15,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>>>  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
>>>  int intel_dp_compute_dsc_params(struct intel_dp *intel_dp,
>>>  				struct intel_crtc_state *pipe_config);
>>> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state);
>>> +
>>>  enum intel_display_power_domain
>>>  intel_dsc_power_domain(const struct intel_crtc_state *crtc_state);
>>>  
>>> -- 
>>> 2.20.1
>>>
>>> _______________________________________________
>>> Intel-gfx mailing list
>>> Intel-gfx@lists.freedesktop.org
>>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
>> -- 
>> Matt Roper
>> Graphics Software Engineer
>> VTT-OSGC Platform Enablement
>> Intel Corporation
>> (916) 356-2795
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-26 19:11         ` Ville Syrjälä
@ 2019-09-27  8:56           ` Maarten Lankhorst
  2019-09-27 14:41             ` Ville Syrjälä
  0 siblings, 1 reply; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-27  8:56 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 26-09-2019 om 21:11 schreef Ville Syrjälä:
> On Thu, Sep 26, 2019 at 07:09:22PM +0300, Ville Syrjälä wrote:
>> On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
>>> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
>>>> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
>>>>> Now that we can program planes from the update_slave callback, and
>>>>> we have done all fb pinning correctly, it's time to program those
>>>>> planes as well.
>>>>>
>>>>> We use the update_slave callback as it allows us to use the
>>>>> separate states correctly.
>>>>>
>>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>>>> ---
>>>>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
>>>>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
>>>>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
>>>>>  3 files changed, 57 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>> index cc088676f0a2..5db091e4ad6a 100644
>>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
>>>>>  	}
>>>>>  }
>>>>>  
>>>>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
>>>>> +					 struct intel_crtc *crtc)
>>>> This plane stuff is where things go very much off the rails IMO.
>>>> Planes should not have to know anything about bigjoiner. They should
>>>> just have their appropriate hw state and blindly bash it into the
>>>> hardware.
>>> We already need this for planar slave/master, what's the issue exactly?
>> That already is too fragile. I don't want this spreading all over
>> the driver and coupling everything to the bigjoiner logic.
>>
>> Here's a crude idea how I think we might avoid this:
>> git://github.com/vsyrjala/linux.git uapi_hw_state_split
>>
>> But I didn't dare boot it yet...
> It took a handful extra fixes to get that to boot. But now I at least
> get a picture on the screen instead of oopses.
>
> Fixes pushed to the same branch.
>
> Looks like still something going wrong with the cursor ioctl though.
>
I've done a uapi-hw split in my series, is that ok with you?

I will do a similar split for planes.

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-27  8:56           ` Maarten Lankhorst
@ 2019-09-27 14:41             ` Ville Syrjälä
  2019-09-27 15:00               ` Ville Syrjälä
  0 siblings, 1 reply; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-27 14:41 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 27, 2019 at 10:56:16AM +0200, Maarten Lankhorst wrote:
> Op 26-09-2019 om 21:11 schreef Ville Syrjälä:
> > On Thu, Sep 26, 2019 at 07:09:22PM +0300, Ville Syrjälä wrote:
> >> On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
> >>> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> >>>> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> >>>>> Now that we can program planes from the update_slave callback, and
> >>>>> we have done all fb pinning correctly, it's time to program those
> >>>>> planes as well.
> >>>>>
> >>>>> We use the update_slave callback as it allows us to use the
> >>>>> separate states correctly.
> >>>>>
> >>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >>>>> ---
> >>>>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
> >>>>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
> >>>>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
> >>>>>  3 files changed, 57 insertions(+), 2 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>> index cc088676f0a2..5db091e4ad6a 100644
> >>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> >>>>>  	}
> >>>>>  }
> >>>>>  
> >>>>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> >>>>> +					 struct intel_crtc *crtc)
> >>>> This plane stuff is where things go very much off the rails IMO.
> >>>> Planes should not have to know anything about bigjoiner. They should
> >>>> just have their appropriate hw state and blindly bash it into the
> >>>> hardware.
> >>> We already need this for planar slave/master, what's the issue exactly?
> >> That already is too fragile. I don't want this spreading all over
> >> the driver and coupling everything to the bigjoiner logic.
> >>
> >> Here's a crude idea how I think we might avoid this:
> >> git://github.com/vsyrjala/linux.git uapi_hw_state_split
> >>
> >> But I didn't dare boot it yet...
> > It took a handful extra fixes to get that to boot. But now I at least
> > get a picture on the screen instead of oopses.
> >
> > Fixes pushed to the same branch.
> >
> > Looks like still something going wrong with the cursor ioctl though.
> >
> I've done a uapi-hw split in my series, is that ok with you?
> 
> I will do a similar split for planes.

I sent out some prep fixes, and respun my test branch as
uapi_hw_state_split_2. Even the legacy cursor now works.
So I think we might even have a chance of making this state
split thing work.

My suggestion on how to do it would be:

1. split the state and do the uapi<->hw copies, but leave the hw state still
   called 'base' to minimize the diff. We can then more easily see all
   the places where we have to consult to the uapi state.
2. probably do the base->hw rename with cocci or something

I think at least one thing missing from your split crtc state was
plane_mask. I added the required helpers for that in my prep patches.

I'm not 100% sure what we should do with the mode_change etc. flags. I
guess we can leave them just in the uapi state as long as we don't get
confused by the appearance of the 'uapi' name in various places.

Oh and to split the state for planes we'll need to hand roll our own
drm_atomic_helper_check_plane_state(). I didn't do that in my prep
patches because I was lazy.

Oh and drm_atomic_helper_setup_commit() is a big problem. In my test
branch I just copy pasted it to i915 and changed it to check the hw
state instead of the uapi state. But I don't really like that apporoach
so maybe we could reuse this helper still and just abstract away the
crtc active check.

Maybe have the caller pass in a function like so?

int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
                                  bool nonblock,
				  bool (*crtc_is_active)(const struct drm_crtc_state *crtc_state));
{
	...
-	if (!old_crtc_state->active && !new_crtc_state->active) {
+       if (!crtc_is_active(old_crtc_state) && !crtc_is_active(new_crtc_state)) {
	...

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 16/23] drm/i915: Program planes in bigjoiner mode.
  2019-09-27 14:41             ` Ville Syrjälä
@ 2019-09-27 15:00               ` Ville Syrjälä
  0 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-09-27 15:00 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 27, 2019 at 05:41:49PM +0300, Ville Syrjälä wrote:
> On Fri, Sep 27, 2019 at 10:56:16AM +0200, Maarten Lankhorst wrote:
> > Op 26-09-2019 om 21:11 schreef Ville Syrjälä:
> > > On Thu, Sep 26, 2019 at 07:09:22PM +0300, Ville Syrjälä wrote:
> > >> On Thu, Sep 26, 2019 at 05:50:05PM +0200, Maarten Lankhorst wrote:
> > >>> Op 26-09-2019 om 15:06 schreef Ville Syrjälä:
> > >>>> On Fri, Sep 20, 2019 at 01:42:28PM +0200, Maarten Lankhorst wrote:
> > >>>>> Now that we can program planes from the update_slave callback, and
> > >>>>> we have done all fb pinning correctly, it's time to program those
> > >>>>> planes as well.
> > >>>>>
> > >>>>> We use the update_slave callback as it allows us to use the
> > >>>>> separate states correctly.
> > >>>>>
> > >>>>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > >>>>> ---
> > >>>>>  .../gpu/drm/i915/display/intel_atomic_plane.c | 53 +++++++++++++++++++
> > >>>>>  .../gpu/drm/i915/display/intel_atomic_plane.h |  2 +
> > >>>>>  drivers/gpu/drm/i915/display/intel_display.c  |  4 +-
> > >>>>>  3 files changed, 57 insertions(+), 2 deletions(-)
> > >>>>>
> > >>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>> index cc088676f0a2..5db091e4ad6a 100644
> > >>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>> @@ -366,6 +366,59 @@ void skl_update_planes_on_crtc(struct intel_atomic_state *state,
> > >>>>>  	}
> > >>>>>  }
> > >>>>>  
> > >>>>> +void icl_update_bigjoiner_planes_on_crtc(struct intel_atomic_state *state,
> > >>>>> +					 struct intel_crtc *crtc)
> > >>>> This plane stuff is where things go very much off the rails IMO.
> > >>>> Planes should not have to know anything about bigjoiner. They should
> > >>>> just have their appropriate hw state and blindly bash it into the
> > >>>> hardware.
> > >>> We already need this for planar slave/master, what's the issue exactly?
> > >> That already is too fragile. I don't want this spreading all over
> > >> the driver and coupling everything to the bigjoiner logic.
> > >>
> > >> Here's a crude idea how I think we might avoid this:
> > >> git://github.com/vsyrjala/linux.git uapi_hw_state_split
> > >>
> > >> But I didn't dare boot it yet...
> > > It took a handful extra fixes to get that to boot. But now I at least
> > > get a picture on the screen instead of oopses.
> > >
> > > Fixes pushed to the same branch.
> > >
> > > Looks like still something going wrong with the cursor ioctl though.
> > >
> > I've done a uapi-hw split in my series, is that ok with you?
> > 
> > I will do a similar split for planes.
> 
> I sent out some prep fixes, and respun my test branch as
> uapi_hw_state_split_2. Even the legacy cursor now works.
> So I think we might even have a chance of making this state
> split thing work.

Drat. At least kms_big_fb is busted. Need to figure out why.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check.
  2019-09-26  3:48   ` Matt Roper
@ 2019-09-30 14:12     ` Maarten Lankhorst
  0 siblings, 0 replies; 82+ messages in thread
From: Maarten Lankhorst @ 2019-09-30 14:12 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

Op 26-09-2019 om 05:48 schreef Matt Roper:
> On Fri, Sep 20, 2019 at 01:42:23PM +0200, Maarten Lankhorst wrote:
>> When the clock is higher than the dotclock, try with 2 pipes enabled.
>> If we can enable 2, then we will go into big joiner mode, and steal
>> the adjacent crtc.
>>
>> This only links the crtc's in software, no hardware or plane
>> programming is done yet. Blobs are also copied from the master's
>> crtc_state, so it doesn't depend at commit time on the other
>> crtc_state.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_atomic.c   |  15 +-
>>  drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 197 +++++++++++++++++-
>>  .../drm/i915/display/intel_display_types.h    |  11 +-
>>  drivers/gpu/drm/i915/display/intel_dp.c       |  25 ++-
>>  5 files changed, 228 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index c50e0b218bd6..0db04064c86e 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -228,25 +228,26 @@ void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state)
>>  	intel_crtc_put_color_blobs(crtc_state);
>>  }
>>  
>> -void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state)
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
>> +				 const struct intel_crtc_state *from_crtc_state)
>>  {
>>  	intel_crtc_put_color_blobs(crtc_state);
>>  
>> -	if (crtc_state->uapi.degamma_lut)
>> +	if (from_crtc_state->uapi.degamma_lut)
>>  		crtc_state->hw.degamma_lut =
>> -			drm_property_blob_get(crtc_state->uapi.degamma_lut);
>> +			drm_property_blob_get(from_crtc_state->uapi.degamma_lut);
>>  	else
>>  		crtc_state->hw.degamma_lut = NULL;
>>  
>> -	if (crtc_state->uapi.gamma_lut)
>> +	if (from_crtc_state->uapi.gamma_lut)
>>  		crtc_state->hw.gamma_lut =
>> -			drm_property_blob_get(crtc_state->uapi.gamma_lut);
>> +			drm_property_blob_get(from_crtc_state->uapi.gamma_lut);
>>  	else
>>  		crtc_state->hw.gamma_lut = NULL;
>>  
>> -	if (crtc_state->uapi.ctm)
>> +	if (from_crtc_state->uapi.ctm)
>>  		crtc_state->hw.ctm =
>> -			drm_property_blob_get(crtc_state->uapi.ctm);
>> +			drm_property_blob_get(from_crtc_state->uapi.ctm);
>>  	else
>>  		crtc_state->hw.ctm = NULL;
>>  }
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
>> index 42be91e0772a..8da84d64aa04 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
>> @@ -36,7 +36,8 @@ struct drm_crtc_state *intel_crtc_duplicate_state(struct drm_crtc *crtc);
>>  void intel_crtc_destroy_state(struct drm_crtc *crtc,
>>  			       struct drm_crtc_state *state);
>>  void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state);
>> -void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state);
>> +void intel_crtc_copy_color_blobs(struct intel_crtc_state *crtc_state,
>> +				 const struct intel_crtc_state *from_crtc_state);
>>  struct drm_atomic_state *intel_atomic_state_alloc(struct drm_device *dev);
>>  void intel_atomic_state_clear(struct drm_atomic_state *state);
>>  
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index ba52a70840fd..143d531c4c81 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -7434,7 +7434,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>>  				     struct intel_crtc_state *pipe_config)
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>> -	const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>> +	struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
>>  	int clock_limit = dev_priv->max_dotclk_freq;
>>  
>>  	if (INTEL_GEN(dev_priv) < 4) {
>> @@ -7451,6 +7451,25 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>>  		}
>>  	}
>>  
>> +	/*
>> +	 * copy hw mode to transcoder mode.
>> +	 * This matters mostly for big joiner, which splits the mode in half.
>> +	 */
>> +	pipe_config->hw.transcoder_mode = pipe_config->hw.adjusted_mode;
>> +	if (pipe_config->bigjoiner) {
>> +		/* Make sure the crtc config is halved horizontally */
>> +		adjusted_mode->crtc_clock /= 2;
>> +		adjusted_mode->crtc_hdisplay /= 2;
>> +		adjusted_mode->crtc_hblank_start /= 2;
>> +		adjusted_mode->crtc_hblank_end /= 2;
>> +		adjusted_mode->crtc_hsync_start /= 2;
>> +		adjusted_mode->crtc_hsync_end /= 2;
>> +		adjusted_mode->crtc_htotal /= 2;
>> +		adjusted_mode->crtc_hskew /= 2;
> If adjusted_mode is the "pipe mode," does anything other than the size
> have meaning or matter at that level?  Not that halving the rest of
> these hurts anything, it just seems strange to consider them at the pipe
> level.

Correct.

A few places look at crtc_htotal/vtotal, for example pixel rate calculations,
watermarks and pipe scaler.

transcoder gets the full mode covering both pipes, anything else looks at the
reduced mode in order to not break anything. :)

>> +
>> +		pipe_config->pipe_src_w /= 2;
>> +	}
>> +
>>  	if (adjusted_mode->crtc_clock > clock_limit) {
>>  		DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
>>  			      adjusted_mode->crtc_clock, clock_limit,
>> @@ -8133,7 +8152,7 @@ static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
> We may want to rename this function to intel_set_transcoder_timings
> now that pipe and transcoder are starting to be different.
+1, will fix.
>
>
>>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
>>  	enum pipe pipe = crtc->pipe;
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>> -	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
>> +	const struct drm_display_mode *adjusted_mode = &crtc_state->hw.transcoder_mode;
>>  	u32 crtc_vtotal, crtc_vblank_end;
>>  	int vsyncshift = 0;
>>  
>> @@ -11774,6 +11793,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  		to_intel_crtc_state(_crtc_state);
>>  	int ret;
>>  	bool mode_changed = needs_modeset(crtc_state);
>> +	struct intel_atomic_state *state =
>> +		to_intel_atomic_state(crtc_state->uapi.state);
>>  
>>  	if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv) &&
>>  	    mode_changed && !crtc_state->hw.active)
>> @@ -11781,6 +11802,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  
>>  	if (mode_changed && crtc_state->hw.enable &&
>>  	    dev_priv->display.crtc_compute_clock &&
>> +	    !crtc_state->bigjoiner_slave &&
>>  	    !WARN_ON(crtc_state->shared_dpll)) {
>>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>>  		if (ret)
>> @@ -11796,8 +11818,15 @@ static int intel_crtc_atomic_check(struct drm_crtc *_crtc,
>>  
>>  	if (mode_changed || crtc_state->update_pipe ||
>>  	    crtc_state->uapi.color_mgmt_changed) {
>> +		const struct intel_crtc_state *master_crtc_state = crtc_state;
>> +
>> +		if (crtc_state->bigjoiner_slave)
>> +			master_crtc_state =
>> +				intel_atomic_get_new_crtc_state(state,
>> +					crtc_state->bigjoiner_linked_crtc);
>> +
>>  		/* Copy color blobs to hw state */
>> -		intel_crtc_copy_color_blobs(crtc_state);
>> +		intel_crtc_copy_color_blobs(crtc_state, master_crtc_state);
>>  
>>  		ret = intel_color_check(crtc_state);
>>  		if (ret)
>> @@ -12259,7 +12288,48 @@ static void copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>>  	crtc_state->uapi.active = crtc_state->hw.active;
>>  	crtc_state->uapi.mode = crtc_state->hw.mode;
>> -	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>> +	crtc_state->uapi.adjusted_mode = crtc_state->hw.transcoder_mode;
>> +}
>> +
>> +static int
>> +copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
>> +			  const struct intel_crtc_state *from_crtc_state)
>> +{
>> +	struct intel_crtc_state *saved_state;
>> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> +
>> +	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
>> +	if (!saved_state)
>> +		return -ENOMEM;
>> +
>> +	saved_state->uapi = crtc_state->uapi;
>> +	saved_state->scaler_state = crtc_state->scaler_state;
>> +	saved_state->shared_dpll = crtc_state->shared_dpll;
>> +	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
>> +	saved_state->crc_enabled = crtc_state->crc_enabled;
>> +
>> +	intel_crtc_free_hw_state(crtc_state);
>> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>> +	kfree(saved_state);
>> +
>> +	/* Re-init hw state */
>> +	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
>> +	crtc_state->hw.enable = from_crtc_state->hw.enable;
>> +	crtc_state->hw.active = from_crtc_state->hw.active;
>> +	crtc_state->hw.mode = from_crtc_state->hw.mode;
>> +	crtc_state->hw.adjusted_mode = from_crtc_state->hw.adjusted_mode;
>> +
>> +	/* Some fixups */
>> +	crtc_state->uapi.mode_changed = from_crtc_state->uapi.mode_changed;
>> +	crtc_state->uapi.connectors_changed = from_crtc_state->uapi.connectors_changed;
>> +	crtc_state->uapi.active_changed = from_crtc_state->uapi.active_changed;
>> +	crtc_state->nv12_planes = crtc_state->c8_planes = crtc_state->update_planes = 0;
>> +	crtc_state->bigjoiner_linked_crtc = to_intel_crtc(from_crtc_state->uapi.crtc);
>> +	crtc_state->bigjoiner_slave = true;
>> +	crtc_state->cpu_transcoder = (enum transcoder)crtc->pipe;
>> +	crtc_state->has_audio = false;
>> +
>> +	return 0;
>>  }
>>  
>>  static int
>> @@ -12432,7 +12502,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  		      base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>>  
>>  	/* uapi wants a copy of the adjusted_mode for vblank bookkeeping */
>> -	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>> +	pipe_config->uapi.adjusted_mode = pipe_config->hw.transcoder_mode;
>>  
>>  	return 0;
>>  }
>> @@ -13549,6 +13619,109 @@ static void intel_crtc_check_fastset(const struct intel_crtc_state *old_crtc_sta
>>  	new_crtc_state->has_drrs = old_crtc_state->has_drrs;
>>  }
>>  
>> +static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>> +	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
>> +	struct intel_crtc *crtc, *slave, *master;
>> +	int i, ret = 0;
>> +
>> +	if (INTEL_GEN(dev_priv) < 11)
>> +		return 0;
>> +
>> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>> +					    new_crtc_state, i) {
>> +		if (!old_crtc_state->bigjoiner_slave)
>> +			continue;
>> +
>> +		if (crtc->pipe == PIPE_A) {
> Rather than a hardcoded PIPE_A check, should we have a bitmask of pipes
> that can be big joiner masters somewhere?  mask = 0b111 for gen12, but
> mask = 0b010 for gen11.  Then the allowable slaves
> would be mask << 1, which would also ensure gen11 doesn't allow a slave on pipe B.
>
>> +			DRM_ERROR("Bigjoiner slave on pipe A?\n");
> We should probably just use a WARN_ON() in the condition above since
> this shouldn't happen unless we screwed up somewhere in the driver.
>
>> +			return -EINVAL;
>> +		}
>> +
>> +		/* crtc staying in slave mode? */
>> +		if (!new_crtc_state->uapi.enable)
>> +			continue;
>> +
>> +		if (needs_modeset(new_crtc_state) || new_crtc_state->update_pipe) {
> Won't needs_modeset() always return true here?  I.e., if we were a slave
> previously but didn't bail on the uapi.enable check above, then
> uapi.enable is flipping from false to true.
>
> Given that enabling the previously-slave CRTC is only possible if the
> previously-master CRTC is also modesetting in a way that won't need a
> slave anymore, it seems like the next step would be
>
>         master_crtc_state = intel_get_existing_crtc_state()
>         if (!master_crtc_state || !needs_modeset(master_crtc_state))
>                 fail
>                 
> otherwise we've now overcommitted our slave CRTC.
>
>> +			master = old_crtc_state->bigjoiner_linked_crtc;
>> +			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
>> +			if (IS_ERR(master_crtc_state))
>> +				return PTR_ERR(master_crtc_state);
>> +
>> +			/*
>> +			 * Force modeset on master, to recalculate bigjoiner
>> +			 * state.
>> +			 *
>> +			 * If master_crtc_state was not part of the atomic commit,
>> +			 * we will fail because the master was not deconfigured,
>> +			 * but at least fail below to unify the checks.
>> +			 */
>> +			master_crtc_state->uapi.mode_changed = true;
> Should we instead update intel_pipe_config_compare to check bigjoiner
> fields and prevent fastsets on states currently using the bigjoiner? 
>
>> +
>> +			ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
>> +			if (ret)
>> +				return ret;
>> +
>> +			ret = drm_atomic_add_affected_connectors(&state->base, &crtc->base);
>> +			if (ret)
>> +				return ret;
>> +		}
>> +	}
>> +
>> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>> +					    new_crtc_state, i) {
>> +		if (!new_crtc_state->uapi.enable || !new_crtc_state->bigjoiner) {
>> +			if (!old_crtc_state->bigjoiner)
>> +				continue;
>> +		}
>> +
>> +		if (!needs_modeset(new_crtc_state) && !new_crtc_state->update_pipe)
>> +			continue;
>> +
>> +		if (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave) {
>> +			if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
>> +				DRM_DEBUG_KMS("Big joiner configuration requires CRTC + 1 to be used, doesn't exist\n");
>> +				return -EINVAL;
>> +			}
>> +
>> +			slave = new_crtc_state->bigjoiner_linked_crtc =
>> +				intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
>> +			slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave);
>> +			if (IS_ERR(slave_crtc_state))
>> +				return PTR_ERR(slave_crtc_state);
>> +
>> +			if (slave_crtc_state->uapi.enable) {
>> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires this CRTC to be unconfigured\n",
>> +					      slave->base.base.id, slave->base.name);
>> +				return -EINVAL;
>> +			} else {
>> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
>> +					      slave->base.base.id, slave->base.name);
>> +				ret = copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
>> +			}
>> +		} else {
>> +			master = new_crtc_state->bigjoiner_linked_crtc;
>> +			if (!master)
>> +				continue;
>> +
> What about the case of a CRTC that previously needed the bigjoiner but
> is performing a modeset such that it no longer does?  In that case
> new_crtc_state->bigjoiner will be false so we'll end up in this branch.
> But then we seem to be trying to grab the ex-master's master which
> doesn't make sense for this case since we actually want to grab the
> slave and clear it out.
>
> The code in this branch seems to be trying to operate on a CRTC that was
> previously a slave, but assuming an ex-slave is staying disabled
> (!new_crtc_state->uapi.enable), then I think we took the 'continue' at
> the top of the loop and never make it down here.
>
>> +			master_crtc_state = intel_atomic_get_crtc_state(&state->base, master);
>> +			if (IS_ERR(master_crtc_state))
>> +				return PTR_ERR(master_crtc_state);
>> +
>> +			if (!master_crtc_state->uapi.enable && !new_crtc_state->uapi.enable) {
>> +				DRM_DEBUG_KMS("[CRTC:%d:%s] Disabling slave from big joiner\n",
>> +					      crtc->base.base.id, crtc->base.name);
>> +				ret = clear_intel_crtc_state(new_crtc_state);
>> +			}
>> +		}
>> +		if (ret)
>> +			return ret;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  /**
>>   * intel_atomic_check - validate state object
>>   * @dev: drm device
>> @@ -13583,7 +13756,10 @@ static int intel_atomic_check(struct drm_device *dev,
>>  
>>  		if (!new_crtc_state->uapi.enable) {
>>  			any_ms = true;
>> -			clear_intel_crtc_state(new_crtc_state);
>> +
>> +			/* big joiner slave is cleared in intel_atomic_check_bigjoiner() */
>> +			if (!new_crtc_state->bigjoiner_slave)
>> +				clear_intel_crtc_state(new_crtc_state);
>>  			continue;
>>  		}
>>  
>> @@ -13597,6 +13773,10 @@ static int intel_atomic_check(struct drm_device *dev,
>>  			any_ms = true;
>>  	}
>>  
>> +	ret = intel_atomic_check_bigjoiner(state);
>> +	if (ret)
>> +		return ret;
>> +
>>  	ret = drm_dp_mst_atomic_check(&state->base);
>>  	if (ret)
>>  		goto fail;
>> @@ -13747,7 +13927,9 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>>  
>>  	commit_pipe_config(state, old_crtc_state, new_crtc_state);
>>  
>> -	if (INTEL_GEN(dev_priv) >= 9)
>> +	if (new_crtc_state->bigjoiner)
>> +		{/* Not supported yet */}
>> +	else if (INTEL_GEN(dev_priv) >= 9)
>>  		skl_update_planes_on_crtc(state, crtc);
>>  	else
>>  		i9xx_update_planes_on_crtc(state, crtc);
>> @@ -16846,7 +17028,6 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  		}
>>  
>>  		intel_bw_crtc_update(bw_state, crtc_state);
>> -
>>  		copy_hw_to_uapi_state(crtc_state);
>>  		intel_pipe_config_sanity_check(dev_priv, crtc_state);
>>  	}
> Strap whitespace change.
>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 394f84e5d583..dd0329a4b9ff 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -774,7 +774,7 @@ struct intel_crtc_state {
>>  	struct {
>>  		bool active, enable;
>>  		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
>> -		struct drm_display_mode mode, adjusted_mode;
>> +		struct drm_display_mode mode, adjusted_mode, transcoder_mode;
>>  	} hw;
>>  
>>  	/**
>> @@ -1005,6 +1005,15 @@ struct intel_crtc_state {
>>  	/* enable pipe csc? */
>>  	bool csc_enable;
>>  
>> +	/* enable pipe big joiner? */
>> +	bool bigjoiner;
>> +
>> +	/* big joiner slave crtc? */
>> +	bool bigjoiner_slave;
>> +
>> +	/* linked crtc for bigjoiner, either slave or master */
>> +	struct intel_crtc *bigjoiner_linked_crtc;
>> +
>>  	/* Display Stream compression state */
>>  	struct {
>>  		bool compression_enable;
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 046e1662d1e3..3d487ce16151 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -2105,6 +2105,19 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>  	pipe_config->port_clock = intel_dp->common_rates[limits->max_clock];
>>  	pipe_config->lane_count = limits->max_lane_count;
>>  
>> +	if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, false)) {
>> +		if (adjusted_mode->crtc_clock > intel_dp_downstream_max_dotclock(intel_dp, true)) {
>> +			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
>> +			return -EINVAL;
>> +		}
>> +		if (intel_dp_is_edp(intel_dp)) {
>> +			DRM_DEBUG_KMS("Cannot split eDP stream in bigjoiner configuration.\n");
>> +			return -EINVAL;
>> +		}
>> +		pipe_config->bigjoiner = true;
>> +		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
>> +	}
>> +
>>  	if (intel_dp_is_edp(intel_dp)) {
>>  		pipe_config->dsc_params.compressed_bpp =
>>  			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
>> @@ -2122,12 +2135,12 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>  						    pipe_config->lane_count,
>>  						    adjusted_mode->crtc_clock,
>>  						    adjusted_mode->crtc_hdisplay,
>> -						    false);
>> +						    pipe_config->bigjoiner);
>>  		dsc_dp_slice_count =
>>  			intel_dp_dsc_get_slice_count(intel_dp,
>>  						     adjusted_mode->crtc_clock,
>>  						     adjusted_mode->crtc_hdisplay,
>> -						     false);
>> +						     pipe_config->bigjoiner);
>>  		if (!dsc_max_output_bpp || !dsc_dp_slice_count) {
>>  			DRM_DEBUG_KMS("Compressed BPP/Slice Count not supported\n");
>>  			return -EINVAL;
>> @@ -2142,13 +2155,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>  	 * is greater than the maximum Cdclock and if slice count is even
>>  	 * then we need to use 2 VDSC instances.
>>  	 */
>> -	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq) {
>> -		if (pipe_config->dsc_params.slice_count > 1) {
>> -			pipe_config->dsc_params.dsc_split = true;
>> -		} else {
>> +	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq || pipe_config->bigjoiner) {
>> +		if (pipe_config->dsc_params.slice_count < 2) {
>>  			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
>>  			return -EINVAL;
>>  		}
>> +
>> +		pipe_config->dsc_params.dsc_split = true;
>>  	}
>>  
>>  	ret = intel_dp_compute_dsc_params(intel_dp, pipe_config);
>> -- 
>> 2.20.1
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration.
  2019-09-20 11:42 ` [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration Maarten Lankhorst
@ 2019-10-01 16:44   ` Matt Roper
  2019-10-01 17:21     ` Ville Syrjälä
  0 siblings, 1 reply; 82+ messages in thread
From: Matt Roper @ 2019-10-01 16:44 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Fri, Sep 20, 2019 at 01:42:27PM +0200, Maarten Lankhorst wrote:
> Make sure that when a plane is set in a bigjoiner mode, we will add
> their counterpart to the atomic state as well. This will allow us to
> make sure all state is available when planes are checked.
> 
> Because of the funny interactions with bigjoiner and planar YUV
> formats, we may end up adding a lot of planes, so we have to keep
> iterating until we no longer add any planes.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c |  31 +++-
>  .../gpu/drm/i915/display/intel_atomic_plane.h |   4 +
>  drivers/gpu/drm/i915/display/intel_display.c  | 142 ++++++++++++++++--
>  .../drm/i915/display/intel_display_types.h    |  11 ++
>  4 files changed, 172 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 964db7774d10..cc088676f0a2 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -182,16 +182,36 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  					       old_plane_state, new_plane_state);
>  }
>  
> -static struct intel_crtc *
> -get_crtc_from_states(const struct intel_plane_state *old_plane_state,
> -		     const struct intel_plane_state *new_plane_state)
> -{
> +struct intel_crtc *
> +intel_plane_get_crtc_from_states(struct intel_atomic_state *state,

This function name seems ambiguous now since it isn't clear whether
we're getting the plane's hardware CRTC or its uapi CRTC.  Maybe call it
something like intel_plane_state_get_uapi_crtc()?



> +				 const struct intel_plane_state *old_plane_state,
> +				 const struct intel_plane_state *new_plane_state)
> +  {
> +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +	struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
> +
>  	if (new_plane_state->base.crtc)
>  		return to_intel_crtc(new_plane_state->base.crtc);
>  
>  	if (old_plane_state->base.crtc)
>  		return to_intel_crtc(old_plane_state->base.crtc);
>  
> +	if (new_plane_state->bigjoiner_slave) {
> +		const struct intel_plane_state *new_master_plane_state =
> +			intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
> +
> +		if (new_master_plane_state->base.crtc)
> +			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> +	}

Will this cause problems if we adjust properties of planes on a a
uapi-disabled CRTC?  E.g., I believe userspace can fiddle with stuff
like rotation properties on disabled planes/crtcs and now I believe that
causes us to needlessly pull in the bigjoiner master crtc and
corresponding plane?

> +
> +	if (old_plane_state->bigjoiner_slave) {
> +		const struct intel_plane_state *old_master_plane_state =
> +			intel_atomic_get_old_plane_state(state, old_plane_state->bigjoiner_plane);
> +
> +		if (old_master_plane_state->base.crtc)
> +			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> +	}
> +
>  	return NULL;
>  }
>  
> @@ -206,7 +226,8 @@ static int intel_plane_atomic_check(struct drm_plane *_plane,
>  	const struct intel_plane_state *old_plane_state =
>  		intel_atomic_get_old_plane_state(state, plane);
>  	struct intel_crtc *crtc =
> -		get_crtc_from_states(old_plane_state, new_plane_state);
> +		intel_plane_get_crtc_from_states(state, old_plane_state,
> +						 new_plane_state);
>  	const struct intel_crtc_state *old_crtc_state;
>  	struct intel_crtc_state *new_crtc_state;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index 33fb85cd3909..901a50e6e2d3 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -42,5 +42,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
>  				    struct intel_crtc_state *crtc_state,
>  				    const struct intel_plane_state *old_plane_state,
>  				    struct intel_plane_state *plane_state);
> +struct intel_crtc *
> +intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
> +				 const struct intel_plane_state *old_plane_state,
> +				 const struct intel_plane_state *new_plane_state);
>  
>  #endif /* __INTEL_ATOMIC_PLANE_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index df588bf47559..06ceac4f1436 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -11811,24 +11811,101 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>  	return true;
>  }
>  
> +static int icl_add_dependent_planes(struct intel_atomic_state *state,
> +				    struct intel_plane_state *plane_state)
> +{
> +	struct intel_plane_state *new_plane_state;
> +	struct intel_plane *plane;
> +	int ret = 0;
> +
> +	plane = plane_state->bigjoiner_plane;
> +	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
> +		new_plane_state = intel_atomic_get_plane_state(state, plane);
> +		if (IS_ERR(new_plane_state))
> +			return PTR_ERR(new_plane_state);
> +
> +		ret = 1;
> +	}
> +
> +	plane = plane_state->planar_linked_plane;
> +	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
> +		new_plane_state = intel_atomic_get_plane_state(state, plane);
> +		if (IS_ERR(new_plane_state))
> +			return PTR_ERR(new_plane_state);
> +
> +		ret = 1;
> +	}
> +
> +	return ret;
> +}
> +
>  static int icl_add_linked_planes(struct intel_atomic_state *state)
>  {
> -	struct intel_plane *plane, *linked;
> -	struct intel_plane_state *plane_state, *linked_plane_state;
> +	struct intel_plane *plane;
> +	struct intel_plane_state *old_plane_state, *new_plane_state;
> +	struct intel_crtc *crtc, *linked_crtc;
> +	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *linked_crtc_state;
> +	bool added;
>  	int i;
>  
> -	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> -		linked = plane_state->planar_linked_plane;
> +	/*
> +	 * Iteratively add plane_state->linked_plane and plane_state->bigjoiner_plane
> +	 *
> +	 * This needs to be done repeatedly, because of is a funny interaction;
> +	 * the Y-plane may be assigned differently on the other bigjoiner crtc,
> +	 * and we could end up with the following evil recursion, when only adding a
> +	 * single plane to state:
> +	 *
> +	 * XRGB8888 master plane 6 adds NV12 slave Y-plane 6, which adds slave UV plane 0,
> +	 * which adds master UV plane 0, which adds master Y-plane 7, which adds XRGB8888
> +	 * slave plane 7.
> +	 *
> +	 * We could pull in even more because of old_plane_state vs new_plane_state.
> +	 *
> +	 * Max depth = 5 (or 7 for evil case) in this case.
> +	 * Number of passes will be less, because newly added planes show up in the
> +	 * same iteration round when added_plane->index > plane->index.
> +	 */
> +	do {
> +		added = false;
>  
> -		if (!linked)
> -			continue;
> +		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
> +			int ret, ret2;
> +
> +			ret = icl_add_dependent_planes(state, old_plane_state);
> +			if (ret < 0)
> +				return ret;
> +
> +			ret2 = icl_add_dependent_planes(state, new_plane_state);
> +			if (ret2 < 0)
> +				return ret2;
>  
> -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> -		if (IS_ERR(linked_plane_state))
> -			return PTR_ERR(linked_plane_state);
> +			added |= ret || ret2;
> +		}
> +	} while (added);
> +
> +	/*
> +	 * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically
> +	 * when adding slave planes, because plane_state->crtc is null.
> +	 */
> +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> +		linked_crtc = old_crtc_state->bigjoiner_linked_crtc;
> +		if (linked_crtc) {
> +			linked_crtc_state =
> +				intel_atomic_get_crtc_state(&state->base, linked_crtc);
> +
> +			if (IS_ERR(linked_crtc_state))
> +				return PTR_ERR(linked_crtc_state);
> +		}
> +
> +		linked_crtc = new_crtc_state->bigjoiner_linked_crtc;
> +		if (linked_crtc && linked_crtc != old_crtc_state->bigjoiner_linked_crtc) {
> +			linked_crtc_state =
> +				intel_atomic_get_crtc_state(&state->base, linked_crtc);
>  
> -		WARN_ON(linked_plane_state->planar_linked_plane != plane);
> -		WARN_ON(linked_plane_state->planar_slave == plane_state->planar_slave);
> +			if (IS_ERR(linked_crtc_state))
> +				return PTR_ERR(linked_crtc_state);
> +		}
>  	}
>  
>  	return 0;
> @@ -13799,6 +13876,7 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
>  	struct intel_crtc *crtc, *slave, *master;
> +	struct intel_plane *plane;
>  	int i, ret = 0;
>  
>  	if (INTEL_GEN(dev_priv) < 11)
> @@ -13894,6 +13972,48 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
>  			return ret;
>  	}
>  
> +	/*
> +	 * Setup and teardown the new bigjoiner plane mappings.
> +	 */
> +	for_each_intel_plane(&dev_priv->drm, plane) {
> +		struct intel_plane_state *plane_state;
> +		struct intel_plane *other_plane = NULL;
> +
> +		crtc = intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> +		old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> +
> +		if (!new_crtc_state || !needs_modeset(new_crtc_state))
> +			continue;
> +
> +		if (new_crtc_state->bigjoiner) {
> +			struct intel_crtc *other_crtc =
> +				new_crtc_state->bigjoiner_linked_crtc;
> +			bool found = false;
> +
> +			for_each_intel_plane_on_crtc(&dev_priv->drm, other_crtc, other_plane) {
> +				if (other_plane->id != plane->id)
> +					continue;
> +
> +				found = true;
> +				break;
> +			}
> +
> +			/* All pipes should have identical planes. */
> +			if (WARN_ON(!found))
> +				return -EINVAL;
> +		} else if (!old_crtc_state->bigjoiner) {
> +			continue;
> +		}
> +
> +		plane_state = intel_atomic_get_plane_state(state, plane);
> +		if (IS_ERR(plane_state))
> +			return PTR_ERR(plane_state);
> +
> +		plane_state->bigjoiner_plane = other_plane;
> +		plane_state->bigjoiner_slave = new_crtc_state->bigjoiner_slave;
> +	}

Is my understanding correct that we always grab the corresponding plane
on the other CRTC when the big joiner is active?  I.e., even in cases
where the uapi plane is restricted to just one half of the screen, we're
still going to grab the bigjoiner slave plane?  I guess trying to
restrict this to only cases where the uapi plane covers both pipes would
make this whole thing even more complicated.


Matt

> +
>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index ace372a76330..f05f4830a529 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -571,6 +571,17 @@ struct intel_plane_state {
>  	 */
>  	struct intel_plane *planar_linked_plane;
>  
> +	/*
> +	 * bigjoiner_plane:
> +	 *
> +	 * When 2 pipes are joined in a bigjoiner configuration,
> +	 * points to the same plane on the other pipe.
> +	 *
> +	 * bigjoiner_slave is set on the slave pipe.
> +	 */
> +	struct intel_plane *bigjoiner_plane;
> +	u32 bigjoiner_slave;
> +
>  	/*
>  	 * planar_slave:
>  	 * If set don't update use the linked plane's state for updating
> -- 
> 2.20.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

* Re: [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration.
  2019-10-01 16:44   ` Matt Roper
@ 2019-10-01 17:21     ` Ville Syrjälä
  0 siblings, 0 replies; 82+ messages in thread
From: Ville Syrjälä @ 2019-10-01 17:21 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx

On Tue, Oct 01, 2019 at 09:44:09AM -0700, Matt Roper wrote:
> On Fri, Sep 20, 2019 at 01:42:27PM +0200, Maarten Lankhorst wrote:
> > Make sure that when a plane is set in a bigjoiner mode, we will add
> > their counterpart to the atomic state as well. This will allow us to
> > make sure all state is available when planes are checked.
> > 
> > Because of the funny interactions with bigjoiner and planar YUV
> > formats, we may end up adding a lot of planes, so we have to keep
> > iterating until we no longer add any planes.
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  .../gpu/drm/i915/display/intel_atomic_plane.c |  31 +++-
> >  .../gpu/drm/i915/display/intel_atomic_plane.h |   4 +
> >  drivers/gpu/drm/i915/display/intel_display.c  | 142 ++++++++++++++++--
> >  .../drm/i915/display/intel_display_types.h    |  11 ++
> >  4 files changed, 172 insertions(+), 16 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index 964db7774d10..cc088676f0a2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -182,16 +182,36 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
> >  					       old_plane_state, new_plane_state);
> >  }
> >  
> > -static struct intel_crtc *
> > -get_crtc_from_states(const struct intel_plane_state *old_plane_state,
> > -		     const struct intel_plane_state *new_plane_state)
> > -{
> > +struct intel_crtc *
> > +intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
> 
> This function name seems ambiguous now since it isn't clear whether
> we're getting the plane's hardware CRTC or its uapi CRTC.  Maybe call it
> something like intel_plane_state_get_uapi_crtc()?

I was actually wondering if we shouldn't just do 
get_crtc(plane->pipe) here. We still don't expose any planes
that can switch pipes so feels like this stuff is unecessary
complexity we don't particularly need.

> 
> 
> 
> > +				 const struct intel_plane_state *old_plane_state,
> > +				 const struct intel_plane_state *new_plane_state)
> > +  {
> > +	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > +	struct intel_plane *plane = to_intel_plane(new_plane_state->base.plane);
> > +
> >  	if (new_plane_state->base.crtc)
> >  		return to_intel_crtc(new_plane_state->base.crtc);
> >  
> >  	if (old_plane_state->base.crtc)
> >  		return to_intel_crtc(old_plane_state->base.crtc);
> >  
> > +	if (new_plane_state->bigjoiner_slave) {
> > +		const struct intel_plane_state *new_master_plane_state =
> > +			intel_atomic_get_new_plane_state(state, new_plane_state->bigjoiner_plane);
> > +
> > +		if (new_master_plane_state->base.crtc)
> > +			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> > +	}
> 
> Will this cause problems if we adjust properties of planes on a a
> uapi-disabled CRTC?  E.g., I believe userspace can fiddle with stuff
> like rotation properties on disabled planes/crtcs and now I believe that
> causes us to needlessly pull in the bigjoiner master crtc and
> corresponding plane?

Not sure it's worth the effort to really try to avoid such things. If
userspace keeps fiddling with disabled stuff all the time it feels a
bit broken to me.

On a semi-related note I've occasionally pondered about trying to
filter out nop commits which don't send out events, even on active
planes/crtcs. But I guess that's already starting to be a change to
the semantics so probably not something that could be done without
a new flag/etc.

> 
> > +
> > +	if (old_plane_state->bigjoiner_slave) {
> > +		const struct intel_plane_state *old_master_plane_state =
> > +			intel_atomic_get_old_plane_state(state, old_plane_state->bigjoiner_plane);
> > +
> > +		if (old_master_plane_state->base.crtc)
> > +			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> > +	}
> > +
> >  	return NULL;
> >  }
> >  
> > @@ -206,7 +226,8 @@ static int intel_plane_atomic_check(struct drm_plane *_plane,
> >  	const struct intel_plane_state *old_plane_state =
> >  		intel_atomic_get_old_plane_state(state, plane);
> >  	struct intel_crtc *crtc =
> > -		get_crtc_from_states(old_plane_state, new_plane_state);
> > +		intel_plane_get_crtc_from_states(state, old_plane_state,
> > +						 new_plane_state);
> >  	const struct intel_crtc_state *old_crtc_state;
> >  	struct intel_crtc_state *new_crtc_state;
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > index 33fb85cd3909..901a50e6e2d3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > @@ -42,5 +42,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
> >  				    struct intel_crtc_state *crtc_state,
> >  				    const struct intel_plane_state *old_plane_state,
> >  				    struct intel_plane_state *plane_state);
> > +struct intel_crtc *
> > +intel_plane_get_crtc_from_states(struct intel_atomic_state *state,
> > +				 const struct intel_plane_state *old_plane_state,
> > +				 const struct intel_plane_state *new_plane_state);
> >  
> >  #endif /* __INTEL_ATOMIC_PLANE_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index df588bf47559..06ceac4f1436 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -11811,24 +11811,101 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
> >  	return true;
> >  }
> >  
> > +static int icl_add_dependent_planes(struct intel_atomic_state *state,
> > +				    struct intel_plane_state *plane_state)
> > +{
> > +	struct intel_plane_state *new_plane_state;
> > +	struct intel_plane *plane;
> > +	int ret = 0;
> > +
> > +	plane = plane_state->bigjoiner_plane;
> > +	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
> > +		new_plane_state = intel_atomic_get_plane_state(state, plane);
> > +		if (IS_ERR(new_plane_state))
> > +			return PTR_ERR(new_plane_state);
> > +
> > +		ret = 1;
> > +	}
> > +
> > +	plane = plane_state->planar_linked_plane;
> > +	if (plane && !intel_atomic_get_new_plane_state(state, plane)) {
> > +		new_plane_state = intel_atomic_get_plane_state(state, plane);
> > +		if (IS_ERR(new_plane_state))
> > +			return PTR_ERR(new_plane_state);
> > +
> > +		ret = 1;
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> >  static int icl_add_linked_planes(struct intel_atomic_state *state)
> >  {
> > -	struct intel_plane *plane, *linked;
> > -	struct intel_plane_state *plane_state, *linked_plane_state;
> > +	struct intel_plane *plane;
> > +	struct intel_plane_state *old_plane_state, *new_plane_state;
> > +	struct intel_crtc *crtc, *linked_crtc;
> > +	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *linked_crtc_state;
> > +	bool added;
> >  	int i;
> >  
> > -	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
> > -		linked = plane_state->planar_linked_plane;
> > +	/*
> > +	 * Iteratively add plane_state->linked_plane and plane_state->bigjoiner_plane
> > +	 *
> > +	 * This needs to be done repeatedly, because of is a funny interaction;
> > +	 * the Y-plane may be assigned differently on the other bigjoiner crtc,
> > +	 * and we could end up with the following evil recursion, when only adding a
> > +	 * single plane to state:
> > +	 *
> > +	 * XRGB8888 master plane 6 adds NV12 slave Y-plane 6, which adds slave UV plane 0,
> > +	 * which adds master UV plane 0, which adds master Y-plane 7, which adds XRGB8888
> > +	 * slave plane 7.
> > +	 *
> > +	 * We could pull in even more because of old_plane_state vs new_plane_state.
> > +	 *
> > +	 * Max depth = 5 (or 7 for evil case) in this case.
> > +	 * Number of passes will be less, because newly added planes show up in the
> > +	 * same iteration round when added_plane->index > plane->index.
> > +	 */
> > +	do {
> > +		added = false;
> >  
> > -		if (!linked)
> > -			continue;
> > +		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
> > +			int ret, ret2;
> > +
> > +			ret = icl_add_dependent_planes(state, old_plane_state);
> > +			if (ret < 0)
> > +				return ret;
> > +
> > +			ret2 = icl_add_dependent_planes(state, new_plane_state);
> > +			if (ret2 < 0)
> > +				return ret2;
> >  
> > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > -		if (IS_ERR(linked_plane_state))
> > -			return PTR_ERR(linked_plane_state);
> > +			added |= ret || ret2;

I suspect passing &added to the functions would be less annoying
than this magic return 1 stuff.

> > +		}
> > +	} while (added);
> > +
> > +	/*
> > +	 * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically
> > +	 * when adding slave planes, because plane_state->crtc is null.
> > +	 */
> > +	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> > +		linked_crtc = old_crtc_state->bigjoiner_linked_crtc;
> > +		if (linked_crtc) {
> > +			linked_crtc_state =
> > +				intel_atomic_get_crtc_state(&state->base, linked_crtc);
> > +
> > +			if (IS_ERR(linked_crtc_state))
> > +				return PTR_ERR(linked_crtc_state);
> > +		}
> > +
> > +		linked_crtc = new_crtc_state->bigjoiner_linked_crtc;
> > +		if (linked_crtc && linked_crtc != old_crtc_state->bigjoiner_linked_crtc) {
> > +			linked_crtc_state =
> > +				intel_atomic_get_crtc_state(&state->base, linked_crtc);
> >  
> > -		WARN_ON(linked_plane_state->planar_linked_plane != plane);
> > -		WARN_ON(linked_plane_state->planar_slave == plane_state->planar_slave);
> > +			if (IS_ERR(linked_crtc_state))
> > +				return PTR_ERR(linked_crtc_state);
> > +		}
> >  	}
> >  
> >  	return 0;
> > @@ -13799,6 +13876,7 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
> >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> >  	struct intel_crtc_state *old_crtc_state, *new_crtc_state, *slave_crtc_state, *master_crtc_state;
> >  	struct intel_crtc *crtc, *slave, *master;
> > +	struct intel_plane *plane;
> >  	int i, ret = 0;
> >  
> >  	if (INTEL_GEN(dev_priv) < 11)
> > @@ -13894,6 +13972,48 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
> >  			return ret;
> >  	}
> >  
> > +	/*
> > +	 * Setup and teardown the new bigjoiner plane mappings.
> > +	 */
> > +	for_each_intel_plane(&dev_priv->drm, plane) {
> > +		struct intel_plane_state *plane_state;
> > +		struct intel_plane *other_plane = NULL;
> > +
> > +		crtc = intel_get_crtc_for_pipe(dev_priv, plane->pipe);
> > +		old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > +
> > +		if (!new_crtc_state || !needs_modeset(new_crtc_state))
> > +			continue;
> > +
> > +		if (new_crtc_state->bigjoiner) {
> > +			struct intel_crtc *other_crtc =
> > +				new_crtc_state->bigjoiner_linked_crtc;
> > +			bool found = false;
> > +
> > +			for_each_intel_plane_on_crtc(&dev_priv->drm, other_crtc, other_plane) {
> > +				if (other_plane->id != plane->id)
> > +					continue;
> > +
> > +				found = true;
> > +				break;
> > +			}
> > +
> > +			/* All pipes should have identical planes. */
> > +			if (WARN_ON(!found))
> > +				return -EINVAL;
> > +		} else if (!old_crtc_state->bigjoiner) {
> > +			continue;
> > +		}
> > +
> > +		plane_state = intel_atomic_get_plane_state(state, plane);
> > +		if (IS_ERR(plane_state))
> > +			return PTR_ERR(plane_state);
> > +
> > +		plane_state->bigjoiner_plane = other_plane;
> > +		plane_state->bigjoiner_slave = new_crtc_state->bigjoiner_slave;
> > +	}
> 
> Is my understanding correct that we always grab the corresponding plane
> on the other CRTC when the big joiner is active?  I.e., even in cases
> where the uapi plane is restricted to just one half of the screen, we're
> still going to grab the bigjoiner slave plane?  I guess trying to
> restrict this to only cases where the uapi plane covers both pipes would
> make this whole thing even more complicated.

Yeah, I'm thinking we can just ignore that particular optimization.
Would need to somehow convince ourselves early that the plane still
remains on its own half of the screen, or we'd need to come up with some
kind of retry loop for this that can restart if a new plane gets added
in the middle of the process. IMO not worth the hassle.

-- 
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 82+ messages in thread

end of thread, other threads:[~2019-10-01 17:21 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-20 11:42 [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 02/23] HAX drm/i915: Disable FEC entirely for now Maarten Lankhorst
2019-09-23 13:08   ` Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 03/23] drm/i915: Prepare to split crtc state in uapi and hw state Maarten Lankhorst
2019-09-24 23:40   ` Matt Roper
2019-09-25  9:09     ` Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 04/23] drm/i915: Handle a few more cases for hw/sw split Maarten Lankhorst
2019-09-24 23:40   ` Matt Roper
2019-09-20 11:42 ` [PATCH 05/23] drm/i915: Complete sw/hw split Maarten Lankhorst
2019-09-24 23:41   ` Matt Roper
2019-09-25  9:29     ` Maarten Lankhorst
2019-09-25 13:01   ` Ville Syrjälä
2019-09-25 14:12     ` Maarten Lankhorst
2019-09-25 14:18     ` Maarten Lankhorst
2019-09-25 14:54       ` Ville Syrjälä
2019-09-20 11:42 ` [PATCH 06/23] drm/i915: Get rid of crtc_state->fb_changed Maarten Lankhorst
2019-09-24 23:44   ` Matt Roper
2019-09-20 11:42 ` [PATCH 07/23] drm/i915: Remove begin/finish_crtc_commit Maarten Lankhorst
2019-09-25  4:17   ` Matt Roper
2019-09-25 14:14     ` Maarten Lankhorst
2019-09-25 22:14   ` Manasi Navare
2019-09-20 11:42 ` [PATCH 08/23] drm/i915: Rename planar linked plane variables Maarten Lankhorst
2019-09-25  4:30   ` Matt Roper
2019-09-20 11:42 ` [PATCH 09/23] drm/i915: Do not add all planes when checking scalers on glk+ Maarten Lankhorst
2019-09-25  4:55   ` Matt Roper
2019-09-25 12:45     ` Maarten Lankhorst
2019-09-25 13:02     ` Ville Syrjälä
2019-09-20 11:42 ` [PATCH 10/23] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid() Maarten Lankhorst
2019-09-25  5:30   ` Matt Roper
2019-09-25  5:56     ` Matt Roper
2019-09-25 22:09     ` Manasi Navare
2019-09-26 16:00       ` Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 11/23] drm/i915: Try to make bigjoiner work in atomic check Maarten Lankhorst
2019-09-26  3:48   ` Matt Roper
2019-09-30 14:12     ` Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 12/23] drm/i915: Enable big joiner support in enable and disable sequences Maarten Lankhorst
2019-09-26  5:18   ` Matt Roper
2019-09-26 23:54     ` Matt Roper
2019-09-27  8:25       ` Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 13/23] drm/i915: Make hardware readout work on i915 Maarten Lankhorst
2019-09-27  0:49   ` Matt Roper
2019-09-20 11:42 ` [PATCH 14/23] drm/i915: Prepare update_slave() for bigjoiner plane updates Maarten Lankhorst
2019-09-27  3:18   ` Matt Roper
2019-09-20 11:42 ` [PATCH 15/23] drm/i915: Link planes in a bigjoiner configuration Maarten Lankhorst
2019-10-01 16:44   ` Matt Roper
2019-10-01 17:21     ` Ville Syrjälä
2019-09-20 11:42 ` [PATCH 16/23] drm/i915: Program planes in bigjoiner mode Maarten Lankhorst
2019-09-26 13:06   ` Ville Syrjälä
2019-09-26 15:50     ` Maarten Lankhorst
2019-09-26 16:09       ` Ville Syrjälä
2019-09-26 16:13         ` Maarten Lankhorst
2019-09-26 16:26           ` Ville Syrjälä
2019-09-26 19:11         ` Ville Syrjälä
2019-09-27  8:56           ` Maarten Lankhorst
2019-09-27 14:41             ` Ville Syrjälä
2019-09-27 15:00               ` Ville Syrjälä
2019-09-20 11:42 ` [PATCH 17/23] drm/i915: Add intel_update_bigjoiner handling Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 18/23] drm/i915: Disable FBC in bigjoiner configuration Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 19/23] drm/i915: Prepare atomic plane check for bigjoiner planes Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 20/23] drm/i915: Make prepare_plane_fb() work with " Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 21/23] drm/i915: Make sure watermarks work correctly with bigjoiner as well Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 22/23] drm/i915: Add debugfs dumping for bigjoiner Maarten Lankhorst
2019-09-20 11:42 ` [PATCH 23/23] HAX to make it work on the icelake test system Maarten Lankhorst
2019-09-20 14:52 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Patchwork
2019-09-20 14:59 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-09-20 15:16 ` ✓ Fi.CI.BAT: success " Patchwork
2019-09-20 16:38 ` [Intel-gfx] [PATCH 01/23] " Ville Syrjälä
2019-09-23 12:52   ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 Maarten Lankhorst
2019-09-23 13:03     ` Ville Syrjälä
2019-09-23 13:03       ` Ville Syrjälä
2019-09-23 14:49       ` [PATCH] drm/i915/dp: Fix dsc bpp calculations, v4 Maarten Lankhorst
2019-09-23 14:50         ` Maarten Lankhorst
2019-09-23 14:57         ` Ville Syrjälä
2019-09-23 15:56           ` Manasi Navare
2019-09-23 15:56           ` [Intel-gfx] " Ville Syrjälä
2019-09-23 14:22     ` [Intel-gfx] [PATCH] drm/i915/dp: Fix dsc bpp calculations, v3 kbuild test robot
2019-09-23 14:22       ` kbuild test robot
2019-09-23 15:53     ` Manasi Navare
2019-09-21 12:06 ` [PATCH 01/23] drm/i915/dp: Fix dsc bpp calculations, v2 Sasha Levin
2019-09-21 15:22 ` ✗ Fi.CI.IGT: failure for series starting with [01/23] " Patchwork
2019-09-23 10:43   ` Maarten Lankhorst
2019-09-23 19:10 ` ✗ Fi.CI.BUILD: failure for series starting with drm/i915/dp: Fix dsc bpp calculations, v4. (rev3) Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.