All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 16:05 ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

DSC is available on the display emulator, but not set in DPCD.
Override the entries to allow bigjoiner testing.

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 2c7870aef469..3d6038f35ea2 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1261,7 +1261,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 {
@@ -1285,7 +1285,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 51ecb5112ef8..2ebd7feffd90 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1270,6 +1270,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.24.0

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

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

* [Intel-gfx] [PATCH 01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 16:05 ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

DSC is available on the display emulator, but not set in DPCD.
Override the entries to allow bigjoiner testing.

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 2c7870aef469..3d6038f35ea2 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1261,7 +1261,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 {
@@ -1285,7 +1285,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 51ecb5112ef8..2ebd7feffd90 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1270,6 +1270,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.24.0

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

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

* [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

The members in hw.mode can be used from adjusted_mode as well,
use that when available.

Some places that use hw.mode can be converted to use adjusted_mode
as well.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
 .../drm/i915/display/intel_display_types.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
 4 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index adf50c4b38ad..18acecc3642d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
 	tmp = I915_READ(PIPESRC(crtc->pipe));
 	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
 	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
-
-	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,
@@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
 			continue;
 		if (!connector->has_tile)
 			continue;
-		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
-		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
+		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
+		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)
 			return 0;
 		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
 		    connector->tile_v_loc == connector->num_v_tile - 1)
@@ -12506,7 +12503,7 @@ 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->hw.mode);
+	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
 	DRM_DEBUG_KMS("adjusted mode:\n");
 	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
 	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
@@ -12640,16 +12637,16 @@ intel_crtc_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;
 	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
 }
 
-static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
+static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
+					     struct drm_display_mode *user_mode)
 {
 	crtc_state->uapi.enable = crtc_state->hw.enable;
 	crtc_state->uapi.active = crtc_state->hw.active;
-	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
+	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
 	kfree(saved_state);
 
+	/* Clear I915_MODE_FLAG_INHERITED */
+	crtc_state->uapi.mode.private_flags = 0;
+	crtc_state->uapi.adjusted_mode.private_flags = 0;
+
 	intel_crtc_copy_uapi_to_hw_state(crtc_state);
 
 	return 0;
@@ -12750,7 +12751,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->hw.mode,
+	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 */
 	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
 
+	/* without bigjoiner, pipe_mode == adjusted_mode */
+	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
 	return 0;
 }
 
@@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	bool ret = true;
 	u32 bp_gamma = 0;
 	bool fixup_inherited = fastset &&
-		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
-		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
+		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
+		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
 
 	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
 		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
@@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
-		    old_crtc_state->hw.mode.private_flags)
+		if (new_crtc_state->hw.adjusted_mode.private_flags !=
+		    old_crtc_state->hw.adjusted_mode.private_flags)
 			new_crtc_state->uapi.mode_changed = true;
 	}
 
@@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 	 * of enabling them on the CRTC's first fastset.
 	 */
 	if (new_crtc_state->update_pipe && !modeset &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
@@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
 	 * of enabling them on the CRTC's first fastset.
 	 */
 	if (new_crtc_state->update_pipe && !modeset &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
@@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		int min_cdclk = 0;
 
 		if (crtc_state->hw.active) {
-			struct drm_display_mode *mode = &crtc_state->hw.mode;
+			struct drm_display_mode mode;
 
 			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
 						    crtc_state);
 
-			*mode = crtc_state->hw.adjusted_mode;
-			mode->hdisplay = crtc_state->pipe_src_w;
-			mode->vdisplay = crtc_state->pipe_src_h;
-
 			/*
 			 * The initial mode needs to be set in order to keep
 			 * the atomic core happy. It wants a valid mode if the
@@ -17542,13 +17541,17 @@ 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.
 			 */
-			mode->private_flags = I915_MODE_FLAG_INHERITED;
+			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
+
+			mode = crtc_state->hw.adjusted_mode;
+			mode.hdisplay = crtc_state->pipe_src_w;
+			mode.vdisplay = crtc_state->pipe_src_h;
 
 			intel_crtc_compute_pixel_rate(crtc_state);
 
 			intel_crtc_update_active_timings(crtc_state);
 
-			intel_crtc_copy_hw_to_uapi_state(crtc_state);
+			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
 		}
 
 		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..0f20c7190eed 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -802,7 +802,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 adjusted_mode;
 	} hw;
 
 	/**
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index a74dc5b915d1..ad8e9959d6e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -207,7 +207,7 @@ 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->hw.mode,
+					 &pipe_config->hw.adjusted_mode,
 					 &pipe_config->hw.adjusted_mode);
 
 	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index a4b1339fcc00..4ba7648a3145 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
 static bool
 intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
 				    struct intel_sdvo_connector *intel_sdvo_connector,
-				    const struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
 {
 	struct intel_sdvo_dtd input_dtd;
@@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
 
 	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
 						      intel_sdvo_connector,
-						      mode->clock / 10,
-						      mode->hdisplay,
-						      mode->vdisplay))
+						      adjusted_mode->clock / 10,
+						      adjusted_mode->hdisplay,
+						      adjusted_mode->vdisplay))
 		return false;
 
 	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
@@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(conn_state->connector);
 	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;
@@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 	 * the sequence to do it. Oh well.
 	 */
 	if (IS_TV(intel_sdvo_connector)) {
-		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
+		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
+							     adjusted_mode))
 			return -EINVAL;
 
 		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
 							   intel_sdvo_connector,
-							   mode,
 							   adjusted_mode);
 		pipe_config->sdvo_tv_clock = true;
 	} else if (IS_LVDS(intel_sdvo_connector)) {
@@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 
 		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
 							   intel_sdvo_connector,
-							   mode,
 							   adjusted_mode);
 	}
 
@@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 		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->hw.mode;
 	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
@@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 		intel_sdvo_get_dtd_from_mode(&output_dtd,
 					     intel_sdvo_connector->base.panel.fixed_mode);
 	else
-		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
 	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
 		DRM_INFO("Setting output timings on %s failed\n",
 			 SDVO_NAME(intel_sdvo));
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

The members in hw.mode can be used from adjusted_mode as well,
use that when available.

Some places that use hw.mode can be converted to use adjusted_mode
as well.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
 .../drm/i915/display/intel_display_types.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
 drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
 4 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index adf50c4b38ad..18acecc3642d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
 	tmp = I915_READ(PIPESRC(crtc->pipe));
 	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
 	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
-
-	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,
@@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
 			continue;
 		if (!connector->has_tile)
 			continue;
-		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
-		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
+		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
+		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)
 			return 0;
 		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
 		    connector->tile_v_loc == connector->num_v_tile - 1)
@@ -12506,7 +12503,7 @@ 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->hw.mode);
+	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
 	DRM_DEBUG_KMS("adjusted mode:\n");
 	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
 	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
@@ -12640,16 +12637,16 @@ intel_crtc_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;
 	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
 }
 
-static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
+static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
+					     struct drm_display_mode *user_mode)
 {
 	crtc_state->uapi.enable = crtc_state->hw.enable;
 	crtc_state->uapi.active = crtc_state->hw.active;
-	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
+	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
 	kfree(saved_state);
 
+	/* Clear I915_MODE_FLAG_INHERITED */
+	crtc_state->uapi.mode.private_flags = 0;
+	crtc_state->uapi.adjusted_mode.private_flags = 0;
+
 	intel_crtc_copy_uapi_to_hw_state(crtc_state);
 
 	return 0;
@@ -12750,7 +12751,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->hw.mode,
+	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 */
 	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
 
+	/* without bigjoiner, pipe_mode == adjusted_mode */
+	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
 	return 0;
 }
 
@@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	bool ret = true;
 	u32 bp_gamma = 0;
 	bool fixup_inherited = fastset &&
-		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
-		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
+		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
+		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
 
 	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
 		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
@@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
-		    old_crtc_state->hw.mode.private_flags)
+		if (new_crtc_state->hw.adjusted_mode.private_flags !=
+		    old_crtc_state->hw.adjusted_mode.private_flags)
 			new_crtc_state->uapi.mode_changed = true;
 	}
 
@@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 	 * of enabling them on the CRTC's first fastset.
 	 */
 	if (new_crtc_state->update_pipe && !modeset &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
@@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
 	 * of enabling them on the CRTC's first fastset.
 	 */
 	if (new_crtc_state->update_pipe && !modeset &&
-	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
+	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
 		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
 }
 
@@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		int min_cdclk = 0;
 
 		if (crtc_state->hw.active) {
-			struct drm_display_mode *mode = &crtc_state->hw.mode;
+			struct drm_display_mode mode;
 
 			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
 						    crtc_state);
 
-			*mode = crtc_state->hw.adjusted_mode;
-			mode->hdisplay = crtc_state->pipe_src_w;
-			mode->vdisplay = crtc_state->pipe_src_h;
-
 			/*
 			 * The initial mode needs to be set in order to keep
 			 * the atomic core happy. It wants a valid mode if the
@@ -17542,13 +17541,17 @@ 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.
 			 */
-			mode->private_flags = I915_MODE_FLAG_INHERITED;
+			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
+
+			mode = crtc_state->hw.adjusted_mode;
+			mode.hdisplay = crtc_state->pipe_src_w;
+			mode.vdisplay = crtc_state->pipe_src_h;
 
 			intel_crtc_compute_pixel_rate(crtc_state);
 
 			intel_crtc_update_active_timings(crtc_state);
 
-			intel_crtc_copy_hw_to_uapi_state(crtc_state);
+			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
 		}
 
 		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 83ea04149b77..0f20c7190eed 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -802,7 +802,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 adjusted_mode;
 	} hw;
 
 	/**
diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
index a74dc5b915d1..ad8e9959d6e1 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -207,7 +207,7 @@ 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->hw.mode,
+					 &pipe_config->hw.adjusted_mode,
 					 &pipe_config->hw.adjusted_mode);
 
 	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
index a4b1339fcc00..4ba7648a3145 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
 static bool
 intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
 				    struct intel_sdvo_connector *intel_sdvo_connector,
-				    const struct drm_display_mode *mode,
 				    struct drm_display_mode *adjusted_mode)
 {
 	struct intel_sdvo_dtd input_dtd;
@@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
 
 	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
 						      intel_sdvo_connector,
-						      mode->clock / 10,
-						      mode->hdisplay,
-						      mode->vdisplay))
+						      adjusted_mode->clock / 10,
+						      adjusted_mode->hdisplay,
+						      adjusted_mode->vdisplay))
 		return false;
 
 	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
@@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 	struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(conn_state->connector);
 	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;
@@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 	 * the sequence to do it. Oh well.
 	 */
 	if (IS_TV(intel_sdvo_connector)) {
-		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
+		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
+							     adjusted_mode))
 			return -EINVAL;
 
 		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
 							   intel_sdvo_connector,
-							   mode,
 							   adjusted_mode);
 		pipe_config->sdvo_tv_clock = true;
 	} else if (IS_LVDS(intel_sdvo_connector)) {
@@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
 
 		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
 							   intel_sdvo_connector,
-							   mode,
 							   adjusted_mode);
 	}
 
@@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 		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->hw.mode;
 	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
@@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
 		intel_sdvo_get_dtd_from_mode(&output_dtd,
 					     intel_sdvo_connector->base.panel.fixed_mode);
 	else
-		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
+		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
 	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
 		DRM_INFO("Setting output timings on %s failed\n",
 			 SDVO_NAME(intel_sdvo));
-- 
2.24.0

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

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

* [PATCH 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

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

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 18acecc3642d..7a6da85823af 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -151,7 +151,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
 static int intel_framebuffer_init(struct intel_framebuffer *ifb,
 				  struct drm_i915_gem_object *obj,
 				  struct drm_mode_fb_cmd2 *mode_cmd);
-static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state);
+static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
 static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
 static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
 					 const struct intel_link_m_n *m_n,
@@ -5651,7 +5651,7 @@ 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->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode = &state->hw.pipe_mode;
 	bool need_scaler = false;
 
 	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
@@ -5660,8 +5660,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
 	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,
-				 adjusted_mode->crtc_vdisplay, NULL, need_scaler);
+				 pipe_mode->crtc_hdisplay,
+				 pipe_mode->crtc_vdisplay, NULL, need_scaler);
 }
 
 /**
@@ -6480,7 +6480,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	if (pipe_config->has_pch_encoder) {
@@ -6607,7 +6607,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
 	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_pipe_timings(pipe_config);
+		intel_set_transcoder_timings(pipe_config);
 
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_enable_trans_port_sync(pipe_config);
@@ -7015,7 +7015,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
@@ -7083,7 +7083,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	i9xx_set_pipeconf(pipe_config);
@@ -7528,7 +7528,7 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
 	u32 pixel_rate;
 
-	pixel_rate = pipe_config->hw.adjusted_mode.crtc_clock;
+	pixel_rate = pipe_config->hw.pipe_mode.crtc_clock;
 
 	/*
 	 * We only use IF-ID interlacing. If we ever use
@@ -7566,7 +7566,7 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
 	if (HAS_GMCH(dev_priv))
 		/* FIXME calculate proper pipe pixel rate for GMCH pfit */
 		crtc_state->pixel_rate =
-			crtc_state->hw.adjusted_mode.crtc_clock;
+			crtc_state->hw.pipe_mode.crtc_clock;
 	else
 		crtc_state->pixel_rate =
 			ilk_pipe_pixel_rate(crtc_state);
@@ -7576,7 +7576,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;
+	const struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
 	if (INTEL_GEN(dev_priv) < 4) {
@@ -7587,15 +7587,15 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 		 * is > 90% of the (display) core speed.
 		 */
 		if (intel_crtc_supports_double_wide(crtc) &&
-		    adjusted_mode->crtc_clock > clock_limit) {
+		    pipe_mode->crtc_clock > clock_limit) {
 			clock_limit = dev_priv->max_dotclk_freq;
 			pipe_config->double_wide = true;
 		}
 	}
 
-	if (adjusted_mode->crtc_clock > clock_limit) {
+	if (pipe_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,
+			      pipe_mode->crtc_clock, clock_limit,
 			      yesno(pipe_config->double_wide));
 		return -EINVAL;
 	}
@@ -7635,7 +7635,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
 	 */
 	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
-		adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
+		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -8294,7 +8294,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc,
 	crtc_state->dpll_hw_state.dpll = dpll;
 }
 
-static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
+static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -8385,8 +8385,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
 		return I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK;
 }
 
-static void intel_get_pipe_timings(struct intel_crtc *crtc,
-				   struct intel_crtc_state *pipe_config)
+static void intel_get_transcoder_timings(struct intel_crtc *crtc,
+					 struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -8987,7 +8987,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 	if (INTEL_GEN(dev_priv) < 4)
 		pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
 
-	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_transcoder_timings(crtc, pipe_config);
 	intel_get_pipe_src_size(crtc, pipe_config);
 
 	i9xx_get_pfit_config(crtc, pipe_config);
@@ -10225,7 +10225,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 		pipe_config->pixel_multiplier = 1;
 	}
 
-	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_transcoder_timings(crtc, pipe_config);
 	intel_get_pipe_src_size(crtc, pipe_config);
 
 	ironlake_get_pfit_config(crtc, pipe_config);
@@ -10680,7 +10680,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	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);
+		intel_get_transcoder_timings(crtc, pipe_config);
 	}
 
 	intel_get_pipe_src_size(crtc, pipe_config);
@@ -12637,7 +12637,7 @@ intel_crtc_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.adjusted_mode = crtc_state->uapi.adjusted_mode;
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
 	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
 }
 
@@ -17543,6 +17543,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			 */
 			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
 
+			/* initialize pipe_mode */
+			crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode;
+
 			mode = crtc_state->hw.adjusted_mode;
 			mode.hdisplay = crtc_state->pipe_src_w;
 			mode.vdisplay = crtc_state->pipe_src_h;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0f20c7190eed..7f46c1646d3f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -794,15 +794,22 @@ struct intel_crtc_state {
 	 * The following members are used to verify the hardware state:
 	 * - enable
 	 * - active
-	 * - mode / adjusted_mode
+	 * - adjusted_mode
 	 * - color property blobs.
 	 *
 	 * During initial hw readout, they need to be copied to uapi.
+	 *
+	 * Bigjoiner will allow a transcoder mode that spans 2 pipes;
+	 * Use the pipe_mode for calculations like watermarks, pipe
+	 * scaler, and bandwidth.
+	 *
+	 * Use adjusted_mode for things that need to know the full
+	 * mode on the transcoder, which spans all pipes.
 	 */
 	struct {
 		bool active, enable;
 		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
-		struct drm_display_mode adjusted_mode;
+		struct drm_display_mode pipe_mode, adjusted_mode;
 	} hw;
 
 	/**
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 05ba9e1bd247..780ff38b6aa1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -849,12 +849,12 @@ 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->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp = fb->format->cpp[0];
-		int clock = adjusted_mode->crtc_clock;
+		int clock = pipe_mode->crtc_clock;
 
 		/* Display SR */
 		wm = intel_calculate_wm(clock, &pineview_display_wm,
@@ -1085,8 +1085,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
 	unsigned int clock, htotal, cpp, width, wm;
 
@@ -1113,8 +1113,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	    level != G4X_WM_LEVEL_NORMAL)
 		cpp = max(cpp, 4u);
 
-	clock = adjusted_mode->crtc_clock;
-	htotal = adjusted_mode->crtc_htotal;
+	clock = pipe_mode->crtc_clock;
+	htotal = pipe_mode->crtc_htotal;
 
 	width = drm_rect_width(&plane_state->uapi.dst);
 
@@ -1591,8 +1591,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	unsigned int clock, htotal, cpp, width, wm;
 
 	if (dev_priv->wm.pri_latency[level] == 0)
@@ -1602,8 +1602,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 		return 0;
 
 	cpp = plane_state->hw.fb->format->cpp[0];
-	clock = adjusted_mode->crtc_clock;
-	htotal = adjusted_mode->crtc_htotal;
+	clock = pipe_mode->crtc_clock;
+	htotal = pipe_mode->crtc_htotal;
 	width = crtc_state->pipe_src_w;
 
 	if (plane->id == PLANE_CURSOR) {
@@ -2186,12 +2186,12 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
 	if (crtc) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
-		int clock = adjusted_mode->crtc_clock;
-		int htotal = adjusted_mode->crtc_htotal;
+		int clock = pipe_mode->crtc_clock;
+		int htotal = pipe_mode->crtc_htotal;
 		int hdisplay = crtc->config->pipe_src_w;
 		int cpp = fb->format->cpp[0];
 		int entries;
@@ -2267,8 +2267,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_A);
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
 	if (intel_crtc_active(crtc)) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2278,7 +2278,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 		else
 			cpp = fb->format->cpp[0];
 
-		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+		planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
 		enabled = crtc;
@@ -2294,8 +2294,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B);
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
 	if (intel_crtc_active(crtc)) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2305,7 +2305,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 		else
 			cpp = fb->format->cpp[0];
 
-		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+		planeb_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
 		if (enabled == NULL)
@@ -2342,12 +2342,12 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	if (HAS_FW_BLC(dev_priv) && enabled) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
-		const struct drm_display_mode *adjusted_mode =
-			&enabled->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&enabled->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			enabled->base.primary->state->fb;
-		int clock = adjusted_mode->crtc_clock;
-		int htotal = adjusted_mode->crtc_htotal;
+		int clock = pipe_mode->crtc_clock;
+		int htotal = pipe_mode->crtc_htotal;
 		int hdisplay = enabled->config->pipe_src_w;
 		int cpp;
 		int entries;
@@ -2393,7 +2393,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev);
 	struct intel_crtc *crtc;
-	const struct drm_display_mode *adjusted_mode;
+	const struct drm_display_mode *pipe_mode;
 	u32 fwater_lo;
 	int planea_wm;
 
@@ -2401,8 +2401,8 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
 	if (crtc == NULL)
 		return;
 
-	adjusted_mode = &crtc->config->hw.adjusted_mode;
-	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+	pipe_mode = &crtc->config->hw.pipe_mode;
+	planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 				       &i845_wm_info,
 				       dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
 				       4, pessimal_latency_ns);
@@ -2491,7 +2491,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->uapi.dst),
 				 cpp, mem_value);
 
@@ -2519,7 +2519,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->uapi.dst),
 				 cpp, mem_value);
 	return min(method1, method2);
@@ -2544,7 +2544,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
 	cpp = plane_state->hw.fb->format->cpp[0];
 
 	return ilk_wm_method2(crtc_state->pixel_rate,
-			      crtc_state->hw.adjusted_mode.crtc_htotal,
+			      crtc_state->hw.pipe_mode.crtc_htotal,
 			      drm_rect_width(&plane_state->uapi.dst),
 			      cpp, mem_value);
 }
@@ -2768,13 +2768,13 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_atomic_state *intel_state =
 		to_intel_atomic_state(crtc_state->uapi.state);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	u32 linetime, ips_linetime;
 
 	if (!crtc_state->hw.active)
 		return 0;
-	if (WARN_ON(adjusted_mode->crtc_clock == 0))
+	if (WARN_ON(pipe_mode->crtc_clock == 0))
 		return 0;
 	if (WARN_ON(intel_state->cdclk.logical.cdclk == 0))
 		return 0;
@@ -2782,9 +2782,9 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 	/* The WM are computed with base on how long it takes to fill a single
 	 * row at the given clock rate, multiplied by 8.
 	 * */
-	linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
-				     adjusted_mode->crtc_clock);
-	ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+	linetime = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
+				     pipe_mode->crtc_clock);
+	ips_linetime = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
 					 intel_state->cdclk.logical.cdclk);
 
 	return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
@@ -3779,7 +3779,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_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
 	for_each_intel_plane_on_crtc(dev, crtc, plane) {
@@ -3820,7 +3820,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 			      const int num_active,
 			      struct skl_ddb_allocation *ddb)
 {
-	const struct drm_display_mode *adjusted_mode;
+	const struct drm_display_mode *pipe_mode;
 	u64 total_data_bw;
 	u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size;
 
@@ -3829,8 +3829,8 @@ 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->hw.adjusted_mode;
-	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
+	pipe_mode = &crtc_state->hw.pipe_mode;
+	total_data_bw = total_data_rate * drm_mode_vrefresh(pipe_mode);
 
 	/*
 	 * 12GB/s is maximum BW supported by single DBuf slice.
@@ -3905,15 +3905,15 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 	 * distribute DDB based on resolution/width of the display.
 	 */
 	for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc_state->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc_state->hw.pipe_mode;
 		enum pipe pipe = crtc->pipe;
 		int hdisplay, vdisplay;
 
 		if (!crtc_state->hw.enable)
 			continue;
 
-		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
+		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
 		total_width += hdisplay;
 
 		if (pipe < for_pipe)
@@ -4497,7 +4497,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->hw.adjusted_mode.crtc_htotal;
+	crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal;
 	linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
 
 	return linetime_us;
@@ -4679,14 +4679,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_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->hw.adjusted_mode.crtc_htotal /
+		if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
 		     wp->dbuf_block_size < 1) &&
 		     (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
 			selected_result = method2;
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

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

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 18acecc3642d..7a6da85823af 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -151,7 +151,7 @@ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
 static int intel_framebuffer_init(struct intel_framebuffer *ifb,
 				  struct drm_i915_gem_object *obj,
 				  struct drm_mode_fb_cmd2 *mode_cmd);
-static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state);
+static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state);
 static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
 static void intel_cpu_transcoder_set_m_n(const struct intel_crtc_state *crtc_state,
 					 const struct intel_link_m_n *m_n,
@@ -5651,7 +5651,7 @@ 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->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode = &state->hw.pipe_mode;
 	bool need_scaler = false;
 
 	if (state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
@@ -5660,8 +5660,8 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
 	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,
-				 adjusted_mode->crtc_vdisplay, NULL, need_scaler);
+				 pipe_mode->crtc_hdisplay,
+				 pipe_mode->crtc_vdisplay, NULL, need_scaler);
 }
 
 /**
@@ -6480,7 +6480,7 @@ static void ironlake_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	if (pipe_config->has_pch_encoder) {
@@ -6607,7 +6607,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
 	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_pipe_timings(pipe_config);
+		intel_set_transcoder_timings(pipe_config);
 
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_enable_trans_port_sync(pipe_config);
@@ -7015,7 +7015,7 @@ static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
@@ -7083,7 +7083,7 @@ static void i9xx_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
-	intel_set_pipe_timings(pipe_config);
+	intel_set_transcoder_timings(pipe_config);
 	intel_set_pipe_src_size(pipe_config);
 
 	i9xx_set_pipeconf(pipe_config);
@@ -7528,7 +7528,7 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config)
 {
 	u32 pixel_rate;
 
-	pixel_rate = pipe_config->hw.adjusted_mode.crtc_clock;
+	pixel_rate = pipe_config->hw.pipe_mode.crtc_clock;
 
 	/*
 	 * We only use IF-ID interlacing. If we ever use
@@ -7566,7 +7566,7 @@ static void intel_crtc_compute_pixel_rate(struct intel_crtc_state *crtc_state)
 	if (HAS_GMCH(dev_priv))
 		/* FIXME calculate proper pipe pixel rate for GMCH pfit */
 		crtc_state->pixel_rate =
-			crtc_state->hw.adjusted_mode.crtc_clock;
+			crtc_state->hw.pipe_mode.crtc_clock;
 	else
 		crtc_state->pixel_rate =
 			ilk_pipe_pixel_rate(crtc_state);
@@ -7576,7 +7576,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;
+	const struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
 	if (INTEL_GEN(dev_priv) < 4) {
@@ -7587,15 +7587,15 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 		 * is > 90% of the (display) core speed.
 		 */
 		if (intel_crtc_supports_double_wide(crtc) &&
-		    adjusted_mode->crtc_clock > clock_limit) {
+		    pipe_mode->crtc_clock > clock_limit) {
 			clock_limit = dev_priv->max_dotclk_freq;
 			pipe_config->double_wide = true;
 		}
 	}
 
-	if (adjusted_mode->crtc_clock > clock_limit) {
+	if (pipe_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,
+			      pipe_mode->crtc_clock, clock_limit,
 			      yesno(pipe_config->double_wide));
 		return -EINVAL;
 	}
@@ -7635,7 +7635,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
 	 */
 	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
-		adjusted_mode->crtc_hsync_start == adjusted_mode->crtc_hdisplay)
+		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -8294,7 +8294,7 @@ static void i8xx_compute_dpll(struct intel_crtc *crtc,
 	crtc_state->dpll_hw_state.dpll = dpll;
 }
 
-static void intel_set_pipe_timings(const struct intel_crtc_state *crtc_state)
+static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -8385,8 +8385,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
 		return I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_INTERLACE_MASK;
 }
 
-static void intel_get_pipe_timings(struct intel_crtc *crtc,
-				   struct intel_crtc_state *pipe_config)
+static void intel_get_transcoder_timings(struct intel_crtc *crtc,
+					 struct intel_crtc_state *pipe_config)
 {
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -8987,7 +8987,7 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 	if (INTEL_GEN(dev_priv) < 4)
 		pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
 
-	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_transcoder_timings(crtc, pipe_config);
 	intel_get_pipe_src_size(crtc, pipe_config);
 
 	i9xx_get_pfit_config(crtc, pipe_config);
@@ -10225,7 +10225,7 @@ static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
 		pipe_config->pixel_multiplier = 1;
 	}
 
-	intel_get_pipe_timings(crtc, pipe_config);
+	intel_get_transcoder_timings(crtc, pipe_config);
 	intel_get_pipe_src_size(crtc, pipe_config);
 
 	ironlake_get_pfit_config(crtc, pipe_config);
@@ -10680,7 +10680,7 @@ static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	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);
+		intel_get_transcoder_timings(crtc, pipe_config);
 	}
 
 	intel_get_pipe_src_size(crtc, pipe_config);
@@ -12637,7 +12637,7 @@ intel_crtc_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.adjusted_mode = crtc_state->uapi.adjusted_mode;
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
 	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
 }
 
@@ -17543,6 +17543,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			 */
 			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
 
+			/* initialize pipe_mode */
+			crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode;
+
 			mode = crtc_state->hw.adjusted_mode;
 			mode.hdisplay = crtc_state->pipe_src_w;
 			mode.vdisplay = crtc_state->pipe_src_h;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 0f20c7190eed..7f46c1646d3f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -794,15 +794,22 @@ struct intel_crtc_state {
 	 * The following members are used to verify the hardware state:
 	 * - enable
 	 * - active
-	 * - mode / adjusted_mode
+	 * - adjusted_mode
 	 * - color property blobs.
 	 *
 	 * During initial hw readout, they need to be copied to uapi.
+	 *
+	 * Bigjoiner will allow a transcoder mode that spans 2 pipes;
+	 * Use the pipe_mode for calculations like watermarks, pipe
+	 * scaler, and bandwidth.
+	 *
+	 * Use adjusted_mode for things that need to know the full
+	 * mode on the transcoder, which spans all pipes.
 	 */
 	struct {
 		bool active, enable;
 		struct drm_property_blob *degamma_lut, *gamma_lut, *ctm;
-		struct drm_display_mode adjusted_mode;
+		struct drm_display_mode pipe_mode, adjusted_mode;
 	} hw;
 
 	/**
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 05ba9e1bd247..780ff38b6aa1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -849,12 +849,12 @@ 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->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp = fb->format->cpp[0];
-		int clock = adjusted_mode->crtc_clock;
+		int clock = pipe_mode->crtc_clock;
 
 		/* Display SR */
 		wm = intel_calculate_wm(clock, &pineview_display_wm,
@@ -1085,8 +1085,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	unsigned int latency = dev_priv->wm.pri_latency[level] * 10;
 	unsigned int clock, htotal, cpp, width, wm;
 
@@ -1113,8 +1113,8 @@ static u16 g4x_compute_wm(const struct intel_crtc_state *crtc_state,
 	    level != G4X_WM_LEVEL_NORMAL)
 		cpp = max(cpp, 4u);
 
-	clock = adjusted_mode->crtc_clock;
-	htotal = adjusted_mode->crtc_htotal;
+	clock = pipe_mode->crtc_clock;
+	htotal = pipe_mode->crtc_htotal;
 
 	width = drm_rect_width(&plane_state->uapi.dst);
 
@@ -1591,8 +1591,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 {
 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	unsigned int clock, htotal, cpp, width, wm;
 
 	if (dev_priv->wm.pri_latency[level] == 0)
@@ -1602,8 +1602,8 @@ static u16 vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
 		return 0;
 
 	cpp = plane_state->hw.fb->format->cpp[0];
-	clock = adjusted_mode->crtc_clock;
-	htotal = adjusted_mode->crtc_htotal;
+	clock = pipe_mode->crtc_clock;
+	htotal = pipe_mode->crtc_htotal;
 	width = crtc_state->pipe_src_w;
 
 	if (plane->id == PLANE_CURSOR) {
@@ -2186,12 +2186,12 @@ static void i965_update_wm(struct intel_crtc *unused_crtc)
 	if (crtc) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 12000;
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
-		int clock = adjusted_mode->crtc_clock;
-		int htotal = adjusted_mode->crtc_htotal;
+		int clock = pipe_mode->crtc_clock;
+		int htotal = pipe_mode->crtc_htotal;
 		int hdisplay = crtc->config->pipe_src_w;
 		int cpp = fb->format->cpp[0];
 		int entries;
@@ -2267,8 +2267,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_A);
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_A);
 	if (intel_crtc_active(crtc)) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2278,7 +2278,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 		else
 			cpp = fb->format->cpp[0];
 
-		planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+		planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
 		enabled = crtc;
@@ -2294,8 +2294,8 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	fifo_size = dev_priv->display.get_fifo_size(dev_priv, PLANE_B);
 	crtc = intel_get_crtc_for_plane(dev_priv, PLANE_B);
 	if (intel_crtc_active(crtc)) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			crtc->base.primary->state->fb;
 		int cpp;
@@ -2305,7 +2305,7 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 		else
 			cpp = fb->format->cpp[0];
 
-		planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+		planeb_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 					       wm_info, fifo_size, cpp,
 					       pessimal_latency_ns);
 		if (enabled == NULL)
@@ -2342,12 +2342,12 @@ static void i9xx_update_wm(struct intel_crtc *unused_crtc)
 	if (HAS_FW_BLC(dev_priv) && enabled) {
 		/* self-refresh has much higher latency */
 		static const int sr_latency_ns = 6000;
-		const struct drm_display_mode *adjusted_mode =
-			&enabled->config->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&enabled->config->hw.pipe_mode;
 		const struct drm_framebuffer *fb =
 			enabled->base.primary->state->fb;
-		int clock = adjusted_mode->crtc_clock;
-		int htotal = adjusted_mode->crtc_htotal;
+		int clock = pipe_mode->crtc_clock;
+		int htotal = pipe_mode->crtc_htotal;
 		int hdisplay = enabled->config->pipe_src_w;
 		int cpp;
 		int entries;
@@ -2393,7 +2393,7 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
 {
 	struct drm_i915_private *dev_priv = to_i915(unused_crtc->base.dev);
 	struct intel_crtc *crtc;
-	const struct drm_display_mode *adjusted_mode;
+	const struct drm_display_mode *pipe_mode;
 	u32 fwater_lo;
 	int planea_wm;
 
@@ -2401,8 +2401,8 @@ static void i845_update_wm(struct intel_crtc *unused_crtc)
 	if (crtc == NULL)
 		return;
 
-	adjusted_mode = &crtc->config->hw.adjusted_mode;
-	planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+	pipe_mode = &crtc->config->hw.pipe_mode;
+	planea_wm = intel_calculate_wm(pipe_mode->crtc_clock,
 				       &i845_wm_info,
 				       dev_priv->display.get_fifo_size(dev_priv, PLANE_A),
 				       4, pessimal_latency_ns);
@@ -2491,7 +2491,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->uapi.dst),
 				 cpp, mem_value);
 
@@ -2519,7 +2519,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_mode.crtc_htotal,
 				 drm_rect_width(&plane_state->uapi.dst),
 				 cpp, mem_value);
 	return min(method1, method2);
@@ -2544,7 +2544,7 @@ static u32 ilk_compute_cur_wm(const struct intel_crtc_state *crtc_state,
 	cpp = plane_state->hw.fb->format->cpp[0];
 
 	return ilk_wm_method2(crtc_state->pixel_rate,
-			      crtc_state->hw.adjusted_mode.crtc_htotal,
+			      crtc_state->hw.pipe_mode.crtc_htotal,
 			      drm_rect_width(&plane_state->uapi.dst),
 			      cpp, mem_value);
 }
@@ -2768,13 +2768,13 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_atomic_state *intel_state =
 		to_intel_atomic_state(crtc_state->uapi.state);
-	const struct drm_display_mode *adjusted_mode =
-		&crtc_state->hw.adjusted_mode;
+	const struct drm_display_mode *pipe_mode =
+		&crtc_state->hw.pipe_mode;
 	u32 linetime, ips_linetime;
 
 	if (!crtc_state->hw.active)
 		return 0;
-	if (WARN_ON(adjusted_mode->crtc_clock == 0))
+	if (WARN_ON(pipe_mode->crtc_clock == 0))
 		return 0;
 	if (WARN_ON(intel_state->cdclk.logical.cdclk == 0))
 		return 0;
@@ -2782,9 +2782,9 @@ hsw_compute_linetime_wm(const struct intel_crtc_state *crtc_state)
 	/* The WM are computed with base on how long it takes to fill a single
 	 * row at the given clock rate, multiplied by 8.
 	 * */
-	linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
-				     adjusted_mode->crtc_clock);
-	ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
+	linetime = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
+				     pipe_mode->crtc_clock);
+	ips_linetime = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
 					 intel_state->cdclk.logical.cdclk);
 
 	return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
@@ -3779,7 +3779,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_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
 	for_each_intel_plane_on_crtc(dev, crtc, plane) {
@@ -3820,7 +3820,7 @@ static u16 intel_get_ddb_size(struct drm_i915_private *dev_priv,
 			      const int num_active,
 			      struct skl_ddb_allocation *ddb)
 {
-	const struct drm_display_mode *adjusted_mode;
+	const struct drm_display_mode *pipe_mode;
 	u64 total_data_bw;
 	u16 ddb_size = INTEL_INFO(dev_priv)->ddb_size;
 
@@ -3829,8 +3829,8 @@ 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->hw.adjusted_mode;
-	total_data_bw = total_data_rate * drm_mode_vrefresh(adjusted_mode);
+	pipe_mode = &crtc_state->hw.pipe_mode;
+	total_data_bw = total_data_rate * drm_mode_vrefresh(pipe_mode);
 
 	/*
 	 * 12GB/s is maximum BW supported by single DBuf slice.
@@ -3905,15 +3905,15 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 	 * distribute DDB based on resolution/width of the display.
 	 */
 	for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
-		const struct drm_display_mode *adjusted_mode =
-			&crtc_state->hw.adjusted_mode;
+		const struct drm_display_mode *pipe_mode =
+			&crtc_state->hw.pipe_mode;
 		enum pipe pipe = crtc->pipe;
 		int hdisplay, vdisplay;
 
 		if (!crtc_state->hw.enable)
 			continue;
 
-		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
+		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
 		total_width += hdisplay;
 
 		if (pipe < for_pipe)
@@ -4497,7 +4497,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->hw.adjusted_mode.crtc_htotal;
+	crtc_htotal = crtc_state->hw.pipe_mode.crtc_htotal;
 	linetime_us = div_fixed16(crtc_htotal * 1000, pixel_rate);
 
 	return linetime_us;
@@ -4679,14 +4679,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->hw.adjusted_mode.crtc_htotal,
+				 crtc_state->hw.pipe_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->hw.adjusted_mode.crtc_htotal /
+		if ((wp->cpp * crtc_state->hw.pipe_mode.crtc_htotal /
 		     wp->dbuf_block_size < 1) &&
 		     (wp->plane_bytes_per_line / wp->dbuf_block_size < 1)) {
 			selected_result = method2;
-- 
2.24.0

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

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

* [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

eDP does not support bigjoiner, so do not expose bigjoiner only
modes on the eDP port.

Changes since v1:
- Disallow bigjoiner on eDP.
Changes since v2:
- Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
  and split off the downstream and source checking to its own function.
  (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3123958e2081..9b7df8e85ea2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
-static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
+static int source_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;
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int max_dotclk = dev_priv->max_dotclk_freq;
-	int ds_max_dotclk;
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))
+		return 2 * i915->max_dotclk_freq;
+
+	return i915->max_dotclk_freq;
+}
 
+static int downstream_max_dotclock(struct intel_dp *intel_dp)
+{
 	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
 
 	if (type != DP_DS_PORT_TYPE_VGA)
-		return max_dotclk;
+		return 0;
 
-	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
-						    intel_dp->downstream_ports);
+	return drm_dp_downstream_max_clock(intel_dp->dpcd,
+					   intel_dp->downstream_ports);
+}
+
+static int
+intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
+{
+	int max_dotclk = source_max_dotclock(intel_dp, allow_bigjoiner);
+	int ds_max_dotclk = downstream_max_dotclock(intel_dp);
 
 	if (ds_max_dotclk != 0)
-		max_dotclk = min(max_dotclk, ds_max_dotclk);
+		return min(max_dotclk, ds_max_dotclk);
 
 	return max_dotclk;
 }
@@ -506,7 +518,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
 
 static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 				       u32 link_clock, u32 lane_count,
-				       u32 mode_clock, u32 mode_hdisplay)
+				       u32 mode_clock, u32 mode_hdisplay,
+				       bool bigjoiner)
 {
 	u32 bits_per_pixel, max_bpp_small_joiner_ram;
 	int i;
@@ -524,6 +537,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
 	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
 		mode_hdisplay;
+
+	if (bigjoiner)
+		max_bpp_small_joiner_ram *= 2;
+
 	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
 
 	/*
@@ -532,6 +549,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 	 */
 	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
 
+	if (bigjoiner) {
+		u32 max_bpp_bigjoiner =
+			i915->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",
@@ -554,7 +580,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 }
 
 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;
@@ -579,12 +606,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);
@@ -623,11 +658,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_max_dotclock(intel_dp, false);
 
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
@@ -639,6 +678,21 @@ 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) {
+		if (intel_dp_is_edp(intel_dp))
+			return MODE_CLOCK_HIGH;
+
+		max_dotclk = intel_dp_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);
 
@@ -666,23 +720,28 @@ intel_dp_mode_valid(struct drm_connector *connector,
 							    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);
 }
@@ -2104,11 +2163,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 						    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.24.0

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

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

* [Intel-gfx] [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

eDP does not support bigjoiner, so do not expose bigjoiner only
modes on the eDP port.

Changes since v1:
- Disallow bigjoiner on eDP.
Changes since v2:
- Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
  and split off the downstream and source checking to its own function.
  (Ville)

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

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3123958e2081..9b7df8e85ea2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
-static int
-intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
+static int source_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;
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	int max_dotclk = dev_priv->max_dotclk_freq;
-	int ds_max_dotclk;
+	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+
+	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))
+		return 2 * i915->max_dotclk_freq;
+
+	return i915->max_dotclk_freq;
+}
 
+static int downstream_max_dotclock(struct intel_dp *intel_dp)
+{
 	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
 
 	if (type != DP_DS_PORT_TYPE_VGA)
-		return max_dotclk;
+		return 0;
 
-	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
-						    intel_dp->downstream_ports);
+	return drm_dp_downstream_max_clock(intel_dp->dpcd,
+					   intel_dp->downstream_ports);
+}
+
+static int
+intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
+{
+	int max_dotclk = source_max_dotclock(intel_dp, allow_bigjoiner);
+	int ds_max_dotclk = downstream_max_dotclock(intel_dp);
 
 	if (ds_max_dotclk != 0)
-		max_dotclk = min(max_dotclk, ds_max_dotclk);
+		return min(max_dotclk, ds_max_dotclk);
 
 	return max_dotclk;
 }
@@ -506,7 +518,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
 
 static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 				       u32 link_clock, u32 lane_count,
-				       u32 mode_clock, u32 mode_hdisplay)
+				       u32 mode_clock, u32 mode_hdisplay,
+				       bool bigjoiner)
 {
 	u32 bits_per_pixel, max_bpp_small_joiner_ram;
 	int i;
@@ -524,6 +537,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
 	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
 		mode_hdisplay;
+
+	if (bigjoiner)
+		max_bpp_small_joiner_ram *= 2;
+
 	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
 
 	/*
@@ -532,6 +549,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 	 */
 	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
 
+	if (bigjoiner) {
+		u32 max_bpp_bigjoiner =
+			i915->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",
@@ -554,7 +580,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
 }
 
 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;
@@ -579,12 +606,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);
@@ -623,11 +658,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_max_dotclock(intel_dp, false);
 
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
@@ -639,6 +678,21 @@ 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) {
+		if (intel_dp_is_edp(intel_dp))
+			return MODE_CLOCK_HIGH;
+
+		max_dotclk = intel_dp_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);
 
@@ -666,23 +720,28 @@ intel_dp_mode_valid(struct drm_connector *connector,
 							    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);
 }
@@ -2104,11 +2163,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
 						    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.24.0

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

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

* [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Changes since v1:
- Rename pipe timings to transcoder timings, as they are now different.
Changes since v2:
- Rework bigjoiner checks; always disable slave when recalculating
  master. No need to have a separate bigjoiner pass any more.
- Use pipe_mode instead of transcoder_mode, to clean up the code.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
 drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 198 ++++++++++++++++--
 .../drm/i915/display/intel_display_types.h    |   9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
 5 files changed, 207 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index fd0026fc3618..b5c17d8c0208 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -229,14 +229,15 @@ 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)
 {
 	drm_property_replace_blob(&crtc_state->hw.degamma_lut,
-				  crtc_state->uapi.degamma_lut);
+				  from_crtc_state->uapi.degamma_lut);
 	drm_property_replace_blob(&crtc_state->hw.gamma_lut,
-				  crtc_state->uapi.gamma_lut);
+				  from_crtc_state->uapi.gamma_lut);
 	drm_property_replace_blob(&crtc_state->hw.ctm,
-				  crtc_state->uapi.ctm);
+				  from_crtc_state->uapi.ctm);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 7b49623419ba..e64473227285 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -37,7 +37,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 7a6da85823af..2dc63ef5caf8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7576,9 +7576,25 @@ 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 *pipe_mode = &pipe_config->hw.pipe_mode;
+	struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
+	*pipe_mode = pipe_config->hw.adjusted_mode;
+
+	/* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
+	if (pipe_config->bigjoiner) {
+		pipe_mode->crtc_clock /= 2;
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_hskew /= 2;
+
+		pipe_config->pipe_src_w /= 2;
+	}
+
 	if (INTEL_GEN(dev_priv) < 4) {
 		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
 
@@ -7635,7 +7651,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
 	 */
 	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
-		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
+	    pipe_config->hw.adjusted_mode.crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -11921,7 +11937,7 @@ static bool encoders_cloneable(const struct intel_encoder *a,
 			  b->cloneable & (1 << a->type));
 }
 
-static bool check_single_encoder_cloning(struct drm_atomic_state *state,
+static bool check_single_encoder_cloning(struct intel_atomic_state *state,
 					 struct intel_crtc *crtc,
 					 struct intel_encoder *encoder)
 {
@@ -11930,7 +11946,7 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
 	struct drm_connector_state *connector_state;
 	int i;
 
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != &crtc->base)
 			continue;
 
@@ -12167,6 +12183,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 
 	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)
@@ -12627,18 +12644,31 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
 }
 
 static void
-intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_crtc_state *crtc_state)
+intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
+					   struct intel_crtc_state *crtc_state)
 {
-	intel_crtc_copy_color_blobs(crtc_state);
+	const struct intel_crtc_state *from_crtc_state = crtc_state;
+
+	if (crtc_state->bigjoiner_slave) {
+		from_crtc_state = intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);
+
+		/* No need to copy state if the master state is unchanged */
+		if (!from_crtc_state)
+			return;
+	}
+
+	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state);
 }
 
 static void
-intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
+intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
-	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
+	intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
 }
 
 static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
@@ -12660,7 +12690,49 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
 }
 
 static int
-intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
+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.pipe_mode = from_crtc_state->hw.pipe_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
+intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
+				 struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(crtc_state->uapi.crtc->dev);
@@ -12703,16 +12775,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	crtc_state->uapi.mode.private_flags = 0;
 	crtc_state->uapi.adjusted_mode.private_flags = 0;
 
-	intel_crtc_copy_uapi_to_hw_state(crtc_state);
+	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
 
 	return 0;
 }
 
 static int
-intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
+intel_modeset_pipe_config(struct intel_atomic_state *state,
+			  struct intel_crtc_state *pipe_config)
 {
 	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;
@@ -12755,7 +12827,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != crtc)
 			continue;
 
@@ -12800,7 +12872,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
 	 */
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != crtc)
 			continue;
 
@@ -12853,8 +12925,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 */
 	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
 
-	/* without bigjoiner, pipe_mode == adjusted_mode */
-	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
 	return 0;
 }
 
@@ -14091,6 +14161,74 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
 	return 0;
 }
 
+static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
+					struct intel_crtc *crtc,
+					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);
+	struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
+	struct intel_crtc *slave, *master;
+
+	/* slave being enabled, is master is still claiming this crtc? */
+	if (old_crtc_state->bigjoiner_slave) {
+		slave = crtc;
+		master = old_crtc_state->bigjoiner_linked_crtc;
+		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
+		if (!master_crtc_state || !needs_modeset(master_crtc_state))
+			goto claimed;
+	}
+
+	if (!new_crtc_state->bigjoiner)
+		return 0;
+
+	if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
+		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
+			      "CRTC + 1 to be used, doesn't exist\n",
+			      crtc->base.base.id, crtc->base.name);
+		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);
+	master = crtc;
+	if (IS_ERR(slave_crtc_state))
+		return PTR_ERR(slave_crtc_state);
+
+	/* master being enabled, slave was already configured? */
+	if (slave_crtc_state->uapi.enable)
+		goto claimed;
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
+		      slave->base.base.id, slave->base.name);
+	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+
+claimed:
+	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
+		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
+		      slave->base.base.id, slave->base.name,
+		      master->base.base.id, master->base.name);
+	return -EINVAL;
+}
+
+static int kill_bigjoiner_slave(struct intel_atomic_state *state,
+				struct intel_crtc_state *master_crtc_state)
+{
+	struct intel_crtc_state *slave_crtc_state =
+		intel_atomic_get_crtc_state(&state->base,
+			master_crtc_state->bigjoiner_linked_crtc);
+
+	if (IS_ERR(slave_crtc_state))
+		return PTR_ERR(slave_crtc_state);
+
+	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
+	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
+	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
+	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
+	return 0;
+}
+
 /**
  * intel_atomic_check - validate state object
  * @dev: drm device
@@ -14122,23 +14260,31 @@ static int intel_atomic_check(struct drm_device *dev,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state)) {
 			/* Light copy */
-			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
+			intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
 
 			continue;
 		}
 
-		if (!new_crtc_state->uapi.enable) {
-			intel_crtc_copy_uapi_to_hw_state(new_crtc_state);
+		/* Kill old bigjoiner link, we may re-establish afterwards */
+		if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) {
+			ret = kill_bigjoiner_slave(state, new_crtc_state);
+			if (ret)
+				goto fail;
+		}
 
-			any_ms = true;
+		if (!new_crtc_state->uapi.enable) {
+			if (!new_crtc_state->bigjoiner_slave) {
+				intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
+				any_ms = true;
+			}
 			continue;
 		}
 
-		ret = intel_crtc_prepare_cleared_state(new_crtc_state);
+		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
-		ret = intel_modeset_pipe_config(new_crtc_state);
+		ret = intel_modeset_pipe_config(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
@@ -14146,6 +14292,10 @@ static int intel_atomic_check(struct drm_device *dev,
 
 		if (needs_modeset(new_crtc_state))
 			any_ms = true;
+
+		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state, new_crtc_state);
+		if (ret)
+			goto fail;
 	}
 
 	if (any_ms && !check_digital_port_conflicts(state)) {
@@ -14350,7 +14500,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);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7f46c1646d3f..cf2ecfa17416 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1044,6 +1044,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 9b7df8e85ea2..54fde4c4c4dd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2147,6 +2147,15 @@ 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_max_dotclock(intel_dp, false)) {
+		if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, true)) {
+			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
+			return -EINVAL;
+		}
+		pipe_config->bigjoiner = true;
+		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
+	}
+
 	if (intel_dp_is_edp(intel_dp)) {
 		pipe_config->dsc.compressed_bpp =
 			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
@@ -2164,12 +2173,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;
@@ -2184,13 +2193,14 @@ 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.slice_count > 1) {
-			pipe_config->dsc.dsc_split = true;
-		} else {
+	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
+	    pipe_config->bigjoiner) {
+		if (pipe_config->dsc.slice_count < 2) {
 			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
 			return -EINVAL;
 		}
+
+		pipe_config->dsc.dsc_split = true;
 	}
 
 	ret = intel_dsc_compute_params(&dig_port->base, pipe_config);
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Changes since v1:
- Rename pipe timings to transcoder timings, as they are now different.
Changes since v2:
- Rework bigjoiner checks; always disable slave when recalculating
  master. No need to have a separate bigjoiner pass any more.
- Use pipe_mode instead of transcoder_mode, to clean up the code.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
 drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 198 ++++++++++++++++--
 .../drm/i915/display/intel_display_types.h    |   9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
 5 files changed, 207 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index fd0026fc3618..b5c17d8c0208 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -229,14 +229,15 @@ 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)
 {
 	drm_property_replace_blob(&crtc_state->hw.degamma_lut,
-				  crtc_state->uapi.degamma_lut);
+				  from_crtc_state->uapi.degamma_lut);
 	drm_property_replace_blob(&crtc_state->hw.gamma_lut,
-				  crtc_state->uapi.gamma_lut);
+				  from_crtc_state->uapi.gamma_lut);
 	drm_property_replace_blob(&crtc_state->hw.ctm,
-				  crtc_state->uapi.ctm);
+				  from_crtc_state->uapi.ctm);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 7b49623419ba..e64473227285 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -37,7 +37,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 7a6da85823af..2dc63ef5caf8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7576,9 +7576,25 @@ 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 *pipe_mode = &pipe_config->hw.pipe_mode;
+	struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
 	int clock_limit = dev_priv->max_dotclk_freq;
 
+	*pipe_mode = pipe_config->hw.adjusted_mode;
+
+	/* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
+	if (pipe_config->bigjoiner) {
+		pipe_mode->crtc_clock /= 2;
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_hskew /= 2;
+
+		pipe_config->pipe_src_w /= 2;
+	}
+
 	if (INTEL_GEN(dev_priv) < 4) {
 		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
 
@@ -7635,7 +7651,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
 	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
 	 */
 	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
-		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
+	    pipe_config->hw.adjusted_mode.crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -11921,7 +11937,7 @@ static bool encoders_cloneable(const struct intel_encoder *a,
 			  b->cloneable & (1 << a->type));
 }
 
-static bool check_single_encoder_cloning(struct drm_atomic_state *state,
+static bool check_single_encoder_cloning(struct intel_atomic_state *state,
 					 struct intel_crtc *crtc,
 					 struct intel_encoder *encoder)
 {
@@ -11930,7 +11946,7 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
 	struct drm_connector_state *connector_state;
 	int i;
 
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != &crtc->base)
 			continue;
 
@@ -12167,6 +12183,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 
 	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)
@@ -12627,18 +12644,31 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
 }
 
 static void
-intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_crtc_state *crtc_state)
+intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
+					   struct intel_crtc_state *crtc_state)
 {
-	intel_crtc_copy_color_blobs(crtc_state);
+	const struct intel_crtc_state *from_crtc_state = crtc_state;
+
+	if (crtc_state->bigjoiner_slave) {
+		from_crtc_state = intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);
+
+		/* No need to copy state if the master state is unchanged */
+		if (!from_crtc_state)
+			return;
+	}
+
+	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state);
 }
 
 static void
-intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
+intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
-	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
+	intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
 }
 
 static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
@@ -12660,7 +12690,49 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
 }
 
 static int
-intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
+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.pipe_mode = from_crtc_state->hw.pipe_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
+intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
+				 struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(crtc_state->uapi.crtc->dev);
@@ -12703,16 +12775,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	crtc_state->uapi.mode.private_flags = 0;
 	crtc_state->uapi.adjusted_mode.private_flags = 0;
 
-	intel_crtc_copy_uapi_to_hw_state(crtc_state);
+	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
 
 	return 0;
 }
 
 static int
-intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
+intel_modeset_pipe_config(struct intel_atomic_state *state,
+			  struct intel_crtc_state *pipe_config)
 {
 	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;
@@ -12755,7 +12827,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != crtc)
 			continue;
 
@@ -12800,7 +12872,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * adjust it according to limitations or connector properties, and also
 	 * a chance to reject the mode entirely.
 	 */
-	for_each_new_connector_in_state(state, connector, connector_state, i) {
+	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
 		if (connector_state->crtc != crtc)
 			continue;
 
@@ -12853,8 +12925,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 */
 	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
 
-	/* without bigjoiner, pipe_mode == adjusted_mode */
-	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
 	return 0;
 }
 
@@ -14091,6 +14161,74 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
 	return 0;
 }
 
+static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
+					struct intel_crtc *crtc,
+					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);
+	struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
+	struct intel_crtc *slave, *master;
+
+	/* slave being enabled, is master is still claiming this crtc? */
+	if (old_crtc_state->bigjoiner_slave) {
+		slave = crtc;
+		master = old_crtc_state->bigjoiner_linked_crtc;
+		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
+		if (!master_crtc_state || !needs_modeset(master_crtc_state))
+			goto claimed;
+	}
+
+	if (!new_crtc_state->bigjoiner)
+		return 0;
+
+	if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
+		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
+			      "CRTC + 1 to be used, doesn't exist\n",
+			      crtc->base.base.id, crtc->base.name);
+		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);
+	master = crtc;
+	if (IS_ERR(slave_crtc_state))
+		return PTR_ERR(slave_crtc_state);
+
+	/* master being enabled, slave was already configured? */
+	if (slave_crtc_state->uapi.enable)
+		goto claimed;
+
+	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
+		      slave->base.base.id, slave->base.name);
+	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+
+claimed:
+	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
+		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
+		      slave->base.base.id, slave->base.name,
+		      master->base.base.id, master->base.name);
+	return -EINVAL;
+}
+
+static int kill_bigjoiner_slave(struct intel_atomic_state *state,
+				struct intel_crtc_state *master_crtc_state)
+{
+	struct intel_crtc_state *slave_crtc_state =
+		intel_atomic_get_crtc_state(&state->base,
+			master_crtc_state->bigjoiner_linked_crtc);
+
+	if (IS_ERR(slave_crtc_state))
+		return PTR_ERR(slave_crtc_state);
+
+	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
+	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
+	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
+	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
+	return 0;
+}
+
 /**
  * intel_atomic_check - validate state object
  * @dev: drm device
@@ -14122,23 +14260,31 @@ static int intel_atomic_check(struct drm_device *dev,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state)) {
 			/* Light copy */
-			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
+			intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
 
 			continue;
 		}
 
-		if (!new_crtc_state->uapi.enable) {
-			intel_crtc_copy_uapi_to_hw_state(new_crtc_state);
+		/* Kill old bigjoiner link, we may re-establish afterwards */
+		if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) {
+			ret = kill_bigjoiner_slave(state, new_crtc_state);
+			if (ret)
+				goto fail;
+		}
 
-			any_ms = true;
+		if (!new_crtc_state->uapi.enable) {
+			if (!new_crtc_state->bigjoiner_slave) {
+				intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
+				any_ms = true;
+			}
 			continue;
 		}
 
-		ret = intel_crtc_prepare_cleared_state(new_crtc_state);
+		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
-		ret = intel_modeset_pipe_config(new_crtc_state);
+		ret = intel_modeset_pipe_config(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
@@ -14146,6 +14292,10 @@ static int intel_atomic_check(struct drm_device *dev,
 
 		if (needs_modeset(new_crtc_state))
 			any_ms = true;
+
+		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state, new_crtc_state);
+		if (ret)
+			goto fail;
 	}
 
 	if (any_ms && !check_digital_port_conflicts(state)) {
@@ -14350,7 +14500,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);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 7f46c1646d3f..cf2ecfa17416 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1044,6 +1044,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 9b7df8e85ea2..54fde4c4c4dd 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2147,6 +2147,15 @@ 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_max_dotclock(intel_dp, false)) {
+		if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, true)) {
+			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
+			return -EINVAL;
+		}
+		pipe_config->bigjoiner = true;
+		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
+	}
+
 	if (intel_dp_is_edp(intel_dp)) {
 		pipe_config->dsc.compressed_bpp =
 			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
@@ -2164,12 +2173,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;
@@ -2184,13 +2193,14 @@ 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.slice_count > 1) {
-			pipe_config->dsc.dsc_split = true;
-		} else {
+	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
+	    pipe_config->bigjoiner) {
+		if (pipe_config->dsc.slice_count < 2) {
 			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
 			return -EINVAL;
 		}
+
+		pipe_config->dsc.dsc_split = true;
 	}
 
 	ret = intel_dsc_compute_params(&dig_port->base, pipe_config);
-- 
2.24.0

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

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

* [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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 still 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.
This is done correctly later in this series.

The next steps are to enable planes correctly, 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      |  48 ++-
 drivers/gpu/drm/i915/display/intel_display.c  | 399 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |  22 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
 6 files changed, 408 insertions(+), 206 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8f817de34460..1215f619da36 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2218,13 +2218,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.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)
@@ -3557,7 +3550,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 
 	/* 7.l Configure and enable FEC if needed */
 	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,
@@ -3629,7 +3623,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,
@@ -4252,19 +4247,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
@@ -4350,6 +4344,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;
+	}
 
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		tgl_dc3co_exitline_get_config(pipe_config);
@@ -4377,7 +4394,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 2dc63ef5caf8..94e4cab00a66 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6583,6 +6583,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)
 {
@@ -6596,40 +6635,41 @@ 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_transcoder_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);
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		icl_enable_trans_port_sync(pipe_config);
+		if (INTEL_GEN(dev_priv) >= 11)
+			icl_enable_trans_port_sync(pipe_config);
 
-	intel_set_pipe_src_size(pipe_config);
+		intel_set_transcoder_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;
 
@@ -6657,7 +6697,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_set_pipe_chicken(intel_crtc);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
+	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
 		intel_ddi_enable_transcoder_func(pipe_config);
 
 	if (dev_priv->display.initial_watermarks != NULL)
@@ -6667,8 +6707,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);
@@ -6796,9 +6838,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)
@@ -6968,6 +7028,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.compression_enable)
+		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
+
 	return mask;
 }
 
@@ -7559,6 +7622,30 @@ 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)
+{
+	struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
+
+	encoder->get_config(encoder, crtc_state);
+
+	*pipe_mode = crtc_state->hw.adjusted_mode;
+	if (crtc_state->bigjoiner) {
+		/*
+		  * transcoder is programmed to the full mode,
+		  * but pipje timings are half of the transcoder mode
+		  */
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_hskew /= 2;
+		pipe_mode->crtc_clock /= 2;
+	}
+}
+
 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);
@@ -8461,20 +8548,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.adjusted_mode;
+
+	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->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->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 = pipe_config->hw.adjusted_mode.flags;
+	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);
@@ -10564,6 +10653,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);
@@ -10689,11 +10780,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;
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+		active = true;
+		pipe_config->pixel_multiplier = 1;
+
+		/* 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_transcoder_timings(crtc, pipe_config);
@@ -10770,7 +10869,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;
@@ -11748,7 +11850,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);
 
@@ -12674,10 +12776,11 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *state,
 static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
 					     struct drm_display_mode *user_mode)
 {
-	crtc_state->uapi.enable = crtc_state->hw.enable;
-	crtc_state->uapi.active = crtc_state->hw.active;
-	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
-
+	if (!crtc_state->bigjoiner_slave) {
+		crtc_state->uapi.enable = crtc_state->hw.enable;
+		crtc_state->uapi.active = crtc_state->hw.active;
+		WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
+	}
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
 	/* copy color blobs to uapi */
@@ -13258,21 +13361,43 @@ 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);
-
-	PIPE_CONF_CHECK_I(pixel_multiplier);
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
+		/* bigjoiner mode = transcoder mode / 2, for calculations */
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal);
+
+		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);
+
+		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_I(pixel_multiplier);
+	}
+
 	PIPE_CONF_CHECK_I(output_format);
 	PIPE_CONF_CHECK_I(dc3co_exitline);
 	PIPE_CONF_CHECK_BOOL(has_hdmi_sink);
@@ -13283,24 +13408,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)
@@ -13324,7 +13436,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))
@@ -13343,48 +13456,51 @@ 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(hw.pipe_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);
@@ -13395,6 +13511,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_I(sync_mode_slaves_mask);
 	PIPE_CONF_CHECK_I(master_transcoder);
+	PIPE_CONF_CHECK_BOOL(bigjoiner);
+	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
+	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
+	PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
+	PIPE_CONF_CHECK_BOOL(dsc.dsc_split);
 
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
@@ -13650,6 +13771,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;
@@ -13679,7 +13801,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);
@@ -13688,12 +13813,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);
@@ -14473,7 +14598,6 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	if (modeset) {
 		intel_crtc_update_active_timings(new_crtc_state);
-
 		dev_priv->display.crtc_enable(new_crtc_state, state);
 
 		/* vblanks work again, re-enable pipe CRC. */
@@ -14613,7 +14737,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;
 
 		/* In case of Transcoder port Sync master slave CRTCs can be
@@ -14637,6 +14761,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);
+			}
 		}
 	}
 }
@@ -17168,7 +17305,7 @@ int intel_modeset_init(struct drm_i915_private *i915)
 	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;
 
 		/*
@@ -17624,7 +17761,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 cf2ecfa17416..86a0524b3cd8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -821,6 +821,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 */
@@ -1639,4 +1640,25 @@ 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);
+
+	if (!INTEL_INFO(dev_priv)->display.has_dsc)
+		return false;
+
+	/* On TGL, DSC is supported on all Pipes */
+	if (INTEL_GEN(dev_priv) >= 12)
+		return true;
+
+	/* gen10 and gen11 have DSC, but not on pipe A, eDP is allowed */
+	if (INTEL_GEN(dev_priv) >= 10 &&
+	    (to_intel_crtc(pipe_config->uapi.crtc)->pipe != PIPE_A ||
+	     pipe_config->cpu_transcoder == TRANSCODER_EDP))
+		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 54fde4c4c4dd..d0b6276f7712 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1948,32 +1948,13 @@ 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);
-
-	if (!INTEL_INFO(dev_priv)->display.has_dsc)
-		return false;
-
-	/* 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)
 {
 	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
 		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 b23ba8d108db..e48608221e71 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -501,11 +501,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
 }
 
-static void intel_dsc_pps_configure(struct intel_encoder *encoder,
-				    const struct intel_crtc_state *crtc_state)
+static void intel_dsc_pps_configure(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->dsc.config;
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
@@ -515,6 +514,9 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
 	u8 num_vdsc_instances = (crtc_state->dsc.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 |
@@ -920,74 +922,104 @@ static void intel_dsc_dp_pps_write(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.compression_enable)
 		return;
 
-	/* Enable Power wells for VDSC/joining */
-	intel_display_power_get(dev_priv,
-				intel_dsc_power_domain(crtc_state));
+	intel_dsc_pps_configure(crtc_state);
 
-	intel_dsc_pps_configure(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_dsc_dp_pps_write(encoder, crtc_state);
 
-	intel_dsc_dp_pps_write(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.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.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.compression_enable = true;
+
+	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
+		crtc_state->dsc.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 4ed2256750c3..79d965fedf0b 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -14,6 +14,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
 int intel_dsc_compute_params(struct intel_encoder *encoder,
 			     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.24.0

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

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

* [Intel-gfx] [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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 still 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.
This is done correctly later in this series.

The next steps are to enable planes correctly, 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      |  48 ++-
 drivers/gpu/drm/i915/display/intel_display.c  | 399 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |  22 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
 6 files changed, 408 insertions(+), 206 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8f817de34460..1215f619da36 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2218,13 +2218,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.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)
@@ -3557,7 +3550,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
 
 	/* 7.l Configure and enable FEC if needed */
 	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,
@@ -3629,7 +3623,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,
@@ -4252,19 +4247,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
@@ -4350,6 +4344,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;
+	}
 
 	if (encoder->type == INTEL_OUTPUT_EDP)
 		tgl_dc3co_exitline_get_config(pipe_config);
@@ -4377,7 +4394,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 2dc63ef5caf8..94e4cab00a66 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6583,6 +6583,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)
 {
@@ -6596,40 +6635,41 @@ 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_transcoder_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);
 
-	if (INTEL_GEN(dev_priv) >= 11)
-		icl_enable_trans_port_sync(pipe_config);
+		if (INTEL_GEN(dev_priv) >= 11)
+			icl_enable_trans_port_sync(pipe_config);
 
-	intel_set_pipe_src_size(pipe_config);
+		intel_set_transcoder_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;
 
@@ -6657,7 +6697,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_set_pipe_chicken(intel_crtc);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
+	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
 		intel_ddi_enable_transcoder_func(pipe_config);
 
 	if (dev_priv->display.initial_watermarks != NULL)
@@ -6667,8 +6707,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);
@@ -6796,9 +6838,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)
@@ -6968,6 +7028,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.compression_enable)
+		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
+
 	return mask;
 }
 
@@ -7559,6 +7622,30 @@ 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)
+{
+	struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
+
+	encoder->get_config(encoder, crtc_state);
+
+	*pipe_mode = crtc_state->hw.adjusted_mode;
+	if (crtc_state->bigjoiner) {
+		/*
+		  * transcoder is programmed to the full mode,
+		  * but pipje timings are half of the transcoder mode
+		  */
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_hskew /= 2;
+		pipe_mode->crtc_clock /= 2;
+	}
+}
+
 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);
@@ -8461,20 +8548,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.adjusted_mode;
+
+	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->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->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 = pipe_config->hw.adjusted_mode.flags;
+	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);
@@ -10564,6 +10653,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);
@@ -10689,11 +10780,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;
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+		active = true;
+		pipe_config->pixel_multiplier = 1;
+
+		/* 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_transcoder_timings(crtc, pipe_config);
@@ -10770,7 +10869,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;
@@ -11748,7 +11850,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);
 
@@ -12674,10 +12776,11 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *state,
 static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
 					     struct drm_display_mode *user_mode)
 {
-	crtc_state->uapi.enable = crtc_state->hw.enable;
-	crtc_state->uapi.active = crtc_state->hw.active;
-	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
-
+	if (!crtc_state->bigjoiner_slave) {
+		crtc_state->uapi.enable = crtc_state->hw.enable;
+		crtc_state->uapi.active = crtc_state->hw.active;
+		WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
+	}
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
 	/* copy color blobs to uapi */
@@ -13258,21 +13361,43 @@ 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);
-
-	PIPE_CONF_CHECK_I(pixel_multiplier);
+	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
+		/* bigjoiner mode = transcoder mode / 2, for calculations */
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay);
+		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal);
+
+		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);
+
+		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_I(pixel_multiplier);
+	}
+
 	PIPE_CONF_CHECK_I(output_format);
 	PIPE_CONF_CHECK_I(dc3co_exitline);
 	PIPE_CONF_CHECK_BOOL(has_hdmi_sink);
@@ -13283,24 +13408,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)
@@ -13324,7 +13436,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))
@@ -13343,48 +13456,51 @@ 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(hw.pipe_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);
@@ -13395,6 +13511,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_I(sync_mode_slaves_mask);
 	PIPE_CONF_CHECK_I(master_transcoder);
+	PIPE_CONF_CHECK_BOOL(bigjoiner);
+	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
+	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
+	PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
+	PIPE_CONF_CHECK_BOOL(dsc.dsc_split);
 
 #undef PIPE_CONF_CHECK_X
 #undef PIPE_CONF_CHECK_I
@@ -13650,6 +13771,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;
@@ -13679,7 +13801,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);
@@ -13688,12 +13813,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);
@@ -14473,7 +14598,6 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	if (modeset) {
 		intel_crtc_update_active_timings(new_crtc_state);
-
 		dev_priv->display.crtc_enable(new_crtc_state, state);
 
 		/* vblanks work again, re-enable pipe CRC. */
@@ -14613,7 +14737,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;
 
 		/* In case of Transcoder port Sync master slave CRTCs can be
@@ -14637,6 +14761,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);
+			}
 		}
 	}
 }
@@ -17168,7 +17305,7 @@ int intel_modeset_init(struct drm_i915_private *i915)
 	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;
 
 		/*
@@ -17624,7 +17761,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 cf2ecfa17416..86a0524b3cd8 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -821,6 +821,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 */
@@ -1639,4 +1640,25 @@ 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);
+
+	if (!INTEL_INFO(dev_priv)->display.has_dsc)
+		return false;
+
+	/* On TGL, DSC is supported on all Pipes */
+	if (INTEL_GEN(dev_priv) >= 12)
+		return true;
+
+	/* gen10 and gen11 have DSC, but not on pipe A, eDP is allowed */
+	if (INTEL_GEN(dev_priv) >= 10 &&
+	    (to_intel_crtc(pipe_config->uapi.crtc)->pipe != PIPE_A ||
+	     pipe_config->cpu_transcoder == TRANSCODER_EDP))
+		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 54fde4c4c4dd..d0b6276f7712 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1948,32 +1948,13 @@ 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);
-
-	if (!INTEL_INFO(dev_priv)->display.has_dsc)
-		return false;
-
-	/* 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)
 {
 	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
 		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 b23ba8d108db..e48608221e71 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -501,11 +501,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
 }
 
-static void intel_dsc_pps_configure(struct intel_encoder *encoder,
-				    const struct intel_crtc_state *crtc_state)
+static void intel_dsc_pps_configure(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->dsc.config;
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
@@ -515,6 +514,9 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
 	u8 num_vdsc_instances = (crtc_state->dsc.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 |
@@ -920,74 +922,104 @@ static void intel_dsc_dp_pps_write(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.compression_enable)
 		return;
 
-	/* Enable Power wells for VDSC/joining */
-	intel_display_power_get(dev_priv,
-				intel_dsc_power_domain(crtc_state));
+	intel_dsc_pps_configure(crtc_state);
 
-	intel_dsc_pps_configure(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_dsc_dp_pps_write(encoder, crtc_state);
 
-	intel_dsc_dp_pps_write(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.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.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.compression_enable = true;
+
+	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
+		crtc_state->dsc.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 4ed2256750c3..79d965fedf0b 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -14,6 +14,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
 int intel_dsc_compute_params(struct intel_encoder *encoder,
 			     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.24.0

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

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

* [PATCH 07/11] drm/i915: Make hardware readout work on i915.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 94e4cab00a66..b1085ef3f1d0 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3231,6 +3231,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)
@@ -3253,7 +3255,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);
@@ -3275,6 +3277,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;
 
@@ -10078,6 +10086,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);
@@ -10181,6 +10190,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;
@@ -17535,7 +17556,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)) {
@@ -17825,6 +17847,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;
+
 		if (crtc_state->hw.active) {
 			struct drm_display_mode mode;
 
@@ -17849,6 +17874,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			mode.hdisplay = crtc_state->pipe_src_w;
 			mode.vdisplay = crtc_state->pipe_src_h;
 
+			if (crtc_state->bigjoiner)
+				mode.hdisplay *= 2;
+
 			intel_crtc_compute_pixel_rate(crtc_state);
 
 			intel_crtc_update_active_timings(crtc_state);
@@ -17898,6 +17926,39 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		intel_bw_crtc_update(bw_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->uapi.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.24.0

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

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

* [Intel-gfx] [PATCH 07/11] drm/i915: Make hardware readout work on i915.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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, 63 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 94e4cab00a66..b1085ef3f1d0 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3231,6 +3231,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)
@@ -3253,7 +3255,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);
@@ -3275,6 +3277,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;
 
@@ -10078,6 +10086,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);
@@ -10181,6 +10190,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;
@@ -17535,7 +17556,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)) {
@@ -17825,6 +17847,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;
+
 		if (crtc_state->hw.active) {
 			struct drm_display_mode mode;
 
@@ -17849,6 +17874,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			mode.hdisplay = crtc_state->pipe_src_w;
 			mode.vdisplay = crtc_state->pipe_src_h;
 
+			if (crtc_state->bigjoiner)
+				mode.hdisplay *= 2;
+
 			intel_crtc_compute_pixel_rate(crtc_state);
 
 			intel_crtc_update_active_timings(crtc_state);
@@ -17898,6 +17926,39 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 		intel_bw_crtc_update(bw_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->uapi.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.24.0

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

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

* [PATCH 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Also fix the atomic intel plane iterator, so things watermarks start
working automagically.

Changes since v1:
- Rebase on top of plane_state split, cleaning up the code a lot.
- Make intel_atomic_crtc_state_for_each_plane_state() bigjoiner capable.
- Add iter macro to intel_atomic_crtc_state_for_each_plane_state() to
  keep iteration working.
Changes since v2:
- Add icl_(un)set_bigjoiner_plane_links, to make it more clear where
  links are made and broken.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  47 +++-
 .../gpu/drm/i915/display/intel_atomic_plane.h |   3 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 207 ++++++++++++++++--
 drivers/gpu/drm/i915/display/intel_display.h  |  18 +-
 .../drm/i915/display/intel_display_types.h    |  11 +
 drivers/gpu/drm/i915/intel_pm.c               |  16 +-
 6 files changed, 268 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 42b3b3449d2e..b26e10519ca4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -190,12 +190,17 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
 	memset(&plane_state->hw, 0, sizeof(plane_state->hw));
 }
 
-void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
+void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state,
+				       struct intel_plane_state *plane_state,
 				       const struct intel_plane_state *from_plane_state)
 {
 	intel_plane_clear_hw_state(plane_state);
 
-	plane_state->hw.crtc = from_plane_state->uapi.crtc;
+	if (from_plane_state->uapi.crtc)
+		plane_state->hw.crtc = crtc_state->uapi.crtc;
+	else
+		plane_state->hw.crtc = NULL;
+
 	plane_state->hw.fb = from_plane_state->uapi.fb;
 	if (plane_state->hw.fb)
 		drm_framebuffer_get(plane_state->hw.fb);
@@ -214,10 +219,20 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					struct intel_plane_state *new_plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+	struct intel_plane_state *new_master_plane_state = new_plane_state;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(new_plane_state->uapi.state);
 	const struct drm_framebuffer *fb;
 	int ret;
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+	if (new_plane_state->bigjoiner_slave)
+		new_master_plane_state =
+			intel_atomic_get_new_plane_state(state,
+				new_plane_state->bigjoiner_plane);
+
+	intel_plane_copy_uapi_to_hw_state(new_crtc_state,
+					  new_plane_state,
+					  new_master_plane_state);
 	fb = new_plane_state->hw.fb;
 
 	new_crtc_state->active_planes &= ~BIT(plane->id);
@@ -257,15 +272,36 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 }
 
 static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
+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->uapi.plane);
+
 	if (new_plane_state->uapi.crtc)
 		return to_intel_crtc(new_plane_state->uapi.crtc);
 
 	if (old_plane_state->uapi.crtc)
 		return to_intel_crtc(old_plane_state->uapi.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);
+
+		/* need to use uapi here, new_master_plane_state might not be copied to hw yet */
+		if (new_master_plane_state->uapi.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->uapi.crtc)
+			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
+	}
+
 	return NULL;
 }
 
@@ -277,7 +313,8 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 	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);
+		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 5cedafdddb55..3129faa30eb6 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -20,7 +20,8 @@ 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_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
+void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state,
+				       struct intel_plane_state *plane_state,
 				       const struct intel_plane_state *from_plane_state);
 void intel_update_plane(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b1085ef3f1d0..59c60436410c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3327,7 +3327,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 
 	plane_state->fb = fb;
 	plane_state->crtc = &intel_crtc->base;
-	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state);
+	intel_plane_copy_uapi_to_hw_state(crtc_state, intel_state, intel_state);
 
 	atomic_or(to_intel_plane(primary)->frontbuffer_bit,
 		  &to_intel_frontbuffer(fb)->bits);
@@ -12082,24 +12082,180 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state,
 	return true;
 }
 
+static int icl_unset_bigjoiner_plane_links(struct intel_atomic_state *state,
+					   struct intel_crtc_state *new_crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+	struct intel_plane *plane;
+
+	/*
+	 * Teardown the old bigjoiner plane mappings.
+	 */
+	for_each_intel_plane_on_crtc(crtc->base.dev, crtc, plane) {
+		struct intel_plane_state *plane_state, *other_plane_state;
+		struct intel_plane *other_plane;
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		other_plane = plane_state->bigjoiner_plane;
+		if (!other_plane)
+			continue;
+
+		plane_state->bigjoiner_plane = NULL;
+		plane_state->bigjoiner_slave = false;
+
+		other_plane_state = intel_atomic_get_plane_state(state, other_plane);
+		if (IS_ERR(other_plane_state))
+			return PTR_ERR(other_plane_state);
+		other_plane_state->bigjoiner_plane = NULL;
+		other_plane_state->bigjoiner_slave = false;
+	}
+	return 0;
+}
+
+static int icl_set_bigjoiner_plane_links(struct intel_atomic_state *state,
+					 struct intel_crtc_state *new_crtc_state)
+{
+	struct intel_plane *plane;
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+	struct intel_crtc *other_crtc = new_crtc_state->bigjoiner_linked_crtc;
+
+	/*
+	 * Setup and teardown the new bigjoiner plane mappings.
+	 */
+	for_each_intel_plane_on_crtc(crtc->base.dev, crtc, plane) {
+		struct intel_plane_state *plane_state;
+		struct intel_plane *other_plane = NULL;
+		bool found_plane = false;
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		for_each_intel_plane_on_crtc(crtc->base.dev, other_crtc, other_plane) {
+			if (other_plane->id != plane->id)
+				continue;
+
+			plane_state->bigjoiner_plane = other_plane;
+			plane_state->bigjoiner_slave = new_crtc_state->bigjoiner_slave;
+
+			plane_state = intel_atomic_get_plane_state(state, other_plane);
+			if (IS_ERR(plane_state))
+				return PTR_ERR(plane_state);
+
+			plane_state->bigjoiner_plane = plane;
+			plane_state->bigjoiner_slave = !new_crtc_state->bigjoiner_slave;
+
+			found_plane = true;
+			break;
+		}
+
+		if (!found_plane) {
+			/* All pipes should have identical planes. */
+			WARN_ON(!found_plane);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+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;
+
+			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_plane_state = intel_atomic_get_plane_state(state, linked);
-		if (IS_ERR(linked_plane_state))
-			return PTR_ERR(linked_plane_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;
@@ -12139,6 +12295,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 
 	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
 		struct intel_plane_state *linked_state = NULL;
+		struct intel_plane_state *master_plane_state;
 
 		if (plane->pipe != crtc->pipe ||
 		    !(crtc_state->nv12_planes & BIT(plane->id)))
@@ -12178,7 +12335,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 		linked_state->color_ctl = plane_state->color_ctl;
 		linked_state->color_plane[0] = plane_state->color_plane[0];
 
-		intel_plane_copy_uapi_to_hw_state(linked_state, plane_state);
+		master_plane_state = plane_state;
+		if (plane_state->bigjoiner_slave)
+			master_plane_state =
+				intel_atomic_get_new_plane_state(state,
+					plane_state->bigjoiner_plane);
+
+		intel_plane_copy_uapi_to_hw_state(crtc_state, linked_state,
+						  master_plane_state);
 		linked_state->uapi.src = plane_state->uapi.src;
 		linked_state->uapi.dst = plane_state->uapi.dst;
 
@@ -14315,6 +14479,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 *slave_crtc_state, *master_crtc_state;
 	struct intel_crtc *slave, *master;
+	int ret;
 
 	/* slave being enabled, is master is still claiming this crtc? */
 	if (old_crtc_state->bigjoiner_slave) {
@@ -14325,6 +14490,12 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
 			goto claimed;
 	}
 
+	if (old_crtc_state->bigjoiner) {
+		ret = icl_unset_bigjoiner_plane_links(state, new_crtc_state);
+		if (ret)
+			return ret;
+	}
+
 	if (!new_crtc_state->bigjoiner)
 		return 0;
 
@@ -14348,7 +14519,12 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
 		      slave->base.base.id, slave->base.name);
-	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+
+	ret = copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+	if (ret)
+		return ret;
+
+	return icl_set_bigjoiner_plane_links(state, new_crtc_state);
 
 claimed:
 	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
@@ -14372,7 +14548,8 @@ static int kill_bigjoiner_slave(struct intel_atomic_state *state,
 	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
 	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
 	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
-	return 0;
+
+	return icl_unset_bigjoiner_plane_links(state, slave_crtc_state);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index a5ec5eeff056..3aae17175913 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -447,12 +447,20 @@ enum phy_fia {
 		for_each_if(crtc)
 
 #define intel_atomic_crtc_state_for_each_plane_state( \
-		  plane, plane_state, \
+		  plane, iter, plane_state, \
 		  crtc_state) \
-	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
-				((crtc_state)->uapi.plane_mask)) \
-		for_each_if ((plane_state = \
-			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))))
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
+		  (((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 ((((plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \
+			      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \
+			      ((plane_state) = (plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (plane_state))))
 
 #define for_each_new_intel_connector_in_state(__state, connector, new_connector_state, __i) \
 	for ((__i) = 0; \
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 86a0524b3cd8..2bb71451e7db 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -596,6 +596,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
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 780ff38b6aa1..1bf304e3ebbd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3085,7 +3085,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 	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 intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	const struct intel_plane_state *pristate = NULL;
 	const struct intel_plane_state *sprstate = NULL;
@@ -3095,7 +3095,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 
 	pipe_wm = &crtc_state->wm.ilk.optimal;
 
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
 			pristate = plane_state;
 		else if (plane->base.type == DRM_PLANE_TYPE_OVERLAY)
@@ -4146,7 +4146,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *uv_plane_data_rate)
 {
 	struct drm_atomic_state *state = crtc_state->uapi.state;
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	u64 total_data_rate = 0;
 
@@ -4154,7 +4154,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		enum plane_id plane_id = plane->id;
 		u64 rate;
 
@@ -4176,7 +4176,7 @@ static u64
 icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate)
 {
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	u64 total_data_rate = 0;
 
@@ -4184,7 +4184,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		enum plane_id plane_id = plane->id;
 		u64 rate;
 
@@ -4975,7 +4975,7 @@ 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 intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	int ret;
 
@@ -4985,7 +4985,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 	 */
 	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
 
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state,
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state,
 						     crtc_state) {
 
 		if (INTEL_GEN(dev_priv) >= 11)
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Also fix the atomic intel plane iterator, so things watermarks start
working automagically.

Changes since v1:
- Rebase on top of plane_state split, cleaning up the code a lot.
- Make intel_atomic_crtc_state_for_each_plane_state() bigjoiner capable.
- Add iter macro to intel_atomic_crtc_state_for_each_plane_state() to
  keep iteration working.
Changes since v2:
- Add icl_(un)set_bigjoiner_plane_links, to make it more clear where
  links are made and broken.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  47 +++-
 .../gpu/drm/i915/display/intel_atomic_plane.h |   3 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 207 ++++++++++++++++--
 drivers/gpu/drm/i915/display/intel_display.h  |  18 +-
 .../drm/i915/display/intel_display_types.h    |  11 +
 drivers/gpu/drm/i915/intel_pm.c               |  16 +-
 6 files changed, 268 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 42b3b3449d2e..b26e10519ca4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -190,12 +190,17 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
 	memset(&plane_state->hw, 0, sizeof(plane_state->hw));
 }
 
-void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
+void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state,
+				       struct intel_plane_state *plane_state,
 				       const struct intel_plane_state *from_plane_state)
 {
 	intel_plane_clear_hw_state(plane_state);
 
-	plane_state->hw.crtc = from_plane_state->uapi.crtc;
+	if (from_plane_state->uapi.crtc)
+		plane_state->hw.crtc = crtc_state->uapi.crtc;
+	else
+		plane_state->hw.crtc = NULL;
+
 	plane_state->hw.fb = from_plane_state->uapi.fb;
 	if (plane_state->hw.fb)
 		drm_framebuffer_get(plane_state->hw.fb);
@@ -214,10 +219,20 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					struct intel_plane_state *new_plane_state)
 {
 	struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
+	struct intel_plane_state *new_master_plane_state = new_plane_state;
+	struct intel_atomic_state *state =
+		to_intel_atomic_state(new_plane_state->uapi.state);
 	const struct drm_framebuffer *fb;
 	int ret;
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+	if (new_plane_state->bigjoiner_slave)
+		new_master_plane_state =
+			intel_atomic_get_new_plane_state(state,
+				new_plane_state->bigjoiner_plane);
+
+	intel_plane_copy_uapi_to_hw_state(new_crtc_state,
+					  new_plane_state,
+					  new_master_plane_state);
 	fb = new_plane_state->hw.fb;
 
 	new_crtc_state->active_planes &= ~BIT(plane->id);
@@ -257,15 +272,36 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 }
 
 static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
+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->uapi.plane);
+
 	if (new_plane_state->uapi.crtc)
 		return to_intel_crtc(new_plane_state->uapi.crtc);
 
 	if (old_plane_state->uapi.crtc)
 		return to_intel_crtc(old_plane_state->uapi.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);
+
+		/* need to use uapi here, new_master_plane_state might not be copied to hw yet */
+		if (new_master_plane_state->uapi.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->uapi.crtc)
+			return intel_get_crtc_for_pipe(dev_priv, plane->pipe);
+	}
+
 	return NULL;
 }
 
@@ -277,7 +313,8 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 	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);
+		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 5cedafdddb55..3129faa30eb6 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -20,7 +20,8 @@ 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_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
+void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state,
+				       struct intel_plane_state *plane_state,
 				       const struct intel_plane_state *from_plane_state);
 void intel_update_plane(struct intel_plane *plane,
 			const struct intel_crtc_state *crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b1085ef3f1d0..59c60436410c 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3327,7 +3327,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 
 	plane_state->fb = fb;
 	plane_state->crtc = &intel_crtc->base;
-	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state);
+	intel_plane_copy_uapi_to_hw_state(crtc_state, intel_state, intel_state);
 
 	atomic_or(to_intel_plane(primary)->frontbuffer_bit,
 		  &to_intel_frontbuffer(fb)->bits);
@@ -12082,24 +12082,180 @@ static bool check_single_encoder_cloning(struct intel_atomic_state *state,
 	return true;
 }
 
+static int icl_unset_bigjoiner_plane_links(struct intel_atomic_state *state,
+					   struct intel_crtc_state *new_crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+	struct intel_plane *plane;
+
+	/*
+	 * Teardown the old bigjoiner plane mappings.
+	 */
+	for_each_intel_plane_on_crtc(crtc->base.dev, crtc, plane) {
+		struct intel_plane_state *plane_state, *other_plane_state;
+		struct intel_plane *other_plane;
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		other_plane = plane_state->bigjoiner_plane;
+		if (!other_plane)
+			continue;
+
+		plane_state->bigjoiner_plane = NULL;
+		plane_state->bigjoiner_slave = false;
+
+		other_plane_state = intel_atomic_get_plane_state(state, other_plane);
+		if (IS_ERR(other_plane_state))
+			return PTR_ERR(other_plane_state);
+		other_plane_state->bigjoiner_plane = NULL;
+		other_plane_state->bigjoiner_slave = false;
+	}
+	return 0;
+}
+
+static int icl_set_bigjoiner_plane_links(struct intel_atomic_state *state,
+					 struct intel_crtc_state *new_crtc_state)
+{
+	struct intel_plane *plane;
+	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
+	struct intel_crtc *other_crtc = new_crtc_state->bigjoiner_linked_crtc;
+
+	/*
+	 * Setup and teardown the new bigjoiner plane mappings.
+	 */
+	for_each_intel_plane_on_crtc(crtc->base.dev, crtc, plane) {
+		struct intel_plane_state *plane_state;
+		struct intel_plane *other_plane = NULL;
+		bool found_plane = false;
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		for_each_intel_plane_on_crtc(crtc->base.dev, other_crtc, other_plane) {
+			if (other_plane->id != plane->id)
+				continue;
+
+			plane_state->bigjoiner_plane = other_plane;
+			plane_state->bigjoiner_slave = new_crtc_state->bigjoiner_slave;
+
+			plane_state = intel_atomic_get_plane_state(state, other_plane);
+			if (IS_ERR(plane_state))
+				return PTR_ERR(plane_state);
+
+			plane_state->bigjoiner_plane = plane;
+			plane_state->bigjoiner_slave = !new_crtc_state->bigjoiner_slave;
+
+			found_plane = true;
+			break;
+		}
+
+		if (!found_plane) {
+			/* All pipes should have identical planes. */
+			WARN_ON(!found_plane);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+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;
+
+			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_plane_state = intel_atomic_get_plane_state(state, linked);
-		if (IS_ERR(linked_plane_state))
-			return PTR_ERR(linked_plane_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;
@@ -12139,6 +12295,7 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 
 	for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
 		struct intel_plane_state *linked_state = NULL;
+		struct intel_plane_state *master_plane_state;
 
 		if (plane->pipe != crtc->pipe ||
 		    !(crtc_state->nv12_planes & BIT(plane->id)))
@@ -12178,7 +12335,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 		linked_state->color_ctl = plane_state->color_ctl;
 		linked_state->color_plane[0] = plane_state->color_plane[0];
 
-		intel_plane_copy_uapi_to_hw_state(linked_state, plane_state);
+		master_plane_state = plane_state;
+		if (plane_state->bigjoiner_slave)
+			master_plane_state =
+				intel_atomic_get_new_plane_state(state,
+					plane_state->bigjoiner_plane);
+
+		intel_plane_copy_uapi_to_hw_state(crtc_state, linked_state,
+						  master_plane_state);
 		linked_state->uapi.src = plane_state->uapi.src;
 		linked_state->uapi.dst = plane_state->uapi.dst;
 
@@ -14315,6 +14479,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 *slave_crtc_state, *master_crtc_state;
 	struct intel_crtc *slave, *master;
+	int ret;
 
 	/* slave being enabled, is master is still claiming this crtc? */
 	if (old_crtc_state->bigjoiner_slave) {
@@ -14325,6 +14490,12 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
 			goto claimed;
 	}
 
+	if (old_crtc_state->bigjoiner) {
+		ret = icl_unset_bigjoiner_plane_links(state, new_crtc_state);
+		if (ret)
+			return ret;
+	}
+
 	if (!new_crtc_state->bigjoiner)
 		return 0;
 
@@ -14348,7 +14519,12 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
 
 	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
 		      slave->base.base.id, slave->base.name);
-	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+
+	ret = copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
+	if (ret)
+		return ret;
+
+	return icl_set_bigjoiner_plane_links(state, new_crtc_state);
 
 claimed:
 	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
@@ -14372,7 +14548,8 @@ static int kill_bigjoiner_slave(struct intel_atomic_state *state,
 	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
 	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
 	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
-	return 0;
+
+	return icl_unset_bigjoiner_plane_links(state, slave_crtc_state);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index a5ec5eeff056..3aae17175913 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -447,12 +447,20 @@ enum phy_fia {
 		for_each_if(crtc)
 
 #define intel_atomic_crtc_state_for_each_plane_state( \
-		  plane, plane_state, \
+		  plane, iter, plane_state, \
 		  crtc_state) \
-	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (plane), \
-				((crtc_state)->uapi.plane_mask)) \
-		for_each_if ((plane_state = \
-			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base))))
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
+		  (((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 ((((plane_state) = \
+			      to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \
+			      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \
+			      ((plane_state) = (plane_state)->bigjoiner_slave ? \
+				to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \
+				  (plane_state))))
 
 #define for_each_new_intel_connector_in_state(__state, connector, new_connector_state, __i) \
 	for ((__i) = 0; \
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 86a0524b3cd8..2bb71451e7db 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -596,6 +596,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
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 780ff38b6aa1..1bf304e3ebbd 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3085,7 +3085,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 	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 intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	const struct intel_plane_state *pristate = NULL;
 	const struct intel_plane_state *sprstate = NULL;
@@ -3095,7 +3095,7 @@ static int ilk_compute_pipe_wm(struct intel_crtc_state *crtc_state)
 
 	pipe_wm = &crtc_state->wm.ilk.optimal;
 
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
 			pristate = plane_state;
 		else if (plane->base.type == DRM_PLANE_TYPE_OVERLAY)
@@ -4146,7 +4146,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *uv_plane_data_rate)
 {
 	struct drm_atomic_state *state = crtc_state->uapi.state;
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	u64 total_data_rate = 0;
 
@@ -4154,7 +4154,7 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		enum plane_id plane_id = plane->id;
 		u64 rate;
 
@@ -4176,7 +4176,7 @@ static u64
 icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate)
 {
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	u64 total_data_rate = 0;
 
@@ -4184,7 +4184,7 @@ icl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 		return 0;
 
 	/* Calculate and cache data rate for each plane */
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state, crtc_state) {
 		enum plane_id plane_id = plane->id;
 		u64 rate;
 
@@ -4975,7 +4975,7 @@ 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 intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	int ret;
 
@@ -4985,7 +4985,7 @@ static int skl_build_pipe_wm(struct intel_crtc_state *crtc_state)
 	 */
 	memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
 
-	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state,
+	intel_atomic_crtc_state_for_each_plane_state(plane, iter, plane_state,
 						     crtc_state) {
 
 		if (INTEL_GEN(dev_priv) >= 11)
-- 
2.24.0

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

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

* [PATCH 09/11] drm/i915: Add bigjoiner aware plane clipping checks
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

We need to look at hw.fb for the framebuffer, and add the translation
for the slave_plane_state. With these changes we set the correct
rectangle on the bigjoiner slave, and don't set incorrect
src/dst/visibility on the slave plane.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 60 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_atomic_plane.h |  4 ++
 drivers/gpu/drm/i915/display/intel_display.c  | 19 +++---
 drivers/gpu/drm/i915/display/intel_sprite.c   | 21 +++----
 4 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index b26e10519ca4..c516f8097945 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -211,6 +211,9 @@ void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state
 	plane_state->hw.rotation = from_plane_state->uapi.rotation;
 	plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
 	plane_state->hw.color_range = from_plane_state->uapi.color_range;
+
+	plane_state->uapi.src = drm_plane_state_src(&from_plane_state->uapi);
+	plane_state->uapi.dst = drm_plane_state_dest(&from_plane_state->uapi);
 }
 
 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
@@ -448,6 +451,63 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
 	}
 }
 
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+				      struct intel_crtc_state *crtc_state,
+				      int min_scale, int max_scale,
+				      bool can_position)
+{
+	struct drm_framebuffer *fb = plane_state->hw.fb;
+	struct drm_rect *src = &plane_state->uapi.src;
+	struct drm_rect *dst = &plane_state->uapi.dst;
+	unsigned int rotation = plane_state->uapi.rotation;
+	struct drm_rect clip = {};
+	int hscale, vscale;
+
+	if (!fb) {
+		plane_state->uapi.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->uapi.visible = drm_rect_clip_scaled(src, dst, &clip);
+
+	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+
+	if (!can_position && plane_state->uapi.visible &&
+	    !drm_rect_equals(dst, &clip)) {
+		DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
+		drm_rect_debug_print("dst: ", dst, false);
+		drm_rect_debug_print("clip: ", &clip, false);
+		return -EINVAL;
+	}
+
+	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 3129faa30eb6..26838d368cb4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -49,5 +49,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 				    struct intel_plane_state *plane_state);
 bool intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
 				struct intel_plane *plane);
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+				      struct intel_crtc_state *crtc_state,
+				      int min_scale, int max_scale,
+				      bool can_position);
 
 #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 59c60436410c..4c4e51e409f6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3890,12 +3890,10 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  i9xx_plane_has_windowing(plane),
-						  true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						i9xx_plane_has_windowing(plane));
 	if (ret)
 		return ret;
 
@@ -11023,11 +11021,10 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 		return -EINVAL;
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						true);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index d7f71fa90659..54b81f5cb4c5 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -1955,10 +1955,8 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						min_scale, max_scale, true);
 	if (ret)
 		return ret;
 
@@ -2012,11 +2010,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						true);
 	if (ret)
 		return ret;
 
@@ -2193,10 +2190,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 		max_scale = skl_plane_max_scale(dev_priv, fb);
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						min_scale, max_scale, true);
 	if (ret)
 		return ret;
 
-- 
2.24.0

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

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

* [Intel-gfx] [PATCH 09/11] drm/i915: Add bigjoiner aware plane clipping checks
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

We need to look at hw.fb for the framebuffer, and add the translation
for the slave_plane_state. With these changes we set the correct
rectangle on the bigjoiner slave, and don't set incorrect
src/dst/visibility on the slave plane.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 60 +++++++++++++++++++
 .../gpu/drm/i915/display/intel_atomic_plane.h |  4 ++
 drivers/gpu/drm/i915/display/intel_display.c  | 19 +++---
 drivers/gpu/drm/i915/display/intel_sprite.c   | 21 +++----
 4 files changed, 80 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index b26e10519ca4..c516f8097945 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -211,6 +211,9 @@ void intel_plane_copy_uapi_to_hw_state(const struct intel_crtc_state *crtc_state
 	plane_state->hw.rotation = from_plane_state->uapi.rotation;
 	plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
 	plane_state->hw.color_range = from_plane_state->uapi.color_range;
+
+	plane_state->uapi.src = drm_plane_state_src(&from_plane_state->uapi);
+	plane_state->uapi.dst = drm_plane_state_dest(&from_plane_state->uapi);
 }
 
 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
@@ -448,6 +451,63 @@ void i9xx_update_planes_on_crtc(struct intel_atomic_state *state,
 	}
 }
 
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+				      struct intel_crtc_state *crtc_state,
+				      int min_scale, int max_scale,
+				      bool can_position)
+{
+	struct drm_framebuffer *fb = plane_state->hw.fb;
+	struct drm_rect *src = &plane_state->uapi.src;
+	struct drm_rect *dst = &plane_state->uapi.dst;
+	unsigned int rotation = plane_state->uapi.rotation;
+	struct drm_rect clip = {};
+	int hscale, vscale;
+
+	if (!fb) {
+		plane_state->uapi.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->uapi.visible = drm_rect_clip_scaled(src, dst, &clip);
+
+	drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
+
+	if (!can_position && plane_state->uapi.visible &&
+	    !drm_rect_equals(dst, &clip)) {
+		DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
+		drm_rect_debug_print("dst: ", dst, false);
+		drm_rect_debug_print("clip: ", &clip, false);
+		return -EINVAL;
+	}
+
+	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 3129faa30eb6..26838d368cb4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -49,5 +49,9 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 				    struct intel_plane_state *plane_state);
 bool intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
 				struct intel_plane *plane);
+int intel_atomic_plane_check_clipping(struct intel_plane_state *plane_state,
+				      struct intel_crtc_state *crtc_state,
+				      int min_scale, int max_scale,
+				      bool can_position);
 
 #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 59c60436410c..4c4e51e409f6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3890,12 +3890,10 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  i9xx_plane_has_windowing(plane),
-						  true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						i9xx_plane_has_windowing(plane));
 	if (ret)
 		return ret;
 
@@ -11023,11 +11021,10 @@ static int intel_check_cursor(struct intel_crtc_state *crtc_state,
 		return -EINVAL;
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						true);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index d7f71fa90659..54b81f5cb4c5 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -1955,10 +1955,8 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
 		}
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						min_scale, max_scale, true);
 	if (ret)
 		return ret;
 
@@ -2012,11 +2010,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
 	if (ret)
 		return ret;
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  DRM_PLANE_HELPER_NO_SCALING,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						DRM_PLANE_HELPER_NO_SCALING,
+						DRM_PLANE_HELPER_NO_SCALING,
+						true);
 	if (ret)
 		return ret;
 
@@ -2193,10 +2190,8 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
 		max_scale = skl_plane_max_scale(dev_priv, fb);
 	}
 
-	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
-						  &crtc_state->uapi,
-						  min_scale, max_scale,
-						  true, true);
+	ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
+						min_scale, max_scale, true);
 	if (ret)
 		return ret;
 
-- 
2.24.0

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

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

* [PATCH 10/11] drm/i915: Add intel_update_bigjoiner handling.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

Enabling is done in a special sequence and 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.

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

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 4c4e51e409f6..f3fc89e52b1b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14826,7 +14826,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);
 
 	/*
 	 * We usually enable FIFO underrun interrupts as part of the
@@ -14973,6 +14973,54 @@ 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 */
+		intel_crtc_update_active_timings(new_slave_crtc_state);
+		dev_priv->display.crtc_enable(new_slave_crtc_state, state);
+
+		/* Then master */
+		intel_crtc_update_active_timings(new_crtc_state);
+		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);
+	skl_update_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;
@@ -15036,7 +15084,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
 	intel_pipe_update_start(new_crtc_state);
 	commit_pipe_config(state, old_crtc_state, new_crtc_state);
 	skl_update_planes_on_crtc(state, crtc);
-	intel_pipe_update_end(new_crtc_state);
+	intel_pipe_update_end(new_crtc_state, NULL);
 
 	/*
 	 * We usually enable FIFO underrun interrupts as part of the
@@ -15098,7 +15146,7 @@ static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc,
 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;
@@ -15106,11 +15154,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)
@@ -15130,16 +15214,16 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			bool vbl_wait = false;
 			bool modeset = needs_modeset(new_crtc_state);
 
-			if (updated & BIT(crtc->pipe) || !new_crtc_state->hw.active)
+			if (updated & BIT(crtc->pipe) || !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 |= BIT(pipe);
-			entries[i] = new_crtc_state->wm.skl.ddb;
+			entries[i] = new_entries[i];
 
 			/*
 			 * If this is an already active pipe, it's DDB changed,
@@ -15147,10 +15231,9 @@ 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) &&
-			    !modeset &&
-			    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;
 
 			if (modeset && is_trans_port_sync_mode(new_crtc_state)) {
@@ -15161,6 +15244,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 									   new_crtc_state);
 				else
 					continue;
+			} else 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);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 54b81f5cb4c5..004de05f3995 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 5eeaa92420d1..31335d12cf56 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.24.0

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

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

* [Intel-gfx] [PATCH 10/11] drm/i915: Add intel_update_bigjoiner handling.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 UTC (permalink / raw)
  To: intel-gfx

Enabling is done in a special sequence and 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.

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

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 4c4e51e409f6..f3fc89e52b1b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -14826,7 +14826,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);
 
 	/*
 	 * We usually enable FIFO underrun interrupts as part of the
@@ -14973,6 +14973,54 @@ 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 */
+		intel_crtc_update_active_timings(new_slave_crtc_state);
+		dev_priv->display.crtc_enable(new_slave_crtc_state, state);
+
+		/* Then master */
+		intel_crtc_update_active_timings(new_crtc_state);
+		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);
+	skl_update_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;
@@ -15036,7 +15084,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
 	intel_pipe_update_start(new_crtc_state);
 	commit_pipe_config(state, old_crtc_state, new_crtc_state);
 	skl_update_planes_on_crtc(state, crtc);
-	intel_pipe_update_end(new_crtc_state);
+	intel_pipe_update_end(new_crtc_state, NULL);
 
 	/*
 	 * We usually enable FIFO underrun interrupts as part of the
@@ -15098,7 +15146,7 @@ static void intel_update_trans_port_sync_crtcs(struct intel_crtc *crtc,
 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;
@@ -15106,11 +15154,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)
@@ -15130,16 +15214,16 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			bool vbl_wait = false;
 			bool modeset = needs_modeset(new_crtc_state);
 
-			if (updated & BIT(crtc->pipe) || !new_crtc_state->hw.active)
+			if (updated & BIT(crtc->pipe) || !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 |= BIT(pipe);
-			entries[i] = new_crtc_state->wm.skl.ddb;
+			entries[i] = new_entries[i];
 
 			/*
 			 * If this is an already active pipe, it's DDB changed,
@@ -15147,10 +15231,9 @@ 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) &&
-			    !modeset &&
-			    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;
 
 			if (modeset && is_trans_port_sync_mode(new_crtc_state)) {
@@ -15161,6 +15244,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 									   new_crtc_state);
 				else
 					continue;
+			} else 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);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 54b81f5cb4c5..004de05f3995 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 5eeaa92420d1..31335d12cf56 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.24.0

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

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

* [PATCH 11/11] drm/i915: Add debugfs dumping for bigjoiner, v2.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Changes since v1:
- Report planar slaves as such, now that we have the plane_state switch.

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

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index cab632791f73..aeefe4a726f4 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2589,6 +2589,17 @@ static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
 		 rotation);
 }
 
+static const char *plane_visibility(struct intel_plane_state *plane_state)
+{
+	if (plane_state->uapi.visible)
+		return "visible";
+
+	if (plane_state->planar_slave)
+		return "planar-slave";
+
+	return "hidden";
+}
+
 static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -2596,42 +2607,29 @@ 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->hw.fb) {
+			drm_get_format_name(state->hw.fb->format->format,
 					    &format_name);
 		} else {
 			sprintf(format_name.str, "N/A");
 		}
 
-		plane_rotation(rot_str, sizeof(rot_str), state->rotation);
+		plane_rotation(rot_str, sizeof(rot_str), state->hw.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, %s, clipped 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);
+			   plane_visibility(state),
+			   DRM_RECT_ARG(&state->uapi.dst),
+			   DRM_RECT_FP_ARG(&state->uapi.src),
+			   format_name.str, rot_str);
 	}
 }
 
@@ -2687,6 +2685,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.24.0

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

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

* [Intel-gfx] [PATCH 11/11] drm/i915: Add debugfs dumping for bigjoiner, v2.
@ 2019-11-14 16:05   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-11-14 16:05 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.

Changes since v1:
- Report planar slaves as such, now that we have the plane_state switch.

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

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index cab632791f73..aeefe4a726f4 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2589,6 +2589,17 @@ static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
 		 rotation);
 }
 
+static const char *plane_visibility(struct intel_plane_state *plane_state)
+{
+	if (plane_state->uapi.visible)
+		return "visible";
+
+	if (plane_state->planar_slave)
+		return "planar-slave";
+
+	return "hidden";
+}
+
 static void intel_plane_info(struct seq_file *m, struct intel_crtc *intel_crtc)
 {
 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
@@ -2596,42 +2607,29 @@ 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->hw.fb) {
+			drm_get_format_name(state->hw.fb->format->format,
 					    &format_name);
 		} else {
 			sprintf(format_name.str, "N/A");
 		}
 
-		plane_rotation(rot_str, sizeof(rot_str), state->rotation);
+		plane_rotation(rot_str, sizeof(rot_str), state->hw.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, %s, clipped 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);
+			   plane_visibility(state),
+			   DRM_RECT_ARG(&state->uapi.dst),
+			   DRM_RECT_FP_ARG(&state->uapi.src),
+			   format_name.str, rot_str);
 	}
 }
 
@@ -2687,6 +2685,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.24.0

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

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

* ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:04   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
e129b15e0bb7 HAX to make DSC work on the icelake test system
9c348f274288 drm/i915: Remove hw.mode
1d5ae5be65dc drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:8: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

-:185: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#185: FILE: drivers/gpu/drm/i915/display/intel_display.c:12640:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 1 warnings, 1 checks, 452 lines checked
dfd57bb0186c drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
0dfc33b4c96e drm/i915: Try to make bigjoiner work in atomic check, v3.
-:141: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#141: FILE: drivers/gpu/drm/i915/display/intel_display.c:12654:
+		from_crtc_state = intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);

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

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

-:322: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:14220:
+		intel_atomic_get_crtc_state(&state->base,
+			master_crtc_state->bigjoiner_linked_crtc);

-:327: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#327: FILE: drivers/gpu/drm/i915/display/intel_display.c:14225:
+	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;

-:328: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#328: FILE: drivers/gpu/drm/i915/display/intel_display.c:14226:
+	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;

-:329: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#329: FILE: drivers/gpu/drm/i915/display/intel_display.c:14227:
+	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

total: 1 errors, 0 warnings, 7 checks, 406 lines checked
4221707d255e drm/i915: Enable big joiner support in enable and disable sequences.
-:107: WARNING:LONG_LINE_COMMENT: line over 100 characters
#107: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4364:
+		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

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

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

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

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

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

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

total: 0 errors, 4 warnings, 3 checks, 914 lines checked
ed66bbff27f8 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:10198:
+		    (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:10199:
+			val = I915_READ(PLANE_SIZE(crtc_state->bigjoiner_linked_crtc->pipe, plane_id));

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

total: 0 errors, 3 warnings, 0 checks, 119 lines checked
79dd9ad5168d drm/i915: Link planes in a bigjoiner configuration, v3.
-:66: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#66: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:231:
+			intel_atomic_get_new_plane_state(state,
+				new_plane_state->bigjoiner_plane);

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

-:358: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#358: FILE: drivers/gpu/drm/i915/display/intel_display.c:12342:
+				intel_atomic_get_new_plane_state(state,
+					plane_state->bigjoiner_plane);

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

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

-:433: WARNING:LONG_LINE: line over 100 characters
#433: FILE: drivers/gpu/drm/i915/display/intel_display.h:460:
+			      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

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

total: 0 errors, 5 warnings, 2 checks, 463 lines checked
c9a540d85b32 drm/i915: Add bigjoiner aware plane clipping checks
c76daafe3429 drm/i915: Add intel_update_bigjoiner handling.
fac798935da8 drm/i915: Add debugfs dumping for bigjoiner, v2.
-:71: WARNING:LONG_LINE: line over 100 characters
#71: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2626:
+		seq_printf(m, "\t--Plane id %d: type=%s, %s, clipped crtc="DRM_RECT_FMT", clipped src="DRM_RECT_FP_FMT", format=%s, rotation=%s\n",

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

total: 0 errors, 1 warnings, 1 checks, 80 lines checked

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:04   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
e129b15e0bb7 HAX to make DSC work on the icelake test system
9c348f274288 drm/i915: Remove hw.mode
1d5ae5be65dc drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:8: WARNING:COMMIT_MESSAGE: Missing commit description - Add an appropriate one

-:185: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#185: FILE: drivers/gpu/drm/i915/display/intel_display.c:12640:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 1 warnings, 1 checks, 452 lines checked
dfd57bb0186c drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
0dfc33b4c96e drm/i915: Try to make bigjoiner work in atomic check, v3.
-:141: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#141: FILE: drivers/gpu/drm/i915/display/intel_display.c:12654:
+		from_crtc_state = intel_atomic_get_new_crtc_state(state,
+					crtc_state->bigjoiner_linked_crtc);

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

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

-:322: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:14220:
+		intel_atomic_get_crtc_state(&state->base,
+			master_crtc_state->bigjoiner_linked_crtc);

-:327: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#327: FILE: drivers/gpu/drm/i915/display/intel_display.c:14225:
+	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;

-:328: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#328: FILE: drivers/gpu/drm/i915/display/intel_display.c:14226:
+	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;

-:329: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#329: FILE: drivers/gpu/drm/i915/display/intel_display.c:14227:
+	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

total: 1 errors, 0 warnings, 7 checks, 406 lines checked
4221707d255e drm/i915: Enable big joiner support in enable and disable sequences.
-:107: WARNING:LONG_LINE_COMMENT: line over 100 characters
#107: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4364:
+		 /* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

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

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

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

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

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

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

total: 0 errors, 4 warnings, 3 checks, 914 lines checked
ed66bbff27f8 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:10198:
+		    (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:10199:
+			val = I915_READ(PLANE_SIZE(crtc_state->bigjoiner_linked_crtc->pipe, plane_id));

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

total: 0 errors, 3 warnings, 0 checks, 119 lines checked
79dd9ad5168d drm/i915: Link planes in a bigjoiner configuration, v3.
-:66: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#66: FILE: drivers/gpu/drm/i915/display/intel_atomic_plane.c:231:
+			intel_atomic_get_new_plane_state(state,
+				new_plane_state->bigjoiner_plane);

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

-:358: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#358: FILE: drivers/gpu/drm/i915/display/intel_display.c:12342:
+				intel_atomic_get_new_plane_state(state,
+					plane_state->bigjoiner_plane);

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

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

-:433: WARNING:LONG_LINE: line over 100 characters
#433: FILE: drivers/gpu/drm/i915/display/intel_display.h:460:
+			      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

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

total: 0 errors, 5 warnings, 2 checks, 463 lines checked
c9a540d85b32 drm/i915: Add bigjoiner aware plane clipping checks
c76daafe3429 drm/i915: Add intel_update_bigjoiner handling.
fac798935da8 drm/i915: Add debugfs dumping for bigjoiner, v2.
-:71: WARNING:LONG_LINE: line over 100 characters
#71: FILE: drivers/gpu/drm/i915/i915_debugfs.c:2626:
+		seq_printf(m, "\t--Plane id %d: type=%s, %s, clipped crtc="DRM_RECT_FMT", clipped src="DRM_RECT_FP_FMT", format=%s, rotation=%s\n",

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

total: 0 errors, 1 warnings, 1 checks, 80 lines checked

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

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

* ✗ Fi.CI.SPARSE: warning for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:06   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:06 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.6.0
Commit: HAX to make DSC work on the icelake test system
Okay!

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

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:06   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:06 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.6.0
Commit: HAX to make DSC work on the icelake test system
Okay!

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

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

* ✓ Fi.CI.BAT: success for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:25   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:25 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7344 -> Patchwork_15263
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/index.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live_gem_contexts:
    - fi-bsw-kefka:       [PASS][1] -> [INCOMPLETE][2] ([fdo# 111542])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-kefka/igt@i915_selftest@live_gem_contexts.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-kefka/igt@i915_selftest@live_gem_contexts.html
    - fi-bsw-n3050:       [PASS][3] -> [INCOMPLETE][4] ([fdo# 111542])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html

  * igt@kms_busy@basic-flip-pipe-a:
    - fi-cml-u2:          [PASS][5] -> [DMESG-WARN][6] ([fdo#105763])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-cml-u2/igt@kms_busy@basic-flip-pipe-a.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-cml-u2/igt@kms_busy@basic-flip-pipe-a.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-6700k2:      [PASS][7] -> [DMESG-WARN][8] ([fdo#105541]) +10 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6700k2/igt@kms_setmode@basic-clone-single-crtc.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6700k2/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@i915_selftest@live_gem_contexts:
    - fi-bsw-nick:        [INCOMPLETE][9] ([fdo# 111542]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-nick/igt@i915_selftest@live_gem_contexts.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-nick/igt@i915_selftest@live_gem_contexts.html

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

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-skl-6770hq:      [FAIL][13] ([fdo#111777]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-modeset.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-modeset.html

  * igt@kms_flip@basic-plain-flip:
    - fi-skl-6770hq:      [DMESG-WARN][15] ([fdo#105541]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_flip@basic-plain-flip.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_flip@basic-plain-flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-6770hq:      [WARN][17] ([fdo#112252]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Warnings ####

  * igt@i915_module_load@reload:
    - fi-icl-u2:          [DMESG-WARN][19] ([fdo#110595]) -> [DMESG-WARN][20] ([fdo#106107] / [fdo#110595])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-icl-u2/igt@i915_module_load@reload.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-icl-u2/igt@i915_module_load@reload.html

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

  [fdo# 111542]: https://bugs.freedesktop.org/show_bug.cgi?id= 111542
  [fdo#105541]: https://bugs.freedesktop.org/show_bug.cgi?id=105541
  [fdo#105604]: https://bugs.freedesktop.org/show_bug.cgi?id=105604
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#109964]: https://bugs.freedesktop.org/show_bug.cgi?id=109964
  [fdo#110343]: https://bugs.freedesktop.org/show_bug.cgi?id=110343
  [fdo#110595]: https://bugs.freedesktop.org/show_bug.cgi?id=110595
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
  [fdo#111777]: https://bugs.freedesktop.org/show_bug.cgi?id=111777
  [fdo#112252]: https://bugs.freedesktop.org/show_bug.cgi?id=112252


Participating hosts (50 -> 45)
------------------------------

  Missing    (5): fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


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

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7344 -> Patchwork_15263

  CI-20190529: 20190529
  CI_DRM_7344: f1908e34ae20deabec070a88efaa495aa8e051f1 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5280: d053b819673dda567faca00ccbd7e826f66da586 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_15263: fac798935da85b597ea18493396732aa01f8e503 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

fac798935da8 drm/i915: Add debugfs dumping for bigjoiner, v2.
c76daafe3429 drm/i915: Add intel_update_bigjoiner handling.
c9a540d85b32 drm/i915: Add bigjoiner aware plane clipping checks
79dd9ad5168d drm/i915: Link planes in a bigjoiner configuration, v3.
ed66bbff27f8 drm/i915: Make hardware readout work on i915.
4221707d255e drm/i915: Enable big joiner support in enable and disable sequences.
0dfc33b4c96e drm/i915: Try to make bigjoiner work in atomic check, v3.
dfd57bb0186c drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
1d5ae5be65dc drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
9c348f274288 drm/i915: Remove hw.mode
e129b15e0bb7 HAX to make DSC work on the icelake test system

== Logs ==

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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-14 17:25   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-14 17:25 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_7344 -> Patchwork_15263
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/index.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@i915_selftest@live_gem_contexts:
    - fi-bsw-kefka:       [PASS][1] -> [INCOMPLETE][2] ([fdo# 111542])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-kefka/igt@i915_selftest@live_gem_contexts.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-kefka/igt@i915_selftest@live_gem_contexts.html
    - fi-bsw-n3050:       [PASS][3] -> [INCOMPLETE][4] ([fdo# 111542])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-n3050/igt@i915_selftest@live_gem_contexts.html

  * igt@kms_busy@basic-flip-pipe-a:
    - fi-cml-u2:          [PASS][5] -> [DMESG-WARN][6] ([fdo#105763])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-cml-u2/igt@kms_busy@basic-flip-pipe-a.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-cml-u2/igt@kms_busy@basic-flip-pipe-a.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-6700k2:      [PASS][7] -> [DMESG-WARN][8] ([fdo#105541]) +10 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6700k2/igt@kms_setmode@basic-clone-single-crtc.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6700k2/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Possible fixes ####

  * igt@i915_selftest@live_gem_contexts:
    - fi-bsw-nick:        [INCOMPLETE][9] ([fdo# 111542]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-bsw-nick/igt@i915_selftest@live_gem_contexts.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-bsw-nick/igt@i915_selftest@live_gem_contexts.html

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

  * igt@kms_flip@basic-flip-vs-modeset:
    - fi-skl-6770hq:      [FAIL][13] ([fdo#111777]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-modeset.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_flip@basic-flip-vs-modeset.html

  * igt@kms_flip@basic-plain-flip:
    - fi-skl-6770hq:      [DMESG-WARN][15] ([fdo#105541]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_flip@basic-plain-flip.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_flip@basic-plain-flip.html

  * igt@kms_setmode@basic-clone-single-crtc:
    - fi-skl-6770hq:      [WARN][17] ([fdo#112252]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-skl-6770hq/igt@kms_setmode@basic-clone-single-crtc.html

  
#### Warnings ####

  * igt@i915_module_load@reload:
    - fi-icl-u2:          [DMESG-WARN][19] ([fdo#110595]) -> [DMESG-WARN][20] ([fdo#106107] / [fdo#110595])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/fi-icl-u2/igt@i915_module_load@reload.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/fi-icl-u2/igt@i915_module_load@reload.html

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

  [fdo# 111542]: https://bugs.freedesktop.org/show_bug.cgi?id= 111542
  [fdo#105541]: https://bugs.freedesktop.org/show_bug.cgi?id=105541
  [fdo#105604]: https://bugs.freedesktop.org/show_bug.cgi?id=105604
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#106107]: https://bugs.freedesktop.org/show_bug.cgi?id=106107
  [fdo#109964]: https://bugs.freedesktop.org/show_bug.cgi?id=109964
  [fdo#110343]: https://bugs.freedesktop.org/show_bug.cgi?id=110343
  [fdo#110595]: https://bugs.freedesktop.org/show_bug.cgi?id=110595
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
  [fdo#111777]: https://bugs.freedesktop.org/show_bug.cgi?id=111777
  [fdo#112252]: https://bugs.freedesktop.org/show_bug.cgi?id=112252


Participating hosts (50 -> 45)
------------------------------

  Missing    (5): fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


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

  * CI: CI-20190529 -> None
  * Linux: CI_DRM_7344 -> Patchwork_15263

  CI-20190529: 20190529
  CI_DRM_7344: f1908e34ae20deabec070a88efaa495aa8e051f1 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5280: d053b819673dda567faca00ccbd7e826f66da586 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_15263: fac798935da85b597ea18493396732aa01f8e503 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

fac798935da8 drm/i915: Add debugfs dumping for bigjoiner, v2.
c76daafe3429 drm/i915: Add intel_update_bigjoiner handling.
c9a540d85b32 drm/i915: Add bigjoiner aware plane clipping checks
79dd9ad5168d drm/i915: Link planes in a bigjoiner configuration, v3.
ed66bbff27f8 drm/i915: Make hardware readout work on i915.
4221707d255e drm/i915: Enable big joiner support in enable and disable sequences.
0dfc33b4c96e drm/i915: Try to make bigjoiner work in atomic check, v3.
dfd57bb0186c drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
1d5ae5be65dc drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
9c348f274288 drm/i915: Remove hw.mode
e129b15e0bb7 HAX to make DSC work on the icelake test system

== Logs ==

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

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

* ✗ Fi.CI.IGT: failure for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-15 17:50   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-15 17:50 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_7344_full -> Patchwork_15263_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_15263_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_15263_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_15263_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive:
    - shard-apl:          [PASS][1] -> [DMESG-FAIL][2] +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl7/igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl1/igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive.html

  * igt@kms_plane_lowres@pipe-a-tiling-x:
    - shard-snb:          [PASS][3] -> [FAIL][4] +3 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-snb2/igt@kms_plane_lowres@pipe-a-tiling-x.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-snb4/igt@kms_plane_lowres@pipe-a-tiling-x.html
    - shard-tglb:         NOTRUN -> [FAIL][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb7/igt@kms_plane_lowres@pipe-a-tiling-x.html

  * igt@kms_plane_lowres@pipe-a-tiling-yf:
    - shard-skl:          [PASS][6] -> [FAIL][7] +11 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl2/igt@kms_plane_lowres@pipe-a-tiling-yf.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_lowres@pipe-a-tiling-yf.html

  * igt@kms_plane_lowres@pipe-b-tiling-none:
    - shard-tglb:         [PASS][8] -> [FAIL][9] +7 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb3/igt@kms_plane_lowres@pipe-b-tiling-none.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb4/igt@kms_plane_lowres@pipe-b-tiling-none.html

  * igt@kms_plane_lowres@pipe-b-tiling-x:
    - shard-glk:          [PASS][10] -> [FAIL][11] +11 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk1/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk5/igt@kms_plane_lowres@pipe-b-tiling-x.html
    - shard-apl:          [PASS][12] -> [FAIL][13] +10 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl7/igt@kms_plane_lowres@pipe-b-tiling-x.html
    - shard-iclb:         NOTRUN -> [FAIL][14] +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@kms_plane_lowres@pipe-b-tiling-x.html

  * igt@kms_plane_lowres@pipe-c-tiling-none:
    - shard-iclb:         [PASS][15] -> [FAIL][16] +9 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb1/igt@kms_plane_lowres@pipe-c-tiling-none.html
    - shard-hsw:          [PASS][17] -> [FAIL][18] +5 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw1/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw1/igt@kms_plane_lowres@pipe-c-tiling-none.html

  * igt@kms_plane_lowres@pipe-c-tiling-yf:
    - shard-kbl:          [PASS][19] -> [FAIL][20] +11 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-kbl4/igt@kms_plane_lowres@pipe-c-tiling-yf.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-kbl1/igt@kms_plane_lowres@pipe-c-tiling-yf.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_isolation@bcs0-s3:
    - shard-apl:          [PASS][21] -> [DMESG-WARN][22] ([fdo#108566])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl8/igt@gem_ctx_isolation@bcs0-s3.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl4/igt@gem_ctx_isolation@bcs0-s3.html

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-tglb:         [PASS][23] -> [INCOMPLETE][24] ([fdo#111832])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb9/igt@gem_ctx_isolation@rcs0-s3.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb5/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-queued:
    - shard-iclb:         [PASS][25] -> [SKIP][26] ([fdo#109276] / [fdo#112080]) +5 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_ctx_persistence@vcs1-queued.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_ctx_persistence@vcs1-queued.html

  * igt@gem_ctx_switch@vcs1-heavy:
    - shard-iclb:         [PASS][27] -> [SKIP][28] ([fdo#112080]) +13 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_ctx_switch@vcs1-heavy.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_ctx_switch@vcs1-heavy.html

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][29] -> [SKIP][30] ([fdo#110854])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_exec_balancer@smoke.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_exec_balancer@smoke.html

  * igt@gem_exec_parallel@fds:
    - shard-tglb:         [PASS][31] -> [INCOMPLETE][32] ([fdo#111867])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb8/igt@gem_exec_parallel@fds.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb6/igt@gem_exec_parallel@fds.html

  * igt@gem_exec_reloc@basic-write-read-active:
    - shard-skl:          [PASS][33] -> [DMESG-WARN][34] ([fdo#106107]) +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl5/igt@gem_exec_reloc@basic-write-read-active.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl10/igt@gem_exec_reloc@basic-write-read-active.html

  * igt@gem_exec_schedule@independent-bsd2:
    - shard-iclb:         [PASS][35] -> [SKIP][36] ([fdo#109276]) +24 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb2/igt@gem_exec_schedule@independent-bsd2.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@gem_exec_schedule@independent-bsd2.html

  * igt@gem_exec_schedule@preempt-bsd:
    - shard-iclb:         [PASS][37] -> [SKIP][38] ([fdo#112146]) +4 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb3/igt@gem_exec_schedule@preempt-bsd.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@gem_exec_schedule@preempt-bsd.html

  * igt@gem_exec_schedule@preempt-queue-contexts-blt:
    - shard-tglb:         [PASS][39] -> [INCOMPLETE][40] ([fdo#111606] / [fdo#111677]) +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb7/igt@gem_exec_schedule@preempt-queue-contexts-blt.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb6/igt@gem_exec_schedule@preempt-queue-contexts-blt.html

  * igt@gem_userptr_blits@sync-unmap-after-close:
    - shard-hsw:          [PASS][41] -> [DMESG-WARN][42] ([fdo#111870]) +2 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw1/igt@gem_userptr_blits@sync-unmap-after-close.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw1/igt@gem_userptr_blits@sync-unmap-after-close.html
    - shard-snb:          [PASS][43] -> [DMESG-WARN][44] ([fdo#111870])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-snb5/igt@gem_userptr_blits@sync-unmap-after-close.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-snb4/igt@gem_userptr_blits@sync-unmap-after-close.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [PASS][45] -> [FAIL][46] ([fdo#111830 ])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb7/igt@i915_pm_dc@dc6-dpms.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-tglb:         [PASS][47] -> [INCOMPLETE][48] ([fdo#111832] / [fdo#111850]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb5/igt@i915_suspend@fence-restore-tiled2untiled.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb7/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen:
    - shard-skl:          [PASS][49] -> [FAIL][50] ([fdo#103232])
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen.html

  * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
    - shard-glk:          [PASS][51] -> [FAIL][52] ([fdo#106509] / [fdo#107409])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk4/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk1/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-skl:          [PASS][53] -> [FAIL][54] ([fdo#102670])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl9/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl2/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
    - shard-glk:          [PASS][55] -> [FAIL][56] ([fdo#105363])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk5/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-tglb:         [PASS][57] -> [INCOMPLETE][58] ([fdo#111850] / [fdo#112031])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb6/igt@kms_flip@flip-vs-suspend.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb8/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-kbl:          [PASS][59] -> [DMESG-WARN][60] ([fdo#108566]) +3 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-kbl4/igt@kms_flip@flip-vs-suspend-interruptible.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-kbl2/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff:
    - shard-tglb:         [PASS][61] -> [FAIL][62] ([fdo#103167]) +1 similar issue
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt:
    - shard-skl:          [PASS][63] -> [FAIL][64] ([fdo#103167])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl8/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl9/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [PASS][65] -> [FAIL][66] ([fdo#108145])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][67] -> [FAIL][68] ([fdo#108145] / [fdo#110403])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_plane_onoff:
    - shard-iclb:         [PASS][69] -> [SKIP][70] ([fdo#109441]) +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb2/igt@kms_psr@psr2_cursor_plane_onoff.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@kms_psr@psr2_cursor_plane_onoff.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@vcs0-s3:
    - shard-tglb:         [INCOMPLETE][71] ([fdo#111832]) -> [PASS][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb7/igt@gem_ctx_isolation@vcs0-s3.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb1/igt@gem_ctx_isolation@vcs0-s3.html

  * igt@gem_ctx_isolation@vcs1-clean:
    - shard-iclb:         [SKIP][73] ([fdo#109276] / [fdo#112080]) -> [PASS][74] +4 similar issues
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb8/igt@gem_ctx_isolation@vcs1-clean.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb1/igt@gem_ctx_isolation@vcs1-clean.html

  * igt@gem_ctx_shared@q-smoketest-bsd2:
    - shard-iclb:         [SKIP][75] ([fdo#109276]) -> [PASS][76] +20 similar issues
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb5/igt@gem_ctx_shared@q-smoketest-bsd2.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb4/igt@gem_ctx_shared@q-smoketest-bsd2.html

  * igt@gem_exec_schedule@preempt-other-chain-bsd:
    - shard-iclb:         [SKIP][77] ([fdo#112146]) -> [PASS][78] +7 similar issues
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb4/igt@gem_exec_schedule@preempt-other-chain-bsd.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb6/igt@gem_exec_schedule@preempt-other-chain-bsd.html

  * igt@gem_persistent_relocs@forked-faulting-reloc-thrashing:
    - shard-iclb:         [TIMEOUT][79] ([fdo#112068 ]) -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html

  * igt@gem_persistent_relocs@forked-thrash-inactive:
    - shard-hsw:          [INCOMPLETE][81] ([fdo#103540] / [fdo#112068 ]) -> [PASS][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw5/igt@gem_persistent_relocs@forked-thrash-inactive.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw2/igt@gem_persistent_relocs@forked-thrash-inactive.html

  * igt@gem_workarounds@suspend-resume:
    - shard-tglb:         [INCOMPLETE][83] ([fdo#111832] / [fdo#111850]) -> [PASS][84] +2 similar issues
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb1/igt@gem_workarounds@suspend-resume.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb9/igt@gem_workarounds@suspend-resume.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [DMESG-WARN][85] ([fdo#108566]) -> [PASS][86] +3 similar issues
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl6/igt@i915_suspend@fence-restore-tiled2untiled.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl2/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_color@pipe-a-ctm-0-5:
    - shard-skl:          [DMESG-WARN][87] ([fdo#106107]) -> [PASS][88] +1 similar issue
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl9/igt@kms_color@pipe-a-ctm-0-5.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl6/igt@kms_color@pipe-a-ctm-0-5.html

  * igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen:
    - shard-skl:          [FAIL][89] ([fdo#103232]) -> [PASS][90]
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl6/igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl7/igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
    - shard-hsw:          [FAIL][91] ([fdo#105767]) -> [PASS][92]
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw4/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-skl:          [FAIL][93] ([fdo#102670]) -> [PASS][94]
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl5/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl10/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-glk:          [FAIL][95] ([fdo#105363]) -> [PASS][96]
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk3/igt@kms_flip@flip-vs-expired-vblank.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk4/igt@kms_flip@flip-vs-expired-vblank.html

  * igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt:
    - shard-tglb:         [FAIL][97] ([fdo#103167]) -> [PASS][98] +6 similar issues
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb5/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb9/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite:
    - shard-iclb:         [FAIL][99] ([fdo#103167]) -> [PASS][100] +3 similar issues
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][101] ([fdo#108145] / [fdo#110403]) -> [PASS][102]
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_primary_mmap_gtt:
    - shard-iclb:         [SKIP][103] ([fdo#109441]) -> [PASS][104] +2 similar issues
   [103]: https://intel-gfx-ci.01.

== Logs ==

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

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [01/11] HAX to make DSC work on the icelake test system
@ 2019-11-15 17:50   ` Patchwork
  0 siblings, 0 replies; 47+ messages in thread
From: Patchwork @ 2019-11-15 17:50 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

== Series Details ==

Series: series starting with [01/11] HAX to make DSC work on the icelake test system
URL   : https://patchwork.freedesktop.org/series/69478/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_7344_full -> Patchwork_15263_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_15263_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_15263_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_15263_full:

### IGT changes ###

#### Possible regressions ####

  * igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive:
    - shard-apl:          [PASS][1] -> [DMESG-FAIL][2] +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl7/igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl1/igt@gem_persistent_relocs@forked-faulting-reloc-thrash-inactive.html

  * igt@kms_plane_lowres@pipe-a-tiling-x:
    - shard-snb:          [PASS][3] -> [FAIL][4] +3 similar issues
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-snb2/igt@kms_plane_lowres@pipe-a-tiling-x.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-snb4/igt@kms_plane_lowres@pipe-a-tiling-x.html
    - shard-tglb:         NOTRUN -> [FAIL][5]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb7/igt@kms_plane_lowres@pipe-a-tiling-x.html

  * igt@kms_plane_lowres@pipe-a-tiling-yf:
    - shard-skl:          [PASS][6] -> [FAIL][7] +11 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl2/igt@kms_plane_lowres@pipe-a-tiling-yf.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_lowres@pipe-a-tiling-yf.html

  * igt@kms_plane_lowres@pipe-b-tiling-none:
    - shard-tglb:         [PASS][8] -> [FAIL][9] +7 similar issues
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb3/igt@kms_plane_lowres@pipe-b-tiling-none.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb4/igt@kms_plane_lowres@pipe-b-tiling-none.html

  * igt@kms_plane_lowres@pipe-b-tiling-x:
    - shard-glk:          [PASS][10] -> [FAIL][11] +11 similar issues
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk1/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk5/igt@kms_plane_lowres@pipe-b-tiling-x.html
    - shard-apl:          [PASS][12] -> [FAIL][13] +10 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl4/igt@kms_plane_lowres@pipe-b-tiling-x.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl7/igt@kms_plane_lowres@pipe-b-tiling-x.html
    - shard-iclb:         NOTRUN -> [FAIL][14] +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@kms_plane_lowres@pipe-b-tiling-x.html

  * igt@kms_plane_lowres@pipe-c-tiling-none:
    - shard-iclb:         [PASS][15] -> [FAIL][16] +9 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb1/igt@kms_plane_lowres@pipe-c-tiling-none.html
    - shard-hsw:          [PASS][17] -> [FAIL][18] +5 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw1/igt@kms_plane_lowres@pipe-c-tiling-none.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw1/igt@kms_plane_lowres@pipe-c-tiling-none.html

  * igt@kms_plane_lowres@pipe-c-tiling-yf:
    - shard-kbl:          [PASS][19] -> [FAIL][20] +11 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-kbl4/igt@kms_plane_lowres@pipe-c-tiling-yf.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-kbl1/igt@kms_plane_lowres@pipe-c-tiling-yf.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_isolation@bcs0-s3:
    - shard-apl:          [PASS][21] -> [DMESG-WARN][22] ([fdo#108566])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl8/igt@gem_ctx_isolation@bcs0-s3.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl4/igt@gem_ctx_isolation@bcs0-s3.html

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-tglb:         [PASS][23] -> [INCOMPLETE][24] ([fdo#111832])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb9/igt@gem_ctx_isolation@rcs0-s3.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb5/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@gem_ctx_persistence@vcs1-queued:
    - shard-iclb:         [PASS][25] -> [SKIP][26] ([fdo#109276] / [fdo#112080]) +5 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_ctx_persistence@vcs1-queued.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_ctx_persistence@vcs1-queued.html

  * igt@gem_ctx_switch@vcs1-heavy:
    - shard-iclb:         [PASS][27] -> [SKIP][28] ([fdo#112080]) +13 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_ctx_switch@vcs1-heavy.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_ctx_switch@vcs1-heavy.html

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][29] -> [SKIP][30] ([fdo#110854])
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb1/igt@gem_exec_balancer@smoke.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb5/igt@gem_exec_balancer@smoke.html

  * igt@gem_exec_parallel@fds:
    - shard-tglb:         [PASS][31] -> [INCOMPLETE][32] ([fdo#111867])
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb8/igt@gem_exec_parallel@fds.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb6/igt@gem_exec_parallel@fds.html

  * igt@gem_exec_reloc@basic-write-read-active:
    - shard-skl:          [PASS][33] -> [DMESG-WARN][34] ([fdo#106107]) +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl5/igt@gem_exec_reloc@basic-write-read-active.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl10/igt@gem_exec_reloc@basic-write-read-active.html

  * igt@gem_exec_schedule@independent-bsd2:
    - shard-iclb:         [PASS][35] -> [SKIP][36] ([fdo#109276]) +24 similar issues
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb2/igt@gem_exec_schedule@independent-bsd2.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@gem_exec_schedule@independent-bsd2.html

  * igt@gem_exec_schedule@preempt-bsd:
    - shard-iclb:         [PASS][37] -> [SKIP][38] ([fdo#112146]) +4 similar issues
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb3/igt@gem_exec_schedule@preempt-bsd.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@gem_exec_schedule@preempt-bsd.html

  * igt@gem_exec_schedule@preempt-queue-contexts-blt:
    - shard-tglb:         [PASS][39] -> [INCOMPLETE][40] ([fdo#111606] / [fdo#111677]) +1 similar issue
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb7/igt@gem_exec_schedule@preempt-queue-contexts-blt.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb6/igt@gem_exec_schedule@preempt-queue-contexts-blt.html

  * igt@gem_userptr_blits@sync-unmap-after-close:
    - shard-hsw:          [PASS][41] -> [DMESG-WARN][42] ([fdo#111870]) +2 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw1/igt@gem_userptr_blits@sync-unmap-after-close.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw1/igt@gem_userptr_blits@sync-unmap-after-close.html
    - shard-snb:          [PASS][43] -> [DMESG-WARN][44] ([fdo#111870])
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-snb5/igt@gem_userptr_blits@sync-unmap-after-close.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-snb4/igt@gem_userptr_blits@sync-unmap-after-close.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-iclb:         [PASS][45] -> [FAIL][46] ([fdo#111830 ])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb7/igt@i915_pm_dc@dc6-dpms.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb3/igt@i915_pm_dc@dc6-dpms.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-tglb:         [PASS][47] -> [INCOMPLETE][48] ([fdo#111832] / [fdo#111850]) +2 similar issues
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb5/igt@i915_suspend@fence-restore-tiled2untiled.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb7/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen:
    - shard-skl:          [PASS][49] -> [FAIL][50] ([fdo#103232])
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_cursor_crc@pipe-a-cursor-64x64-offscreen.html

  * igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic:
    - shard-glk:          [PASS][51] -> [FAIL][52] ([fdo#106509] / [fdo#107409])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk4/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk1/igt@kms_cursor_legacy@2x-long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-skl:          [PASS][53] -> [FAIL][54] ([fdo#102670])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl9/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl2/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_flip@2x-flip-vs-expired-vblank-interruptible:
    - shard-glk:          [PASS][55] -> [FAIL][56] ([fdo#105363])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk5/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk7/igt@kms_flip@2x-flip-vs-expired-vblank-interruptible.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-tglb:         [PASS][57] -> [INCOMPLETE][58] ([fdo#111850] / [fdo#112031])
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb6/igt@kms_flip@flip-vs-suspend.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb8/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-kbl:          [PASS][59] -> [DMESG-WARN][60] ([fdo#108566]) +3 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-kbl4/igt@kms_flip@flip-vs-suspend-interruptible.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-kbl2/igt@kms_flip@flip-vs-suspend-interruptible.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff:
    - shard-tglb:         [PASS][61] -> [FAIL][62] ([fdo#103167]) +1 similar issue
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-cur-indfb-onoff.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt:
    - shard-skl:          [PASS][63] -> [FAIL][64] ([fdo#103167])
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl8/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl9/igt@kms_frontbuffer_tracking@psr-1p-primscrn-indfb-msflip-blt.html

  * igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min:
    - shard-skl:          [PASS][65] -> [FAIL][66] ([fdo#108145])
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_alpha_blend@pipe-a-constant-alpha-min.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][67] -> [FAIL][68] ([fdo#108145] / [fdo#110403])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl3/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl8/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_plane_onoff:
    - shard-iclb:         [PASS][69] -> [SKIP][70] ([fdo#109441]) +1 similar issue
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb2/igt@kms_psr@psr2_cursor_plane_onoff.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@kms_psr@psr2_cursor_plane_onoff.html

  
#### Possible fixes ####

  * igt@gem_ctx_isolation@vcs0-s3:
    - shard-tglb:         [INCOMPLETE][71] ([fdo#111832]) -> [PASS][72]
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb7/igt@gem_ctx_isolation@vcs0-s3.html
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb1/igt@gem_ctx_isolation@vcs0-s3.html

  * igt@gem_ctx_isolation@vcs1-clean:
    - shard-iclb:         [SKIP][73] ([fdo#109276] / [fdo#112080]) -> [PASS][74] +4 similar issues
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb8/igt@gem_ctx_isolation@vcs1-clean.html
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb1/igt@gem_ctx_isolation@vcs1-clean.html

  * igt@gem_ctx_shared@q-smoketest-bsd2:
    - shard-iclb:         [SKIP][75] ([fdo#109276]) -> [PASS][76] +20 similar issues
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb5/igt@gem_ctx_shared@q-smoketest-bsd2.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb4/igt@gem_ctx_shared@q-smoketest-bsd2.html

  * igt@gem_exec_schedule@preempt-other-chain-bsd:
    - shard-iclb:         [SKIP][77] ([fdo#112146]) -> [PASS][78] +7 similar issues
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb4/igt@gem_exec_schedule@preempt-other-chain-bsd.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb6/igt@gem_exec_schedule@preempt-other-chain-bsd.html

  * igt@gem_persistent_relocs@forked-faulting-reloc-thrashing:
    - shard-iclb:         [TIMEOUT][79] ([fdo#112068 ]) -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb2/igt@gem_persistent_relocs@forked-faulting-reloc-thrashing.html

  * igt@gem_persistent_relocs@forked-thrash-inactive:
    - shard-hsw:          [INCOMPLETE][81] ([fdo#103540] / [fdo#112068 ]) -> [PASS][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw5/igt@gem_persistent_relocs@forked-thrash-inactive.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw2/igt@gem_persistent_relocs@forked-thrash-inactive.html

  * igt@gem_workarounds@suspend-resume:
    - shard-tglb:         [INCOMPLETE][83] ([fdo#111832] / [fdo#111850]) -> [PASS][84] +2 similar issues
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb1/igt@gem_workarounds@suspend-resume.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb9/igt@gem_workarounds@suspend-resume.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [DMESG-WARN][85] ([fdo#108566]) -> [PASS][86] +3 similar issues
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-apl6/igt@i915_suspend@fence-restore-tiled2untiled.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-apl2/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_color@pipe-a-ctm-0-5:
    - shard-skl:          [DMESG-WARN][87] ([fdo#106107]) -> [PASS][88] +1 similar issue
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl9/igt@kms_color@pipe-a-ctm-0-5.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl6/igt@kms_color@pipe-a-ctm-0-5.html

  * igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen:
    - shard-skl:          [FAIL][89] ([fdo#103232]) -> [PASS][90]
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl6/igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl7/igt@kms_cursor_crc@pipe-c-cursor-256x85-onscreen.html

  * igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic:
    - shard-hsw:          [FAIL][91] ([fdo#105767]) -> [PASS][92]
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-hsw4/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-hsw5/igt@kms_cursor_legacy@2x-long-cursor-vs-flip-atomic.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions:
    - shard-skl:          [FAIL][93] ([fdo#102670]) -> [PASS][94]
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl5/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl10/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions.html

  * igt@kms_flip@flip-vs-expired-vblank:
    - shard-glk:          [FAIL][95] ([fdo#105363]) -> [PASS][96]
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-glk3/igt@kms_flip@flip-vs-expired-vblank.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-glk4/igt@kms_flip@flip-vs-expired-vblank.html

  * igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt:
    - shard-tglb:         [FAIL][97] ([fdo#103167]) -> [PASS][98] +6 similar issues
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-tglb5/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-tglb9/igt@kms_frontbuffer_tracking@fbc-rgb565-draw-mmap-gtt.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite:
    - shard-iclb:         [FAIL][99] ([fdo#103167]) -> [PASS][100] +3 similar issues
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-iclb7/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-pwrite.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [FAIL][101] ([fdo#108145] / [fdo#110403]) -> [PASS][102]
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_7344/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_15263/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_primary_mmap_gtt:
    - shard-iclb:         [SKIP][103] ([fdo#109441]) -> [PASS][104] +2 similar issues
   [103]: https://intel-gfx-ci.01.

== Logs ==

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

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

* Re: [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-18 17:17     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-18 17:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:13PM +0100, Maarten Lankhorst wrote:
> The members in hw.mode can be used from adjusted_mode as well,
> use that when available.
> 
> Some places that use hw.mode can be converted to use adjusted_mode
> as well.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
>  .../drm/i915/display/intel_display_types.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
>  drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
>  4 files changed, 34 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index adf50c4b38ad..18acecc3642d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	tmp = I915_READ(PIPESRC(crtc->pipe));
>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
> -
> -	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,
> @@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
>  			continue;
>  		if (!connector->has_tile)
>  			continue;
> -		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
> -		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
> +		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
> +		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)

Using adjusted_mode before .compute_config() seems like a bad idea.

>  			return 0;
>  		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
>  		    connector->tile_v_loc == connector->num_v_tile - 1)
> @@ -12506,7 +12503,7 @@ 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->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>  	DRM_DEBUG_KMS("adjusted mode:\n");
>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>  	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
> @@ -12640,16 +12637,16 @@ intel_crtc_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;
>  	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>  }
>  
> -static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> +					     struct drm_display_mode *user_mode)
>  {
>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>  	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>  	kfree(saved_state);
>  
> +	/* Clear I915_MODE_FLAG_INHERITED */
> +	crtc_state->uapi.mode.private_flags = 0;
> +	crtc_state->uapi.adjusted_mode.private_flags = 0;
> +
>  	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>  
>  	return 0;
> @@ -12750,7 +12751,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->hw.mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> +	/* without bigjoiner, pipe_mode == adjusted_mode */
> +	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;

Misplaced hunks?

>  	return 0;
>  }
>  
> @@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	bool ret = true;
>  	u32 bp_gamma = 0;
>  	bool fixup_inherited = fastset &&
> -		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> -		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
> +		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> +		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
>  
>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
> @@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
> -		    old_crtc_state->hw.mode.private_flags)
> +		if (new_crtc_state->hw.adjusted_mode.private_flags !=
> +		    old_crtc_state->hw.adjusted_mode.private_flags)
>  			new_crtc_state->uapi.mode_changed = true;
>  	}
>  
> @@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		int min_cdclk = 0;
>  
>  		if (crtc_state->hw.active) {
> -			struct drm_display_mode *mode = &crtc_state->hw.mode;
> +			struct drm_display_mode mode;
>  
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
>  
> -			*mode = crtc_state->hw.adjusted_mode;
> -			mode->hdisplay = crtc_state->pipe_src_w;
> -			mode->vdisplay = crtc_state->pipe_src_h;
> -
>  			/*
>  			 * The initial mode needs to be set in order to keep
>  			 * the atomic core happy. It wants a valid mode if the
> @@ -17542,13 +17541,17 @@ 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.
>  			 */
> -			mode->private_flags = I915_MODE_FLAG_INHERITED;
> +			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
> +
> +			mode = crtc_state->hw.adjusted_mode;
> +			mode.hdisplay = crtc_state->pipe_src_w;
> +			mode.vdisplay = crtc_state->pipe_src_h;
>  
>  			intel_crtc_compute_pixel_rate(crtc_state);
>  
>  			intel_crtc_update_active_timings(crtc_state);
>  
> -			intel_crtc_copy_hw_to_uapi_state(crtc_state);
> +			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
>  		}
>  
>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..0f20c7190eed 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -802,7 +802,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 adjusted_mode;
>  	} hw;
>  
>  	/**
> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
> index a74dc5b915d1..ad8e9959d6e1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -207,7 +207,7 @@ 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->hw.mode,
> +					 &pipe_config->hw.adjusted_mode,
>  					 &pipe_config->hw.adjusted_mode);
>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index a4b1339fcc00..4ba7648a3145 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
>  static bool
>  intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  				    struct intel_sdvo_connector *intel_sdvo_connector,
> -				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode)
>  {
>  	struct intel_sdvo_dtd input_dtd;
> @@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  
>  	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
>  						      intel_sdvo_connector,
> -						      mode->clock / 10,
> -						      mode->hdisplay,
> -						      mode->vdisplay))
> +						      adjusted_mode->clock / 10,
> +						      adjusted_mode->hdisplay,
> +						      adjusted_mode->vdisplay))
>  		return false;
>  
>  	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
> @@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
>  	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;
> @@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	 * the sequence to do it. Oh well.
>  	 */
>  	if (IS_TV(intel_sdvo_connector)) {
> -		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
> +		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
> +							     adjusted_mode))
>  			return -EINVAL;
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  		pipe_config->sdvo_tv_clock = true;
>  	} else if (IS_LVDS(intel_sdvo_connector)) {
> @@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  	}
>  
> @@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		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->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		intel_sdvo_get_dtd_from_mode(&output_dtd,
>  					     intel_sdvo_connector->base.panel.fixed_mode);
>  	else
> -		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
> +		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
>  	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
>  		DRM_INFO("Setting output timings on %s failed\n",
>  			 SDVO_NAME(intel_sdvo));
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-18 17:17     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-18 17:17 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:13PM +0100, Maarten Lankhorst wrote:
> The members in hw.mode can be used from adjusted_mode as well,
> use that when available.
> 
> Some places that use hw.mode can be converted to use adjusted_mode
> as well.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
>  .../drm/i915/display/intel_display_types.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
>  drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
>  4 files changed, 34 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index adf50c4b38ad..18acecc3642d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	tmp = I915_READ(PIPESRC(crtc->pipe));
>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
> -
> -	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,
> @@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
>  			continue;
>  		if (!connector->has_tile)
>  			continue;
> -		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
> -		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
> +		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
> +		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)

Using adjusted_mode before .compute_config() seems like a bad idea.

>  			return 0;
>  		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
>  		    connector->tile_v_loc == connector->num_v_tile - 1)
> @@ -12506,7 +12503,7 @@ 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->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>  	DRM_DEBUG_KMS("adjusted mode:\n");
>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>  	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
> @@ -12640,16 +12637,16 @@ intel_crtc_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;
>  	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>  }
>  
> -static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> +					     struct drm_display_mode *user_mode)
>  {
>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>  	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>  	kfree(saved_state);
>  
> +	/* Clear I915_MODE_FLAG_INHERITED */
> +	crtc_state->uapi.mode.private_flags = 0;
> +	crtc_state->uapi.adjusted_mode.private_flags = 0;
> +
>  	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>  
>  	return 0;
> @@ -12750,7 +12751,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->hw.mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> +	/* without bigjoiner, pipe_mode == adjusted_mode */
> +	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;

Misplaced hunks?

>  	return 0;
>  }
>  
> @@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	bool ret = true;
>  	u32 bp_gamma = 0;
>  	bool fixup_inherited = fastset &&
> -		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> -		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
> +		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> +		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
>  
>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
> @@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
> -		    old_crtc_state->hw.mode.private_flags)
> +		if (new_crtc_state->hw.adjusted_mode.private_flags !=
> +		    old_crtc_state->hw.adjusted_mode.private_flags)
>  			new_crtc_state->uapi.mode_changed = true;
>  	}
>  
> @@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		int min_cdclk = 0;
>  
>  		if (crtc_state->hw.active) {
> -			struct drm_display_mode *mode = &crtc_state->hw.mode;
> +			struct drm_display_mode mode;
>  
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
>  
> -			*mode = crtc_state->hw.adjusted_mode;
> -			mode->hdisplay = crtc_state->pipe_src_w;
> -			mode->vdisplay = crtc_state->pipe_src_h;
> -
>  			/*
>  			 * The initial mode needs to be set in order to keep
>  			 * the atomic core happy. It wants a valid mode if the
> @@ -17542,13 +17541,17 @@ 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.
>  			 */
> -			mode->private_flags = I915_MODE_FLAG_INHERITED;
> +			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
> +
> +			mode = crtc_state->hw.adjusted_mode;
> +			mode.hdisplay = crtc_state->pipe_src_w;
> +			mode.vdisplay = crtc_state->pipe_src_h;
>  
>  			intel_crtc_compute_pixel_rate(crtc_state);
>  
>  			intel_crtc_update_active_timings(crtc_state);
>  
> -			intel_crtc_copy_hw_to_uapi_state(crtc_state);
> +			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
>  		}
>  
>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..0f20c7190eed 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -802,7 +802,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 adjusted_mode;
>  	} hw;
>  
>  	/**
> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
> index a74dc5b915d1..ad8e9959d6e1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -207,7 +207,7 @@ 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->hw.mode,
> +					 &pipe_config->hw.adjusted_mode,
>  					 &pipe_config->hw.adjusted_mode);
>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index a4b1339fcc00..4ba7648a3145 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
>  static bool
>  intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  				    struct intel_sdvo_connector *intel_sdvo_connector,
> -				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode)
>  {
>  	struct intel_sdvo_dtd input_dtd;
> @@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  
>  	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
>  						      intel_sdvo_connector,
> -						      mode->clock / 10,
> -						      mode->hdisplay,
> -						      mode->vdisplay))
> +						      adjusted_mode->clock / 10,
> +						      adjusted_mode->hdisplay,
> +						      adjusted_mode->vdisplay))
>  		return false;
>  
>  	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
> @@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
>  	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;
> @@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	 * the sequence to do it. Oh well.
>  	 */
>  	if (IS_TV(intel_sdvo_connector)) {
> -		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
> +		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
> +							     adjusted_mode))
>  			return -EINVAL;
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  		pipe_config->sdvo_tv_clock = true;
>  	} else if (IS_LVDS(intel_sdvo_connector)) {
> @@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  	}
>  
> @@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		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->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		intel_sdvo_get_dtd_from_mode(&output_dtd,
>  					     intel_sdvo_connector->base.panel.fixed_mode);
>  	else
> -		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
> +		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
>  	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
>  		DRM_INFO("Setting output timings on %s failed\n",
>  			 SDVO_NAME(intel_sdvo));
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-18 17:39     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-18 17:39 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:13PM +0100, Maarten Lankhorst wrote:
> The members in hw.mode can be used from adjusted_mode as well,
> use that when available.
> 
> Some places that use hw.mode can be converted to use adjusted_mode
> as well.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
>  .../drm/i915/display/intel_display_types.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
>  drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
>  4 files changed, 34 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index adf50c4b38ad..18acecc3642d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	tmp = I915_READ(PIPESRC(crtc->pipe));
>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
> -
> -	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,
> @@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
>  			continue;
>  		if (!connector->has_tile)
>  			continue;
> -		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
> -		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
> +		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
> +		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)
>  			return 0;
>  		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
>  		    connector->tile_v_loc == connector->num_v_tile - 1)
> @@ -12506,7 +12503,7 @@ 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->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>  	DRM_DEBUG_KMS("adjusted mode:\n");
>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>  	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
> @@ -12640,16 +12637,16 @@ intel_crtc_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;
>  	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>  }
>  
> -static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> +					     struct drm_display_mode *user_mode)
>  {
>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>  	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>  	kfree(saved_state);
>  
> +	/* Clear I915_MODE_FLAG_INHERITED */
> +	crtc_state->uapi.mode.private_flags = 0;
> +	crtc_state->uapi.adjusted_mode.private_flags = 0;
> +
>  	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>  
>  	return 0;
> @@ -12750,7 +12751,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->hw.mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> +	/* without bigjoiner, pipe_mode == adjusted_mode */
> +	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>  	return 0;
>  }
>  
> @@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	bool ret = true;
>  	u32 bp_gamma = 0;
>  	bool fixup_inherited = fastset &&
> -		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> -		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
> +		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> +		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
>  
>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
> @@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
> -		    old_crtc_state->hw.mode.private_flags)
> +		if (new_crtc_state->hw.adjusted_mode.private_flags !=
> +		    old_crtc_state->hw.adjusted_mode.private_flags)
>  			new_crtc_state->uapi.mode_changed = true;
>  	}
>  
> @@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		int min_cdclk = 0;
>  
>  		if (crtc_state->hw.active) {
> -			struct drm_display_mode *mode = &crtc_state->hw.mode;
> +			struct drm_display_mode mode;
>  
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
>  
> -			*mode = crtc_state->hw.adjusted_mode;
> -			mode->hdisplay = crtc_state->pipe_src_w;
> -			mode->vdisplay = crtc_state->pipe_src_h;
> -
>  			/*
>  			 * The initial mode needs to be set in order to keep
>  			 * the atomic core happy. It wants a valid mode if the
> @@ -17542,13 +17541,17 @@ 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.
>  			 */
> -			mode->private_flags = I915_MODE_FLAG_INHERITED;
> +			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
> +
> +			mode = crtc_state->hw.adjusted_mode;
> +			mode.hdisplay = crtc_state->pipe_src_w;
> +			mode.vdisplay = crtc_state->pipe_src_h;
>  
>  			intel_crtc_compute_pixel_rate(crtc_state);
>  
>  			intel_crtc_update_active_timings(crtc_state);
>  
> -			intel_crtc_copy_hw_to_uapi_state(crtc_state);
> +			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
>  		}
>  
>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..0f20c7190eed 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -802,7 +802,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 adjusted_mode;
>  	} hw;
>  
>  	/**
> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
> index a74dc5b915d1..ad8e9959d6e1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -207,7 +207,7 @@ 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->hw.mode,
> +					 &pipe_config->hw.adjusted_mode,
>  					 &pipe_config->hw.adjusted_mode);

This looks very wrong.

>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index a4b1339fcc00..4ba7648a3145 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
>  static bool
>  intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  				    struct intel_sdvo_connector *intel_sdvo_connector,
> -				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode)
>  {
>  	struct intel_sdvo_dtd input_dtd;
> @@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  
>  	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
>  						      intel_sdvo_connector,
> -						      mode->clock / 10,
> -						      mode->hdisplay,
> -						      mode->vdisplay))
> +						      adjusted_mode->clock / 10,
> +						      adjusted_mode->hdisplay,
> +						      adjusted_mode->vdisplay))
>  		return false;
>  
>  	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
> @@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
>  	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;
> @@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	 * the sequence to do it. Oh well.
>  	 */
>  	if (IS_TV(intel_sdvo_connector)) {
> -		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
> +		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
> +							     adjusted_mode))
>  			return -EINVAL;
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  		pipe_config->sdvo_tv_clock = true;
>  	} else if (IS_LVDS(intel_sdvo_connector)) {
> @@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  	}
>  
> @@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		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->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		intel_sdvo_get_dtd_from_mode(&output_dtd,
>  					     intel_sdvo_connector->base.panel.fixed_mode);
>  	else
> -		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
> +		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
>  	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
>  		DRM_INFO("Setting output timings on %s failed\n",
>  			 SDVO_NAME(intel_sdvo));
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 02/11] drm/i915: Remove hw.mode
@ 2019-11-18 17:39     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-18 17:39 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:13PM +0100, Maarten Lankhorst wrote:
> The members in hw.mode can be used from adjusted_mode as well,
> use that when available.
> 
> Some places that use hw.mode can be converted to use adjusted_mode
> as well.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
>  .../drm/i915/display/intel_display_types.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
>  drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
>  4 files changed, 34 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index adf50c4b38ad..18acecc3642d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	tmp = I915_READ(PIPESRC(crtc->pipe));
>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
> -
> -	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,
> @@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
>  			continue;
>  		if (!connector->has_tile)
>  			continue;
> -		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
> -		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
> +		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
> +		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)
>  			return 0;
>  		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
>  		    connector->tile_v_loc == connector->num_v_tile - 1)
> @@ -12506,7 +12503,7 @@ 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->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>  	DRM_DEBUG_KMS("adjusted mode:\n");
>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>  	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
> @@ -12640,16 +12637,16 @@ intel_crtc_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;
>  	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>  }
>  
> -static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
> +static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> +					     struct drm_display_mode *user_mode)
>  {
>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>  	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>  	kfree(saved_state);
>  
> +	/* Clear I915_MODE_FLAG_INHERITED */
> +	crtc_state->uapi.mode.private_flags = 0;
> +	crtc_state->uapi.adjusted_mode.private_flags = 0;
> +
>  	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>  
>  	return 0;
> @@ -12750,7 +12751,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->hw.mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> +	/* without bigjoiner, pipe_mode == adjusted_mode */
> +	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>  	return 0;
>  }
>  
> @@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	bool ret = true;
>  	u32 bp_gamma = 0;
>  	bool fixup_inherited = fastset &&
> -		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> -		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
> +		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
> +		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
>  
>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
> @@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
> -		    old_crtc_state->hw.mode.private_flags)
> +		if (new_crtc_state->hw.adjusted_mode.private_flags !=
> +		    old_crtc_state->hw.adjusted_mode.private_flags)
>  			new_crtc_state->uapi.mode_changed = true;
>  	}
>  
> @@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
>  	 * of enabling them on the CRTC's first fastset.
>  	 */
>  	if (new_crtc_state->update_pipe && !modeset &&
> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
>  
> @@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  		int min_cdclk = 0;
>  
>  		if (crtc_state->hw.active) {
> -			struct drm_display_mode *mode = &crtc_state->hw.mode;
> +			struct drm_display_mode mode;
>  
>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>  						    crtc_state);
>  
> -			*mode = crtc_state->hw.adjusted_mode;
> -			mode->hdisplay = crtc_state->pipe_src_w;
> -			mode->vdisplay = crtc_state->pipe_src_h;
> -
>  			/*
>  			 * The initial mode needs to be set in order to keep
>  			 * the atomic core happy. It wants a valid mode if the
> @@ -17542,13 +17541,17 @@ 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.
>  			 */
> -			mode->private_flags = I915_MODE_FLAG_INHERITED;
> +			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
> +
> +			mode = crtc_state->hw.adjusted_mode;
> +			mode.hdisplay = crtc_state->pipe_src_w;
> +			mode.vdisplay = crtc_state->pipe_src_h;
>  
>  			intel_crtc_compute_pixel_rate(crtc_state);
>  
>  			intel_crtc_update_active_timings(crtc_state);
>  
> -			intel_crtc_copy_hw_to_uapi_state(crtc_state);
> +			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
>  		}
>  
>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 83ea04149b77..0f20c7190eed 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -802,7 +802,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 adjusted_mode;
>  	} hw;
>  
>  	/**
> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
> index a74dc5b915d1..ad8e9959d6e1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -207,7 +207,7 @@ 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->hw.mode,
> +					 &pipe_config->hw.adjusted_mode,
>  					 &pipe_config->hw.adjusted_mode);

This looks very wrong.

>  
>  	I915_WRITE(dvo_reg, temp | DVO_ENABLE);
> diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c
> index a4b1339fcc00..4ba7648a3145 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1213,7 +1213,6 @@ intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo,
>  static bool
>  intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  				    struct intel_sdvo_connector *intel_sdvo_connector,
> -				    const struct drm_display_mode *mode,
>  				    struct drm_display_mode *adjusted_mode)
>  {
>  	struct intel_sdvo_dtd input_dtd;
> @@ -1224,9 +1223,9 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
>  
>  	if (!intel_sdvo_create_preferred_input_timing(intel_sdvo,
>  						      intel_sdvo_connector,
> -						      mode->clock / 10,
> -						      mode->hdisplay,
> -						      mode->vdisplay))
> +						      adjusted_mode->clock / 10,
> +						      adjusted_mode->hdisplay,
> +						      adjusted_mode->vdisplay))
>  		return false;
>  
>  	if (!intel_sdvo_get_preferred_input_timing(intel_sdvo,
> @@ -1277,7 +1276,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
>  	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;
> @@ -1293,12 +1291,12 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  	 * the sequence to do it. Oh well.
>  	 */
>  	if (IS_TV(intel_sdvo_connector)) {
> -		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode))
> +		if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo,
> +							     adjusted_mode))
>  			return -EINVAL;
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  		pipe_config->sdvo_tv_clock = true;
>  	} else if (IS_LVDS(intel_sdvo_connector)) {
> @@ -1308,7 +1306,6 @@ static int intel_sdvo_compute_config(struct intel_encoder *encoder,
>  
>  		(void) intel_sdvo_get_preferred_input_mode(intel_sdvo,
>  							   intel_sdvo_connector,
> -							   mode,
>  							   adjusted_mode);
>  	}
>  
> @@ -1435,7 +1432,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		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->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1468,7 +1464,7 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
>  		intel_sdvo_get_dtd_from_mode(&output_dtd,
>  					     intel_sdvo_connector->base.panel.fixed_mode);
>  	else
> -		intel_sdvo_get_dtd_from_mode(&output_dtd, mode);
> +		intel_sdvo_get_dtd_from_mode(&output_dtd, adjusted_mode);
>  	if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd))
>  		DRM_INFO("Setting output timings on %s failed\n",
>  			 SDVO_NAME(intel_sdvo));
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
@ 2019-11-28 19:04     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:15PM +0100, 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.
> 
> eDP does not support bigjoiner, so do not expose bigjoiner only
> modes on the eDP port.
> 
> Changes since v1:
> - Disallow bigjoiner on eDP.
> Changes since v2:
> - Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
>   and split off the downstream and source checking to its own function.
>   (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 117 ++++++++++++++++++------
>  1 file changed, 89 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3123958e2081..9b7df8e85ea2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>  	return max_link_clock * max_lanes;
>  }
>  
> -static int
> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> +static int source_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;
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	int max_dotclk = dev_priv->max_dotclk_freq;
> -	int ds_max_dotclk;
> +	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> +
> +	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))

Should the edp check actually be check for the edp transcoder
(ie. port A) on icl?

> +		return 2 * i915->max_dotclk_freq;
> +
> +	return i915->max_dotclk_freq;
> +}
>  
> +static int downstream_max_dotclock(struct intel_dp *intel_dp)
> +{
>  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
>  
>  	if (type != DP_DS_PORT_TYPE_VGA)
> -		return max_dotclk;
> +		return 0;
>  
> -	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
> -						    intel_dp->downstream_ports);
> +	return drm_dp_downstream_max_clock(intel_dp->dpcd,
> +					   intel_dp->downstream_ports);
> +}
> +
> +static int
> +intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> +{
> +	int max_dotclk = source_max_dotclock(intel_dp, allow_bigjoiner);
> +	int ds_max_dotclk = downstream_max_dotclock(intel_dp);
>  
>  	if (ds_max_dotclk != 0)
> -		max_dotclk = min(max_dotclk, ds_max_dotclk);
> +		return min(max_dotclk, ds_max_dotclk);
>  
>  	return max_dotclk;
>  }
> @@ -506,7 +518,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
>  
>  static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  				       u32 link_clock, u32 lane_count,
> -				       u32 mode_clock, u32 mode_hdisplay)
> +				       u32 mode_clock, u32 mode_hdisplay,
> +				       bool bigjoiner)
>  {
>  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
>  	int i;
> @@ -524,6 +537,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
>  	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
>  		mode_hdisplay;
> +
> +	if (bigjoiner)
> +		max_bpp_small_joiner_ram *= 2;
> +
>  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
>  
>  	/*
> @@ -532,6 +549,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  	 */
>  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
>  
> +	if (bigjoiner) {
> +		u32 max_bpp_bigjoiner =
> +			i915->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",
> @@ -554,7 +580,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  }
>  
>  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;
> @@ -579,12 +606,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 ?

The test_ prefix is throwing me off. Just slice_count?

> +			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)

slice_count > min_slice_count? Would feel a bit more naturalto me.

> +			return test_slice_count;
>  	}
>  
>  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> @@ -623,11 +658,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_max_dotclock(intel_dp, false);
>  
>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>  		if (mode->hdisplay > fixed_mode->hdisplay)
> @@ -639,6 +678,21 @@ 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) {
> +		if (intel_dp_is_edp(intel_dp))
> +			return MODE_CLOCK_HIGH;
> +
> +		max_dotclk = intel_dp_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);
>  
> @@ -666,23 +720,28 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  							    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");

I don't think we spew debugs from mode_valid() elsewhere.

>  		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) {

Not a huge fan of this dsc boolean. Would feel more natural if the dsc
thing would compute a new mode_rate with max achievable compression,
or something along those lines. But this could be cleaned up later.

> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> +		return MODE_CLOCK_HIGH;
> +	}
>  
>  	return intel_mode_valid_max_plane_size(dev_priv, mode);
>  }
> @@ -2104,11 +2163,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  						    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.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
@ 2019-11-28 19:04     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:15PM +0100, 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.
> 
> eDP does not support bigjoiner, so do not expose bigjoiner only
> modes on the eDP port.
> 
> Changes since v1:
> - Disallow bigjoiner on eDP.
> Changes since v2:
> - Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
>   and split off the downstream and source checking to its own function.
>   (Ville)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 117 ++++++++++++++++++------
>  1 file changed, 89 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 3123958e2081..9b7df8e85ea2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>  	return max_link_clock * max_lanes;
>  }
>  
> -static int
> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> +static int source_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;
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	int max_dotclk = dev_priv->max_dotclk_freq;
> -	int ds_max_dotclk;
> +	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> +
> +	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))

Should the edp check actually be check for the edp transcoder
(ie. port A) on icl?

> +		return 2 * i915->max_dotclk_freq;
> +
> +	return i915->max_dotclk_freq;
> +}
>  
> +static int downstream_max_dotclock(struct intel_dp *intel_dp)
> +{
>  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
>  
>  	if (type != DP_DS_PORT_TYPE_VGA)
> -		return max_dotclk;
> +		return 0;
>  
> -	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
> -						    intel_dp->downstream_ports);
> +	return drm_dp_downstream_max_clock(intel_dp->dpcd,
> +					   intel_dp->downstream_ports);
> +}
> +
> +static int
> +intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> +{
> +	int max_dotclk = source_max_dotclock(intel_dp, allow_bigjoiner);
> +	int ds_max_dotclk = downstream_max_dotclock(intel_dp);
>  
>  	if (ds_max_dotclk != 0)
> -		max_dotclk = min(max_dotclk, ds_max_dotclk);
> +		return min(max_dotclk, ds_max_dotclk);
>  
>  	return max_dotclk;
>  }
> @@ -506,7 +518,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
>  
>  static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  				       u32 link_clock, u32 lane_count,
> -				       u32 mode_clock, u32 mode_hdisplay)
> +				       u32 mode_clock, u32 mode_hdisplay,
> +				       bool bigjoiner)
>  {
>  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
>  	int i;
> @@ -524,6 +537,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
>  	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
>  		mode_hdisplay;
> +
> +	if (bigjoiner)
> +		max_bpp_small_joiner_ram *= 2;
> +
>  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
>  
>  	/*
> @@ -532,6 +549,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  	 */
>  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
>  
> +	if (bigjoiner) {
> +		u32 max_bpp_bigjoiner =
> +			i915->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",
> @@ -554,7 +580,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>  }
>  
>  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;
> @@ -579,12 +606,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 ?

The test_ prefix is throwing me off. Just slice_count?

> +			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)

slice_count > min_slice_count? Would feel a bit more naturalto me.

> +			return test_slice_count;
>  	}
>  
>  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
> @@ -623,11 +658,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_max_dotclock(intel_dp, false);
>  
>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>  		if (mode->hdisplay > fixed_mode->hdisplay)
> @@ -639,6 +678,21 @@ 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) {
> +		if (intel_dp_is_edp(intel_dp))
> +			return MODE_CLOCK_HIGH;
> +
> +		max_dotclk = intel_dp_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);
>  
> @@ -666,23 +720,28 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  							    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");

I don't think we spew debugs from mode_valid() elsewhere.

>  		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) {

Not a huge fan of this dsc boolean. Would feel more natural if the dsc
thing would compute a new mode_rate with max achievable compression,
or something along those lines. But this could be cleaned up later.

> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> +		return MODE_CLOCK_HIGH;
> +	}
>  
>  	return intel_mode_valid_max_plane_size(dev_priv, mode);
>  }
> @@ -2104,11 +2163,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>  						    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.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3.
@ 2019-11-28 19:24     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:24 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:16PM +0100, 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.
> 
> Changes since v1:
> - Rename pipe timings to transcoder timings, as they are now different.
> Changes since v2:
> - Rework bigjoiner checks; always disable slave when recalculating
>   master. No need to have a separate bigjoiner pass any more.
> - Use pipe_mode instead of transcoder_mode, to clean up the code.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
>  drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 198 ++++++++++++++++--
>  .../drm/i915/display/intel_display_types.h    |   9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
>  5 files changed, 207 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index fd0026fc3618..b5c17d8c0208 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -229,14 +229,15 @@ 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)
>  {
>  	drm_property_replace_blob(&crtc_state->hw.degamma_lut,
> -				  crtc_state->uapi.degamma_lut);
> +				  from_crtc_state->uapi.degamma_lut);
>  	drm_property_replace_blob(&crtc_state->hw.gamma_lut,
> -				  crtc_state->uapi.gamma_lut);
> +				  from_crtc_state->uapi.gamma_lut);
>  	drm_property_replace_blob(&crtc_state->hw.ctm,
> -				  crtc_state->uapi.ctm);
> +				  from_crtc_state->uapi.ctm);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> index 7b49623419ba..e64473227285 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -37,7 +37,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 7a6da85823af..2dc63ef5caf8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7576,9 +7576,25 @@ 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 *pipe_mode = &pipe_config->hw.pipe_mode;
> +	struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
>  	int clock_limit = dev_priv->max_dotclk_freq;
>  
> +	*pipe_mode = pipe_config->hw.adjusted_mode;
> +
> +	/* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
> +	if (pipe_config->bigjoiner) {
> +		pipe_mode->crtc_clock /= 2;
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_hskew /= 2;
> +
> +		pipe_config->pipe_src_w /= 2;
> +	}
> +
>  	if (INTEL_GEN(dev_priv) < 4) {
>  		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
>  
> @@ -7635,7 +7651,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
>  	 */
>  	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
> -		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
> +	    pipe_config->hw.adjusted_mode.crtc_hsync_start == pipe_mode->crtc_hdisplay)

A bit inconsistent now.

>  		return -EINVAL;
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -11921,7 +11937,7 @@ static bool encoders_cloneable(const struct intel_encoder *a,
>  			  b->cloneable & (1 << a->type));
>  }
>  
> -static bool check_single_encoder_cloning(struct drm_atomic_state *state,
> +static bool check_single_encoder_cloning(struct intel_atomic_state *state,
>  					 struct intel_crtc *crtc,
>  					 struct intel_encoder *encoder)
>  {
> @@ -11930,7 +11946,7 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>  	struct drm_connector_state *connector_state;
>  	int i;
>  
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != &crtc->base)
>  			continue;
>  
> @@ -12167,6 +12183,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
>  
>  	if (mode_changed && crtc_state->hw.enable &&
>  	    dev_priv->display.crtc_compute_clock &&
> +	    !crtc_state->bigjoiner_slave &&

Why do we need this? Wouldn't we just end up sharing the same DPLL
for both pipes anyway?

>  	    !WARN_ON(crtc_state->shared_dpll)) {
>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>  		if (ret)
> @@ -12627,18 +12644,31 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>  }
>  
>  static void
> -intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_crtc_state *crtc_state)
> +intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
> +					   struct intel_crtc_state *crtc_state)
>  {
> -	intel_crtc_copy_color_blobs(crtc_state);
> +	const struct intel_crtc_state *from_crtc_state = crtc_state;
> +
> +	if (crtc_state->bigjoiner_slave) {
> +		from_crtc_state = intel_atomic_get_new_crtc_state(state,
> +					crtc_state->bigjoiner_linked_crtc);
> +
> +		/* No need to copy state if the master state is unchanged */
> +		if (!from_crtc_state)
> +			return;
> +	}
> +
> +	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state);
>  }
>  
>  static void
> -intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> +intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
> -	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
> +	intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
>  }
>  
>  static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> @@ -12660,7 +12690,49 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
>  }
>  
>  static int
> -intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
> +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.pipe_mode = from_crtc_state->hw.pipe_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
> +intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
> +				 struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv =
>  		to_i915(crtc_state->uapi.crtc->dev);
> @@ -12703,16 +12775,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	crtc_state->uapi.mode.private_flags = 0;
>  	crtc_state->uapi.adjusted_mode.private_flags = 0;
>  
> -	intel_crtc_copy_uapi_to_hw_state(crtc_state);
> +	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
>  
>  	return 0;
>  }
>  
>  static int
> -intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> +intel_modeset_pipe_config(struct intel_atomic_state *state,
> +			  struct intel_crtc_state *pipe_config)
>  {
>  	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;
> @@ -12755,7 +12827,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != crtc)
>  			continue;
>  
> @@ -12800,7 +12872,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * adjust it according to limitations or connector properties, and also
>  	 * a chance to reject the mode entirely.
>  	 */
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != crtc)
>  			continue;
>  
> @@ -12853,8 +12925,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> -	/* without bigjoiner, pipe_mode == adjusted_mode */
> -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>  	return 0;
>  }
>  
> @@ -14091,6 +14161,74 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
>  	return 0;
>  }
>  
> +static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
> +					struct intel_crtc *crtc,
> +					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);
> +	struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
> +	struct intel_crtc *slave, *master;
> +
> +	/* slave being enabled, is master is still claiming this crtc? */
> +	if (old_crtc_state->bigjoiner_slave) {
> +		slave = crtc;
> +		master = old_crtc_state->bigjoiner_linked_crtc;
> +		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
> +		if (!master_crtc_state || !needs_modeset(master_crtc_state))
> +			goto claimed;
> +	}
> +
> +	if (!new_crtc_state->bigjoiner)
> +		return 0;
> +
> +	if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
> +		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
> +			      "CRTC + 1 to be used, doesn't exist\n",
> +			      crtc->base.base.id, crtc->base.name);
> +		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);
> +	master = crtc;
> +	if (IS_ERR(slave_crtc_state))
> +		return PTR_ERR(slave_crtc_state);
> +
> +	/* master being enabled, slave was already configured? */
> +	if (slave_crtc_state->uapi.enable)
> +		goto claimed;
> +
> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
> +		      slave->base.base.id, slave->base.name);
> +	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
> +
> +claimed:
> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
> +		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
> +		      slave->base.base.id, slave->base.name,
> +		      master->base.base.id, master->base.name);
> +	return -EINVAL;
> +}
> +
> +static int kill_bigjoiner_slave(struct intel_atomic_state *state,
> +				struct intel_crtc_state *master_crtc_state)
> +{
> +	struct intel_crtc_state *slave_crtc_state =
> +		intel_atomic_get_crtc_state(&state->base,
> +			master_crtc_state->bigjoiner_linked_crtc);

nit: I'd do this as

struct foo *bar;

bar = whatever();
if (IS_ERR)
	...

to make it stand out more since that function has some real
side effects.

> +
> +	if (IS_ERR(slave_crtc_state))
> +		return PTR_ERR(slave_crtc_state);
> +
> +	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
> +	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
> +	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
> +	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
> +	return 0;
> +}
> +
>  /**
>   * intel_atomic_check - validate state object
>   * @dev: drm device
> @@ -14122,23 +14260,31 @@ static int intel_atomic_check(struct drm_device *dev,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state)) {
>  			/* Light copy */
> -			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
> +			intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
>  
>  			continue;
>  		}
>  
> -		if (!new_crtc_state->uapi.enable) {
> -			intel_crtc_copy_uapi_to_hw_state(new_crtc_state);
> +		/* Kill old bigjoiner link, we may re-establish afterwards */
> +		if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) {
> +			ret = kill_bigjoiner_slave(state, new_crtc_state);
> +			if (ret)
> +				goto fail;
> +		}
>  
> -			any_ms = true;
> +		if (!new_crtc_state->uapi.enable) {
> +			if (!new_crtc_state->bigjoiner_slave) {
> +				intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
> +				any_ms = true;
> +			}
>  			continue;
>  		}

How does this handle the case where the slave uapi.enable gets
enabled but the master is not part of the state yet?

>  
> -		ret = intel_crtc_prepare_cleared_state(new_crtc_state);
> +		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
>  		if (ret)
>  			goto fail;
>  
> -		ret = intel_modeset_pipe_config(new_crtc_state);
> +		ret = intel_modeset_pipe_config(state, new_crtc_state);
>  		if (ret)
>  			goto fail;
>  
> @@ -14146,6 +14292,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  
>  		if (needs_modeset(new_crtc_state))
>  			any_ms = true;
> +
> +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state, new_crtc_state);
> +		if (ret)
> +			goto fail;
>  	}
>  
>  	if (any_ms && !check_digital_port_conflicts(state)) {
> @@ -14350,7 +14500,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);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 7f46c1646d3f..cf2ecfa17416 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1044,6 +1044,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 9b7df8e85ea2..54fde4c4c4dd 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2147,6 +2147,15 @@ 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_max_dotclock(intel_dp, false)) {
> +		if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, true)) {
> +			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
> +			return -EINVAL;
> +		}
> +		pipe_config->bigjoiner = true;
> +		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
> +	}
> +
>  	if (intel_dp_is_edp(intel_dp)) {
>  		pipe_config->dsc.compressed_bpp =
>  			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
> @@ -2164,12 +2173,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;
> @@ -2184,13 +2193,14 @@ 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.slice_count > 1) {
> -			pipe_config->dsc.dsc_split = true;
> -		} else {
> +	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
> +	    pipe_config->bigjoiner) {
> +		if (pipe_config->dsc.slice_count < 2) {
>  			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
>  			return -EINVAL;
>  		}
> +
> +		pipe_config->dsc.dsc_split = true;
>  	}
>  
>  	ret = intel_dsc_compute_params(&dig_port->base, pipe_config);
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3.
@ 2019-11-28 19:24     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:24 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:16PM +0100, 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.
> 
> Changes since v1:
> - Rename pipe timings to transcoder timings, as they are now different.
> Changes since v2:
> - Rework bigjoiner checks; always disable slave when recalculating
>   master. No need to have a separate bigjoiner pass any more.
> - Use pipe_mode instead of transcoder_mode, to clean up the code.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
>  drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 198 ++++++++++++++++--
>  .../drm/i915/display/intel_display_types.h    |   9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
>  5 files changed, 207 insertions(+), 34 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index fd0026fc3618..b5c17d8c0208 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -229,14 +229,15 @@ 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)
>  {
>  	drm_property_replace_blob(&crtc_state->hw.degamma_lut,
> -				  crtc_state->uapi.degamma_lut);
> +				  from_crtc_state->uapi.degamma_lut);
>  	drm_property_replace_blob(&crtc_state->hw.gamma_lut,
> -				  crtc_state->uapi.gamma_lut);
> +				  from_crtc_state->uapi.gamma_lut);
>  	drm_property_replace_blob(&crtc_state->hw.ctm,
> -				  crtc_state->uapi.ctm);
> +				  from_crtc_state->uapi.ctm);
>  }
>  
>  /**
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
> index 7b49623419ba..e64473227285 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -37,7 +37,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 7a6da85823af..2dc63ef5caf8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7576,9 +7576,25 @@ 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 *pipe_mode = &pipe_config->hw.pipe_mode;
> +	struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
>  	int clock_limit = dev_priv->max_dotclk_freq;
>  
> +	*pipe_mode = pipe_config->hw.adjusted_mode;
> +
> +	/* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
> +	if (pipe_config->bigjoiner) {
> +		pipe_mode->crtc_clock /= 2;
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_hskew /= 2;
> +
> +		pipe_config->pipe_src_w /= 2;
> +	}
> +
>  	if (INTEL_GEN(dev_priv) < 4) {
>  		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
>  
> @@ -7635,7 +7651,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>  	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
>  	 */
>  	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
> -		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
> +	    pipe_config->hw.adjusted_mode.crtc_hsync_start == pipe_mode->crtc_hdisplay)

A bit inconsistent now.

>  		return -EINVAL;
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -11921,7 +11937,7 @@ static bool encoders_cloneable(const struct intel_encoder *a,
>  			  b->cloneable & (1 << a->type));
>  }
>  
> -static bool check_single_encoder_cloning(struct drm_atomic_state *state,
> +static bool check_single_encoder_cloning(struct intel_atomic_state *state,
>  					 struct intel_crtc *crtc,
>  					 struct intel_encoder *encoder)
>  {
> @@ -11930,7 +11946,7 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>  	struct drm_connector_state *connector_state;
>  	int i;
>  
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != &crtc->base)
>  			continue;
>  
> @@ -12167,6 +12183,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
>  
>  	if (mode_changed && crtc_state->hw.enable &&
>  	    dev_priv->display.crtc_compute_clock &&
> +	    !crtc_state->bigjoiner_slave &&

Why do we need this? Wouldn't we just end up sharing the same DPLL
for both pipes anyway?

>  	    !WARN_ON(crtc_state->shared_dpll)) {
>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>  		if (ret)
> @@ -12627,18 +12644,31 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>  }
>  
>  static void
> -intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_crtc_state *crtc_state)
> +intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
> +					   struct intel_crtc_state *crtc_state)
>  {
> -	intel_crtc_copy_color_blobs(crtc_state);
> +	const struct intel_crtc_state *from_crtc_state = crtc_state;
> +
> +	if (crtc_state->bigjoiner_slave) {
> +		from_crtc_state = intel_atomic_get_new_crtc_state(state,
> +					crtc_state->bigjoiner_linked_crtc);
> +
> +		/* No need to copy state if the master state is unchanged */
> +		if (!from_crtc_state)
> +			return;
> +	}
> +
> +	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state);
>  }
>  
>  static void
> -intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
> +intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
> -	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
> +	intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
>  }
>  
>  static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> @@ -12660,7 +12690,49 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
>  }
>  
>  static int
> -intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
> +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.pipe_mode = from_crtc_state->hw.pipe_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
> +intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
> +				 struct intel_crtc_state *crtc_state)
>  {
>  	struct drm_i915_private *dev_priv =
>  		to_i915(crtc_state->uapi.crtc->dev);
> @@ -12703,16 +12775,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>  	crtc_state->uapi.mode.private_flags = 0;
>  	crtc_state->uapi.adjusted_mode.private_flags = 0;
>  
> -	intel_crtc_copy_uapi_to_hw_state(crtc_state);
> +	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
>  
>  	return 0;
>  }
>  
>  static int
> -intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> +intel_modeset_pipe_config(struct intel_atomic_state *state,
> +			  struct intel_crtc_state *pipe_config)
>  {
>  	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;
> @@ -12755,7 +12827,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != crtc)
>  			continue;
>  
> @@ -12800,7 +12872,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * adjust it according to limitations or connector properties, and also
>  	 * a chance to reject the mode entirely.
>  	 */
> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>  		if (connector_state->crtc != crtc)
>  			continue;
>  
> @@ -12853,8 +12925,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 */
>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>  
> -	/* without bigjoiner, pipe_mode == adjusted_mode */
> -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>  	return 0;
>  }
>  
> @@ -14091,6 +14161,74 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
>  	return 0;
>  }
>  
> +static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
> +					struct intel_crtc *crtc,
> +					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);
> +	struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
> +	struct intel_crtc *slave, *master;
> +
> +	/* slave being enabled, is master is still claiming this crtc? */
> +	if (old_crtc_state->bigjoiner_slave) {
> +		slave = crtc;
> +		master = old_crtc_state->bigjoiner_linked_crtc;
> +		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
> +		if (!master_crtc_state || !needs_modeset(master_crtc_state))
> +			goto claimed;
> +	}
> +
> +	if (!new_crtc_state->bigjoiner)
> +		return 0;
> +
> +	if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
> +		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
> +			      "CRTC + 1 to be used, doesn't exist\n",
> +			      crtc->base.base.id, crtc->base.name);
> +		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);
> +	master = crtc;
> +	if (IS_ERR(slave_crtc_state))
> +		return PTR_ERR(slave_crtc_state);
> +
> +	/* master being enabled, slave was already configured? */
> +	if (slave_crtc_state->uapi.enable)
> +		goto claimed;
> +
> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
> +		      slave->base.base.id, slave->base.name);
> +	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
> +
> +claimed:
> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
> +		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
> +		      slave->base.base.id, slave->base.name,
> +		      master->base.base.id, master->base.name);
> +	return -EINVAL;
> +}
> +
> +static int kill_bigjoiner_slave(struct intel_atomic_state *state,
> +				struct intel_crtc_state *master_crtc_state)
> +{
> +	struct intel_crtc_state *slave_crtc_state =
> +		intel_atomic_get_crtc_state(&state->base,
> +			master_crtc_state->bigjoiner_linked_crtc);

nit: I'd do this as

struct foo *bar;

bar = whatever();
if (IS_ERR)
	...

to make it stand out more since that function has some real
side effects.

> +
> +	if (IS_ERR(slave_crtc_state))
> +		return PTR_ERR(slave_crtc_state);
> +
> +	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
> +	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
> +	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
> +	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
> +	return 0;
> +}
> +
>  /**
>   * intel_atomic_check - validate state object
>   * @dev: drm device
> @@ -14122,23 +14260,31 @@ static int intel_atomic_check(struct drm_device *dev,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state)) {
>  			/* Light copy */
> -			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
> +			intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
>  
>  			continue;
>  		}
>  
> -		if (!new_crtc_state->uapi.enable) {
> -			intel_crtc_copy_uapi_to_hw_state(new_crtc_state);
> +		/* Kill old bigjoiner link, we may re-establish afterwards */
> +		if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) {
> +			ret = kill_bigjoiner_slave(state, new_crtc_state);
> +			if (ret)
> +				goto fail;
> +		}
>  
> -			any_ms = true;
> +		if (!new_crtc_state->uapi.enable) {
> +			if (!new_crtc_state->bigjoiner_slave) {
> +				intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
> +				any_ms = true;
> +			}
>  			continue;
>  		}

How does this handle the case where the slave uapi.enable gets
enabled but the master is not part of the state yet?

>  
> -		ret = intel_crtc_prepare_cleared_state(new_crtc_state);
> +		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
>  		if (ret)
>  			goto fail;
>  
> -		ret = intel_modeset_pipe_config(new_crtc_state);
> +		ret = intel_modeset_pipe_config(state, new_crtc_state);
>  		if (ret)
>  			goto fail;
>  
> @@ -14146,6 +14292,10 @@ static int intel_atomic_check(struct drm_device *dev,
>  
>  		if (needs_modeset(new_crtc_state))
>  			any_ms = true;
> +
> +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state, new_crtc_state);
> +		if (ret)
> +			goto fail;
>  	}
>  
>  	if (any_ms && !check_digital_port_conflicts(state)) {
> @@ -14350,7 +14500,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);
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 7f46c1646d3f..cf2ecfa17416 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1044,6 +1044,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 9b7df8e85ea2..54fde4c4c4dd 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2147,6 +2147,15 @@ 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_max_dotclock(intel_dp, false)) {
> +		if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, true)) {
> +			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
> +			return -EINVAL;
> +		}
> +		pipe_config->bigjoiner = true;
> +		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
> +	}
> +
>  	if (intel_dp_is_edp(intel_dp)) {
>  		pipe_config->dsc.compressed_bpp =
>  			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
> @@ -2164,12 +2173,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;
> @@ -2184,13 +2193,14 @@ 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.slice_count > 1) {
> -			pipe_config->dsc.dsc_split = true;
> -		} else {
> +	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
> +	    pipe_config->bigjoiner) {
> +		if (pipe_config->dsc.slice_count < 2) {
>  			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
>  			return -EINVAL;
>  		}
> +
> +		pipe_config->dsc.dsc_split = true;
>  	}
>  
>  	ret = intel_dsc_compute_params(&dig_port->base, pipe_config);
> -- 
> 2.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
@ 2019-11-28 19:43     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:17PM +0100, 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 still 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.
> This is done correctly later in this series.
> 
> The next steps are to enable planes correctly, 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      |  48 ++-
>  drivers/gpu/drm/i915/display/intel_display.c  | 399 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |  22 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
>  6 files changed, 408 insertions(+), 206 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 8f817de34460..1215f619da36 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2218,13 +2218,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.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)
> @@ -3557,7 +3550,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	/* 7.l Configure and enable FEC if needed */
>  	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,
> @@ -3629,7 +3623,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,
> @@ -4252,19 +4247,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
> @@ -4350,6 +4344,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;

That's pretty horrible.

I don't understand the enable/disable sequence enough to know what
we need to configure/enable where exactly. Bspec just says:

"2. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe C, but
    do not configure or enable transcoder C.
 3. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe B and
    transcoder B."

So we need to enable transcoder for pipe C but not enable transcoder C?
I have no idea what actually means.

> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> +		pipe_config->cpu_transcoder = save;
> +	}
>  
>  	if (encoder->type == INTEL_OUTPUT_EDP)
>  		tgl_dc3co_exitline_get_config(pipe_config);
> @@ -4377,7 +4394,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 2dc63ef5caf8..94e4cab00a66 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6583,6 +6583,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)
>  {
> @@ -6596,40 +6635,41 @@ 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_transcoder_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);
>  
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		icl_enable_trans_port_sync(pipe_config);
> +		if (INTEL_GEN(dev_priv) >= 11)
> +			icl_enable_trans_port_sync(pipe_config);
>  
> -	intel_set_pipe_src_size(pipe_config);
> +		intel_set_transcoder_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;
>  
> @@ -6657,7 +6697,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (INTEL_GEN(dev_priv) >= 11)
>  		icl_set_pipe_chicken(intel_crtc);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
>  		intel_ddi_enable_transcoder_func(pipe_config);
>  
>  	if (dev_priv->display.initial_watermarks != NULL)
> @@ -6667,8 +6707,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);
> @@ -6796,9 +6838,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)
> @@ -6968,6 +7028,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.compression_enable)
> +		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
> +
>  	return mask;
>  }
>  
> @@ -7559,6 +7622,30 @@ 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)
> +{
> +	struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
> +
> +	encoder->get_config(encoder, crtc_state);
> +
> +	*pipe_mode = crtc_state->hw.adjusted_mode;
> +	if (crtc_state->bigjoiner) {
> +		/*
> +		  * transcoder is programmed to the full mode,
> +		  * but pipje timings are half of the transcoder mode
> +		  */
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_hskew /= 2;
> +		pipe_mode->crtc_clock /= 2;
> +	}
> +}
> +
>  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);
> @@ -8461,20 +8548,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.adjusted_mode;
> +
> +	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->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->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 = pipe_config->hw.adjusted_mode.flags;
> +	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);
> @@ -10564,6 +10653,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);
> @@ -10689,11 +10780,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;
>  
> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> +		active = true;
> +		pipe_config->pixel_multiplier = 1;
> +
> +		/* 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_transcoder_timings(crtc, pipe_config);
> @@ -10770,7 +10869,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;
> @@ -11748,7 +11850,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);
>  
> @@ -12674,10 +12776,11 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *state,
>  static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
>  					     struct drm_display_mode *user_mode)
>  {
> -	crtc_state->uapi.enable = crtc_state->hw.enable;
> -	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> -
> +	if (!crtc_state->bigjoiner_slave) {
> +		crtc_state->uapi.enable = crtc_state->hw.enable;
> +		crtc_state->uapi.active = crtc_state->hw.active;
> +		WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> +	}
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
>  	/* copy color blobs to uapi */
> @@ -13258,21 +13361,43 @@ 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);
> -
> -	PIPE_CONF_CHECK_I(pixel_multiplier);
> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
> +		/* bigjoiner mode = transcoder mode / 2, for calculations */
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal);
> +
> +		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);
> +
> +		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_I(pixel_multiplier);
> +	}
> +
>  	PIPE_CONF_CHECK_I(output_format);
>  	PIPE_CONF_CHECK_I(dc3co_exitline);
>  	PIPE_CONF_CHECK_BOOL(has_hdmi_sink);
> @@ -13283,24 +13408,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)
> @@ -13324,7 +13436,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))
> @@ -13343,48 +13456,51 @@ 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(hw.pipe_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);
> @@ -13395,6 +13511,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_I(sync_mode_slaves_mask);
>  	PIPE_CONF_CHECK_I(master_transcoder);
> +	PIPE_CONF_CHECK_BOOL(bigjoiner);
> +	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
> +	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
> +	PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
> +	PIPE_CONF_CHECK_BOOL(dsc.dsc_split);
>  
>  #undef PIPE_CONF_CHECK_X
>  #undef PIPE_CONF_CHECK_I
> @@ -13650,6 +13771,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;
> @@ -13679,7 +13801,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);
> @@ -13688,12 +13813,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);
> @@ -14473,7 +14598,6 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  
>  	if (modeset) {
>  		intel_crtc_update_active_timings(new_crtc_state);
> -
>  		dev_priv->display.crtc_enable(new_crtc_state, state);
>  
>  		/* vblanks work again, re-enable pipe CRC. */
> @@ -14613,7 +14737,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;
>  
>  		/* In case of Transcoder port Sync master slave CRTCs can be
> @@ -14637,6 +14761,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);
> +			}
>  		}
>  	}
>  }
> @@ -17168,7 +17305,7 @@ int intel_modeset_init(struct drm_i915_private *i915)
>  	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;
>  
>  		/*
> @@ -17624,7 +17761,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 cf2ecfa17416..86a0524b3cd8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -821,6 +821,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 */
> @@ -1639,4 +1640,25 @@ 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);
> +
> +	if (!INTEL_INFO(dev_priv)->display.has_dsc)
> +		return false;
> +
> +	/* On TGL, DSC is supported on all Pipes */
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		return true;
> +
> +	/* gen10 and gen11 have DSC, but not on pipe A, eDP is allowed */
> +	if (INTEL_GEN(dev_priv) >= 10 &&
> +	    (to_intel_crtc(pipe_config->uapi.crtc)->pipe != PIPE_A ||
> +	     pipe_config->cpu_transcoder == TRANSCODER_EDP))
> +		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 54fde4c4c4dd..d0b6276f7712 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1948,32 +1948,13 @@ 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);
> -
> -	if (!INTEL_INFO(dev_priv)->display.has_dsc)
> -		return false;
> -
> -	/* 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)
>  {
>  	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
>  		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 b23ba8d108db..e48608221e71 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -501,11 +501,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
>  }
>  
> -static void intel_dsc_pps_configure(struct intel_encoder *encoder,
> -				    const struct intel_crtc_state *crtc_state)
> +static void intel_dsc_pps_configure(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->dsc.config;
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> @@ -515,6 +514,9 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
>  	u8 num_vdsc_instances = (crtc_state->dsc.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 |
> @@ -920,74 +922,104 @@ static void intel_dsc_dp_pps_write(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.compression_enable)
>  		return;
>  
> -	/* Enable Power wells for VDSC/joining */
> -	intel_display_power_get(dev_priv,
> -				intel_dsc_power_domain(crtc_state));
> +	intel_dsc_pps_configure(crtc_state);
>  
> -	intel_dsc_pps_configure(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner_slave)
> +		intel_dsc_dp_pps_write(encoder, crtc_state);
>  
> -	intel_dsc_dp_pps_write(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.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.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.compression_enable = true;
> +
> +	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
> +		crtc_state->dsc.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 4ed2256750c3..79d965fedf0b 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -14,6 +14,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
>  int intel_dsc_compute_params(struct intel_encoder *encoder,
>  			     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.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
@ 2019-11-28 19:43     ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-11-28 19:43 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:17PM +0100, 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 still 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.
> This is done correctly later in this series.
> 
> The next steps are to enable planes correctly, 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      |  48 ++-
>  drivers/gpu/drm/i915/display/intel_display.c  | 399 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |  22 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
>  6 files changed, 408 insertions(+), 206 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 8f817de34460..1215f619da36 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2218,13 +2218,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.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)
> @@ -3557,7 +3550,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
>  
>  	/* 7.l Configure and enable FEC if needed */
>  	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,
> @@ -3629,7 +3623,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,
> @@ -4252,19 +4247,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
> @@ -4350,6 +4344,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;

That's pretty horrible.

I don't understand the enable/disable sequence enough to know what
we need to configure/enable where exactly. Bspec just says:

"2. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe C, but
    do not configure or enable transcoder C.
 3. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe B and
    transcoder B."

So we need to enable transcoder for pipe C but not enable transcoder C?
I have no idea what actually means.

> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> +		pipe_config->cpu_transcoder = save;
> +	}
>  
>  	if (encoder->type == INTEL_OUTPUT_EDP)
>  		tgl_dc3co_exitline_get_config(pipe_config);
> @@ -4377,7 +4394,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 2dc63ef5caf8..94e4cab00a66 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6583,6 +6583,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)
>  {
> @@ -6596,40 +6635,41 @@ 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_transcoder_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);
>  
> -	if (INTEL_GEN(dev_priv) >= 11)
> -		icl_enable_trans_port_sync(pipe_config);
> +		if (INTEL_GEN(dev_priv) >= 11)
> +			icl_enable_trans_port_sync(pipe_config);
>  
> -	intel_set_pipe_src_size(pipe_config);
> +		intel_set_transcoder_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;
>  
> @@ -6657,7 +6697,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
>  	if (INTEL_GEN(dev_priv) >= 11)
>  		icl_set_pipe_chicken(intel_crtc);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
> +	if (!pipe_config->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder))
>  		intel_ddi_enable_transcoder_func(pipe_config);
>  
>  	if (dev_priv->display.initial_watermarks != NULL)
> @@ -6667,8 +6707,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);
> @@ -6796,9 +6838,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)
> @@ -6968,6 +7028,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.compression_enable)
> +		mask |= BIT_ULL(intel_dsc_power_domain(crtc_state));
> +
>  	return mask;
>  }
>  
> @@ -7559,6 +7622,30 @@ 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)
> +{
> +	struct drm_display_mode *pipe_mode = &crtc_state->hw.pipe_mode;
> +
> +	encoder->get_config(encoder, crtc_state);
> +
> +	*pipe_mode = crtc_state->hw.adjusted_mode;
> +	if (crtc_state->bigjoiner) {
> +		/*
> +		  * transcoder is programmed to the full mode,
> +		  * but pipje timings are half of the transcoder mode
> +		  */
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_hskew /= 2;
> +		pipe_mode->crtc_clock /= 2;
> +	}
> +}
> +
>  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);
> @@ -8461,20 +8548,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.adjusted_mode;
> +
> +	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->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->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 = pipe_config->hw.adjusted_mode.flags;
> +	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);
> @@ -10564,6 +10653,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);
> @@ -10689,11 +10780,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;
>  
> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> +		active = true;
> +		pipe_config->pixel_multiplier = 1;
> +
> +		/* 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_transcoder_timings(crtc, pipe_config);
> @@ -10770,7 +10869,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;
> @@ -11748,7 +11850,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);
>  
> @@ -12674,10 +12776,11 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *state,
>  static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
>  					     struct drm_display_mode *user_mode)
>  {
> -	crtc_state->uapi.enable = crtc_state->hw.enable;
> -	crtc_state->uapi.active = crtc_state->hw.active;
> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> -
> +	if (!crtc_state->bigjoiner_slave) {
> +		crtc_state->uapi.enable = crtc_state->hw.enable;
> +		crtc_state->uapi.active = crtc_state->hw.active;
> +		WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> +	}
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
>  	/* copy color blobs to uapi */
> @@ -13258,21 +13361,43 @@ 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);
> -
> -	PIPE_CONF_CHECK_I(pixel_multiplier);
> +	if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_BIGJOINER_SLAVE)) {
> +		/* bigjoiner mode = transcoder mode / 2, for calculations */
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_hdisplay);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_htotal);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vdisplay);
> +		PIPE_CONF_CHECK_I(hw.pipe_mode.crtc_vtotal);
> +
> +		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);
> +
> +		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_I(pixel_multiplier);
> +	}
> +
>  	PIPE_CONF_CHECK_I(output_format);
>  	PIPE_CONF_CHECK_I(dc3co_exitline);
>  	PIPE_CONF_CHECK_BOOL(has_hdmi_sink);
> @@ -13283,24 +13408,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)
> @@ -13324,7 +13436,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))
> @@ -13343,48 +13456,51 @@ 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(hw.pipe_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);
> @@ -13395,6 +13511,11 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_I(sync_mode_slaves_mask);
>  	PIPE_CONF_CHECK_I(master_transcoder);
> +	PIPE_CONF_CHECK_BOOL(bigjoiner);
> +	PIPE_CONF_CHECK_BOOL(bigjoiner_slave);
> +	PIPE_CONF_CHECK_P(bigjoiner_linked_crtc);
> +	PIPE_CONF_CHECK_BOOL(dsc.compression_enable);
> +	PIPE_CONF_CHECK_BOOL(dsc.dsc_split);
>  
>  #undef PIPE_CONF_CHECK_X
>  #undef PIPE_CONF_CHECK_I
> @@ -13650,6 +13771,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;
> @@ -13679,7 +13801,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);
> @@ -13688,12 +13813,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);
> @@ -14473,7 +14598,6 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>  
>  	if (modeset) {
>  		intel_crtc_update_active_timings(new_crtc_state);
> -
>  		dev_priv->display.crtc_enable(new_crtc_state, state);
>  
>  		/* vblanks work again, re-enable pipe CRC. */
> @@ -14613,7 +14737,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;
>  
>  		/* In case of Transcoder port Sync master slave CRTCs can be
> @@ -14637,6 +14761,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);
> +			}
>  		}
>  	}
>  }
> @@ -17168,7 +17305,7 @@ int intel_modeset_init(struct drm_i915_private *i915)
>  	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;
>  
>  		/*
> @@ -17624,7 +17761,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 cf2ecfa17416..86a0524b3cd8 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -821,6 +821,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 */
> @@ -1639,4 +1640,25 @@ 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);
> +
> +	if (!INTEL_INFO(dev_priv)->display.has_dsc)
> +		return false;
> +
> +	/* On TGL, DSC is supported on all Pipes */
> +	if (INTEL_GEN(dev_priv) >= 12)
> +		return true;
> +
> +	/* gen10 and gen11 have DSC, but not on pipe A, eDP is allowed */
> +	if (INTEL_GEN(dev_priv) >= 10 &&
> +	    (to_intel_crtc(pipe_config->uapi.crtc)->pipe != PIPE_A ||
> +	     pipe_config->cpu_transcoder == TRANSCODER_EDP))
> +		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 54fde4c4c4dd..d0b6276f7712 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1948,32 +1948,13 @@ 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);
> -
> -	if (!INTEL_INFO(dev_priv)->display.has_dsc)
> -		return false;
> -
> -	/* 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)
>  {
>  	if (!intel_dp_is_edp(intel_dp) && !pipe_config->fec_enable)
>  		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 b23ba8d108db..e48608221e71 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -501,11 +501,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
>  }
>  
> -static void intel_dsc_pps_configure(struct intel_encoder *encoder,
> -				    const struct intel_crtc_state *crtc_state)
> +static void intel_dsc_pps_configure(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->dsc.config;
>  	enum pipe pipe = crtc->pipe;
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> @@ -515,6 +514,9 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
>  	u8 num_vdsc_instances = (crtc_state->dsc.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 |
> @@ -920,74 +922,104 @@ static void intel_dsc_dp_pps_write(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.compression_enable)
>  		return;
>  
> -	/* Enable Power wells for VDSC/joining */
> -	intel_display_power_get(dev_priv,
> -				intel_dsc_power_domain(crtc_state));
> +	intel_dsc_pps_configure(crtc_state);
>  
> -	intel_dsc_pps_configure(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner_slave)
> +		intel_dsc_dp_pps_write(encoder, crtc_state);
>  
> -	intel_dsc_dp_pps_write(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.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.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.compression_enable = true;
> +
> +	if ((dss_ctl1_val & JOINER_ENABLE) && (dss_ctl2_val & RIGHT_BRANCH_VDSC_ENABLE))
> +		crtc_state->dsc.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 4ed2256750c3..79d965fedf0b 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -14,6 +14,8 @@ void intel_dsc_enable(struct intel_encoder *encoder,
>  void intel_dsc_disable(const struct intel_crtc_state *crtc_state);
>  int intel_dsc_compute_params(struct intel_encoder *encoder,
>  			     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.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2019-11-28 19:43     ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2019-12-03  9:05     ` Maarten Lankhorst
  -1 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-12-03  9:05 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 28-11-2019 om 20:43 schreef Ville Syrjälä:
> On Thu, Nov 14, 2019 at 05:05:17PM +0100, 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 still 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.
>> This is done correctly later in this series.
>>
>> The next steps are to enable planes correctly, 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      |  48 ++-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 399 ++++++++++++------
>>  .../drm/i915/display/intel_display_types.h    |  22 +
>>  drivers/gpu/drm/i915/display/intel_dp.c       |  21 +-
>>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 122 ++++--
>>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   2 +
>>  6 files changed, 408 insertions(+), 206 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>> index 8f817de34460..1215f619da36 100644
>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>> @@ -2218,13 +2218,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.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)
>> @@ -3557,7 +3550,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_encoder *encoder,
>>  
>>  	/* 7.l Configure and enable FEC if needed */
>>  	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,
>> @@ -3629,7 +3623,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,
>> @@ -4252,19 +4247,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
>> @@ -4350,6 +4344,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;
> That's pretty horrible.
>
> I don't understand the enable/disable sequence enough to know what
> we need to configure/enable where exactly. Bspec just says:
> "2. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe C, but
>     do not configure or enable transcoder C.
>  3. Follow the steps to Enable Planes, Pipe, and Transcoder for pipe B and
>     transcoder B."
>
> So we need to enable transcoder for pipe C but not enable transcoder C?
> I have no idea what actually means.

Correct, bspec is slightly unclear here.

First we have to bring up the transcoder for pipe B, up to and including enabling FEC.

After this, we enable pipe C. None of the transcoder registers for pipe C are ever
touched. On pipe C, only the PIPE_* registers are touched, after that we set
DSS_CTL1/2 to the correct values for bigjoiner slave mode.

After we set up pipe C, we bring up pipe B, continuing from the step after enabling FEC.

When immplementing this I was getting a consistent FIFO underrun, but that was because
we missed the FEC overhead and it wasn't tested on real hw before. It was fixed in
commit cffb4c3ea372 "drm/i915/dp: Fix dsc bpp calculations, v5."

After fixing that, the FIFO underrun disappeared and presumably it works on real
hardware now, wasn't able to verify on a real DSC monitor. Only on a DSC emulator. :)

~Maarten

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

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

* Re: [Intel-gfx] [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3.
  2019-11-28 19:24     ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2019-12-03  9:13     ` Maarten Lankhorst
  -1 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-12-03  9:13 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 28-11-2019 om 20:24 schreef Ville Syrjälä:
> On Thu, Nov 14, 2019 at 05:05:16PM +0100, 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.
>>
>> Changes since v1:
>> - Rename pipe timings to transcoder timings, as they are now different.
>> Changes since v2:
>> - Rework bigjoiner checks; always disable slave when recalculating
>>   master. No need to have a separate bigjoiner pass any more.
>> - Use pipe_mode instead of transcoder_mode, to clean up the code.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
>>  drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 198 ++++++++++++++++--
>>  .../drm/i915/display/intel_display_types.h    |   9 +
>>  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
>>  5 files changed, 207 insertions(+), 34 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
>> index fd0026fc3618..b5c17d8c0208 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
>> @@ -229,14 +229,15 @@ 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)
>>  {
>>  	drm_property_replace_blob(&crtc_state->hw.degamma_lut,
>> -				  crtc_state->uapi.degamma_lut);
>> +				  from_crtc_state->uapi.degamma_lut);
>>  	drm_property_replace_blob(&crtc_state->hw.gamma_lut,
>> -				  crtc_state->uapi.gamma_lut);
>> +				  from_crtc_state->uapi.gamma_lut);
>>  	drm_property_replace_blob(&crtc_state->hw.ctm,
>> -				  crtc_state->uapi.ctm);
>> +				  from_crtc_state->uapi.ctm);
>>  }
>>  
>>  /**
>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
>> index 7b49623419ba..e64473227285 100644
>> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
>> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
>> @@ -37,7 +37,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 7a6da85823af..2dc63ef5caf8 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -7576,9 +7576,25 @@ 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 *pipe_mode = &pipe_config->hw.pipe_mode;
>> +	struct drm_display_mode *pipe_mode = &pipe_config->hw.pipe_mode;
>>  	int clock_limit = dev_priv->max_dotclk_freq;
>>  
>> +	*pipe_mode = pipe_config->hw.adjusted_mode;
>> +
>> +	/* Adjust pipe_mode for bigjoiner, with half the horizontal mode */
>> +	if (pipe_config->bigjoiner) {
>> +		pipe_mode->crtc_clock /= 2;
>> +		pipe_mode->crtc_hdisplay /= 2;
>> +		pipe_mode->crtc_hblank_start /= 2;
>> +		pipe_mode->crtc_hblank_end /= 2;
>> +		pipe_mode->crtc_hsync_start /= 2;
>> +		pipe_mode->crtc_hsync_end /= 2;
>> +		pipe_mode->crtc_htotal /= 2;
>> +		pipe_mode->crtc_hskew /= 2;
>> +
>> +		pipe_config->pipe_src_w /= 2;
>> +	}
>> +
>>  	if (INTEL_GEN(dev_priv) < 4) {
>>  		clock_limit = dev_priv->max_cdclk_freq * 9 / 10;
>>  
>> @@ -7635,7 +7651,7 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
>>  	 * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
>>  	 */
>>  	if ((INTEL_GEN(dev_priv) > 4 || IS_G4X(dev_priv)) &&
>> -		pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
>> +	    pipe_config->hw.adjusted_mode.crtc_hsync_start == pipe_mode->crtc_hdisplay)
> A bit inconsistent now.
Yeah should probably use adjusted_mode for both.
>>  		return -EINVAL;
>>  
>>  	intel_crtc_compute_pixel_rate(pipe_config);
>> @@ -11921,7 +11937,7 @@ static bool encoders_cloneable(const struct intel_encoder *a,
>>  			  b->cloneable & (1 << a->type));
>>  }
>>  
>> -static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>> +static bool check_single_encoder_cloning(struct intel_atomic_state *state,
>>  					 struct intel_crtc *crtc,
>>  					 struct intel_encoder *encoder)
>>  {
>> @@ -11930,7 +11946,7 @@ static bool check_single_encoder_cloning(struct drm_atomic_state *state,
>>  	struct drm_connector_state *connector_state;
>>  	int i;
>>  
>> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
>> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>>  		if (connector_state->crtc != &crtc->base)
>>  			continue;
>>  
>> @@ -12167,6 +12183,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
>>  
>>  	if (mode_changed && crtc_state->hw.enable &&
>>  	    dev_priv->display.crtc_compute_clock &&
>> +	    !crtc_state->bigjoiner_slave &&
> Why do we need this? Wouldn't we just end up sharing the same DPLL
> for both pipes anyway?
There is no dpll on bigjoiner slave. Only the pipe registers are touched. :)
>
>>  	    !WARN_ON(crtc_state->shared_dpll)) {
>>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>>  		if (ret)
>> @@ -12627,18 +12644,31 @@ static bool check_digital_port_conflicts(struct intel_atomic_state *state)
>>  }
>>  
>>  static void
>> -intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_crtc_state *crtc_state)
>> +intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *state,
>> +					   struct intel_crtc_state *crtc_state)
>>  {
>> -	intel_crtc_copy_color_blobs(crtc_state);
>> +	const struct intel_crtc_state *from_crtc_state = crtc_state;
>> +
>> +	if (crtc_state->bigjoiner_slave) {
>> +		from_crtc_state = intel_atomic_get_new_crtc_state(state,
>> +					crtc_state->bigjoiner_linked_crtc);
>> +
>> +		/* No need to copy state if the master state is unchanged */
>> +		if (!from_crtc_state)
>> +			return;
>> +	}
>> +
>> +	intel_crtc_copy_color_blobs(crtc_state, from_crtc_state);
>>  }
>>  
>>  static void
>> -intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
>> +intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
>> -	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>> +	intel_crtc_copy_uapi_to_hw_state_nomodeset(state, crtc_state);
>>  }
>>  
>>  static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
>> @@ -12660,7 +12690,49 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
>>  }
>>  
>>  static int
>> -intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>> +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.pipe_mode = from_crtc_state->hw.pipe_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
>> +intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
>> +				 struct intel_crtc_state *crtc_state)
>>  {
>>  	struct drm_i915_private *dev_priv =
>>  		to_i915(crtc_state->uapi.crtc->dev);
>> @@ -12703,16 +12775,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>>  	crtc_state->uapi.mode.private_flags = 0;
>>  	crtc_state->uapi.adjusted_mode.private_flags = 0;
>>  
>> -	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>> +	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
>>  
>>  	return 0;
>>  }
>>  
>>  static int
>> -intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>> +intel_modeset_pipe_config(struct intel_atomic_state *state,
>> +			  struct intel_crtc_state *pipe_config)
>>  {
>>  	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;
>> @@ -12755,7 +12827,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  			       &pipe_config->pipe_src_w,
>>  			       &pipe_config->pipe_src_h);
>>  
>> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
>> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>>  		if (connector_state->crtc != crtc)
>>  			continue;
>>  
>> @@ -12800,7 +12872,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	 * adjust it according to limitations or connector properties, and also
>>  	 * a chance to reject the mode entirely.
>>  	 */
>> -	for_each_new_connector_in_state(state, connector, connector_state, i) {
>> +	for_each_new_connector_in_state(&state->base, connector, connector_state, i) {
>>  		if (connector_state->crtc != crtc)
>>  			continue;
>>  
>> @@ -12853,8 +12925,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	 */
>>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>>  
>> -	/* without bigjoiner, pipe_mode == adjusted_mode */
>> -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>>  	return 0;
>>  }
>>  
>> @@ -14091,6 +14161,74 @@ static int intel_atomic_check_crtcs(struct intel_atomic_state *state)
>>  	return 0;
>>  }
>>  
>> +static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state,
>> +					struct intel_crtc *crtc,
>> +					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);
>> +	struct intel_crtc_state *slave_crtc_state, *master_crtc_state;
>> +	struct intel_crtc *slave, *master;
>> +
>> +	/* slave being enabled, is master is still claiming this crtc? */
>> +	if (old_crtc_state->bigjoiner_slave) {
>> +		slave = crtc;
>> +		master = old_crtc_state->bigjoiner_linked_crtc;
>> +		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
>> +		if (!master_crtc_state || !needs_modeset(master_crtc_state))
>> +			goto claimed;
>> +	}
>> +
>> +	if (!new_crtc_state->bigjoiner)
>> +		return 0;
>> +
>> +	if (1 + crtc->pipe >= INTEL_NUM_PIPES(dev_priv)) {
>> +		DRM_DEBUG_KMS("[CRTC:%d:%s] Big joiner configuration requires "
>> +			      "CRTC + 1 to be used, doesn't exist\n",
>> +			      crtc->base.base.id, crtc->base.name);
>> +		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);
>> +	master = crtc;
>> +	if (IS_ERR(slave_crtc_state))
>> +		return PTR_ERR(slave_crtc_state);
>> +
>> +	/* master being enabled, slave was already configured? */
>> +	if (slave_crtc_state->uapi.enable)
>> +		goto claimed;
>> +
>> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Used as slave for big joiner\n",
>> +		      slave->base.base.id, slave->base.name);
>> +	return copy_bigjoiner_crtc_state(slave_crtc_state, new_crtc_state);
>> +
>> +claimed:
>> +	DRM_DEBUG_KMS("[CRTC:%d:%s] Slave is enabled as normal CRTC, but "
>> +		      "[CRTC:%d:%s] claiming this CRTC for bigjoiner.\n",
>> +		      slave->base.base.id, slave->base.name,
>> +		      master->base.base.id, master->base.name);
>> +	return -EINVAL;
>> +}
>> +
>> +static int kill_bigjoiner_slave(struct intel_atomic_state *state,
>> +				struct intel_crtc_state *master_crtc_state)
>> +{
>> +	struct intel_crtc_state *slave_crtc_state =
>> +		intel_atomic_get_crtc_state(&state->base,
>> +			master_crtc_state->bigjoiner_linked_crtc);
> nit: I'd do this as
>
> struct foo *bar;
>
> bar = whatever();
> if (IS_ERR)
> 	...
>
> to make it stand out more since that function has some real
> side effects.
I think the name gives it away. :)
>> +
>> +	if (IS_ERR(slave_crtc_state))
>> +		return PTR_ERR(slave_crtc_state);
>> +
>> +	slave_crtc_state->bigjoiner = master_crtc_state->bigjoiner = false;
>> +	slave_crtc_state->bigjoiner_slave = master_crtc_state->bigjoiner_slave = false;
>> +	slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;
>> +	intel_crtc_copy_uapi_to_hw_state(state, slave_crtc_state);
>> +	return 0;
>> +}
>> +
>>  /**
>>   * intel_atomic_check - validate state object
>>   * @dev: drm device
>> @@ -14122,23 +14260,31 @@ static int intel_atomic_check(struct drm_device *dev,
>>  					    new_crtc_state, i) {
>>  		if (!needs_modeset(new_crtc_state)) {
>>  			/* Light copy */
>> -			intel_crtc_copy_uapi_to_hw_state_nomodeset(new_crtc_state);
>> +			intel_crtc_copy_uapi_to_hw_state_nomodeset(state, new_crtc_state);
>>  
>>  			continue;
>>  		}
>>  
>> -		if (!new_crtc_state->uapi.enable) {
>> -			intel_crtc_copy_uapi_to_hw_state(new_crtc_state);
>> +		/* Kill old bigjoiner link, we may re-establish afterwards */
>> +		if (old_crtc_state->bigjoiner && !old_crtc_state->bigjoiner_slave) {
>> +			ret = kill_bigjoiner_slave(state, new_crtc_state);
>> +			if (ret)
>> +				goto fail;
>> +		}
>>  
>> -			any_ms = true;
>> +		if (!new_crtc_state->uapi.enable) {
>> +			if (!new_crtc_state->bigjoiner_slave) {
>> +				intel_crtc_copy_uapi_to_hw_state(state, new_crtc_state);
>> +				any_ms = true;
>> +			}
>>  			continue;
>>  		}
> How does this handle the case where the slave uapi.enable gets
> enabled but the master is not part of the state yet?

First lines in intel_atomic_check_bigjoiner intel_atomic_check_bigjoiner() handle this.

	/* slave being enabled, is master is still claiming this crtc? */
	if (old_crtc_state->bigjoiner_slave) {
		slave = crtc;
		master = old_crtc_state->bigjoiner_linked_crtc;
		master_crtc_state = intel_atomic_get_new_crtc_state(state, master);
		if (!master_crtc_state || !needs_modeset(master_crtc_state))
			goto claimed;
	}

>
>>  
>> -		ret = intel_crtc_prepare_cleared_state(new_crtc_state);
>> +		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
>>  		if (ret)
>>  			goto fail;
>>  
>> -		ret = intel_modeset_pipe_config(new_crtc_state);
>> +		ret = intel_modeset_pipe_config(state, new_crtc_state);
>>  		if (ret)
>>  			goto fail;
>>  
>> @@ -14146,6 +14292,10 @@ static int intel_atomic_check(struct drm_device *dev,
>>  
>>  		if (needs_modeset(new_crtc_state))
>>  			any_ms = true;
>> +
>> +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state, new_crtc_state);
>> +		if (ret)
>> +			goto fail;
>>  	}
>>  
>>  	if (any_ms && !check_digital_port_conflicts(state)) {
>> @@ -14350,7 +14500,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);
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 7f46c1646d3f..cf2ecfa17416 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -1044,6 +1044,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 9b7df8e85ea2..54fde4c4c4dd 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -2147,6 +2147,15 @@ 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_max_dotclock(intel_dp, false)) {
>> +		if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, true)) {
>> +			DRM_DEBUG_KMS("Clock rate too high for big joiner\n");
>> +			return -EINVAL;
>> +		}
>> +		pipe_config->bigjoiner = true;
>> +		DRM_DEBUG_KMS("Using bigjoiner configuration\n");
>> +	}
>> +
>>  	if (intel_dp_is_edp(intel_dp)) {
>>  		pipe_config->dsc.compressed_bpp =
>>  			min_t(u16, drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4,
>> @@ -2164,12 +2173,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;
>> @@ -2184,13 +2193,14 @@ 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.slice_count > 1) {
>> -			pipe_config->dsc.dsc_split = true;
>> -		} else {
>> +	if (adjusted_mode->crtc_clock > dev_priv->max_cdclk_freq ||
>> +	    pipe_config->bigjoiner) {
>> +		if (pipe_config->dsc.slice_count < 2) {
>>  			DRM_DEBUG_KMS("Cannot split stream to use 2 VDSC instances\n");
>>  			return -EINVAL;
>>  		}
>> +
>> +		pipe_config->dsc.dsc_split = true;
>>  	}
>>  
>>  	ret = intel_dsc_compute_params(&dig_port->base, pipe_config);
>> -- 
>> 2.24.0
>>
>> _______________________________________________
>> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2019-11-28 19:04     ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2019-12-03  9:18     ` Maarten Lankhorst
  2019-12-03 13:39       ` Ville Syrjälä
  -1 siblings, 1 reply; 47+ messages in thread
From: Maarten Lankhorst @ 2019-12-03  9:18 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 28-11-2019 om 20:04 schreef Ville Syrjälä:
> On Thu, Nov 14, 2019 at 05:05:15PM +0100, 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.
>>
>> eDP does not support bigjoiner, so do not expose bigjoiner only
>> modes on the eDP port.
>>
>> Changes since v1:
>> - Disallow bigjoiner on eDP.
>> Changes since v2:
>> - Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
>>   and split off the downstream and source checking to its own function.
>>   (Ville)
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_dp.c | 117 ++++++++++++++++++------
>>  1 file changed, 89 insertions(+), 28 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 3123958e2081..9b7df8e85ea2 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>>  	return max_link_clock * max_lanes;
>>  }
>>  
>> -static int
>> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
>> +static int source_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;
>> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	int max_dotclk = dev_priv->max_dotclk_freq;
>> -	int ds_max_dotclk;
>> +	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
>> +
>> +	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))
> Should the edp check actually be check for the edp transcoder
> (ie. port A) on icl?
Isn't that equivalent to this check?
>
>> +		return 2 * i915->max_dotclk_freq;
>> +
>> +	return i915->max_dotclk_freq;
>> +}
>>  
>> +static int downstream_max_dotclock(struct intel_dp *intel_dp)
>> +{
>>  	int type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
>>  
>>  	if (type != DP_DS_PORT_TYPE_VGA)
>> -		return max_dotclk;
>> +		return 0;
>>  
>> -	ds_max_dotclk = drm_dp_downstream_max_clock(intel_dp->dpcd,
>> -						    intel_dp->downstream_ports);
>> +	return drm_dp_downstream_max_clock(intel_dp->dpcd,
>> +					   intel_dp->downstream_ports);
>> +}
>> +
>> +static int
>> +intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
>> +{
>> +	int max_dotclk = source_max_dotclock(intel_dp, allow_bigjoiner);
>> +	int ds_max_dotclk = downstream_max_dotclock(intel_dp);
>>  
>>  	if (ds_max_dotclk != 0)
>> -		max_dotclk = min(max_dotclk, ds_max_dotclk);
>> +		return min(max_dotclk, ds_max_dotclk);
>>  
>>  	return max_dotclk;
>>  }
>> @@ -506,7 +518,8 @@ small_joiner_ram_size_bits(struct drm_i915_private *i915)
>>  
>>  static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>>  				       u32 link_clock, u32 lane_count,
>> -				       u32 mode_clock, u32 mode_hdisplay)
>> +				       u32 mode_clock, u32 mode_hdisplay,
>> +				       bool bigjoiner)
>>  {
>>  	u32 bits_per_pixel, max_bpp_small_joiner_ram;
>>  	int i;
>> @@ -524,6 +537,10 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>>  	/* Small Joiner Check: output bpp <= joiner RAM (bits) / Horiz. width */
>>  	max_bpp_small_joiner_ram = small_joiner_ram_size_bits(i915) /
>>  		mode_hdisplay;
>> +
>> +	if (bigjoiner)
>> +		max_bpp_small_joiner_ram *= 2;
>> +
>>  	DRM_DEBUG_KMS("Max small joiner bpp: %u\n", max_bpp_small_joiner_ram);
>>  
>>  	/*
>> @@ -532,6 +549,15 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>>  	 */
>>  	bits_per_pixel = min(bits_per_pixel, max_bpp_small_joiner_ram);
>>  
>> +	if (bigjoiner) {
>> +		u32 max_bpp_bigjoiner =
>> +			i915->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",
>> @@ -554,7 +580,8 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915,
>>  }
>>  
>>  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;
>> @@ -579,12 +606,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 ?
> The test_ prefix is throwing me off. Just slice_count?
>
>> +			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)
> slice_count > min_slice_count? Would feel a bit more naturalto me.
Yeah makes sense.
>> +			return test_slice_count;
>>  	}
>>  
>>  	DRM_DEBUG_KMS("Unsupported Slice Count %d\n", min_slice_count);
>> @@ -623,11 +658,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_max_dotclock(intel_dp, false);
>>  
>>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>>  		if (mode->hdisplay > fixed_mode->hdisplay)
>> @@ -639,6 +678,21 @@ 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) {
>> +		if (intel_dp_is_edp(intel_dp))
>> +			return MODE_CLOCK_HIGH;
>> +
>> +		max_dotclk = intel_dp_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);
>>  
>> @@ -666,23 +720,28 @@ intel_dp_mode_valid(struct drm_connector *connector,
>>  							    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");
> I don't think we spew debugs from mode_valid() elsewhere.
Good for debugging, but yeah can kill debug messages if wanted.
>>  		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) {
> Not a huge fan of this dsc boolean. Would feel more natural if the dsc
> thing would compute a new mode_rate with max achievable compression,
> or something along those lines. But this could be cleaned up later.
Yeah.
>
>> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
>> +		return MODE_CLOCK_HIGH;
>> +	}
>>  
>>  	return intel_mode_valid_max_plane_size(dev_priv, mode);
>>  }
>> @@ -2104,11 +2163,13 @@ static int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
>>  						    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.24.0
>>
>> _______________________________________________
>> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 02/11] drm/i915: Remove hw.mode
  2019-11-18 17:39     ` [Intel-gfx] " Ville Syrjälä
  (?)
@ 2019-12-03  9:28     ` Maarten Lankhorst
  -1 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-12-03  9:28 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Op 18-11-2019 om 18:39 schreef Ville Syrjälä:
> On Thu, Nov 14, 2019 at 05:05:13PM +0100, Maarten Lankhorst wrote:
>> The members in hw.mode can be used from adjusted_mode as well,
>> use that when available.
>>
>> Some places that use hw.mode can be converted to use adjusted_mode
>> as well.
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/intel_display.c  | 49 ++++++++++---------
>>  .../drm/i915/display/intel_display_types.h    |  2 +-
>>  drivers/gpu/drm/i915/display/intel_dvo.c      |  2 +-
>>  drivers/gpu/drm/i915/display/intel_sdvo.c     | 16 +++---
>>  4 files changed, 34 insertions(+), 35 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
>> index adf50c4b38ad..18acecc3642d 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -8440,9 +8440,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>>  	tmp = I915_READ(PIPESRC(crtc->pipe));
>>  	pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
>>  	pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
>> -
>> -	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,
>> @@ -12098,8 +12095,8 @@ static int icl_add_sync_mode_crtcs(struct intel_crtc_state *crtc_state)
>>  			continue;
>>  		if (!connector->has_tile)
>>  			continue;
>> -		if (crtc_state->hw.mode.hdisplay != connector->tile_h_size ||
>> -		    crtc_state->hw.mode.vdisplay != connector->tile_v_size)
>> +		if (crtc_state->hw.adjusted_mode.crtc_hdisplay != connector->tile_h_size ||
>> +		    crtc_state->hw.adjusted_mode.crtc_vdisplay != connector->tile_v_size)
>>  			return 0;
>>  		if (connector->tile_h_loc == connector->num_h_tile - 1 &&
>>  		    connector->tile_v_loc == connector->num_v_tile - 1)
>> @@ -12506,7 +12503,7 @@ 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->hw.mode);
>> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>>  	DRM_DEBUG_KMS("adjusted mode:\n");
>>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>>  	intel_dump_crtc_timings(&pipe_config->hw.adjusted_mode);
>> @@ -12640,16 +12637,16 @@ intel_crtc_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;
>>  	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
>>  }
>>  
>> -static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state)
>> +static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
>> +					     struct drm_display_mode *user_mode)
>>  {
>>  	crtc_state->uapi.enable = crtc_state->hw.enable;
>>  	crtc_state->uapi.active = crtc_state->hw.active;
>> -	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
>> +	WARN_ON(drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>>  
>>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>>  
>> @@ -12702,6 +12699,10 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
>>  	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
>>  	kfree(saved_state);
>>  
>> +	/* Clear I915_MODE_FLAG_INHERITED */
>> +	crtc_state->uapi.mode.private_flags = 0;
>> +	crtc_state->uapi.adjusted_mode.private_flags = 0;
>> +
>>  	intel_crtc_copy_uapi_to_hw_state(crtc_state);
>>  
>>  	return 0;
>> @@ -12750,7 +12751,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->hw.mode,
>> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>>  			       &pipe_config->pipe_src_w,
>>  			       &pipe_config->pipe_src_h);
>>  
>> @@ -12852,6 +12853,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>>  	 */
>>  	pipe_config->uapi.adjusted_mode = pipe_config->hw.adjusted_mode;
>>  
>> +	/* without bigjoiner, pipe_mode == adjusted_mode */
>> +	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
>>  	return 0;
>>  }
>>  
>> @@ -12995,8 +12998,8 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  	bool ret = true;
>>  	u32 bp_gamma = 0;
>>  	bool fixup_inherited = fastset &&
>> -		(current_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED) &&
>> -		!(pipe_config->hw.mode.private_flags & I915_MODE_FLAG_INHERITED);
>> +		(current_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED) &&
>> +		!(pipe_config->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED);
>>  
>>  	if (fixup_inherited && !fastboot_enabled(dev_priv)) {
>>  		DRM_DEBUG_KMS("initial modeset and fastboot not set\n");
>> @@ -14106,8 +14109,8 @@ 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->hw.mode.private_flags !=
>> -		    old_crtc_state->hw.mode.private_flags)
>> +		if (new_crtc_state->hw.adjusted_mode.private_flags !=
>> +		    old_crtc_state->hw.adjusted_mode.private_flags)
>>  			new_crtc_state->uapi.mode_changed = true;
>>  	}
>>  
>> @@ -14361,7 +14364,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
>>  	 * of enabling them on the CRTC's first fastset.
>>  	 */
>>  	if (new_crtc_state->update_pipe && !modeset &&
>> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
>> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>>  }
>>  
>> @@ -14558,7 +14561,7 @@ static void intel_post_crtc_enable_updates(struct intel_crtc *crtc,
>>  	 * of enabling them on the CRTC's first fastset.
>>  	 */
>>  	if (new_crtc_state->update_pipe && !modeset &&
>> -	    old_crtc_state->hw.mode.private_flags & I915_MODE_FLAG_INHERITED)
>> +	    old_crtc_state->hw.adjusted_mode.private_flags & I915_MODE_FLAG_INHERITED)
>>  		intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>>  }
>>  
>> @@ -17524,15 +17527,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>>  		int min_cdclk = 0;
>>  
>>  		if (crtc_state->hw.active) {
>> -			struct drm_display_mode *mode = &crtc_state->hw.mode;
>> +			struct drm_display_mode mode;
>>  
>>  			intel_mode_from_pipe_config(&crtc_state->hw.adjusted_mode,
>>  						    crtc_state);
>>  
>> -			*mode = crtc_state->hw.adjusted_mode;
>> -			mode->hdisplay = crtc_state->pipe_src_w;
>> -			mode->vdisplay = crtc_state->pipe_src_h;
>> -
>>  			/*
>>  			 * The initial mode needs to be set in order to keep
>>  			 * the atomic core happy. It wants a valid mode if the
>> @@ -17542,13 +17541,17 @@ 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.
>>  			 */
>> -			mode->private_flags = I915_MODE_FLAG_INHERITED;
>> +			crtc_state->hw.adjusted_mode.private_flags = I915_MODE_FLAG_INHERITED;
>> +
>> +			mode = crtc_state->hw.adjusted_mode;
>> +			mode.hdisplay = crtc_state->pipe_src_w;
>> +			mode.vdisplay = crtc_state->pipe_src_h;
>>  
>>  			intel_crtc_compute_pixel_rate(crtc_state);
>>  
>>  			intel_crtc_update_active_timings(crtc_state);
>>  
>> -			intel_crtc_copy_hw_to_uapi_state(crtc_state);
>> +			intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode);
>>  		}
>>  
>>  		for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
>> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
>> index 83ea04149b77..0f20c7190eed 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -802,7 +802,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 adjusted_mode;
>>  	} hw;
>>  
>>  	/**
>> diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c
>> index a74dc5b915d1..ad8e9959d6e1 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
>> @@ -207,7 +207,7 @@ 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->hw.mode,
>> +					 &pipe_config->hw.adjusted_mode,
>>  					 &pipe_config->hw.adjusted_mode);
> This looks very wrong.
Hmm yeah, should probably be pipe_config->uapi.mode for the first parameter, or panel fitter for IVCH stops working.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2019-12-03  9:18     ` Maarten Lankhorst
@ 2019-12-03 13:39       ` Ville Syrjälä
  0 siblings, 0 replies; 47+ messages in thread
From: Ville Syrjälä @ 2019-12-03 13:39 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Tue, Dec 03, 2019 at 10:18:51AM +0100, Maarten Lankhorst wrote:
> Op 28-11-2019 om 20:04 schreef Ville Syrjälä:
> > On Thu, Nov 14, 2019 at 05:05:15PM +0100, 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.
> >>
> >> eDP does not support bigjoiner, so do not expose bigjoiner only
> >> modes on the eDP port.
> >>
> >> Changes since v1:
> >> - Disallow bigjoiner on eDP.
> >> Changes since v2:
> >> - Rename intel_dp_downstream_max_dotclock to intel_dp_max_dotclock,
> >>   and split off the downstream and source checking to its own function.
> >>   (Ville)
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/display/intel_dp.c | 117 ++++++++++++++++++------
> >>  1 file changed, 89 insertions(+), 28 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> >> index 3123958e2081..9b7df8e85ea2 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> >> @@ -243,25 +243,37 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> >>  	return max_link_clock * max_lanes;
> >>  }
> >>  
> >> -static int
> >> -intel_dp_downstream_max_dotclock(struct intel_dp *intel_dp)
> >> +static int source_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;
> >> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >> -	int max_dotclk = dev_priv->max_dotclk_freq;
> >> -	int ds_max_dotclk;
> >> +	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> >> +
> >> +	if (allow_bigjoiner && INTEL_GEN(i915) >= 11 && !intel_dp_is_edp(intel_dp))
> > Should the edp check actually be check for the edp transcoder
> > (ie. port A) on icl?
> Isn't that equivalent to this check?

You can have eDP on other ports (at least in theory).
Also on tgl+ there is no eDP transcoder anymore.

-- 
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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 01/11] HAX to make DSC work on the icelake test system
  2019-11-14 16:05 ` [Intel-gfx] " Maarten Lankhorst
                   ` (14 preceding siblings ...)
  (?)
@ 2019-12-12  0:27 ` Manasi Navare
  2019-12-12 10:09   ` Maarten Lankhorst
  -1 siblings, 1 reply; 47+ messages in thread
From: Manasi Navare @ 2019-12-12  0:27 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Thu, Nov 14, 2019 at 05:05:12PM +0100, Maarten Lankhorst wrote:
> DSC is available on the display emulator, but not set in DPCD.
> Override the entries to allow bigjoiner testing.

In general for these hacks for specific emulator, can we base it on certain i915 parameter like
dsc_emaulator or something to override these values else we might actually affect DSC
behaviour for the actual dsc panels.

> 
> 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 2c7870aef469..3d6038f35ea2 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -1261,7 +1261,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;

Is this also needed for the big joiner since it doesnt return 4 slice count?

Manasi

>  		if (slice_cap1 & DP_DSC_1_PER_DP_DSC_SINK)
>  			return 1;
>  	} else {
> @@ -1285,7 +1285,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 51ecb5112ef8..2ebd7feffd90 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1270,6 +1270,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.24.0
> 
> _______________________________________________
> 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] 47+ messages in thread

* Re: [Intel-gfx] [PATCH 01/11] HAX to make DSC work on the icelake test system
  2019-12-12  0:27 ` [Intel-gfx] [PATCH 01/11] " Manasi Navare
@ 2019-12-12 10:09   ` Maarten Lankhorst
  0 siblings, 0 replies; 47+ messages in thread
From: Maarten Lankhorst @ 2019-12-12 10:09 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

Op 12-12-2019 om 01:27 schreef Manasi Navare:
> On Thu, Nov 14, 2019 at 05:05:12PM +0100, Maarten Lankhorst wrote:
>> DSC is available on the display emulator, but not set in DPCD.
>> Override the entries to allow bigjoiner testing.
> In general for these hacks for specific emulator, can we base it on certain i915 parameter like
> dsc_emaulator or something to override these values else we might actually affect DSC
> behaviour for the actual dsc panels.
>
>> 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 2c7870aef469..3d6038f35ea2 100644
>> --- a/drivers/gpu/drm/drm_dp_helper.c
>> +++ b/drivers/gpu/drm/drm_dp_helper.c
>> @@ -1261,7 +1261,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;
> Is this also needed for the big joiner since it doesnt return 4 slice count?
>
> Manasi
This patch is not for upstream, just a hack to make it work on the tgl with the emulator.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2019-12-12 10:09 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-11-14 16:05 [PATCH 01/11] HAX to make DSC work on the icelake test system Maarten Lankhorst
2019-11-14 16:05 ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 02/11] drm/i915: Remove hw.mode Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-18 17:17   ` Ville Syrjälä
2019-11-18 17:17     ` [Intel-gfx] " Ville Syrjälä
2019-11-18 17:39   ` Ville Syrjälä
2019-11-18 17:39     ` [Intel-gfx] " Ville Syrjälä
2019-12-03  9:28     ` Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-28 19:04   ` Ville Syrjälä
2019-11-28 19:04     ` [Intel-gfx] " Ville Syrjälä
2019-12-03  9:18     ` Maarten Lankhorst
2019-12-03 13:39       ` Ville Syrjälä
2019-11-14 16:05 ` [PATCH 05/11] drm/i915: Try to make bigjoiner work in atomic check, v3 Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-28 19:24   ` Ville Syrjälä
2019-11-28 19:24     ` [Intel-gfx] " Ville Syrjälä
2019-12-03  9:13     ` Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 06/11] drm/i915: Enable big joiner support in enable and disable sequences Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-28 19:43   ` Ville Syrjälä
2019-11-28 19:43     ` [Intel-gfx] " Ville Syrjälä
2019-12-03  9:05     ` Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 07/11] drm/i915: Make hardware readout work on i915 Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 08/11] drm/i915: Link planes in a bigjoiner configuration, v3 Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 09/11] drm/i915: Add bigjoiner aware plane clipping checks Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 10/11] drm/i915: Add intel_update_bigjoiner handling Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 16:05 ` [PATCH 11/11] drm/i915: Add debugfs dumping for bigjoiner, v2 Maarten Lankhorst
2019-11-14 16:05   ` [Intel-gfx] " Maarten Lankhorst
2019-11-14 17:04 ` ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/11] HAX to make DSC work on the icelake test system Patchwork
2019-11-14 17:04   ` [Intel-gfx] " Patchwork
2019-11-14 17:06 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-11-14 17:06   ` [Intel-gfx] " Patchwork
2019-11-14 17:25 ` ✓ Fi.CI.BAT: success " Patchwork
2019-11-14 17:25   ` [Intel-gfx] " Patchwork
2019-11-15 17:50 ` ✗ Fi.CI.IGT: failure " Patchwork
2019-11-15 17:50   ` [Intel-gfx] " Patchwork
2019-12-12  0:27 ` [Intel-gfx] [PATCH 01/11] " Manasi Navare
2019-12-12 10:09   ` Maarten Lankhorst

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.