All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system
@ 2020-07-15 22:42 Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
                   ` (24 more replies)
  0 siblings, 25 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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 a3c82e726057..d3aa9b696e31 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1434,7 +1434,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 {
@@ -1458,7 +1458,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 e47dc22ebf50..2cce09a37e95 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1416,6 +1416,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.19.1

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

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

* [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-17  7:26   ` Manna, Animesh
  2020-09-03 17:49   ` Ville Syrjälä
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
                   ` (23 subsequent siblings)
  24 siblings, 2 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual rebase (Manasi)
* remove the use of pipe_mode defined in patch 3 (Manasi)

v3:
* Rebase on drm-tip (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
 .../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, 23 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 729ec6e0d43a..8652a7c6bf11 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
 	tmp = intel_de_read(dev_priv, 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,
@@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
 		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
 
 	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
-	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
+	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
 	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
 	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
 	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
@@ -13221,17 +13218,17 @@ 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;
 	drm_WARN_ON(crtc_state->uapi.crtc->dev,
-		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
+		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -13277,6 +13274,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;
@@ -13324,7 +13325,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.adjusted_mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -18461,15 +18462,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
@@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			 */
 			crtc_state->inherited = true;
 
+			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 e8f809161c75..f1e29d9a75d0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
--- a/drivers/gpu/drm/i915/display/intel_dvo.c
+++ b/drivers/gpu/drm/i915/display/intel_dvo.c
@@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
 	u32 temp = intel_de_read(dev_priv, 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);
 
 	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
--- a/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1223,7 +1223,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;
@@ -1234,9 +1233,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,
@@ -1308,7 +1307,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;
@@ -1324,12 +1322,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)) {
@@ -1339,7 +1337,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);
 	}
 
@@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
 		to_intel_sdvo_connector_state(conn_state);
 	const struct intel_sdvo_connector *intel_sdvo_connector =
 		to_intel_sdvo_connector(conn_state->connector);
-	const struct drm_display_mode *mode = &crtc_state->hw.mode;
 	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
 	u32 sdvox;
 	struct intel_sdvo_in_out_map in_out;
@@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
 		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(&dev_priv->drm,
 			 "Setting output timings on %s failed\n",
-- 
2.19.1

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

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

* [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-10 12:38   ` Maarten Lankhorst
                     ` (2 more replies)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
                   ` (22 subsequent siblings)
  24 siblings, 3 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

v4:
* Manual rebase (Manasi)
v3:
* Change state to crtc_state, fix rebase err  (Manasi)
v2:
* Manual Rebase (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
 .../drm/i915/display/intel_display_types.h    | 11 ++-
 drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
 3 files changed, 79 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 8652a7c6bf11..78cbfefbfa62 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -152,7 +152,7 @@ static void ilk_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,
@@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
 
 static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
 	int width, height;
 
 	if (crtc_state->pch_pfit.enabled) {
 		width = drm_rect_width(&crtc_state->pch_pfit.dst);
 		height = drm_rect_height(&crtc_state->pch_pfit.dst);
 	} else {
-		width = adjusted_mode->crtc_hdisplay;
-		height = adjusted_mode->crtc_vdisplay;
+		width = pipe_mode->crtc_hdisplay;
+		height = pipe_mode->crtc_vdisplay;
 	}
-
 	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
 				 SKL_CRTC_INDEX,
 				 &crtc_state->scaler_state.scaler_id,
@@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
 	if (intel_crtc_has_dp_encoder(new_crtc_state))
 		intel_dp_set_m_n(new_crtc_state, M1_N1);
 
-	intel_set_pipe_timings(new_crtc_state);
+	intel_set_transcoder_timings(new_crtc_state);
 	intel_set_pipe_src_size(new_crtc_state);
 
 	if (new_crtc_state->has_pch_encoder)
@@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	intel_encoders_pre_enable(state, crtc);
 
 	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_pipe_timings(new_crtc_state);
+		intel_set_transcoder_timings(new_crtc_state);
 
 	intel_set_pipe_src_size(new_crtc_state);
 
@@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
 	if (intel_crtc_has_dp_encoder(new_crtc_state))
 		intel_dp_set_m_n(new_crtc_state, M1_N1);
 
-	intel_set_pipe_timings(new_crtc_state);
+	intel_set_transcoder_timings(new_crtc_state);
 	intel_set_pipe_src_size(new_crtc_state);
 
 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
@@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
 	if (intel_crtc_has_dp_encoder(new_crtc_state))
 		intel_dp_set_m_n(new_crtc_state, M1_N1);
 
-	intel_set_pipe_timings(new_crtc_state);
+	intel_set_transcoder_timings(new_crtc_state);
 	intel_set_pipe_src_size(new_crtc_state);
 
 	i9xx_set_pipeconf(new_crtc_state);
@@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
 
 static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
 {
-	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
+	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
 	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
 
 	/*
@@ -8008,7 +8006,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);
@@ -8018,7 +8016,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) {
@@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
 			    "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;
 	}
@@ -8081,7 +8079,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);
@@ -8751,7 +8749,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);
@@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
 		return intel_de_read(dev_priv, 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);
@@ -9458,7 +9456,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(pipe_config);
@@ -10739,7 +10737,7 @@ static bool ilk_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);
 
 	ilk_get_pfit_config(pipe_config);
@@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
 	    INTEL_GEN(dev_priv) >= 11) {
 		hsw_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);
@@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
 
 static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
 	int linetime_wm;
 
 	if (!crtc_state->hw.enable)
 		return 0;
 
-	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
-					adjusted_mode->crtc_clock);
+	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
+					pipe_mode->crtc_clock);
 
 	return min(linetime_wm, 0x1ff);
 }
@@ -13218,7 +13216,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);
 }
 
@@ -13325,7 +13323,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.adjusted_mode,
+	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * drm_atomic_helper_update_legacy_modeset_state() happy
 	 */
 	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;
 }
@@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			 */
 			crtc_state->inherited = true;
 
+			/* 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 f1e29d9a75d0..c52c8f42df68 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
@@ -1141,8 +1141,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;
 
@@ -1169,8 +1169,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);
 
@@ -1666,8 +1666,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)
@@ -1677,8 +1677,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) {
@@ -2267,12 +2267,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;
@@ -2351,8 +2351,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;
@@ -2362,7 +2362,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;
@@ -2378,8 +2378,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;
@@ -2389,7 +2389,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)
@@ -2427,12 +2427,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;
@@ -2480,7 +2480,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;
 
@@ -2488,8 +2488,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);
@@ -2579,7 +2579,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);
 
@@ -2607,7 +2607,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);
@@ -2632,7 +2632,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);
 }
@@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 	if (!crtc_state->hw.active)
 		return true;
 
-	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
+	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
 	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
@@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 	 */
 	total_slice_mask = dbuf_slice_mask;
 	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;
 		u32 pipe_dbuf_slice_mask;
@@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
 		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
 			continue;
 
-		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
+		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
 
 		total_width_in_range += hdisplay;
 
@@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
 	if (drm_WARN_ON(&dev_priv->drm, 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;
@@ -5288,14 +5288,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.19.1

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

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

* [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-10 12:40   ` Maarten Lankhorst
                     ` (2 more replies)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check Manasi Navare
                   ` (21 subsequent siblings)
  24 siblings, 3 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v5:
* Increase max plane width to support 8K with bigjoiner (Maarten)
v4:
* Rebase (Manasi)

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)
v3:
* Rebase (Manasi)

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c |   2 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
 2 files changed, 91 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 78cbfefbfa62..3ecb642805a6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
 	 * too big for that.
 	 */
 	if (INTEL_GEN(dev_priv) >= 11) {
-		plane_width_max = 5120;
+		plane_width_max = 7680;
 		plane_height_max = 4320;
 	} else {
 		plane_width_max = 5120;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index d6295eb20b63..fbfea99fd804 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
-	struct intel_encoder *encoder = &dig_port->base;
+	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;
 
+	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
+		return 2 * dev_priv->max_dotclk_freq;
+
+	return dev_priv->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;
 }
@@ -527,7 +539,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;
@@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
 		    max_bpp_small_joiner_ram);
 
@@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
@@ -576,7 +602,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)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	u8 min_slice_count, i;
@@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
@@ -648,11 +683,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)
@@ -664,6 +703,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);
 
@@ -691,23 +745,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);
 }
@@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
 				    "Compressed BPP/Slice Count not supported\n");
-- 
2.19.1

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

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

* [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (2 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-21 10:16   ` Manna, Animesh
  2020-09-03 18:38   ` Ville Syrjälä
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences Manasi Navare
                   ` (20 subsequent siblings)
  24 siblings, 2 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

 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.

v3:
* Manual Rebase (Manasi)
 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>
Signed-off-by: Manasi Navare <manasi.d.navare@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  | 201 ++++++++++++++++--
 .../drm/i915/display/intel_display_types.h    |   9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
 5 files changed, 211 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 630f49b7aa01..b9dcdc74a10d 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -270,14 +270,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 11146292b06f..fc556c032c8f 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -43,7 +43,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_free(struct drm_atomic_state *state);
 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 3ecb642805a6..955e19abb563 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8016,9 +8016,24 @@ 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;
 
@@ -8079,7 +8094,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);
@@ -12433,7 +12448,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)
 {
@@ -12442,7 +12457,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;
 
@@ -12682,6 +12697,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 &&
 	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
 		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
 		if (ret)
@@ -13206,18 +13222,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,
@@ -13240,7 +13269,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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
@@ -13276,16 +13347,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 drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
 	struct drm_connector *connector;
 	struct drm_connector_state *connector_state;
@@ -13327,7 +13398,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) {
 		struct intel_encoder *encoder =
 			to_intel_encoder(connector_state->best_encoder);
 
@@ -13365,7 +13436,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) {
 		struct intel_encoder *encoder =
 			to_intel_encoder(connector_state->best_encoder);
 
@@ -13422,8 +13493,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * drm_atomic_helper_update_legacy_modeset_state() happy
 	 */
 	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;
 }
@@ -14820,6 +14889,75 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
 	return false;
 }
 
+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
@@ -14849,19 +14987,36 @@ 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;
 		}
 
-		ret = intel_crtc_prepare_cleared_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;
+		}
+
+		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(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
-		if (!new_crtc_state->hw.enable)
-			continue;
+		ret = intel_modeset_pipe_config(state, new_crtc_state);
+		if (ret)
+			goto fail;
 
-		ret = intel_modeset_pipe_config(new_crtc_state);
+		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
+						   new_crtc_state);
 		if (ret)
 			goto fail;
 	}
@@ -15193,7 +15348,9 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 
 	commit_pipe_config(state, crtc);
 
-	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 c52c8f42df68..4694cfd90a0a 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1053,6 +1053,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 fbfea99fd804..29f45d2206af 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2247,6 +2247,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,
@@ -2264,12 +2273,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_dbg_kms(&dev_priv->drm,
 				    "Compressed BPP/Slice Count not supported\n");
@@ -2285,14 +2294,15 @@ 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_dbg_kms(&dev_priv->drm,
 				    "Cannot split stream to use 2 VDSC instances\n");
 			return -EINVAL;
 		}
+
+		pipe_config->dsc.dsc_split = true;
 	}
 
 	ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
-- 
2.19.1

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

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

* [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (3 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-07-16 19:27   ` Manasi Navare
  2020-07-16 21:12   ` [Intel-gfx] [PATCH v7 " Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 07/11] drm/i915: Make hardware readout work on i915 Manasi Navare
                   ` (19 subsequent siblings)
  24 siblings, 2 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual rebase (Manasi)

v3:
* Rebase (Manasi)

v4:
* Rebase (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
 drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
 drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 199 ++++-----
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
 7 files changed, 414 insertions(+), 246 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 8c55f5bee9ab..26f7372b4c25 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 
-	intel_dsc_get_config(encoder, pipe_config);
-
 	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
 	pipe_config->port_clock = intel_dpll_get_freq(i915,
 						      pipe_config->shared_dpll);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 424d59671561..dd97d725ae65 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include <drm/drm_scdc_helper.h>
 
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "intel_audio.h"
 #include "intel_combo_phy.h"
 #include "intel_connector.h"
@@ -2040,12 +2041,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 		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(struct intel_encoder *encoder,
@@ -3313,7 +3308,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 
 	/* 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_atomic_state *state,
@@ -3384,7 +3380,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	if (!is_mst)
 		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
@@ -3639,6 +3636,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
 			ilk_pfit_disable(old_crtc_state);
 	}
 
+	if (old_crtc_state->bigjoiner_linked_crtc) {
+		struct intel_atomic_state *state =
+			to_intel_atomic_state(old_crtc_state->uapi.state);
+		struct intel_crtc *slave =
+			old_crtc_state->bigjoiner_linked_crtc;
+		const struct intel_crtc_state *old_slave_crtc_state =
+			intel_atomic_get_old_crtc_state(state, slave);
+
+		intel_crtc_vblank_off(old_slave_crtc_state);
+		trace_intel_pipe_disable(slave);
+
+		intel_dsc_disable(old_slave_crtc_state);
+		skl_scaler_disable(old_slave_crtc_state);
+	}
+
 	/*
 	 * When called from DP MST code:
 	 * - old_conn_state will be NULL
@@ -3853,7 +3865,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
 {
 	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
-	intel_ddi_enable_transcoder_func(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
 	intel_enable_pipe(crtc_state);
 
@@ -4200,8 +4213,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
 		    crtc_state->sync_mode_slaves_mask);
 }
 
-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);
@@ -4209,13 +4222,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	u32 temp, flags = 0;
 
-	/* XXX: DSI transcoder paranoia */
-	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
+	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (!(temp & TRANS_DDI_FUNC_ENABLE))
 		return;
 
-	intel_dsc_get_config(encoder, pipe_config);
-
-	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
 		flags |= DRM_MODE_FLAG_PHSYNC;
 	else
@@ -4323,6 +4333,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
 		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
 	}
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+
+	/* XXX: DSI transcoder paranoia */
+	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+		return;
+
+	intel_ddi_read_func_ctl(encoder, pipe_config);
+	if (pipe_config->bigjoiner_slave) {
+		/* read out pipe settings from master */
+		enum transcoder save = pipe_config->cpu_transcoder;
+
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
+		WARN_ON(pipe_config->output_types);
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
+		intel_ddi_read_func_ctl(encoder, pipe_config);
+		pipe_config->cpu_transcoder = save;
+	}
 
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
@@ -4348,7 +4381,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 955e19abb563..1cda8900d8f5 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7023,6 +7023,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 	intel_de_write(dev_priv, reg, val);
 }
 
+static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
+					 const 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(state, master);
+		intel_enable_shared_dpll(master_crtc_state);
+		intel_encoders_pre_enable(state, master);
+
+		/* and DSC on slave */
+		intel_dsc_enable(NULL, crtc_state);
+	}
+}
+
 static void hsw_crtc_enable(struct intel_atomic_state *state,
 			    struct intel_crtc *crtc)
 {
@@ -7036,34 +7075,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
 		return;
 
-	intel_encoders_pre_pll_enable(state, crtc);
-
-	if (new_crtc_state->shared_dpll)
-		intel_enable_shared_dpll(new_crtc_state);
+	if (!new_crtc_state->bigjoiner) {
+		intel_encoders_pre_pll_enable(state, crtc);
 
-	intel_encoders_pre_enable(state, crtc);
+		if (new_crtc_state->shared_dpll)
+			intel_enable_shared_dpll(new_crtc_state);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_transcoder_timings(new_crtc_state);
+		intel_encoders_pre_enable(state, crtc);
+	} else {
+		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
+	}
 
 	intel_set_pipe_src_size(new_crtc_state);
+	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+		bdw_set_pipemisc(new_crtc_state);
 
-	if (cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(cpu_transcoder))
-		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
-			       new_crtc_state->pixel_multiplier - 1);
+	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
+		if (!transcoder_is_dsi(cpu_transcoder))
+			intel_set_transcoder_timings(new_crtc_state);
 
-	if (new_crtc_state->has_pch_encoder)
-		intel_cpu_transcoder_set_m_n(new_crtc_state,
-					     &new_crtc_state->fdi_m_n, NULL);
+		if (cpu_transcoder != TRANSCODER_EDP &&
+		    !transcoder_is_dsi(cpu_transcoder))
+			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
+				       new_crtc_state->pixel_multiplier - 1);
+
+		if (new_crtc_state->has_pch_encoder)
+			intel_cpu_transcoder_set_m_n(new_crtc_state,
+						     &new_crtc_state->fdi_m_n, NULL);
 
-	if (!transcoder_is_dsi(cpu_transcoder)) {
 		hsw_set_frame_start_delay(new_crtc_state);
-		hsw_set_pipeconf(new_crtc_state);
 	}
 
-	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-		bdw_set_pipemisc(new_crtc_state);
+	if (!transcoder_is_dsi(cpu_transcoder))
+		hsw_set_pipeconf(new_crtc_state);
 
 	crtc->active = true;
 
@@ -7099,6 +7143,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_pipe_mbus_enable(crtc);
 
+	if (new_crtc_state->bigjoiner_slave) {
+		trace_intel_pipe_enable(crtc);
+		intel_crtc_vblank_on(new_crtc_state);
+	}
+
 	intel_encoders_enable(state, crtc);
 
 	if (psl_clkgate_wa) {
@@ -7381,6 +7430,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;
 }
 
@@ -7999,6 +8051,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
 		       pfit_w * pfit_h);
 }
 
+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 pipe timings are half of the transcoder mode
+		 */
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_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);
@@ -8910,20 +8986,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
-	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
-	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
-	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
+	mode->hdisplay = hw_mode->crtc_hdisplay;
+	mode->htotal = hw_mode->crtc_htotal;
+	mode->hsync_start = hw_mode->crtc_hsync_start;
+	mode->hsync_end = hw_mode->crtc_hsync_end;
 
-	mode->flags = pipe_config->hw.adjusted_mode.flags;
+	mode->vdisplay = hw_mode->crtc_vdisplay;
+	mode->vtotal = hw_mode->crtc_vtotal;
+	mode->vsync_start = hw_mode->crtc_vsync_start;
+	mode->vsync_end = hw_mode->crtc_vsync_end;
+
+	mode->flags = hw_mode->flags;
 	mode->type = DRM_MODE_TYPE_DRIVER;
 
-	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
+	mode->clock = hw_mode->crtc_clock;
 
 	drm_mode_set_name(mode);
 }
@@ -11081,6 +11159,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
 	} else {
 		tmp = intel_de_read(dev_priv,
 				    TRANS_DDI_FUNC_CTL(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);
 		else
@@ -11153,12 +11234,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		drm_WARN_ON(&dev_priv->drm, 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) ||
-	    INTEL_GEN(dev_priv) >= 11) {
+		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) {
 		hsw_get_ddi_port_state(crtc, pipe_config);
 		intel_get_transcoder_timings(crtc, pipe_config);
 	}
@@ -11244,8 +11333,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
-	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+	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 =
 			intel_de_read(dev_priv,
 				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
@@ -12260,7 +12352,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);
 
@@ -13252,10 +13344,12 @@ 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;
-	drm_WARN_ON(crtc_state->uapi.crtc->dev,
-		    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;
+		drm_WARN_ON(crtc_state->uapi.crtc->dev,
+			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
+	}
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -13902,21 +13996,42 @@ 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_BOOL(has_hdmi_sink);
 	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
@@ -13926,24 +14041,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)
@@ -13969,7 +14071,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))
@@ -13990,48 +14093,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(double_wide);
 
 	PIPE_CONF_CHECK_P(shared_dpll);
-	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);
+	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(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);
@@ -14043,11 +14149,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
 	PIPE_CONF_CHECK_I(dsc.dsc_split);
 	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
-
 	PIPE_CONF_CHECK_I(mst_master_transcoder);
 
 #undef PIPE_CONF_CHECK_X
@@ -14314,6 +14421,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 	struct intel_encoder *encoder;
 	struct intel_crtc_state *pipe_config = old_crtc_state;
 	struct drm_atomic_state *state = old_crtc_state->uapi.state;
+	struct intel_crtc *master = crtc;
 	bool active;
 
 	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
@@ -14340,7 +14448,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);
@@ -14349,12 +14460,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);
@@ -15376,7 +15487,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 
+	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
+
 	intel_crtc_disable_planes(state, crtc);
+	if (old_crtc_state->bigjoiner)
+		intel_crtc_disable_planes(state,
+					  old_crtc_state->bigjoiner_linked_crtc);
 
 	/*
 	 * We need to disable pipe CRC before disabling the pipe,
@@ -15406,7 +15522,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	/* Only disable port sync and MST slaves */
 	for_each_oldnew_intel_crtc_in_state(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;
 
 		if (!old_crtc_state->hw.active)
@@ -15421,7 +15537,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		    !intel_dp_mst_is_slave_trans(old_crtc_state))
 			continue;
 
-		intel_pre_plane_update(state, crtc);
 		intel_old_crtc_state_disables(state, old_crtc_state,
 					      new_crtc_state, crtc);
 		handled |= BIT(crtc->pipe);
@@ -15431,10 +15546,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state) ||
-		    (handled & BIT(crtc->pipe)))
+		    (handled & BIT(crtc->pipe)) ||
+		    old_crtc_state->bigjoiner_slave)
 			continue;
 
 		intel_pre_plane_update(state, crtc);
+		if (old_crtc_state->bigjoiner) {
+			struct intel_crtc *slave =
+				old_crtc_state->bigjoiner_linked_crtc;
+
+			intel_pre_plane_update(state, slave);
+		}
+
 		if (old_crtc_state->hw.active)
 			intel_old_crtc_state_disables(state, old_crtc_state,
 						      new_crtc_state, crtc);
@@ -18063,7 +18186,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;
 
 		/*
@@ -18562,7 +18685,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 4694cfd90a0a..943709f192f7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -826,6 +826,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 */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 29f45d2206af..41cb9f9c0292 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *crtc_state)
 {
-	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
-
-	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
 		return false;
 
-	return intel_dsc_source_support(encoder, crtc_state) &&
+	return intel_dsc_source_support(crtc_state) &&
 		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 c5735c365659..2d343ccef497 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
 	return &rc_parameters[row_index][column_index];
 }
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state)
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 
@@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
 }
 
-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;
 	u32 pps_val = 0;
@@ -503,6 +501,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 |
@@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
 	}
 }
 
-void intel_dsc_get_config(struct intel_encoder *encoder,
-			  struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	enum pipe pipe = crtc->pipe;
-	enum intel_display_power_domain power_domain;
-	intel_wakeref_t wakeref;
-	u32 dss_ctl1, dss_ctl2, val;
-
-	if (!intel_dsc_source_support(encoder, crtc_state))
-		return;
-
-	power_domain = intel_dsc_power_domain(crtc_state);
-
-	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
-	if (!wakeref)
-		return;
-
-	if (!is_pipe_dsc(crtc_state)) {
-		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
-		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
-	} else {
-		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
-		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
-	}
-
-	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
-	if (!crtc_state->dsc.compression_enable)
-		goto out;
-
-	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
-		(dss_ctl1 & JOINER_ENABLE);
-
-	/* FIXME: add more state readout as needed */
-
-	/* PPS1 */
-	if (!is_pipe_dsc(crtc_state))
-		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
-	else
-		val = intel_de_read(dev_priv,
-				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
-	vdsc_cfg->bits_per_pixel = val;
-	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
-out:
-	intel_display_power_put(dev_priv, power_domain, wakeref);
-}
-
 static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
 				    const struct intel_crtc_state *crtc_state)
 {
@@ -1060,77 +1012,130 @@ 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 (encoder->type == INTEL_OUTPUT_DSI)
-		intel_dsc_dsi_pps_write(encoder, crtc_state);
-	else
-		intel_dsc_dp_pps_write(encoder, crtc_state);
-
-	if (!is_pipe_dsc(crtc_state)) {
-		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);
+	if (!crtc_state->bigjoiner_slave) {
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
+			intel_dsc_dsi_pps_write(encoder, crtc_state);
+		else
+			intel_dsc_dp_pps_write(encoder, crtc_state);
 	}
+
 	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;
 	}
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-	intel_de_write(dev_priv, 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;
+	}
+	intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
+	intel_de_write(dev_priv, 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 (!is_pipe_dsc(old_crtc_state)) {
-		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_ctl1_val = intel_de_read(dev_priv, dss_ctl1_reg);
-	if (dss_ctl1_val & JOINER_ENABLE)
-		dss_ctl1_val &= ~JOINER_ENABLE;
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-
-	dss_ctl2_val = intel_de_read(dev_priv, 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);
-	intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
+	intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
+	intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
 
 	/* Disable Power wells for VDSC/joining */
 	intel_display_power_put_unchecked(dev_priv,
 					  intel_dsc_power_domain(old_crtc_state));
 }
+
+void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
+{
+	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	enum intel_display_power_domain power_domain;
+	intel_wakeref_t wakeref;
+	u32 dss_ctl1, dss_ctl2, val;
+
+	if (!intel_dsc_source_support(crtc_state))
+		return;
+
+	power_domain = intel_dsc_power_domain(crtc_state);
+
+	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+	if (!wakeref)
+		return;
+
+	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
+	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
+
+	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
+	if (!crtc_state->dsc.compression_enable)
+		goto out;
+
+	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
+		(dss_ctl1 & JOINER_ENABLE);
+
+	if (dss_ctl1 & BIG_JOINER_ENABLE) {
+		crtc_state->bigjoiner = true;
+
+		if (!(dss_ctl1 & 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);
+		}
+	}
+
+	/* FIXME: add more state readout as needed */
+
+	/* PPS1 */
+	if (!is_pipe_dsc(crtc_state))
+		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
+	else
+		val = intel_de_read(dev_priv,
+				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
+	vdsc_cfg->bits_per_pixel = val;
+	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
+out:
+	intel_display_power_put(dev_priv, power_domain, wakeref);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index e56a3254c214..5301345ac5e7 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -11,15 +11,14 @@
 struct intel_encoder;
 struct intel_crtc_state;
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state);
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
 void intel_dsc_enable(struct intel_encoder *encoder,
 		      const struct intel_crtc_state *crtc_state);
 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_encoder *encoder,
-			  struct intel_crtc_state *crtc_state);
+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.19.1

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

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

* [Intel-gfx] [PATCH v6 07/11] drm/i915: Make hardware readout work on i915.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (4 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual Rebase (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 64 +++++++++++++++++++-
 1 file changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 1cda8900d8f5..bfc5c890ab4e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3606,6 +3606,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;
 	struct i915_vma *vma;
 
@@ -3628,7 +3630,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);
@@ -3650,6 +3652,11 @@ 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;
 
@@ -10570,6 +10577,7 @@ static void
 skl_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);
@@ -10678,6 +10686,18 @@ skl_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 &&
+		    (intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000) == plane_config->base) {
+			val = intel_de_read(dev_priv, PLANE_SIZE(bigjoiner_pipe, plane_id));
+			fb->height += ((val >> 16) & 0xfff) + 1;
+			fb->width += ((val >> 0) & 0x1fff) + 1;
+		}
+	}
+
 	val = intel_de_read(dev_priv, PLANE_STRIDE(pipe, plane_id));
 	stride_mult = skl_plane_stride_mult(fb, 0, DRM_MODE_ROTATE_0);
 	fb->pitches[0] = (val & 0x3ff) * stride_mult;
@@ -18474,7 +18494,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, ctx);
 
 	if (crtc_state->hw.active || HAS_GMCH(dev_priv)) {
@@ -18751,6 +18772,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;
 
@@ -18775,6 +18799,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);
@@ -18825,6 +18852,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;
+
+			cdclk_state->min_cdclk[slave->pipe] = min_cdclk;
+			cdclk_state->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.19.1

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

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

* [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (5 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 07/11] drm/i915: Make hardware readout work on i915 Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-09-03 19:19   ` Ville Syrjälä
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 09/11] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
                   ` (17 subsequent siblings)
  24 siblings, 1 reply; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

 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.

v5:
* Rebase after adding sagv support (Manasi)
v4:
* Manual rebase (Manasi)
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>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
 .../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  |  20 +-
 .../drm/i915/display/intel_display_types.h    |  11 +
 drivers/gpu/drm/i915/intel_pm.c               |  20 +-
 6 files changed, 274 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 79032701873a..5c6e72063fac 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -246,11 +246,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);
 
+	if (from_plane_state->uapi.crtc)
+		plane_state->hw.crtc = crtc_state->uapi.crtc;
+	else
+		plane_state->hw.crtc = NULL;
+
 	plane_state->hw.crtc = from_plane_state->uapi.crtc;
 	plane_state->hw.fb = from_plane_state->uapi.fb;
 	if (plane_state->hw.fb)
@@ -319,15 +325,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;
 }
 
@@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
 		intel_atomic_get_new_plane_state(state, plane);
 	const struct intel_plane_state *old_plane_state =
 		intel_atomic_get_old_plane_state(state, plane);
+	const struct intel_plane_state *new_master_plane_state;
 	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;
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+	if (crtc)
+		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
+	else
+		new_crtc_state = NULL;
+
+	new_master_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);
+
 	new_plane_state->uapi.visible = false;
 	if (!crtc)
 		return 0;
 
 	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
-	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 
 	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
 
 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 bfc5c890ab4e..6f4a2845674d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 	drm_framebuffer_get(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);
 
 	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
 
@@ -12582,26 +12582,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);
 
-		drm_WARN_ON(state->base.dev,
-			    linked_plane_state->planar_linked_plane != plane);
-		drm_WARN_ON(state->base.dev,
-			    linked_plane_state->planar_slave == plane_state->planar_slave);
+			if (IS_ERR(linked_crtc_state))
+				return PTR_ERR(linked_crtc_state);
+		}
 	}
 
 	return 0;
@@ -12641,6 +12795,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)))
@@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
 		memcpy(linked_state->color_plane, plane_state->color_plane,
 		       sizeof(linked_state->color_plane));
 
-		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;
 
@@ -15028,6 +15190,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) {
@@ -15038,6 +15201,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;
 
@@ -15062,7 +15231,11 @@ 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 "
@@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
 	new_plane_state->uapi.crtc_w = crtc_w;
 	new_plane_state->uapi.crtc_h = crtc_h;
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
 
 	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
 						  old_plane_state, new_plane_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index e890c8fb779b..78010ee364f3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -467,12 +467,20 @@ enum phy_fia {
 		for_each_if(crtc)
 
 #define intel_atomic_crtc_state_for_each_plane_state( \
-		  plane, 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))))
+	plane, iter, plane_state, \
+	crtc_state) \
+	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 943709f192f7..6957eac140cd 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3150,7 +3150,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 *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;
@@ -3160,7 +3160,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)
@@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	int level, latency;
 
@@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
 	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
 		return false;
 
-	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) {
 		const struct skl_plane_wm *wm =
 			&crtc_state->wm.skl.optimal.planes[plane->id];
 
@@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
 				 u64 *plane_data_rate,
 				 u64 *uv_plane_data_rate)
 {
-	struct intel_plane *plane;
+	struct intel_plane *plane, *iter;
 	const struct intel_plane_state *plane_state;
 	u64 total_data_rate = 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;
 
@@ -4741,12 +4741,12 @@ 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;
 
 	/* 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;
 
@@ -5593,7 +5593,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;
 
@@ -5603,7 +5603,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.19.1

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

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

* [Intel-gfx] [PATCH v6 09/11] drm/i915: Add bigjoiner aware plane clipping checks
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (6 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling Manasi Navare
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual rebase (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@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 5c6e72063fac..fe19cbaa83b0 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -268,6 +268,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);
 }
 
 void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
@@ -516,6 +519,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 c2a1e7c86e6c..d0a599d00ecd 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -53,6 +53,10 @@ int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_stat
 int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
 			       struct intel_plane *plane,
 			       bool *need_cdclk_calc);
+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);
 void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
 			       struct intel_plane_state *plane_state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 6f4a2845674d..a1011414da6d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4356,12 +4356,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;
 
@@ -11485,11 +11483,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 d03860fef2d7..60eeed06a780 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -2010,10 +2010,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;
 
@@ -2068,11 +2066,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;
 
@@ -2279,10 +2276,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.19.1

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

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

* [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (7 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 09/11] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-24 22:15   ` Navare, Manasi
  2020-09-03 19:23   ` Ville Syrjälä
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
                   ` (15 subsequent siblings)
  24 siblings, 2 replies; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

****This needs to be checked if it still works since lot of refactoring
in skl_commit_modeset_enables

v2:
* Manual Rebase (Manasi)
* Refactoring on intel_update_crtc and enable_crtc and removing
special trans_port_sync_update (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
 drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
 drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
 3 files changed, 129 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index a1011414da6d..00b26863ffc6 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
 	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
@@ -15754,6 +15754,52 @@ 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);
+
+	if (modeset) {
+		/* Enable slave first */
+		intel_crtc_update_active_timings(new_slave_crtc_state);
+		dev_priv->display.crtc_enable(state, slave);
+
+		/* Then master */
+		intel_crtc_update_active_timings(new_crtc_state);
+		dev_priv->display.crtc_enable(state, crtc);
+
+		/* vblanks work again, re-enable pipe CRC. */
+		intel_crtc_enable_pipe_crc(crtc);
+
+	} else {
+		intel_pre_plane_update(state, crtc);
+		intel_pre_plane_update(state, slave);
+
+		if (new_crtc_state->update_pipe)
+			intel_encoders_update_pipe(state, crtc);
+	}
+
+	/*
+	 * 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, crtc);
+	commit_pipe_config(state, slave);
+
+	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_state *new_crtc_state;
@@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
 static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-	struct intel_crtc *crtc;
+	struct intel_crtc *crtc, *slave;
 	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
 	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
+	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
 	u8 update_pipes = 0, modeset_pipes = 0;
+	const struct intel_crtc_state *slave_crtc_state;
 	int i;
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
 		enum pipe pipe = crtc->pipe;
 
+		if (new_crtc_state->bigjoiner_slave) {
+			/* We're updated from master */
+			continue;
+		}
+
 		if (!new_crtc_state->hw.active)
 			continue;
 
@@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 		} else {
 			modeset_pipes |= BIT(pipe);
 		}
+
+		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;
+		}
+
+		/* ignore allocations for crtc's that have been turned off during modeset. */
+		if (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;
+		}
 	}
 
 	/*
@@ -15806,28 +15887,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 						    new_crtc_state, i) {
 			enum pipe pipe = crtc->pipe;
+			bool ddb_changed;
 
 			if ((update_pipes & BIT(pipe)) == 0)
 				continue;
 
-			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
+			if (skl_ddb_allocation_overlaps(&new_entries[pipe],
 							entries, I915_MAX_PIPES, pipe))
 				continue;
 
-			entries[pipe] = new_crtc_state->wm.skl.ddb;
+			ddb_changed = !skl_ddb_entry_equal(&new_entries[pipe], &entries[pipe]);
+			entries[pipe] = new_entries[pipe];
 			update_pipes &= ~BIT(pipe);
 
-			intel_update_crtc(state, crtc);
-
 			/*
 			 * If this is an already active pipe, it's DDB changed,
 			 * and this isn't the last pipe that needs updating
 			 * 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) &&
-			    (update_pipes | modeset_pipes))
+			if (new_crtc_state->bigjoiner) {
+				intel_update_bigjoiner(crtc, state,
+						       old_crtc_state,
+						       new_crtc_state);
+			} else {
+				intel_update_crtc(state, crtc);
+			}
+
+			if (ddb_changed && (update_pipes | modeset_pipes))
 				intel_wait_for_vblank(dev_priv, pipe);
 		}
 	}
@@ -15863,9 +15950,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 		if ((modeset_pipes & BIT(pipe)) == 0)
 			continue;
 
+		WARN_ON(skl_ddb_allocation_overlaps(&new_entries[pipe],
+						    entries, I915_MAX_PIPES, pipe));
+
+		entries[pipe] = new_entries[pipe];
 		modeset_pipes &= ~BIT(pipe);
 
-		intel_enable_crtc(state, crtc);
+		if (new_crtc_state->bigjoiner)
+			intel_update_bigjoiner(crtc, state,
+					       old_crtc_state,
+					       new_crtc_state);
+		else
+			intel_enable_crtc(state, crtc);
 	}
 
 	/*
@@ -15877,10 +15973,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 		if ((update_pipes & BIT(pipe)) == 0)
 			continue;
 
-		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
+		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_entries[pipe],
 									entries, I915_MAX_PIPES, pipe));
 
-		entries[pipe] = new_crtc_state->wm.skl.ddb;
+		entries[pipe] = new_entries[pipe];
 		update_pipes &= ~BIT(pipe);
 
 		intel_update_crtc(state, crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 60eeed06a780..eaae5df546fe 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -99,6 +99,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;
 
@@ -191,7 +193,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;
@@ -206,16 +209,26 @@ 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) {
-		drm_WARN_ON(&dev_priv->drm,
-			    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)
+			drm_WARN_ON(&dev_priv->drm,
+				    drm_crtc_vblank_get(&crtc->base) != 0);
+		if (slave_crtc_state && slave_crtc_state->uapi.event)
+			drm_WARN_ON(&dev_priv->drm,
+				    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 cd2104ba1ca1..15e7c112ec77 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.19.1

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

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

* [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3.
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (8 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling Manasi Navare
@ 2020-07-15 22:42 ` Manasi Navare
  2020-08-10 12:47   ` Maarten Lankhorst
  2020-07-15 22:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system Patchwork
                   ` (14 subsequent siblings)
  24 siblings, 1 reply; 80+ messages in thread
From: Manasi Navare @ 2020-07-15 22:42 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

Dump debugfs and planar links as well, this will make it easier to debug
when things go wrong.

v4:
* Rebase
Changes since v1:
- Report planar slaves as such, now that we have the plane_state switch.
Changes since v2:
- Rebase on top of the new plane format dumping

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 .../drm/i915/display/intel_display_debugfs.c  | 29 ++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 3644752cc5ec..5576f79f84ab 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -745,6 +745,17 @@ static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
 		 rotation);
 }
 
+static const char *plane_visibility(const 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_uapi_info(struct seq_file *m, struct intel_plane *plane)
 {
 	const struct intel_plane_state *plane_state =
@@ -763,12 +774,22 @@ static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
 	plane_rotation(rot_str, sizeof(rot_str),
 		       plane_state->uapi.rotation);
 
-	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
+	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
 		   fb ? fb->base.id : 0, fb ? format_name.str : "n/a",
 		   fb ? fb->width : 0, fb ? fb->height : 0,
+		   plane_visibility(plane_state),
 		   DRM_RECT_FP_ARG(&src),
 		   DRM_RECT_ARG(&dst),
 		   rot_str);
+
+	if (plane_state->planar_linked_plane)
+		seq_printf(m, "\t\tplanar: Linked to [PLANE:%d:%s] as a %s\n",
+			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,
+			   plane_state->planar_slave ? "slave" : "master");
+	if (plane_state->bigjoiner_plane)
+		seq_printf(m, "\t\tbigjoiner: Linked to [PLANE:%d:%s] as a %s\n",
+			   plane_state->bigjoiner_plane->base.base.id, plane_state->bigjoiner_plane->base.name,
+			   plane_state->bigjoiner_slave ? "slave" : "master");
 }
 
 static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
@@ -864,6 +885,12 @@ static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
 		intel_scaler_info(m, crtc);
 	}
 
+	if (crtc_state->bigjoiner)
+		seq_printf(m, "\tLinked to [CRTC:%d:%s] as a %s\n",
+			   crtc_state->bigjoiner_linked_crtc->base.base.id,
+			   crtc_state->bigjoiner_linked_crtc->base.name,
+			   crtc_state->bigjoiner_slave ? "slave" : "master");
+
 	for_each_intel_encoder_mask(&dev_priv->drm, encoder,
 				    crtc_state->uapi.encoder_mask)
 		intel_encoder_info(m, crtc, encoder);
-- 
2.19.1

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (9 preceding siblings ...)
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
@ 2020-07-15 22:50 ` Patchwork
  2020-07-15 22:51 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-15 22:50 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim checkpatch origin/drm-tip
97213337456c HAX to make DSC work on the icelake test system
c5f13f63734e drm/i915: Remove hw.mode
06b1c3fee1b8 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:216: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#216: FILE: drivers/gpu/drm/i915/display/intel_display.c:13219:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 0 warnings, 1 checks, 445 lines checked
7f531ea79d54 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
dd3180f28a31 drm/i915: Try to make bigjoiner work in atomic check
-:143: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#143: FILE: drivers/gpu/drm/i915/display/intel_display.c:13232:
+								  crtc_state->bigjoiner_linked_crtc);

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

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

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

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

-:332: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#332: FILE: drivers/gpu/drm/i915/display/intel_display.c:14956:
+		slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

-:387: WARNING:BRACES: braces {} are not necessary for any arm of this statement
#387: FILE: drivers/gpu/drm/i915/display/intel_display.c:15351:
+	if (new_crtc_state->bigjoiner) {
[...]
+	} else if (INTEL_GEN(dev_priv) >= 9)
[...]
 	else
[...]

total: 0 errors, 3 warnings, 5 checks, 401 lines checked
e1bdcad4337a drm/i915: Enable big joiner support in enable and disable sequences.
-:172: WARNING:LONG_LINE_COMMENT: line length of 106 exceeds 100 columns
#172: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4353:
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

-:174: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#174: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4355:
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;

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

total: 0 errors, 2 warnings, 1 checks, 996 lines checked
90d6f402f5d0 drm/i915: Make hardware readout work on i915.
-:33: WARNING:TABSTOP: Statements should start on a tabstop
#33: FILE: drivers/gpu/drm/i915/display/intel_display.c:3609:
+	 struct intel_crtc_state *crtc_state =

-:76: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#76: FILE: drivers/gpu/drm/i915/display/intel_display.c:10694:
+		    (intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000) == plane_config->base) {

total: 0 errors, 2 warnings, 0 checks, 118 lines checked
7298e6626786 drm/i915: Link planes in a bigjoiner configuration, v3.
-:203: ERROR:CODE_INDENT: code indent should use tabs where possible
#203: FILE: drivers/gpu/drm/i915/display/intel_display.c:12626:
+         * Setup and teardown the new bigjoiner plane mappings.$

-:204: ERROR:CODE_INDENT: code indent should use tabs where possible
#204: FILE: drivers/gpu/drm/i915/display/intel_display.c:12627:
+         */$

-:289: ERROR:CODE_INDENT: code indent should use tabs where possible
#289: FILE: drivers/gpu/drm/i915/display/intel_display.c:12708:
+         *$

-:305: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#305: FILE: drivers/gpu/drm/i915/display/intel_display.c:12722:
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {

-:321: ERROR:CODE_INDENT: code indent should use tabs where possible
#321: FILE: drivers/gpu/drm/i915/display/intel_display.c:12738:
+         * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically$

-:322: ERROR:CODE_INDENT: code indent should use tabs where possible
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:12739:
+         * when adding slave planes, because plane_state->crtc is null.$

-:323: ERROR:CODE_INDENT: code indent should use tabs where possible
#323: FILE: drivers/gpu/drm/i915/display/intel_display.c:12740:
+         */$

-:435: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#435: FILE: drivers/gpu/drm/i915/display/intel_display.h:472:
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
[...]
+	for_each_if ((((plane_state) = \

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

-:442: WARNING:LONG_LINE: line length of 124 exceeds 100 columns
#442: FILE: drivers/gpu/drm/i915/display/intel_display.h:479:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \

-:443: WARNING:LONG_LINE: line length of 109 exceeds 100 columns
#443: FILE: drivers/gpu/drm/i915/display/intel_display.h:480:
+		      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

-:445: WARNING:LONG_LINE: line length of 125 exceeds 100 columns
#445: FILE: drivers/gpu/drm/i915/display/intel_display.h:482:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \

total: 6 errors, 6 warnings, 0 checks, 481 lines checked
89341c274ddb drm/i915: Add bigjoiner aware plane clipping checks
7dfe04b30dac drm/i915: Add intel_update_bigjoiner handling.
bf27758c62ad drm/i915: Add debugfs dumping for bigjoiner, v3.
-:46: WARNING:LONG_LINE: line length of 123 exceeds 100 columns
#46: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:777:
+	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",

-:56: WARNING:LONG_LINE: line length of 119 exceeds 100 columns
#56: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:787:
+			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,

-:60: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#60: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:791:
+			   plane_state->bigjoiner_plane->base.base.id, plane_state->bigjoiner_plane->base.name,

total: 0 errors, 3 warnings, 0 checks, 52 lines checked


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

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (10 preceding siblings ...)
  2020-07-15 22:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system Patchwork
@ 2020-07-15 22:51 ` Patchwork
  2020-07-15 23:12 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-15 22:51 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.0
Fast mode used, each commit won't be checked separately.


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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [v6,01/11] HAX to make DSC work on the icelake test system
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (11 preceding siblings ...)
  2020-07-15 22:51 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-07-15 23:12 ` Patchwork
  2020-07-16  5:48 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-15 23:12 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7916 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8752 -> Patchwork_18184
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Issues hit ####

  * igt@i915_module_load@reload:
    - fi-kbl-soraka:      [PASS][1] -> [DMESG-WARN][2] ([i915#1982])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-kbl-soraka/igt@i915_module_load@reload.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-kbl-soraka/igt@i915_module_load@reload.html
    - fi-tgl-u2:          [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-tgl-u2/igt@i915_module_load@reload.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-tgl-u2/igt@i915_module_load@reload.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
    - fi-bsw-kefka:       [PASS][5] -> [DMESG-WARN][6] ([i915#1982])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-icl-u2:          [PASS][7] -> [DMESG-WARN][8] ([i915#1982])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@vgem_basic@sysfs:
    - fi-tgl-y:           [PASS][9] -> [DMESG-WARN][10] ([i915#402]) +1 similar issue
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-tgl-y/igt@vgem_basic@sysfs.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-tgl-y/igt@vgem_basic@sysfs.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-ilk-650:         [DMESG-WARN][11] ([i915#164]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-ilk-650/igt@gem_exec_suspend@basic-s3.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-ilk-650/igt@gem_exec_suspend@basic-s3.html

  * igt@i915_selftest@live@execlists:
    - fi-cfl-8109u:       [INCOMPLETE][13] -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-cfl-8109u/igt@i915_selftest@live@execlists.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-cfl-8109u/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@gem_contexts:
    - fi-tgl-u2:          [INCOMPLETE][15] ([i915#2045]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-tgl-u2/igt@i915_selftest@live@gem_contexts.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-tgl-u2/igt@i915_selftest@live@gem_contexts.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-bsw-n3050:       [DMESG-WARN][17] ([i915#1982]) -> [PASS][18] +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-bsw-kefka:       [DMESG-WARN][19] ([i915#1982]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@vgem_basic@setversion:
    - fi-tgl-y:           [DMESG-WARN][21] ([i915#402]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-tgl-y/igt@vgem_basic@setversion.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-tgl-y/igt@vgem_basic@setversion.html

  
#### Warnings ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-kbl-x1275:       [DMESG-WARN][23] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][24] ([i915#62] / [i915#92]) +5 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-kbl-x1275/igt@gem_exec_suspend@basic-s0.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - fi-kbl-x1275:       [DMESG-WARN][25] ([i915#62] / [i915#92]) -> [DMESG-WARN][26] ([i915#62] / [i915#92] / [i915#95]) +3 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-kbl-x1275/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-kbl-x1275/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  * igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a:
    - fi-kbl-x1275:       [DMESG-WARN][27] ([i915#1982] / [i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][28] ([i915#62] / [i915#92])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/fi-kbl-x1275/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/fi-kbl-x1275/igt@kms_pipe_crc_basic@suspend-read-crc-pipe-a.html

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

  [i915#164]: https://gitlab.freedesktop.org/drm/intel/issues/164
  [i915#1887]: https://gitlab.freedesktop.org/drm/intel/issues/1887
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2045]: https://gitlab.freedesktop.org/drm/intel/issues/2045
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (47 -> 40)
------------------------------

  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus 


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

  * Linux: CI_DRM_8752 -> Patchwork_18184

  CI-20190529: 20190529
  CI_DRM_8752: 1930108b29bad150bd4b521f4a73948bd91997e0 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5737: c18a9c1083ce9344ff71ae405b9f2deaa82b6702 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18184: bf27758c62ad1f53fbb305e0749bf0457cb95896 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

bf27758c62ad drm/i915: Add debugfs dumping for bigjoiner, v3.
7dfe04b30dac drm/i915: Add intel_update_bigjoiner handling.
89341c274ddb drm/i915: Add bigjoiner aware plane clipping checks
7298e6626786 drm/i915: Link planes in a bigjoiner configuration, v3.
90d6f402f5d0 drm/i915: Make hardware readout work on i915.
e1bdcad4337a drm/i915: Enable big joiner support in enable and disable sequences.
dd3180f28a31 drm/i915: Try to make bigjoiner work in atomic check
7f531ea79d54 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
06b1c3fee1b8 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
c5f13f63734e drm/i915: Remove hw.mode
97213337456c 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_18184/index.html

[-- Attachment #1.2: Type: text/html, Size: 10031 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [v6,01/11] HAX to make DSC work on the icelake test system
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (12 preceding siblings ...)
  2020-07-15 23:12 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-07-16  5:48 ` Patchwork
  2020-07-16 21:53 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2) Patchwork
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-16  5:48 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 16253 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8752_full -> Patchwork_18184_full
====================================================

Summary
-------

  **FAILURE**

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

### IGT changes ###

#### Possible regressions ####

  * igt@kms_dp_dsc@basic-dsc-enable-edp:
    - shard-tglb:         [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb2/igt@kms_dp_dsc@basic-dsc-enable-edp.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb6/igt@kms_dp_dsc@basic-dsc-enable-edp.html

  
#### Warnings ####

  * igt@runner@aborted:
    - shard-tglb:         ([FAIL][3], [FAIL][4], [FAIL][5]) ([i915#1764] / [i915#2110]) -> [FAIL][6]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb7/igt@runner@aborted.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb3/igt@runner@aborted.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb7/igt@runner@aborted.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb6/igt@runner@aborted.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@bonded-early:
    - shard-kbl:          [PASS][7] -> [FAIL][8] ([i915#2079])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-kbl2/igt@gem_exec_balancer@bonded-early.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-kbl3/igt@gem_exec_balancer@bonded-early.html

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-glk:          [PASS][9] -> [FAIL][10] ([i915#1930])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk8/igt@gem_exec_reloc@basic-concurrent0.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk7/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@gem_exec_whisper@basic-contexts-priority-all:
    - shard-glk:          [PASS][11] -> [DMESG-WARN][12] ([i915#118] / [i915#95])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk2/igt@gem_exec_whisper@basic-contexts-priority-all.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk6/igt@gem_exec_whisper@basic-contexts-priority-all.html

  * igt@gem_workarounds@suspend-resume-context:
    - shard-skl:          [PASS][13] -> [INCOMPLETE][14] ([CI#80] / [i915#69])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl1/igt@gem_workarounds@suspend-resume-context.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl9/igt@gem_workarounds@suspend-resume-context.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-180:
    - shard-glk:          [PASS][15] -> [DMESG-FAIL][16] ([i915#118] / [i915#95])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk2/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk8/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html

  * igt@kms_color@pipe-c-ctm-green-to-red:
    - shard-skl:          [PASS][17] -> [DMESG-WARN][18] ([i915#1982]) +10 similar issues
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl9/igt@kms_color@pipe-c-ctm-green-to-red.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl1/igt@kms_color@pipe-c-ctm-green-to-red.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-skl:          [PASS][19] -> [INCOMPLETE][20] ([i915#300])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl2/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl3/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size:
    - shard-apl:          [PASS][21] -> [DMESG-WARN][22] ([i915#1635] / [i915#1982])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-apl8/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-apl6/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size.html

  * igt@kms_flip@flip-vs-expired-vblank-interruptible@c-dp1:
    - shard-apl:          [PASS][23] -> [FAIL][24] ([i915#1635] / [i915#79])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-apl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-dp1.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-apl6/igt@kms_flip@flip-vs-expired-vblank-interruptible@c-dp1.html

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          [PASS][25] -> [DMESG-WARN][26] ([i915#180]) +4 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-kbl7/igt@kms_frontbuffer_tracking@fbc-suspend.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-kbl1/igt@kms_frontbuffer_tracking@fbc-suspend.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt:
    - shard-skl:          [PASS][27] -> [FAIL][28] ([i915#49])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl2/igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl3/igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt.html

  * igt@kms_frontbuffer_tracking@psr-rgb565-draw-pwrite:
    - shard-tglb:         [PASS][29] -> [DMESG-WARN][30] ([i915#1982]) +2 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb2/igt@kms_frontbuffer_tracking@psr-rgb565-draw-pwrite.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb1/igt@kms_frontbuffer_tracking@psr-rgb565-draw-pwrite.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [PASS][31] -> [FAIL][32] ([fdo#108145] / [i915#265]) +3 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl4/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl10/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_basic:
    - shard-iclb:         [PASS][33] -> [SKIP][34] ([fdo#109441]) +1 similar issue
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-iclb2/igt@kms_psr@psr2_basic.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-iclb7/igt@kms_psr@psr2_basic.html

  * igt@kms_setmode@clone-exclusive-crtc:
    - shard-tglb:         [PASS][35] -> [DMESG-WARN][36] ([i915#402])
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb1/igt@kms_setmode@clone-exclusive-crtc.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb2/igt@kms_setmode@clone-exclusive-crtc.html

  * igt@perf@blocking-parameterized:
    - shard-iclb:         [PASS][37] -> [FAIL][38] ([i915#1542])
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-iclb1/igt@perf@blocking-parameterized.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-iclb6/igt@perf@blocking-parameterized.html

  
#### Possible fixes ####

  * igt@gem_busy@close-race:
    - shard-skl:          [DMESG-WARN][39] ([i915#1982]) -> [PASS][40] +9 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl9/igt@gem_busy@close-race.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl4/igt@gem_busy@close-race.html

  * igt@gem_exec_create@forked:
    - shard-glk:          [DMESG-WARN][41] ([i915#118] / [i915#95]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk2/igt@gem_exec_create@forked.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk6/igt@gem_exec_create@forked.html

  * {igt@gem_huc_copy@huc-copy}:
    - shard-tglb:         [SKIP][43] -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb6/igt@gem_huc_copy@huc-copy.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb8/igt@gem_huc_copy@huc-copy.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [DMESG-WARN][45] ([i915#1436] / [i915#716]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl7/igt@gen9_exec_parse@allowed-single.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl9/igt@gen9_exec_parse@allowed-single.html

  * igt@i915_module_load@reload:
    - shard-tglb:         [DMESG-WARN][47] ([i915#402]) -> [PASS][48] +1 similar issue
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb8/igt@i915_module_load@reload.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb1/igt@i915_module_load@reload.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-0:
    - shard-glk:          [DMESG-FAIL][49] ([i915#118] / [i915#95]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk8/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk7/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html

  * igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size:
    - shard-kbl:          [DMESG-WARN][51] ([i915#1982]) -> [PASS][52]
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-kbl4/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-kbl7/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions-varying-size.html

  * igt@kms_draw_crc@draw-method-rgb565-render-ytiled:
    - shard-glk:          [DMESG-WARN][53] ([i915#1982]) -> [PASS][54]
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk2/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk6/igt@kms_draw_crc@draw-method-rgb565-render-ytiled.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-blt-untiled:
    - shard-apl:          [DMESG-WARN][55] ([i915#1635] / [i915#1982]) -> [PASS][56]
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-apl4/igt@kms_draw_crc@draw-method-xrgb2101010-blt-untiled.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-apl1/igt@kms_draw_crc@draw-method-xrgb2101010-blt-untiled.html

  * igt@kms_flip@blocking-wf_vblank@b-hdmi-a1:
    - shard-glk:          [FAIL][57] ([i915#2122]) -> [PASS][58]
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-glk9/igt@kms_flip@blocking-wf_vblank@b-hdmi-a1.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-glk9/igt@kms_flip@blocking-wf_vblank@b-hdmi-a1.html

  * igt@kms_flip@flip-vs-suspend@c-dp1:
    - shard-kbl:          [DMESG-WARN][59] ([i915#180]) -> [PASS][60] +9 similar issues
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-kbl3/igt@kms_flip@flip-vs-suspend@c-dp1.html
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-kbl7/igt@kms_flip@flip-vs-suspend@c-dp1.html

  * igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1:
    - shard-skl:          [FAIL][61] ([i915#2122]) -> [PASS][62] +1 similar issue
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl2/igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1.html
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl3/igt@kms_flip@plain-flip-fb-recreate-interruptible@c-edp1.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move:
    - shard-tglb:         [SKIP][63] ([i915#668]) -> [PASS][64] +2 similar issues
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb8/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move.html
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-spr-indfb-move.html

  * igt@kms_hdr@bpc-switch:
    - shard-skl:          [FAIL][65] ([i915#1188]) -> [PASS][66]
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-skl8/igt@kms_hdr@bpc-switch.html
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-skl5/igt@kms_hdr@bpc-switch.html

  * igt@kms_psr@psr2_cursor_blt:
    - shard-iclb:         [SKIP][67] ([fdo#109441]) -> [PASS][68] +1 similar issue
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-iclb3/igt@kms_psr@psr2_cursor_blt.html
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-iclb2/igt@kms_psr@psr2_cursor_blt.html

  * igt@perf@polling-parameterized:
    - shard-tglb:         [FAIL][69] ([i915#1542]) -> [PASS][70]
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8752/shard-tglb2/igt@perf@polling-parameterized.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/shard-tglb6/igt@perf@polling-parameterized.html

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

  [CI#80]: https://gitlab.freedesktop.org/gfx-ci/i915-infra/issues/80
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#1764]: https://gitlab.freedesktop.org/drm/intel/issues/1764
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1930]: https://gitlab.freedesktop.org/drm/intel/issues/1930
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2079]: https://gitlab.freedesktop.org/drm/intel/issues/2079
  [i915#2110]: https://gitlab.freedesktop.org/drm/intel/issues/2110
  [i915#2122]: https://gitlab.freedesktop.org/drm/intel/issues/2122
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#300]: https://gitlab.freedesktop.org/drm/intel/issues/300
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#49]: https://gitlab.freedesktop.org/drm/intel/issues/49
  [i915#668]: https://gitlab.freedesktop.org/drm/intel/issues/668
  [i915#69]: https://gitlab.freedesktop.org/drm/intel/issues/69
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


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

  * Linux: CI_DRM_8752 -> Patchwork_18184

  CI-20190529: 20190529
  CI_DRM_8752: 1930108b29bad150bd4b521f4a73948bd91997e0 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5737: c18a9c1083ce9344ff71ae405b9f2deaa82b6702 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18184: bf27758c62ad1f53fbb305e0749bf0457cb95896 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18184/index.html

[-- Attachment #1.2: Type: text/html, Size: 18970 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences Manasi Navare
@ 2020-07-16 19:27   ` Manasi Navare
  2020-08-10 12:45     ` Maarten Lankhorst
  2020-07-16 21:12   ` [Intel-gfx] [PATCH v7 " Manasi Navare
  1 sibling, 1 reply; 80+ messages in thread
From: Manasi Navare @ 2020-07-16 19:27 UTC (permalink / raw)
  To: intel-gfx

On Wed, Jul 15, 2020 at 03:42:17PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> v2:
> * Manual rebase (Manasi)
> 
> v3:
> * Rebase (Manasi)
> 
> v4:
> * Rebase (Manasi)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
>  drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 199 ++++-----
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
>  7 files changed, 414 insertions(+), 246 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 8c55f5bee9ab..26f7372b4c25 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>  	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
>  
> -	intel_dsc_get_config(encoder, pipe_config);
> -
>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
>  						      pipe_config->shared_dpll);
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 424d59671561..dd97d725ae65 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -28,6 +28,7 @@
>  #include <drm/drm_scdc_helper.h>
>  
>  #include "i915_drv.h"
> +#include "i915_trace.h"
>  #include "intel_audio.h"
>  #include "intel_combo_phy.h"
>  #include "intel_connector.h"
> @@ -2040,12 +2041,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>  		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(struct intel_encoder *encoder,
> @@ -3313,7 +3308,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
>  
>  	/* 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_atomic_state *state,
> @@ -3384,7 +3380,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
>  	if (!is_mst)
>  		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
> @@ -3639,6 +3636,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
>  			ilk_pfit_disable(old_crtc_state);
>  	}
>  
> +	if (old_crtc_state->bigjoiner_linked_crtc) {
> +		struct intel_atomic_state *state =
> +			to_intel_atomic_state(old_crtc_state->uapi.state);
> +		struct intel_crtc *slave =
> +			old_crtc_state->bigjoiner_linked_crtc;
> +		const struct intel_crtc_state *old_slave_crtc_state =
> +			intel_atomic_get_old_crtc_state(state, slave);
> +
> +		intel_crtc_vblank_off(old_slave_crtc_state);
> +		trace_intel_pipe_disable(slave);
> +
> +		intel_dsc_disable(old_slave_crtc_state);
> +		skl_scaler_disable(old_slave_crtc_state);
> +	}
> +
>  	/*
>  	 * When called from DP MST code:
>  	 * - old_conn_state will be NULL
> @@ -3853,7 +3865,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
>  {
>  	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
>  
> -	intel_ddi_enable_transcoder_func(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner_slave)
> +		intel_ddi_enable_transcoder_func(encoder, crtc_state);
>  
>  	intel_enable_pipe(crtc_state);
>  
> @@ -4200,8 +4213,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
>  		    crtc_state->sync_mode_slaves_mask);
>  }
>  
> -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);
> @@ -4209,13 +4222,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  	u32 temp, flags = 0;
>  
> -	/* XXX: DSI transcoder paranoia */
> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> +	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>  		return;
>  
> -	intel_dsc_get_config(encoder, pipe_config);
> -
> -	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
>  		flags |= DRM_MODE_FLAG_PHSYNC;
>  	else
> @@ -4323,6 +4333,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
>  		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
>  	}
> +}
> +
> +void intel_ddi_get_config(struct intel_encoder *encoder,
> +			  struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +
> +	/* XXX: DSI transcoder paranoia */
> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> +		return;
> +
> +	intel_ddi_read_func_ctl(encoder, pipe_config);
> +	if (pipe_config->bigjoiner_slave) {
> +		/* read out pipe settings from master */
> +		enum transcoder save = pipe_config->cpu_transcoder;
> +
> +		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
> +		WARN_ON(pipe_config->output_types);
> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> +		pipe_config->cpu_transcoder = save;
> +	}
>  
>  	pipe_config->has_audio =
>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
> @@ -4348,7 +4381,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 955e19abb563..1cda8900d8f5 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7023,6 +7023,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
>  	intel_de_write(dev_priv, reg, val);
>  }
>  
> +static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
> +					 const 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(state, master);
> +		intel_enable_shared_dpll(master_crtc_state);
> +		intel_encoders_pre_enable(state, master);
> +
> +		/* and DSC on slave */
> +		intel_dsc_enable(NULL, crtc_state);
> +	}
> +}
> +
>  static void hsw_crtc_enable(struct intel_atomic_state *state,
>  			    struct intel_crtc *crtc)
>  {
> @@ -7036,34 +7075,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
>  		return;
>  
> -	intel_encoders_pre_pll_enable(state, crtc);
> -
> -	if (new_crtc_state->shared_dpll)
> -		intel_enable_shared_dpll(new_crtc_state);
> +	if (!new_crtc_state->bigjoiner) {
> +		intel_encoders_pre_pll_enable(state, crtc);
>  
> -	intel_encoders_pre_enable(state, crtc);
> +		if (new_crtc_state->shared_dpll)
> +			intel_enable_shared_dpll(new_crtc_state);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_transcoder_timings(new_crtc_state);
> +		intel_encoders_pre_enable(state, crtc);
> +	} else {
> +		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
> +	}
>  
>  	intel_set_pipe_src_size(new_crtc_state);
> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> +		bdw_set_pipemisc(new_crtc_state);
>  
> -	if (cpu_transcoder != TRANSCODER_EDP &&
> -	    !transcoder_is_dsi(cpu_transcoder))
> -		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> -			       new_crtc_state->pixel_multiplier - 1);
> +	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> +		if (!transcoder_is_dsi(cpu_transcoder))
> +			intel_set_transcoder_timings(new_crtc_state);
>  
> -	if (new_crtc_state->has_pch_encoder)
> -		intel_cpu_transcoder_set_m_n(new_crtc_state,
> -					     &new_crtc_state->fdi_m_n, NULL);
> +		if (cpu_transcoder != TRANSCODER_EDP &&
> +		    !transcoder_is_dsi(cpu_transcoder))
> +			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> +				       new_crtc_state->pixel_multiplier - 1);
> +
> +		if (new_crtc_state->has_pch_encoder)
> +			intel_cpu_transcoder_set_m_n(new_crtc_state,
> +						     &new_crtc_state->fdi_m_n, NULL);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder)) {
>  		hsw_set_frame_start_delay(new_crtc_state);
> -		hsw_set_pipeconf(new_crtc_state);
>  	}
>  
> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> -		bdw_set_pipemisc(new_crtc_state);
> +	if (!transcoder_is_dsi(cpu_transcoder))
> +		hsw_set_pipeconf(new_crtc_state);
>  
>  	crtc->active = true;
>  
> @@ -7099,6 +7143,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	if (INTEL_GEN(dev_priv) >= 11)
>  		icl_pipe_mbus_enable(crtc);
>  
> +	if (new_crtc_state->bigjoiner_slave) {
> +		trace_intel_pipe_enable(crtc);
> +		intel_crtc_vblank_on(new_crtc_state);
> +	}
> +
>  	intel_encoders_enable(state, crtc);
>  
>  	if (psl_clkgate_wa) {
> @@ -7381,6 +7430,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;
>  }
>  
> @@ -7999,6 +8051,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>  		       pfit_w * pfit_h);
>  }
>  
> +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 pipe timings are half of the transcoder mode
> +		 */
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_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);
> @@ -8910,20 +8986,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
> +	mode->hdisplay = hw_mode->crtc_hdisplay;
> +	mode->htotal = hw_mode->crtc_htotal;
> +	mode->hsync_start = hw_mode->crtc_hsync_start;
> +	mode->hsync_end = hw_mode->crtc_hsync_end;
>  
> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
> +	mode->vdisplay = hw_mode->crtc_vdisplay;
> +	mode->vtotal = hw_mode->crtc_vtotal;
> +	mode->vsync_start = hw_mode->crtc_vsync_start;
> +	mode->vsync_end = hw_mode->crtc_vsync_end;
> +
> +	mode->flags = hw_mode->flags;
>  	mode->type = DRM_MODE_TYPE_DRIVER;
>  
> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
> +	mode->clock = hw_mode->crtc_clock;
>  
>  	drm_mode_set_name(mode);
>  }
> @@ -11081,6 +11159,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
>  	} else {
>  		tmp = intel_de_read(dev_priv,
>  				    TRANS_DDI_FUNC_CTL(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);
>  		else
> @@ -11153,12 +11234,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		drm_WARN_ON(&dev_priv->drm, 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) ||
> -	    INTEL_GEN(dev_priv) >= 11) {
> +		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) {
>  		hsw_get_ddi_port_state(crtc, pipe_config);
>  		intel_get_transcoder_timings(crtc, pipe_config);
>  	}
> @@ -11244,8 +11333,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> -	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> +	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 =
>  			intel_de_read(dev_priv,
>  				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> @@ -12260,7 +12352,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);
>  
> @@ -13252,10 +13344,12 @@ 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;
> -	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> -		    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;
> +		drm_WARN_ON(crtc_state->uapi.crtc->dev,
> +			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> +	}
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -13902,21 +13996,42 @@ 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_BOOL(has_hdmi_sink);
>  	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
> @@ -13926,24 +14041,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)
> @@ -13969,7 +14071,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))
> @@ -13990,48 +14093,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(double_wide);
>  
>  	PIPE_CONF_CHECK_P(shared_dpll);
> -	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);
> +	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(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);
> @@ -14043,11 +14149,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
>  	PIPE_CONF_CHECK_I(dsc.dsc_split);
>  	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
> -
>  	PIPE_CONF_CHECK_I(mst_master_transcoder);
>  
>  #undef PIPE_CONF_CHECK_X
> @@ -14314,6 +14421,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>  	struct intel_encoder *encoder;
>  	struct intel_crtc_state *pipe_config = old_crtc_state;
>  	struct drm_atomic_state *state = old_crtc_state->uapi.state;
> +	struct intel_crtc *master = crtc;
>  	bool active;
>  
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> @@ -14340,7 +14448,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);
> @@ -14349,12 +14460,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);
> @@ -15376,7 +15487,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  
> +	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
> +
>  	intel_crtc_disable_planes(state, crtc);
> +	if (old_crtc_state->bigjoiner)
> +		intel_crtc_disable_planes(state,
> +					  old_crtc_state->bigjoiner_linked_crtc);
>  
>  	/*
>  	 * We need to disable pipe CRC before disabling the pipe,
> @@ -15406,7 +15522,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	/* Only disable port sync and MST slaves */
>  	for_each_oldnew_intel_crtc_in_state(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;
>  
>  		if (!old_crtc_state->hw.active)
> @@ -15421,7 +15537,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		    !intel_dp_mst_is_slave_trans(old_crtc_state))
>  			continue;
>  
> -		intel_pre_plane_update(state, crtc);
>  		intel_old_crtc_state_disables(state, old_crtc_state,
>  					      new_crtc_state, crtc);
>  		handled |= BIT(crtc->pipe);
> @@ -15431,10 +15546,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state) ||
> -		    (handled & BIT(crtc->pipe)))
> +		    (handled & BIT(crtc->pipe)) ||
> +		    old_crtc_state->bigjoiner_slave)
>  			continue;
>  
>  		intel_pre_plane_update(state, crtc);
> +		if (old_crtc_state->bigjoiner) {
> +			struct intel_crtc *slave =
> +				old_crtc_state->bigjoiner_linked_crtc;
> +
> +			intel_pre_plane_update(state, slave);
> +		}
> +
>  		if (old_crtc_state->hw.active)
>  			intel_old_crtc_state_disables(state, old_crtc_state,
>  						      new_crtc_state, crtc);
> @@ -18063,7 +18186,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;
>  
>  		/*
> @@ -18562,7 +18685,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 4694cfd90a0a..943709f192f7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -826,6 +826,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 */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 29f45d2206af..41cb9f9c0292 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>  				  const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> -
> -	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
> +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
>  		return false;
>  
> -	return intel_dsc_source_support(encoder, crtc_state) &&
> +	return intel_dsc_source_support(crtc_state) &&
>  		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 c5735c365659..2d343ccef497 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
>  	return &rc_parameters[row_index][column_index];
>  }
>  
> -bool intel_dsc_source_support(struct intel_encoder *encoder,
> -			      const struct intel_crtc_state *crtc_state)
> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
>  {
>  	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
>  }
>  
> -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;
>  	u32 pps_val = 0;
> @@ -503,6 +501,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 |
> @@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
>  	}
>  }
>  
> -void intel_dsc_get_config(struct intel_encoder *encoder,
> -			  struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	enum pipe pipe = crtc->pipe;
> -	enum intel_display_power_domain power_domain;
> -	intel_wakeref_t wakeref;
> -	u32 dss_ctl1, dss_ctl2, val;
> -
> -	if (!intel_dsc_source_support(encoder, crtc_state))
> -		return;
> -
> -	power_domain = intel_dsc_power_domain(crtc_state);
> -
> -	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> -	if (!wakeref)
> -		return;
> -
> -	if (!is_pipe_dsc(crtc_state)) {
> -		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
> -		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
> -	} else {
> -		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
> -		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
> -	}
> -
> -	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
> -	if (!crtc_state->dsc.compression_enable)
> -		goto out;
> -
> -	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
> -		(dss_ctl1 & JOINER_ENABLE);
> -
> -	/* FIXME: add more state readout as needed */
> -
> -	/* PPS1 */
> -	if (!is_pipe_dsc(crtc_state))
> -		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
> -	else
> -		val = intel_de_read(dev_priv,
> -				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
> -	vdsc_cfg->bits_per_pixel = val;
> -	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
> -out:
> -	intel_display_power_put(dev_priv, power_domain, wakeref);
> -}
> -
>  static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
>  				    const struct intel_crtc_state *crtc_state)
>  {
> @@ -1060,77 +1012,130 @@ 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));

Why do we remove the power get for dsc_power_domains here? IMO this is causing the CI error since 
in dsc_disables we do try to put the dsc_power_domains but we error out saying on dsc disable:

"Use count on VDSC POWER DOMAIN already 0"

we need to get power domains here since for Pipe A/eDP on TGL, we do need a separate PW2 for VDSC.

Manasi

> +	intel_dsc_pps_configure(crtc_state);
>  
> -	intel_dsc_pps_configure(encoder, crtc_state);
> -
> -	if (encoder->type == INTEL_OUTPUT_DSI)
> -		intel_dsc_dsi_pps_write(encoder, crtc_state);
> -	else
> -		intel_dsc_dp_pps_write(encoder, crtc_state);
> -
> -	if (!is_pipe_dsc(crtc_state)) {
> -		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);
> +	if (!crtc_state->bigjoiner_slave) {
> +		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
> +			intel_dsc_dsi_pps_write(encoder, crtc_state);
> +		else
> +			intel_dsc_dp_pps_write(encoder, crtc_state);
>  	}
> +
>  	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;
>  	}
> -	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
> -	intel_de_write(dev_priv, 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;
> +	}
> +	intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
> +	intel_de_write(dev_priv, 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 (!is_pipe_dsc(old_crtc_state)) {
> -		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_ctl1_val = intel_de_read(dev_priv, dss_ctl1_reg);
> -	if (dss_ctl1_val & JOINER_ENABLE)
> -		dss_ctl1_val &= ~JOINER_ENABLE;
> -	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
> -
> -	dss_ctl2_val = intel_de_read(dev_priv, 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);
> -	intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
> +	intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
> +	intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
>  
>  	/* Disable Power wells for VDSC/joining */
>  	intel_display_power_put_unchecked(dev_priv,
>  					  intel_dsc_power_domain(old_crtc_state));
>  }
> +
> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +	enum intel_display_power_domain power_domain;
> +	intel_wakeref_t wakeref;
> +	u32 dss_ctl1, dss_ctl2, val;
> +
> +	if (!intel_dsc_source_support(crtc_state))
> +		return;
> +
> +	power_domain = intel_dsc_power_domain(crtc_state);
> +
> +	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> +	if (!wakeref)
> +		return;
> +
> +	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
> +	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
> +
> +	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
> +	if (!crtc_state->dsc.compression_enable)
> +		goto out;
> +
> +	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
> +		(dss_ctl1 & JOINER_ENABLE);
> +
> +	if (dss_ctl1 & BIG_JOINER_ENABLE) {
> +		crtc_state->bigjoiner = true;
> +
> +		if (!(dss_ctl1 & 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);
> +		}
> +	}
> +
> +	/* FIXME: add more state readout as needed */
> +
> +	/* PPS1 */
> +	if (!is_pipe_dsc(crtc_state))
> +		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
> +	else
> +		val = intel_de_read(dev_priv,
> +				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
> +	vdsc_cfg->bits_per_pixel = val;
> +	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
> +out:
> +	intel_display_power_put(dev_priv, power_domain, wakeref);
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
> index e56a3254c214..5301345ac5e7 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -11,15 +11,14 @@
>  struct intel_encoder;
>  struct intel_crtc_state;
>  
> -bool intel_dsc_source_support(struct intel_encoder *encoder,
> -			      const struct intel_crtc_state *crtc_state);
> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
>  void intel_dsc_enable(struct intel_encoder *encoder,
>  		      const struct intel_crtc_state *crtc_state);
>  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_encoder *encoder,
> -			  struct intel_crtc_state *crtc_state);
> +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.19.1
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* [Intel-gfx] [PATCH v7 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences Manasi Navare
  2020-07-16 19:27   ` Manasi Navare
@ 2020-07-16 21:12   ` Manasi Navare
  2020-08-10 23:28     ` [Intel-gfx] [PATCH v8 " Manasi Navare
  1 sibling, 1 reply; 80+ messages in thread
From: Manasi Navare @ 2020-07-16 21:12 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual rebase (Manasi)

v3:
* Rebase (Manasi)

v4:
* Rebase (Manasi)

v5:
* Get dsc power domain in ddi_init (Manasi)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
 drivers/gpu/drm/i915/display/intel_ddi.c      |  65 ++-
 drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 199 ++++-----
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
 7 files changed, 416 insertions(+), 241 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 8c55f5bee9ab..26f7372b4c25 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 
-	intel_dsc_get_config(encoder, pipe_config);
-
 	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
 	pipe_config->port_clock = intel_dpll_get_freq(i915,
 						      pipe_config->shared_dpll);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index c52ad5ecb645..3e32412eaaac 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include <drm/drm_scdc_helper.h>
 
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "intel_audio.h"
 #include "intel_combo_phy.h"
 #include "intel_connector.h"
@@ -2075,11 +2076,12 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 					intel_ddi_main_link_aux_domain(dig_port));
 
 	/*
-	 * VDSC power is needed when DSC is enabled
+	 * VDSC power well needed when DSC 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(struct intel_encoder *encoder,
@@ -3356,7 +3358,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 
 	/* 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_atomic_state *state,
@@ -3427,7 +3430,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	if (!is_mst)
 		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
@@ -3682,6 +3686,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
 			ilk_pfit_disable(old_crtc_state);
 	}
 
+	if (old_crtc_state->bigjoiner_linked_crtc) {
+		struct intel_atomic_state *state =
+			to_intel_atomic_state(old_crtc_state->uapi.state);
+		struct intel_crtc *slave =
+			old_crtc_state->bigjoiner_linked_crtc;
+		const struct intel_crtc_state *old_slave_crtc_state =
+			intel_atomic_get_old_crtc_state(state, slave);
+
+		intel_crtc_vblank_off(old_slave_crtc_state);
+		trace_intel_pipe_disable(slave);
+
+		intel_dsc_disable(old_slave_crtc_state);
+		skl_scaler_disable(old_slave_crtc_state);
+	}
+
 	/*
 	 * When called from DP MST code:
 	 * - old_conn_state will be NULL
@@ -3896,7 +3915,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
 {
 	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
-	intel_ddi_enable_transcoder_func(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
 	intel_enable_pipe(crtc_state);
 
@@ -4243,8 +4263,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
 		    crtc_state->sync_mode_slaves_mask);
 }
 
-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);
@@ -4252,13 +4272,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	u32 temp, flags = 0;
 
-	/* XXX: DSI transcoder paranoia */
-	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
+	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (!(temp & TRANS_DDI_FUNC_ENABLE))
 		return;
 
-	intel_dsc_get_config(encoder, pipe_config);
-
-	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
 		flags |= DRM_MODE_FLAG_PHSYNC;
 	else
@@ -4366,6 +4383,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
 		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
 	}
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+
+	/* XXX: DSI transcoder paranoia */
+	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+		return;
+
+	intel_ddi_read_func_ctl(encoder, pipe_config);
+	if (pipe_config->bigjoiner_slave) {
+		/* read out pipe settings from master */
+		enum transcoder save = pipe_config->cpu_transcoder;
+
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
+		WARN_ON(pipe_config->output_types);
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
+		intel_ddi_read_func_ctl(encoder, pipe_config);
+		pipe_config->cpu_transcoder = save;
+	}
 
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
@@ -4391,7 +4431,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 955e19abb563..1cda8900d8f5 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7023,6 +7023,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 	intel_de_write(dev_priv, reg, val);
 }
 
+static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
+					 const 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(state, master);
+		intel_enable_shared_dpll(master_crtc_state);
+		intel_encoders_pre_enable(state, master);
+
+		/* and DSC on slave */
+		intel_dsc_enable(NULL, crtc_state);
+	}
+}
+
 static void hsw_crtc_enable(struct intel_atomic_state *state,
 			    struct intel_crtc *crtc)
 {
@@ -7036,34 +7075,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
 		return;
 
-	intel_encoders_pre_pll_enable(state, crtc);
-
-	if (new_crtc_state->shared_dpll)
-		intel_enable_shared_dpll(new_crtc_state);
+	if (!new_crtc_state->bigjoiner) {
+		intel_encoders_pre_pll_enable(state, crtc);
 
-	intel_encoders_pre_enable(state, crtc);
+		if (new_crtc_state->shared_dpll)
+			intel_enable_shared_dpll(new_crtc_state);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_transcoder_timings(new_crtc_state);
+		intel_encoders_pre_enable(state, crtc);
+	} else {
+		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
+	}
 
 	intel_set_pipe_src_size(new_crtc_state);
+	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+		bdw_set_pipemisc(new_crtc_state);
 
-	if (cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(cpu_transcoder))
-		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
-			       new_crtc_state->pixel_multiplier - 1);
+	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
+		if (!transcoder_is_dsi(cpu_transcoder))
+			intel_set_transcoder_timings(new_crtc_state);
 
-	if (new_crtc_state->has_pch_encoder)
-		intel_cpu_transcoder_set_m_n(new_crtc_state,
-					     &new_crtc_state->fdi_m_n, NULL);
+		if (cpu_transcoder != TRANSCODER_EDP &&
+		    !transcoder_is_dsi(cpu_transcoder))
+			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
+				       new_crtc_state->pixel_multiplier - 1);
+
+		if (new_crtc_state->has_pch_encoder)
+			intel_cpu_transcoder_set_m_n(new_crtc_state,
+						     &new_crtc_state->fdi_m_n, NULL);
 
-	if (!transcoder_is_dsi(cpu_transcoder)) {
 		hsw_set_frame_start_delay(new_crtc_state);
-		hsw_set_pipeconf(new_crtc_state);
 	}
 
-	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-		bdw_set_pipemisc(new_crtc_state);
+	if (!transcoder_is_dsi(cpu_transcoder))
+		hsw_set_pipeconf(new_crtc_state);
 
 	crtc->active = true;
 
@@ -7099,6 +7143,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_pipe_mbus_enable(crtc);
 
+	if (new_crtc_state->bigjoiner_slave) {
+		trace_intel_pipe_enable(crtc);
+		intel_crtc_vblank_on(new_crtc_state);
+	}
+
 	intel_encoders_enable(state, crtc);
 
 	if (psl_clkgate_wa) {
@@ -7381,6 +7430,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;
 }
 
@@ -7999,6 +8051,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
 		       pfit_w * pfit_h);
 }
 
+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 pipe timings are half of the transcoder mode
+		 */
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_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);
@@ -8910,20 +8986,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
-	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
-	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
-	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
+	mode->hdisplay = hw_mode->crtc_hdisplay;
+	mode->htotal = hw_mode->crtc_htotal;
+	mode->hsync_start = hw_mode->crtc_hsync_start;
+	mode->hsync_end = hw_mode->crtc_hsync_end;
 
-	mode->flags = pipe_config->hw.adjusted_mode.flags;
+	mode->vdisplay = hw_mode->crtc_vdisplay;
+	mode->vtotal = hw_mode->crtc_vtotal;
+	mode->vsync_start = hw_mode->crtc_vsync_start;
+	mode->vsync_end = hw_mode->crtc_vsync_end;
+
+	mode->flags = hw_mode->flags;
 	mode->type = DRM_MODE_TYPE_DRIVER;
 
-	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
+	mode->clock = hw_mode->crtc_clock;
 
 	drm_mode_set_name(mode);
 }
@@ -11081,6 +11159,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
 	} else {
 		tmp = intel_de_read(dev_priv,
 				    TRANS_DDI_FUNC_CTL(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);
 		else
@@ -11153,12 +11234,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		drm_WARN_ON(&dev_priv->drm, 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) ||
-	    INTEL_GEN(dev_priv) >= 11) {
+		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) {
 		hsw_get_ddi_port_state(crtc, pipe_config);
 		intel_get_transcoder_timings(crtc, pipe_config);
 	}
@@ -11244,8 +11333,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
-	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+	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 =
 			intel_de_read(dev_priv,
 				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
@@ -12260,7 +12352,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);
 
@@ -13252,10 +13344,12 @@ 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;
-	drm_WARN_ON(crtc_state->uapi.crtc->dev,
-		    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;
+		drm_WARN_ON(crtc_state->uapi.crtc->dev,
+			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
+	}
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -13902,21 +13996,42 @@ 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_BOOL(has_hdmi_sink);
 	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
@@ -13926,24 +14041,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)
@@ -13969,7 +14071,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))
@@ -13990,48 +14093,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(double_wide);
 
 	PIPE_CONF_CHECK_P(shared_dpll);
-	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);
+	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(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);
@@ -14043,11 +14149,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
 	PIPE_CONF_CHECK_I(dsc.dsc_split);
 	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
-
 	PIPE_CONF_CHECK_I(mst_master_transcoder);
 
 #undef PIPE_CONF_CHECK_X
@@ -14314,6 +14421,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 	struct intel_encoder *encoder;
 	struct intel_crtc_state *pipe_config = old_crtc_state;
 	struct drm_atomic_state *state = old_crtc_state->uapi.state;
+	struct intel_crtc *master = crtc;
 	bool active;
 
 	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
@@ -14340,7 +14448,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);
@@ -14349,12 +14460,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);
@@ -15376,7 +15487,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 
+	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
+
 	intel_crtc_disable_planes(state, crtc);
+	if (old_crtc_state->bigjoiner)
+		intel_crtc_disable_planes(state,
+					  old_crtc_state->bigjoiner_linked_crtc);
 
 	/*
 	 * We need to disable pipe CRC before disabling the pipe,
@@ -15406,7 +15522,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	/* Only disable port sync and MST slaves */
 	for_each_oldnew_intel_crtc_in_state(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;
 
 		if (!old_crtc_state->hw.active)
@@ -15421,7 +15537,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		    !intel_dp_mst_is_slave_trans(old_crtc_state))
 			continue;
 
-		intel_pre_plane_update(state, crtc);
 		intel_old_crtc_state_disables(state, old_crtc_state,
 					      new_crtc_state, crtc);
 		handled |= BIT(crtc->pipe);
@@ -15431,10 +15546,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state) ||
-		    (handled & BIT(crtc->pipe)))
+		    (handled & BIT(crtc->pipe)) ||
+		    old_crtc_state->bigjoiner_slave)
 			continue;
 
 		intel_pre_plane_update(state, crtc);
+		if (old_crtc_state->bigjoiner) {
+			struct intel_crtc *slave =
+				old_crtc_state->bigjoiner_linked_crtc;
+
+			intel_pre_plane_update(state, slave);
+		}
+
 		if (old_crtc_state->hw.active)
 			intel_old_crtc_state_disables(state, old_crtc_state,
 						      new_crtc_state, crtc);
@@ -18063,7 +18186,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;
 
 		/*
@@ -18562,7 +18685,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 d9d56f15bff1..e93493757cbf 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -826,6 +826,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 */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 29f45d2206af..41cb9f9c0292 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *crtc_state)
 {
-	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
-
-	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
 		return false;
 
-	return intel_dsc_source_support(encoder, crtc_state) &&
+	return intel_dsc_source_support(crtc_state) &&
 		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 c5735c365659..2d343ccef497 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
 	return &rc_parameters[row_index][column_index];
 }
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state)
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 
@@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
 }
 
-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;
 	u32 pps_val = 0;
@@ -503,6 +501,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 |
@@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
 	}
 }
 
-void intel_dsc_get_config(struct intel_encoder *encoder,
-			  struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	enum pipe pipe = crtc->pipe;
-	enum intel_display_power_domain power_domain;
-	intel_wakeref_t wakeref;
-	u32 dss_ctl1, dss_ctl2, val;
-
-	if (!intel_dsc_source_support(encoder, crtc_state))
-		return;
-
-	power_domain = intel_dsc_power_domain(crtc_state);
-
-	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
-	if (!wakeref)
-		return;
-
-	if (!is_pipe_dsc(crtc_state)) {
-		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
-		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
-	} else {
-		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
-		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
-	}
-
-	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
-	if (!crtc_state->dsc.compression_enable)
-		goto out;
-
-	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
-		(dss_ctl1 & JOINER_ENABLE);
-
-	/* FIXME: add more state readout as needed */
-
-	/* PPS1 */
-	if (!is_pipe_dsc(crtc_state))
-		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
-	else
-		val = intel_de_read(dev_priv,
-				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
-	vdsc_cfg->bits_per_pixel = val;
-	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
-out:
-	intel_display_power_put(dev_priv, power_domain, wakeref);
-}
-
 static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
 				    const struct intel_crtc_state *crtc_state)
 {
@@ -1060,77 +1012,130 @@ 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 (encoder->type == INTEL_OUTPUT_DSI)
-		intel_dsc_dsi_pps_write(encoder, crtc_state);
-	else
-		intel_dsc_dp_pps_write(encoder, crtc_state);
-
-	if (!is_pipe_dsc(crtc_state)) {
-		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);
+	if (!crtc_state->bigjoiner_slave) {
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
+			intel_dsc_dsi_pps_write(encoder, crtc_state);
+		else
+			intel_dsc_dp_pps_write(encoder, crtc_state);
 	}
+
 	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;
 	}
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-	intel_de_write(dev_priv, 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;
+	}
+	intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
+	intel_de_write(dev_priv, 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 (!is_pipe_dsc(old_crtc_state)) {
-		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_ctl1_val = intel_de_read(dev_priv, dss_ctl1_reg);
-	if (dss_ctl1_val & JOINER_ENABLE)
-		dss_ctl1_val &= ~JOINER_ENABLE;
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-
-	dss_ctl2_val = intel_de_read(dev_priv, 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);
-	intel_de_write(dev_priv, dss_ctl2_reg, dss_ctl2_val);
+	intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
+	intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
 
 	/* Disable Power wells for VDSC/joining */
 	intel_display_power_put_unchecked(dev_priv,
 					  intel_dsc_power_domain(old_crtc_state));
 }
+
+void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
+{
+	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	enum intel_display_power_domain power_domain;
+	intel_wakeref_t wakeref;
+	u32 dss_ctl1, dss_ctl2, val;
+
+	if (!intel_dsc_source_support(crtc_state))
+		return;
+
+	power_domain = intel_dsc_power_domain(crtc_state);
+
+	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+	if (!wakeref)
+		return;
+
+	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
+	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
+
+	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
+	if (!crtc_state->dsc.compression_enable)
+		goto out;
+
+	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
+		(dss_ctl1 & JOINER_ENABLE);
+
+	if (dss_ctl1 & BIG_JOINER_ENABLE) {
+		crtc_state->bigjoiner = true;
+
+		if (!(dss_ctl1 & 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);
+		}
+	}
+
+	/* FIXME: add more state readout as needed */
+
+	/* PPS1 */
+	if (!is_pipe_dsc(crtc_state))
+		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
+	else
+		val = intel_de_read(dev_priv,
+				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
+	vdsc_cfg->bits_per_pixel = val;
+	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
+out:
+	intel_display_power_put(dev_priv, power_domain, wakeref);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index e56a3254c214..5301345ac5e7 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -11,15 +11,14 @@
 struct intel_encoder;
 struct intel_crtc_state;
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state);
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
 void intel_dsc_enable(struct intel_encoder *encoder,
 		      const struct intel_crtc_state *crtc_state);
 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_encoder *encoder,
-			  struct intel_crtc_state *crtc_state);
+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.19.1

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (13 preceding siblings ...)
  2020-07-16  5:48 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
@ 2020-07-16 21:53 ` Patchwork
  2020-07-16 21:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-16 21:53 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim checkpatch origin/drm-tip
6756ad0df458 HAX to make DSC work on the icelake test system
42b7ec254efd drm/i915: Remove hw.mode
fb6b540c3882 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:216: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#216: FILE: drivers/gpu/drm/i915/display/intel_display.c:13219:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 0 warnings, 1 checks, 445 lines checked
e1afb809eac2 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
07b3d174ba99 drm/i915: Try to make bigjoiner work in atomic check
-:143: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#143: FILE: drivers/gpu/drm/i915/display/intel_display.c:13232:
+								  crtc_state->bigjoiner_linked_crtc);

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

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

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

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

-:332: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#332: FILE: drivers/gpu/drm/i915/display/intel_display.c:14956:
+		slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

-:387: WARNING:BRACES: braces {} are not necessary for any arm of this statement
#387: FILE: drivers/gpu/drm/i915/display/intel_display.c:15351:
+	if (new_crtc_state->bigjoiner) {
[...]
+	} else if (INTEL_GEN(dev_priv) >= 9)
[...]
 	else
[...]

total: 0 errors, 3 warnings, 5 checks, 401 lines checked
52facad4f0f8 drm/i915: Enable big joiner support in enable and disable sequences.
-:176: WARNING:LONG_LINE_COMMENT: line length of 106 exceeds 100 columns
#176: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4403:
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

-:178: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#178: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4405:
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;

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

total: 0 errors, 2 warnings, 1 checks, 997 lines checked
01023aaf7c78 drm/i915: Make hardware readout work on i915.
-:33: WARNING:TABSTOP: Statements should start on a tabstop
#33: FILE: drivers/gpu/drm/i915/display/intel_display.c:3609:
+	 struct intel_crtc_state *crtc_state =

-:76: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#76: FILE: drivers/gpu/drm/i915/display/intel_display.c:10694:
+		    (intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000) == plane_config->base) {

total: 0 errors, 2 warnings, 0 checks, 118 lines checked
4f5779f44812 drm/i915: Link planes in a bigjoiner configuration, v3.
-:203: ERROR:CODE_INDENT: code indent should use tabs where possible
#203: FILE: drivers/gpu/drm/i915/display/intel_display.c:12626:
+         * Setup and teardown the new bigjoiner plane mappings.$

-:204: ERROR:CODE_INDENT: code indent should use tabs where possible
#204: FILE: drivers/gpu/drm/i915/display/intel_display.c:12627:
+         */$

-:289: ERROR:CODE_INDENT: code indent should use tabs where possible
#289: FILE: drivers/gpu/drm/i915/display/intel_display.c:12708:
+         *$

-:305: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#305: FILE: drivers/gpu/drm/i915/display/intel_display.c:12722:
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {

-:321: ERROR:CODE_INDENT: code indent should use tabs where possible
#321: FILE: drivers/gpu/drm/i915/display/intel_display.c:12738:
+         * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically$

-:322: ERROR:CODE_INDENT: code indent should use tabs where possible
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:12739:
+         * when adding slave planes, because plane_state->crtc is null.$

-:323: ERROR:CODE_INDENT: code indent should use tabs where possible
#323: FILE: drivers/gpu/drm/i915/display/intel_display.c:12740:
+         */$

-:435: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#435: FILE: drivers/gpu/drm/i915/display/intel_display.h:472:
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
[...]
+	for_each_if ((((plane_state) = \

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

-:442: WARNING:LONG_LINE: line length of 124 exceeds 100 columns
#442: FILE: drivers/gpu/drm/i915/display/intel_display.h:479:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \

-:443: WARNING:LONG_LINE: line length of 109 exceeds 100 columns
#443: FILE: drivers/gpu/drm/i915/display/intel_display.h:480:
+		      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

-:445: WARNING:LONG_LINE: line length of 125 exceeds 100 columns
#445: FILE: drivers/gpu/drm/i915/display/intel_display.h:482:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \

total: 6 errors, 6 warnings, 0 checks, 481 lines checked
81c299846f0d drm/i915: Add bigjoiner aware plane clipping checks
ce260481299f drm/i915: Add intel_update_bigjoiner handling.
f4de44a552c1 drm/i915: Add debugfs dumping for bigjoiner, v3.
-:46: WARNING:LONG_LINE: line length of 123 exceeds 100 columns
#46: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:777:
+	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",

-:56: WARNING:LONG_LINE: line length of 119 exceeds 100 columns
#56: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:787:
+			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,

-:60: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#60: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:791:
+			   plane_state->bigjoiner_plane->base.base.id, plane_state->bigjoiner_plane->base.name,

total: 0 errors, 3 warnings, 0 checks, 52 lines checked


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

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (14 preceding siblings ...)
  2020-07-16 21:53 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2) Patchwork
@ 2020-07-16 21:54 ` Patchwork
  2020-07-16 22:14 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-16 21:54 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.0
Fast mode used, each commit won't be checked separately.


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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (15 preceding siblings ...)
  2020-07-16 21:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-07-16 22:14 ` Patchwork
  2020-07-17  1:04 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-16 22:14 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 8028 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8758 -> Patchwork_18196
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-tgl-u2:          [PASS][1] -> [FAIL][2] ([i915#1888]) +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-u2/igt@gem_exec_suspend@basic-s3.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-tgl-y:           [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-y/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-y/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
    - fi-icl-u2:          [PASS][5] -> [DMESG-WARN][6] ([i915#1982]) +1 similar issue
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html

  * igt@prime_self_import@basic-with_two_bos:
    - fi-tgl-y:           [PASS][7] -> [DMESG-WARN][8] ([i915#402]) +1 similar issue
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-y/igt@prime_self_import@basic-with_two_bos.html

  
#### Possible fixes ####

  * igt@i915_module_load@reload:
    - fi-tgl-u2:          [DMESG-WARN][9] ([i915#402]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-u2/igt@i915_module_load@reload.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-u2/igt@i915_module_load@reload.html

  * igt@i915_pm_rpm@basic-pci-d3-state:
    - fi-tgl-y:           [DMESG-WARN][11] ([i915#1982]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-y/igt@i915_pm_rpm@basic-pci-d3-state.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-y/igt@i915_pm_rpm@basic-pci-d3-state.html

  * igt@i915_pm_rpm@module-reload:
    - fi-skl-6700k2:      [INCOMPLETE][13] ([i915#151]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-skl-6700k2/igt@i915_pm_rpm@module-reload.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-skl-6700k2/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@gt_lrc:
    - fi-tgl-u2:          [DMESG-FAIL][15] ([i915#1233]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-u2/igt@i915_selftest@live@gt_lrc.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-u2/igt@i915_selftest@live@gt_lrc.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-bsw-n3050:       [DMESG-WARN][17] ([i915#1982]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@vgem_basic@setversion:
    - fi-tgl-y:           [DMESG-WARN][19] ([i915#402]) -> [PASS][20] +1 similar issue
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-tgl-y/igt@vgem_basic@setversion.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-tgl-y/igt@vgem_basic@setversion.html

  * igt@vgem_basic@unload:
    - fi-blb-e6850:       [INCOMPLETE][21] -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-blb-e6850/igt@vgem_basic@unload.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-blb-e6850/igt@vgem_basic@unload.html

  
#### Warnings ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-x1275:       [SKIP][23] ([fdo#109271]) -> [DMESG-FAIL][24] ([i915#62])
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-kbl-x1275:       [DMESG-WARN][25] ([i915#62] / [i915#92]) -> [DMESG-WARN][26] ([i915#62] / [i915#92] / [i915#95]) +6 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-kbl-x1275/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  * igt@kms_flip@basic-flip-vs-dpms@a-dp1:
    - fi-kbl-x1275:       [DMESG-WARN][27] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][28] ([i915#62] / [i915#92])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/fi-kbl-x1275/igt@kms_flip@basic-flip-vs-dpms@a-dp1.html

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

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1233]: https://gitlab.freedesktop.org/drm/intel/issues/1233
  [i915#151]: https://gitlab.freedesktop.org/drm/intel/issues/151
  [i915#1887]: https://gitlab.freedesktop.org/drm/intel/issues/1887
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (45 -> 40)
------------------------------

  Missing    (5): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper 


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

  * Linux: CI_DRM_8758 -> Patchwork_18196

  CI-20190529: 20190529
  CI_DRM_8758: b6738761bde03de00a1c84c6a85f9379f53f585c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5738: bc8b56fe177af34fbde7b96f1f66614a0014c6ef @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18196: f4de44a552c14b647651ed909c64dfdde6eaa525 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

f4de44a552c1 drm/i915: Add debugfs dumping for bigjoiner, v3.
ce260481299f drm/i915: Add intel_update_bigjoiner handling.
81c299846f0d drm/i915: Add bigjoiner aware plane clipping checks
4f5779f44812 drm/i915: Link planes in a bigjoiner configuration, v3.
01023aaf7c78 drm/i915: Make hardware readout work on i915.
52facad4f0f8 drm/i915: Enable big joiner support in enable and disable sequences.
07b3d174ba99 drm/i915: Try to make bigjoiner work in atomic check
e1afb809eac2 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
fb6b540c3882 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
42b7ec254efd drm/i915: Remove hw.mode
6756ad0df458 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_18196/index.html

[-- Attachment #1.2: Type: text/html, Size: 9765 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (16 preceding siblings ...)
  2020-07-16 22:14 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-07-17  1:04 ` Patchwork
  2020-08-10 23:47 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3) Patchwork
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-07-17  1:04 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 14091 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8758_full -> Patchwork_18196_full
====================================================

Summary
-------

  **FAILURE**

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

### IGT changes ###

#### Possible regressions ####

  * igt@kms_dp_dsc@basic-dsc-enable-edp:
    - shard-tglb:         [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-tglb5/igt@kms_dp_dsc@basic-dsc-enable-edp.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-tglb1/igt@kms_dp_dsc@basic-dsc-enable-edp.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_balancer@bonded-early:
    - shard-kbl:          [PASS][3] -> [FAIL][4] ([i915#2079])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-kbl4/igt@gem_exec_balancer@bonded-early.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-kbl3/igt@gem_exec_balancer@bonded-early.html

  * igt@i915_selftest@live@execlists:
    - shard-iclb:         [PASS][5] -> [INCOMPLETE][6] ([i915#1580] / [i915#1684])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-iclb1/igt@i915_selftest@live@execlists.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-iclb5/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@mock@requests:
    - shard-skl:          [PASS][7] -> [INCOMPLETE][8] ([i915#198] / [i915#2110])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl5/igt@i915_selftest@mock@requests.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl4/igt@i915_selftest@mock@requests.html

  * igt@kms_big_fb@x-tiled-8bpp-rotate-180:
    - shard-glk:          [PASS][9] -> [DMESG-WARN][10] ([i915#1982])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-glk8/igt@kms_big_fb@x-tiled-8bpp-rotate-180.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-glk5/igt@kms_big_fb@x-tiled-8bpp-rotate-180.html

  * igt@kms_big_fb@yf-tiled-32bpp-rotate-270:
    - shard-apl:          [PASS][11] -> [DMESG-WARN][12] ([i915#1635] / [i915#1982])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl4/igt@kms_big_fb@yf-tiled-32bpp-rotate-270.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-apl2/igt@kms_big_fb@yf-tiled-32bpp-rotate-270.html

  * igt@kms_cursor_crc@pipe-b-cursor-256x256-rapid-movement:
    - shard-snb:          [PASS][13] -> [SKIP][14] ([fdo#109271])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-snb4/igt@kms_cursor_crc@pipe-b-cursor-256x256-rapid-movement.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-snb2/igt@kms_cursor_crc@pipe-b-cursor-256x256-rapid-movement.html

  * igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions:
    - shard-tglb:         [PASS][15] -> [DMESG-WARN][16] ([i915#1982]) +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-tglb1/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-tglb2/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions.html

  * igt@kms_flip@flip-vs-expired-vblank@b-dp1:
    - shard-apl:          [PASS][17] -> [FAIL][18] ([i915#1635] / [i915#79]) +1 similar issue
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl1/igt@kms_flip@flip-vs-expired-vblank@b-dp1.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-apl3/igt@kms_flip@flip-vs-expired-vblank@b-dp1.html

  * igt@kms_flip@flip-vs-suspend@c-dp1:
    - shard-kbl:          [PASS][19] -> [DMESG-WARN][20] ([i915#180]) +3 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-kbl3/igt@kms_flip@flip-vs-suspend@c-dp1.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-kbl4/igt@kms_flip@flip-vs-suspend@c-dp1.html

  * igt@kms_flip_tiling@flip-changes-tiling-yf:
    - shard-kbl:          [PASS][21] -> [DMESG-WARN][22] ([i915#1982]) +2 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-kbl6/igt@kms_flip_tiling@flip-changes-tiling-yf.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-kbl1/igt@kms_flip_tiling@flip-changes-tiling-yf.html

  * igt@kms_psr@psr2_dpms:
    - shard-iclb:         [PASS][23] -> [SKIP][24] ([fdo#109441]) +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-iclb2/igt@kms_psr@psr2_dpms.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-iclb7/igt@kms_psr@psr2_dpms.html

  * igt@kms_vblank@crtc-id:
    - shard-skl:          [PASS][25] -> [DMESG-WARN][26] ([i915#1982]) +6 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl8/igt@kms_vblank@crtc-id.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl8/igt@kms_vblank@crtc-id.html

  
#### Possible fixes ####

  * igt@gem_exec_reloc@basic-concurrent0:
    - shard-glk:          [FAIL][27] ([i915#1930]) -> [PASS][28]
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-glk2/igt@gem_exec_reloc@basic-concurrent0.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-glk5/igt@gem_exec_reloc@basic-concurrent0.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-0:
    - shard-glk:          [DMESG-FAIL][29] ([i915#118] / [i915#95]) -> [PASS][30] +1 similar issue
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-glk8/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-glk6/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html

  * igt@kms_color@pipe-c-ctm-0-25:
    - shard-skl:          [DMESG-WARN][31] ([i915#1982]) -> [PASS][32] +9 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl5/igt@kms_color@pipe-c-ctm-0-25.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl2/igt@kms_color@pipe-c-ctm-0-25.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-skl:          [INCOMPLETE][33] ([i915#300]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl9/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl6/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions:
    - shard-kbl:          [DMESG-WARN][35] ([i915#1982]) -> [PASS][36]
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-kbl4/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-kbl2/igt@kms_cursor_legacy@short-flip-after-cursor-atomic-transitions.html

  * igt@kms_draw_crc@draw-method-xrgb2101010-mmap-wc-untiled:
    - shard-apl:          [DMESG-WARN][37] ([i915#1635] / [i915#1982]) -> [PASS][38]
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl8/igt@kms_draw_crc@draw-method-xrgb2101010-mmap-wc-untiled.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-apl6/igt@kms_draw_crc@draw-method-xrgb2101010-mmap-wc-untiled.html

  * igt@kms_flip@flip-vs-suspend@b-dp1:
    - shard-kbl:          [DMESG-WARN][39] ([i915#180]) -> [PASS][40] +5 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-kbl3/igt@kms_flip@flip-vs-suspend@b-dp1.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-kbl4/igt@kms_flip@flip-vs-suspend@b-dp1.html

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt:
    - shard-tglb:         [DMESG-WARN][41] ([i915#1982]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-tglb1/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-tglb2/igt@kms_frontbuffer_tracking@fbc-1p-primscrn-pri-indfb-draw-blt.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [FAIL][43] ([fdo#108145] / [i915#265]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl1/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl5/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_primary_mmap_cpu:
    - shard-iclb:         [SKIP][45] ([fdo#109441]) -> [PASS][46] +1 similar issue
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-iclb4/igt@kms_psr@psr2_primary_mmap_cpu.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-iclb2/igt@kms_psr@psr2_primary_mmap_cpu.html

  * igt@perf@blocking-parameterized:
    - shard-tglb:         [FAIL][47] ([i915#1542]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-tglb3/igt@perf@blocking-parameterized.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-tglb5/igt@perf@blocking-parameterized.html

  * igt@perf@polling-small-buf:
    - shard-skl:          [FAIL][49] ([i915#1722]) -> [PASS][50]
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-skl1/igt@perf@polling-small-buf.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-skl5/igt@perf@polling-small-buf.html

  
#### Warnings ####

  * igt@kms_dp_dsc@basic-dsc-enable-edp:
    - shard-iclb:         [DMESG-WARN][51] ([i915#1226]) -> [SKIP][52] ([fdo#109349])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-iclb2/igt@kms_dp_dsc@basic-dsc-enable-edp.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-iclb1/igt@kms_dp_dsc@basic-dsc-enable-edp.html

  * igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
    - shard-apl:          [FAIL][53] ([fdo#108145] / [i915#1635] / [i915#265]) -> [DMESG-FAIL][54] ([fdo#108145] / [i915#1635] / [i915#1982])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl3/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-apl3/igt@kms_plane_alpha_blend@pipe-a-alpha-7efc.html

  * igt@runner@aborted:
    - shard-apl:          ([FAIL][55], [FAIL][56], [FAIL][57]) ([i915#1610] / [i915#1635] / [i915#2110] / [i915#637]) -> [FAIL][58] ([i915#1635] / [i915#2110])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl8/igt@runner@aborted.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl1/igt@runner@aborted.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8758/shard-apl8/igt@runner@aborted.html
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/shard-apl1/igt@runner@aborted.html

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

  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109349]: https://bugs.freedesktop.org/show_bug.cgi?id=109349
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1226]: https://gitlab.freedesktop.org/drm/intel/issues/1226
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#1580]: https://gitlab.freedesktop.org/drm/intel/issues/1580
  [i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#1684]: https://gitlab.freedesktop.org/drm/intel/issues/1684
  [i915#1722]: https://gitlab.freedesktop.org/drm/intel/issues/1722
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1930]: https://gitlab.freedesktop.org/drm/intel/issues/1930
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2079]: https://gitlab.freedesktop.org/drm/intel/issues/2079
  [i915#2110]: https://gitlab.freedesktop.org/drm/intel/issues/2110
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#300]: https://gitlab.freedesktop.org/drm/intel/issues/300
  [i915#637]: https://gitlab.freedesktop.org/drm/intel/issues/637
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts


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

  * Linux: CI_DRM_8758 -> Patchwork_18196

  CI-20190529: 20190529
  CI_DRM_8758: b6738761bde03de00a1c84c6a85f9379f53f585c @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5738: bc8b56fe177af34fbde7b96f1f66614a0014c6ef @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18196: f4de44a552c14b647651ed909c64dfdde6eaa525 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18196/index.html

[-- Attachment #1.2: Type: text/html, Size: 16775 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
@ 2020-08-10 12:38   ` Maarten Lankhorst
  2020-08-17  7:32   ` Manna, Animesh
  2020-09-03 17:54   ` Ville Syrjälä
  2 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2020-08-10 12:38 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx

This patch probably needs a description, typing somethign here since it was originally my patch:

With bigjoiner, there will be 2 pipes driving 2 halfs of 1 transcoder,
because of this, we need a pipe_mode for various calculations, including
for example watermarks, plane clipping, etc.
The transcoder_mode has the full timings, and is used for configuring
the transcoder with the intended mode after joining the 2 halves.

To clear the confusion, we rename intel_set_pipe_timings to intel_set_transcoder_timings,
and use pipe_mode where the pipe timings are needed.

Op 16-07-2020 om 00:42 schreef Manasi Navare:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> v4:
> * Manual rebase (Manasi)
> v3:
> * Change state to crtc_state, fix rebase err  (Manasi)
> v2:
> * Manual Rebase (Manasi)
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
>  .../drm/i915/display/intel_display_types.h    | 11 ++-
>  drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
>  3 files changed, 79 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8652a7c6bf11..78cbfefbfa62 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -152,7 +152,7 @@ static void ilk_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,
> @@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  
>  static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
>  	int width, height;
>  
>  	if (crtc_state->pch_pfit.enabled) {
>  		width = drm_rect_width(&crtc_state->pch_pfit.dst);
>  		height = drm_rect_height(&crtc_state->pch_pfit.dst);
>  	} else {
> -		width = adjusted_mode->crtc_hdisplay;
> -		height = adjusted_mode->crtc_vdisplay;
> +		width = pipe_mode->crtc_hdisplay;
> +		height = pipe_mode->crtc_vdisplay;
>  	}
> -
>  	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
>  				 SKL_CRTC_INDEX,
>  				 &crtc_state->scaler_state.scaler_id,
> @@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	if (new_crtc_state->has_pch_encoder)
> @@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	intel_encoders_pre_enable(state, crtc);
>  
>  	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_pipe_timings(new_crtc_state);
> +		intel_set_transcoder_timings(new_crtc_state);
>  
>  	intel_set_pipe_src_size(new_crtc_state);
>  
> @@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> @@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	i9xx_set_pipeconf(new_crtc_state);
> @@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
>  
>  static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>  {
> -	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
> +	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
>  	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
>  
>  	/*
> @@ -8008,7 +8006,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);
> @@ -8018,7 +8016,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) {
> @@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
>  			    "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;
>  	}
> @@ -8081,7 +8079,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);
> @@ -8751,7 +8749,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);
> @@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
>  		return intel_de_read(dev_priv, 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);
> @@ -9458,7 +9456,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(pipe_config);
> @@ -10739,7 +10737,7 @@ static bool ilk_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);
>  
>  	ilk_get_pfit_config(pipe_config);
> @@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>  	    INTEL_GEN(dev_priv) >= 11) {
>  		hsw_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);
> @@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
>  
>  static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
>  	int linetime_wm;
>  
>  	if (!crtc_state->hw.enable)
>  		return 0;
>  
> -	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
> -					adjusted_mode->crtc_clock);
> +	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
> +					pipe_mode->crtc_clock);
>  
>  	return min(linetime_wm, 0x1ff);
>  }
> @@ -13218,7 +13216,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);
>  }
>  
> @@ -13325,7 +13323,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.adjusted_mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * drm_atomic_helper_update_legacy_modeset_state() happy
>  	 */
>  	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;
>  }
> @@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			 */
>  			crtc_state->inherited = true;
>  
> +			/* 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 f1e29d9a75d0..c52c8f42df68 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
> @@ -1141,8 +1141,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;
>  
> @@ -1169,8 +1169,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);
>  
> @@ -1666,8 +1666,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)
> @@ -1677,8 +1677,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) {
> @@ -2267,12 +2267,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;
> @@ -2351,8 +2351,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;
> @@ -2362,7 +2362,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;
> @@ -2378,8 +2378,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;
> @@ -2389,7 +2389,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)
> @@ -2427,12 +2427,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;
> @@ -2480,7 +2480,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;
>  
> @@ -2488,8 +2488,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);
> @@ -2579,7 +2579,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);
>  
> @@ -2607,7 +2607,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);
> @@ -2632,7 +2632,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);
>  }
> @@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>  	if (!crtc_state->hw.active)
>  		return true;
>  
> -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		return false;
>  
>  	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> @@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  	 */
>  	total_slice_mask = dbuf_slice_mask;
>  	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;
>  		u32 pipe_dbuf_slice_mask;
> @@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
>  			continue;
>  
> -		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> +		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
>  
>  		total_width_in_range += hdisplay;
>  
> @@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>  	if (drm_WARN_ON(&dev_priv->drm, 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;
> @@ -5288,14 +5288,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;


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

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
@ 2020-08-10 12:40   ` Maarten Lankhorst
  2020-08-21  9:41   ` Manna, Animesh
  2020-09-07 11:20   ` Ville Syrjälä
  2 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2020-08-10 12:40 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx

Op 16-07-2020 om 00:42 schreef Manasi Navare:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> 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.
>
> v5:
> * Increase max plane width to support 8K with bigjoiner (Maarten)
> v4:
> * Rebase (Manasi)
>
> 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)
> v3:
> * Rebase (Manasi)
>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Looking good, but I think you should have someone else review it as well to be certain. :)
> ---
>  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
>  2 files changed, 91 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 78cbfefbfa62..3ecb642805a6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
>  	 * too big for that.
>  	 */
>  	if (INTEL_GEN(dev_priv) >= 11) {
> -		plane_width_max = 5120;
> +		plane_width_max = 7680;
>  		plane_height_max = 4320;
>  	} else {
>  		plane_width_max = 5120;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d6295eb20b63..fbfea99fd804 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> -	struct intel_encoder *encoder = &dig_port->base;
> +	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;
>  
> +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> +		return 2 * dev_priv->max_dotclk_freq;
> +
> +	return dev_priv->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;
>  }
> @@ -527,7 +539,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;
> @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
>  		    max_bpp_small_joiner_ram);
>  
> @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> @@ -576,7 +602,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)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	u8 min_slice_count, i;
> @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> @@ -648,11 +683,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)
> @@ -664,6 +703,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);
>  
> @@ -691,23 +745,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);
>  }
> @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
>  				    "Compressed BPP/Slice Count not supported\n");


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

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

* Re: [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-07-16 19:27   ` Manasi Navare
@ 2020-08-10 12:45     ` Maarten Lankhorst
  2020-08-10 23:04       ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Maarten Lankhorst @ 2020-08-10 12:45 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx

Op 16-07-2020 om 21:27 schreef Manasi Navare:
> On Wed, Jul 15, 2020 at 03:42:17PM -0700, Manasi Navare wrote:
>> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>
>> 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.
>>
>> v2:
>> * Manual rebase (Manasi)
>>
>> v3:
>> * Rebase (Manasi)
>>
>> v4:
>> * Rebase (Manasi)
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>>  drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
>>  .../drm/i915/display/intel_display_types.h    |   1 +
>>  drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
>>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 199 ++++-----
>>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
>>  7 files changed, 414 insertions(+), 246 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
>> index 8c55f5bee9ab..26f7372b4c25 100644
>> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
>> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
>> @@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>>  	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
>>  
>> -	intel_dsc_get_config(encoder, pipe_config);
>> -
>>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
>>  						      pipe_config->shared_dpll);
>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>> index 424d59671561..dd97d725ae65 100644
>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>> @@ -28,6 +28,7 @@
>>  #include <drm/drm_scdc_helper.h>
>>  
>>  #include "i915_drv.h"
>> +#include "i915_trace.h"
>>  #include "intel_audio.h"
>>  #include "intel_combo_phy.h"
>>  #include "intel_connector.h"
>> @@ -2040,12 +2041,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>>  		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(struct intel_encoder *encoder,
>> @@ -3313,7 +3308,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
>>  
>>  	/* 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_atomic_state *state,
>> @@ -3384,7 +3380,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
>>  	if (!is_mst)
>>  		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
>> @@ -3639,6 +3636,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
>>  			ilk_pfit_disable(old_crtc_state);
>>  	}
>>  
>> +	if (old_crtc_state->bigjoiner_linked_crtc) {
>> +		struct intel_atomic_state *state =
>> +			to_intel_atomic_state(old_crtc_state->uapi.state);
>> +		struct intel_crtc *slave =
>> +			old_crtc_state->bigjoiner_linked_crtc;
>> +		const struct intel_crtc_state *old_slave_crtc_state =
>> +			intel_atomic_get_old_crtc_state(state, slave);
>> +
>> +		intel_crtc_vblank_off(old_slave_crtc_state);
>> +		trace_intel_pipe_disable(slave);
>> +
>> +		intel_dsc_disable(old_slave_crtc_state);
>> +		skl_scaler_disable(old_slave_crtc_state);
>> +	}
>> +
>>  	/*
>>  	 * When called from DP MST code:
>>  	 * - old_conn_state will be NULL
>> @@ -3853,7 +3865,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
>>  {
>>  	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
>>  
>> -	intel_ddi_enable_transcoder_func(encoder, crtc_state);
>> +	if (!crtc_state->bigjoiner_slave)
>> +		intel_ddi_enable_transcoder_func(encoder, crtc_state);
>>  
>>  	intel_enable_pipe(crtc_state);
>>  
>> @@ -4200,8 +4213,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
>>  		    crtc_state->sync_mode_slaves_mask);
>>  }
>>  
>> -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);
>> @@ -4209,13 +4222,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>>  	u32 temp, flags = 0;
>>  
>> -	/* XXX: DSI transcoder paranoia */
>> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
>> +	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>>  		return;
>>  
>> -	intel_dsc_get_config(encoder, pipe_config);
>> -
>> -	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>  	if (temp & TRANS_DDI_PHSYNC)
>>  		flags |= DRM_MODE_FLAG_PHSYNC;
>>  	else
>> @@ -4323,6 +4333,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
>>  		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
>>  	}
>> +}
>> +
>> +void intel_ddi_get_config(struct intel_encoder *encoder,
>> +			  struct intel_crtc_state *pipe_config)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>> +
>> +	/* XXX: DSI transcoder paranoia */
>> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
>> +		return;
>> +
>> +	intel_ddi_read_func_ctl(encoder, pipe_config);
>> +	if (pipe_config->bigjoiner_slave) {
>> +		/* read out pipe settings from master */
>> +		enum transcoder save = pipe_config->cpu_transcoder;
>> +
>> +		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
>> +		WARN_ON(pipe_config->output_types);
>> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
>> +		intel_ddi_read_func_ctl(encoder, pipe_config);
>> +		pipe_config->cpu_transcoder = save;
>> +	}
>>  
>>  	pipe_config->has_audio =
>>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
>> @@ -4348,7 +4381,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 955e19abb563..1cda8900d8f5 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -7023,6 +7023,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
>>  	intel_de_write(dev_priv, reg, val);
>>  }
>>  
>> +static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
>> +					 const 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(state, master);
>> +		intel_enable_shared_dpll(master_crtc_state);
>> +		intel_encoders_pre_enable(state, master);
>> +
>> +		/* and DSC on slave */
>> +		intel_dsc_enable(NULL, crtc_state);
>> +	}
>> +}
>> +
>>  static void hsw_crtc_enable(struct intel_atomic_state *state,
>>  			    struct intel_crtc *crtc)
>>  {
>> @@ -7036,34 +7075,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>>  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
>>  		return;
>>  
>> -	intel_encoders_pre_pll_enable(state, crtc);
>> -
>> -	if (new_crtc_state->shared_dpll)
>> -		intel_enable_shared_dpll(new_crtc_state);
>> +	if (!new_crtc_state->bigjoiner) {
>> +		intel_encoders_pre_pll_enable(state, crtc);
>>  
>> -	intel_encoders_pre_enable(state, crtc);
>> +		if (new_crtc_state->shared_dpll)
>> +			intel_enable_shared_dpll(new_crtc_state);
>>  
>> -	if (!transcoder_is_dsi(cpu_transcoder))
>> -		intel_set_transcoder_timings(new_crtc_state);
>> +		intel_encoders_pre_enable(state, crtc);
>> +	} else {
>> +		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
>> +	}
>>  
>>  	intel_set_pipe_src_size(new_crtc_state);
>> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
>> +		bdw_set_pipemisc(new_crtc_state);
>>  
>> -	if (cpu_transcoder != TRANSCODER_EDP &&
>> -	    !transcoder_is_dsi(cpu_transcoder))
>> -		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
>> -			       new_crtc_state->pixel_multiplier - 1);
>> +	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
>> +		if (!transcoder_is_dsi(cpu_transcoder))
>> +			intel_set_transcoder_timings(new_crtc_state);
>>  
>> -	if (new_crtc_state->has_pch_encoder)
>> -		intel_cpu_transcoder_set_m_n(new_crtc_state,
>> -					     &new_crtc_state->fdi_m_n, NULL);
>> +		if (cpu_transcoder != TRANSCODER_EDP &&
>> +		    !transcoder_is_dsi(cpu_transcoder))
>> +			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
>> +				       new_crtc_state->pixel_multiplier - 1);
>> +
>> +		if (new_crtc_state->has_pch_encoder)
>> +			intel_cpu_transcoder_set_m_n(new_crtc_state,
>> +						     &new_crtc_state->fdi_m_n, NULL);
>>  
>> -	if (!transcoder_is_dsi(cpu_transcoder)) {
>>  		hsw_set_frame_start_delay(new_crtc_state);
>> -		hsw_set_pipeconf(new_crtc_state);
>>  	}
>>  
>> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
>> -		bdw_set_pipemisc(new_crtc_state);
>> +	if (!transcoder_is_dsi(cpu_transcoder))
>> +		hsw_set_pipeconf(new_crtc_state);
>>  
>>  	crtc->active = true;
>>  
>> @@ -7099,6 +7143,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>>  	if (INTEL_GEN(dev_priv) >= 11)
>>  		icl_pipe_mbus_enable(crtc);
>>  
>> +	if (new_crtc_state->bigjoiner_slave) {
>> +		trace_intel_pipe_enable(crtc);
>> +		intel_crtc_vblank_on(new_crtc_state);
>> +	}
>> +
>>  	intel_encoders_enable(state, crtc);
>>  
>>  	if (psl_clkgate_wa) {
>> @@ -7381,6 +7430,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;
>>  }
>>  
>> @@ -7999,6 +8051,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>>  		       pfit_w * pfit_h);
>>  }
>>  
>> +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 pipe timings are half of the transcoder mode
>> +		 */
>> +		pipe_mode->crtc_hdisplay /= 2;
>> +		pipe_mode->crtc_hblank_start /= 2;
>> +		pipe_mode->crtc_hblank_end /= 2;
>> +		pipe_mode->crtc_hsync_start /= 2;
>> +		pipe_mode->crtc_hsync_end /= 2;
>> +		pipe_mode->crtc_htotal /= 2;
>> +		pipe_mode->crtc_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);
>> @@ -8910,20 +8986,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
>> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
>> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
>> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
>> +	mode->hdisplay = hw_mode->crtc_hdisplay;
>> +	mode->htotal = hw_mode->crtc_htotal;
>> +	mode->hsync_start = hw_mode->crtc_hsync_start;
>> +	mode->hsync_end = hw_mode->crtc_hsync_end;
>>  
>> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
>> +	mode->vdisplay = hw_mode->crtc_vdisplay;
>> +	mode->vtotal = hw_mode->crtc_vtotal;
>> +	mode->vsync_start = hw_mode->crtc_vsync_start;
>> +	mode->vsync_end = hw_mode->crtc_vsync_end;
>> +
>> +	mode->flags = hw_mode->flags;
>>  	mode->type = DRM_MODE_TYPE_DRIVER;
>>  
>> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
>> +	mode->clock = hw_mode->crtc_clock;
>>  
>>  	drm_mode_set_name(mode);
>>  }
>> @@ -11081,6 +11159,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
>>  	} else {
>>  		tmp = intel_de_read(dev_priv,
>>  				    TRANS_DDI_FUNC_CTL(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);
>>  		else
>> @@ -11153,12 +11234,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>>  		drm_WARN_ON(&dev_priv->drm, 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) ||
>> -	    INTEL_GEN(dev_priv) >= 11) {
>> +		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) {
>>  		hsw_get_ddi_port_state(crtc, pipe_config);
>>  		intel_get_transcoder_timings(crtc, pipe_config);
>>  	}
>> @@ -11244,8 +11333,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>>  		}
>>  	}
>>  
>> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>> -	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
>> +	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 =
>>  			intel_de_read(dev_priv,
>>  				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
>> @@ -12260,7 +12352,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);
>>  
>> @@ -13252,10 +13344,12 @@ 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;
>> -	drm_WARN_ON(crtc_state->uapi.crtc->dev,
>> -		    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;
>> +		drm_WARN_ON(crtc_state->uapi.crtc->dev,
>> +			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>> +	}
>>  
>>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>>  
>> @@ -13902,21 +13996,42 @@ 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_BOOL(has_hdmi_sink);
>>  	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
>> @@ -13926,24 +14041,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)
>> @@ -13969,7 +14071,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))
>> @@ -13990,48 +14093,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  	PIPE_CONF_CHECK_BOOL(double_wide);
>>  
>>  	PIPE_CONF_CHECK_P(shared_dpll);
>> -	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);
>> +	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(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);
>> @@ -14043,11 +14149,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>>  
>>  	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
>>  	PIPE_CONF_CHECK_I(dsc.dsc_split);
>>  	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
>> -
>>  	PIPE_CONF_CHECK_I(mst_master_transcoder);
>>  
>>  #undef PIPE_CONF_CHECK_X
>> @@ -14314,6 +14421,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>>  	struct intel_encoder *encoder;
>>  	struct intel_crtc_state *pipe_config = old_crtc_state;
>>  	struct drm_atomic_state *state = old_crtc_state->uapi.state;
>> +	struct intel_crtc *master = crtc;
>>  	bool active;
>>  
>>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>> @@ -14340,7 +14448,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);
>> @@ -14349,12 +14460,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);
>> @@ -15376,7 +15487,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>>  {
>>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>>  
>> +	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
>> +
>>  	intel_crtc_disable_planes(state, crtc);
>> +	if (old_crtc_state->bigjoiner)
>> +		intel_crtc_disable_planes(state,
>> +					  old_crtc_state->bigjoiner_linked_crtc);
>>  
>>  	/*
>>  	 * We need to disable pipe CRC before disabling the pipe,
>> @@ -15406,7 +15522,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>  	/* Only disable port sync and MST slaves */
>>  	for_each_oldnew_intel_crtc_in_state(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;
>>  
>>  		if (!old_crtc_state->hw.active)
>> @@ -15421,7 +15537,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>  		    !intel_dp_mst_is_slave_trans(old_crtc_state))
>>  			continue;
>>  
>> -		intel_pre_plane_update(state, crtc);
>>  		intel_old_crtc_state_disables(state, old_crtc_state,
>>  					      new_crtc_state, crtc);
>>  		handled |= BIT(crtc->pipe);
>> @@ -15431,10 +15546,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>>  					    new_crtc_state, i) {
>>  		if (!needs_modeset(new_crtc_state) ||
>> -		    (handled & BIT(crtc->pipe)))
>> +		    (handled & BIT(crtc->pipe)) ||
>> +		    old_crtc_state->bigjoiner_slave)
>>  			continue;
>>  
>>  		intel_pre_plane_update(state, crtc);
>> +		if (old_crtc_state->bigjoiner) {
>> +			struct intel_crtc *slave =
>> +				old_crtc_state->bigjoiner_linked_crtc;
>> +
>> +			intel_pre_plane_update(state, slave);
>> +		}
>> +
>>  		if (old_crtc_state->hw.active)
>>  			intel_old_crtc_state_disables(state, old_crtc_state,
>>  						      new_crtc_state, crtc);
>> @@ -18063,7 +18186,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;
>>  
>>  		/*
>> @@ -18562,7 +18685,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 4694cfd90a0a..943709f192f7 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
>> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
>> @@ -826,6 +826,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 */
>> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
>> index 29f45d2206af..41cb9f9c0292 100644
>> --- a/drivers/gpu/drm/i915/display/intel_dp.c
>> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
>> @@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
>>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>>  				  const struct intel_crtc_state *crtc_state)
>>  {
>> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
>> -
>> -	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
>> +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
>>  		return false;
>>  
>> -	return intel_dsc_source_support(encoder, crtc_state) &&
>> +	return intel_dsc_source_support(crtc_state) &&
>>  		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 c5735c365659..2d343ccef497 100644
>> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
>> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
>> @@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
>>  	return &rc_parameters[row_index][column_index];
>>  }
>>  
>> -bool intel_dsc_source_support(struct intel_encoder *encoder,
>> -			      const struct intel_crtc_state *crtc_state)
>> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
>>  {
>>  	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> -	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
>> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
>>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>>  	enum pipe pipe = crtc->pipe;
>>  
>> @@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>>  		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
>>  }
>>  
>> -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;
>>  	u32 pps_val = 0;
>> @@ -503,6 +501,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 |
>> @@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
>>  	}
>>  }
>>  
>> -void intel_dsc_get_config(struct intel_encoder *encoder,
>> -			  struct intel_crtc_state *crtc_state)
>> -{
>> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> -	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
>> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>> -	enum pipe pipe = crtc->pipe;
>> -	enum intel_display_power_domain power_domain;
>> -	intel_wakeref_t wakeref;
>> -	u32 dss_ctl1, dss_ctl2, val;
>> -
>> -	if (!intel_dsc_source_support(encoder, crtc_state))
>> -		return;
>> -
>> -	power_domain = intel_dsc_power_domain(crtc_state);
>> -
>> -	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
>> -	if (!wakeref)
>> -		return;
>> -
>> -	if (!is_pipe_dsc(crtc_state)) {
>> -		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
>> -		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
>> -	} else {
>> -		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
>> -		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
>> -	}
>> -
>> -	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
>> -	if (!crtc_state->dsc.compression_enable)
>> -		goto out;
>> -
>> -	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
>> -		(dss_ctl1 & JOINER_ENABLE);
>> -
>> -	/* FIXME: add more state readout as needed */
>> -
>> -	/* PPS1 */
>> -	if (!is_pipe_dsc(crtc_state))
>> -		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
>> -	else
>> -		val = intel_de_read(dev_priv,
>> -				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
>> -	vdsc_cfg->bits_per_pixel = val;
>> -	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
>> -out:
>> -	intel_display_power_put(dev_priv, power_domain, wakeref);
>> -}
>> -
>>  static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
>>  				    const struct intel_crtc_state *crtc_state)
>>  {
>> @@ -1060,77 +1012,130 @@ 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));
> Why do we remove the power get for dsc_power_domains here? IMO this is causing the CI error since 
> in dsc_disables we do try to put the dsc_power_domains but we error out saying on dsc disable:
>
> "Use count on VDSC POWER DOMAIN already 0"
>
> we need to get power domains here since for Pipe A/eDP on TGL, we do need a separate PW2 for VDSC.

It's the other way around, we need to remove it from dsc_disable.

get_crtc_power_domains() ensures we always have the dsc power domain correct, even when reading out from the original hw state. It had to be decoupled from the encoder as the slave pipe doesn't have an encoder, and we still want the DSC power domain in that case. :)


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

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

* Re: [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
@ 2020-08-10 12:47   ` Maarten Lankhorst
  0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2020-08-10 12:47 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx

Op 16-07-2020 om 00:42 schreef Manasi Navare:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> Dump debugfs and planar links as well, this will make it easier to debug
> when things go wrong.
>
> v4:
> * Rebase
> Changes since v1:
> - Report planar slaves as such, now that we have the plane_state switch.
> Changes since v2:
> - Rebase on top of the new plane format dumping
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  .../drm/i915/display/intel_display_debugfs.c  | 29 ++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
Series looks good. I think I'm not the right person to review this as I wrote those patches, if really required I can do this but it's best to get someone else to review, as I'm already the original author. :)
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-08-10 12:45     ` Maarten Lankhorst
@ 2020-08-10 23:04       ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-08-10 23:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Mon, Aug 10, 2020 at 02:45:52PM +0200, Maarten Lankhorst wrote:
> Op 16-07-2020 om 21:27 schreef Manasi Navare:
> > On Wed, Jul 15, 2020 at 03:42:17PM -0700, Manasi Navare wrote:
> >> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >>
> >> 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.
> >>
> >> v2:
> >> * Manual rebase (Manasi)
> >>
> >> v3:
> >> * Rebase (Manasi)
> >>
> >> v4:
> >> * Rebase (Manasi)
> >>
> >> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> >> ---
> >>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
> >>  drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
> >>  drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
> >>  .../drm/i915/display/intel_display_types.h    |   1 +
> >>  drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
> >>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 199 ++++-----
> >>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
> >>  7 files changed, 414 insertions(+), 246 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> >> index 8c55f5bee9ab..26f7372b4c25 100644
> >> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> >> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> >> @@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
> >>  	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
> >>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
> >>  
> >> -	intel_dsc_get_config(encoder, pipe_config);
> >> -
> >>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
> >>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
> >>  						      pipe_config->shared_dpll);
> >> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> >> index 424d59671561..dd97d725ae65 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> >> @@ -28,6 +28,7 @@
> >>  #include <drm/drm_scdc_helper.h>
> >>  
> >>  #include "i915_drv.h"
> >> +#include "i915_trace.h"
> >>  #include "intel_audio.h"
> >>  #include "intel_combo_phy.h"
> >>  #include "intel_connector.h"
> >> @@ -2040,12 +2041,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
> >>  		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(struct intel_encoder *encoder,
> >> @@ -3313,7 +3308,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
> >>  
> >>  	/* 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_atomic_state *state,
> >> @@ -3384,7 +3380,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
> >>  	if (!is_mst)
> >>  		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
> >> @@ -3639,6 +3636,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
> >>  			ilk_pfit_disable(old_crtc_state);
> >>  	}
> >>  
> >> +	if (old_crtc_state->bigjoiner_linked_crtc) {
> >> +		struct intel_atomic_state *state =
> >> +			to_intel_atomic_state(old_crtc_state->uapi.state);
> >> +		struct intel_crtc *slave =
> >> +			old_crtc_state->bigjoiner_linked_crtc;
> >> +		const struct intel_crtc_state *old_slave_crtc_state =
> >> +			intel_atomic_get_old_crtc_state(state, slave);
> >> +
> >> +		intel_crtc_vblank_off(old_slave_crtc_state);
> >> +		trace_intel_pipe_disable(slave);
> >> +
> >> +		intel_dsc_disable(old_slave_crtc_state);
> >> +		skl_scaler_disable(old_slave_crtc_state);
> >> +	}
> >> +
> >>  	/*
> >>  	 * When called from DP MST code:
> >>  	 * - old_conn_state will be NULL
> >> @@ -3853,7 +3865,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
> >>  {
> >>  	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> >>  
> >> -	intel_ddi_enable_transcoder_func(encoder, crtc_state);
> >> +	if (!crtc_state->bigjoiner_slave)
> >> +		intel_ddi_enable_transcoder_func(encoder, crtc_state);
> >>  
> >>  	intel_enable_pipe(crtc_state);
> >>  
> >> @@ -4200,8 +4213,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
> >>  		    crtc_state->sync_mode_slaves_mask);
> >>  }
> >>  
> >> -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);
> >> @@ -4209,13 +4222,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> >>  	u32 temp, flags = 0;
> >>  
> >> -	/* XXX: DSI transcoder paranoia */
> >> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> >> +	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> >> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
> >>  		return;
> >>  
> >> -	intel_dsc_get_config(encoder, pipe_config);
> >> -
> >> -	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> >>  	if (temp & TRANS_DDI_PHSYNC)
> >>  		flags |= DRM_MODE_FLAG_PHSYNC;
> >>  	else
> >> @@ -4323,6 +4333,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >>  		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
> >>  		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
> >>  	}
> >> +}
> >> +
> >> +void intel_ddi_get_config(struct intel_encoder *encoder,
> >> +			  struct intel_crtc_state *pipe_config)
> >> +{
> >> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> >> +
> >> +	/* XXX: DSI transcoder paranoia */
> >> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> >> +		return;
> >> +
> >> +	intel_ddi_read_func_ctl(encoder, pipe_config);
> >> +	if (pipe_config->bigjoiner_slave) {
> >> +		/* read out pipe settings from master */
> >> +		enum transcoder save = pipe_config->cpu_transcoder;
> >> +
> >> +		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
> >> +		WARN_ON(pipe_config->output_types);
> >> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
> >> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> >> +		pipe_config->cpu_transcoder = save;
> >> +	}
> >>  
> >>  	pipe_config->has_audio =
> >>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
> >> @@ -4348,7 +4381,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 955e19abb563..1cda8900d8f5 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> >> @@ -7023,6 +7023,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
> >>  	intel_de_write(dev_priv, reg, val);
> >>  }
> >>  
> >> +static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
> >> +					 const 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(state, master);
> >> +		intel_enable_shared_dpll(master_crtc_state);
> >> +		intel_encoders_pre_enable(state, master);
> >> +
> >> +		/* and DSC on slave */
> >> +		intel_dsc_enable(NULL, crtc_state);
> >> +	}
> >> +}
> >> +
> >>  static void hsw_crtc_enable(struct intel_atomic_state *state,
> >>  			    struct intel_crtc *crtc)
> >>  {
> >> @@ -7036,34 +7075,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
> >>  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
> >>  		return;
> >>  
> >> -	intel_encoders_pre_pll_enable(state, crtc);
> >> -
> >> -	if (new_crtc_state->shared_dpll)
> >> -		intel_enable_shared_dpll(new_crtc_state);
> >> +	if (!new_crtc_state->bigjoiner) {
> >> +		intel_encoders_pre_pll_enable(state, crtc);
> >>  
> >> -	intel_encoders_pre_enable(state, crtc);
> >> +		if (new_crtc_state->shared_dpll)
> >> +			intel_enable_shared_dpll(new_crtc_state);
> >>  
> >> -	if (!transcoder_is_dsi(cpu_transcoder))
> >> -		intel_set_transcoder_timings(new_crtc_state);
> >> +		intel_encoders_pre_enable(state, crtc);
> >> +	} else {
> >> +		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
> >> +	}
> >>  
> >>  	intel_set_pipe_src_size(new_crtc_state);
> >> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> >> +		bdw_set_pipemisc(new_crtc_state);
> >>  
> >> -	if (cpu_transcoder != TRANSCODER_EDP &&
> >> -	    !transcoder_is_dsi(cpu_transcoder))
> >> -		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> >> -			       new_crtc_state->pixel_multiplier - 1);
> >> +	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> >> +		if (!transcoder_is_dsi(cpu_transcoder))
> >> +			intel_set_transcoder_timings(new_crtc_state);
> >>  
> >> -	if (new_crtc_state->has_pch_encoder)
> >> -		intel_cpu_transcoder_set_m_n(new_crtc_state,
> >> -					     &new_crtc_state->fdi_m_n, NULL);
> >> +		if (cpu_transcoder != TRANSCODER_EDP &&
> >> +		    !transcoder_is_dsi(cpu_transcoder))
> >> +			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> >> +				       new_crtc_state->pixel_multiplier - 1);
> >> +
> >> +		if (new_crtc_state->has_pch_encoder)
> >> +			intel_cpu_transcoder_set_m_n(new_crtc_state,
> >> +						     &new_crtc_state->fdi_m_n, NULL);
> >>  
> >> -	if (!transcoder_is_dsi(cpu_transcoder)) {
> >>  		hsw_set_frame_start_delay(new_crtc_state);
> >> -		hsw_set_pipeconf(new_crtc_state);
> >>  	}
> >>  
> >> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> >> -		bdw_set_pipemisc(new_crtc_state);
> >> +	if (!transcoder_is_dsi(cpu_transcoder))
> >> +		hsw_set_pipeconf(new_crtc_state);
> >>  
> >>  	crtc->active = true;
> >>  
> >> @@ -7099,6 +7143,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
> >>  	if (INTEL_GEN(dev_priv) >= 11)
> >>  		icl_pipe_mbus_enable(crtc);
> >>  
> >> +	if (new_crtc_state->bigjoiner_slave) {
> >> +		trace_intel_pipe_enable(crtc);
> >> +		intel_crtc_vblank_on(new_crtc_state);
> >> +	}
> >> +
> >>  	intel_encoders_enable(state, crtc);
> >>  
> >>  	if (psl_clkgate_wa) {
> >> @@ -7381,6 +7430,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;
> >>  }
> >>  
> >> @@ -7999,6 +8051,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
> >>  		       pfit_w * pfit_h);
> >>  }
> >>  
> >> +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 pipe timings are half of the transcoder mode
> >> +		 */
> >> +		pipe_mode->crtc_hdisplay /= 2;
> >> +		pipe_mode->crtc_hblank_start /= 2;
> >> +		pipe_mode->crtc_hblank_end /= 2;
> >> +		pipe_mode->crtc_hsync_start /= 2;
> >> +		pipe_mode->crtc_hsync_end /= 2;
> >> +		pipe_mode->crtc_htotal /= 2;
> >> +		pipe_mode->crtc_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);
> >> @@ -8910,20 +8986,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> >> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> >> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> >> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
> >> +	mode->hdisplay = hw_mode->crtc_hdisplay;
> >> +	mode->htotal = hw_mode->crtc_htotal;
> >> +	mode->hsync_start = hw_mode->crtc_hsync_start;
> >> +	mode->hsync_end = hw_mode->crtc_hsync_end;
> >>  
> >> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
> >> +	mode->vdisplay = hw_mode->crtc_vdisplay;
> >> +	mode->vtotal = hw_mode->crtc_vtotal;
> >> +	mode->vsync_start = hw_mode->crtc_vsync_start;
> >> +	mode->vsync_end = hw_mode->crtc_vsync_end;
> >> +
> >> +	mode->flags = hw_mode->flags;
> >>  	mode->type = DRM_MODE_TYPE_DRIVER;
> >>  
> >> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
> >> +	mode->clock = hw_mode->crtc_clock;
> >>  
> >>  	drm_mode_set_name(mode);
> >>  }
> >> @@ -11081,6 +11159,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
> >>  	} else {
> >>  		tmp = intel_de_read(dev_priv,
> >>  				    TRANS_DDI_FUNC_CTL(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);
> >>  		else
> >> @@ -11153,12 +11234,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> >>  		drm_WARN_ON(&dev_priv->drm, 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) ||
> >> -	    INTEL_GEN(dev_priv) >= 11) {
> >> +		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) {
> >>  		hsw_get_ddi_port_state(crtc, pipe_config);
> >>  		intel_get_transcoder_timings(crtc, pipe_config);
> >>  	}
> >> @@ -11244,8 +11333,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> >>  		}
> >>  	}
> >>  
> >> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> >> -	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> >> +	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 =
> >>  			intel_de_read(dev_priv,
> >>  				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> >> @@ -12260,7 +12352,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);
> >>  
> >> @@ -13252,10 +13344,12 @@ 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;
> >> -	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> >> -		    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;
> >> +		drm_WARN_ON(crtc_state->uapi.crtc->dev,
> >> +			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> >> +	}
> >>  
> >>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> >>  
> >> @@ -13902,21 +13996,42 @@ 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_BOOL(has_hdmi_sink);
> >>  	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
> >> @@ -13926,24 +14041,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)
> >> @@ -13969,7 +14071,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))
> >> @@ -13990,48 +14093,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >>  	PIPE_CONF_CHECK_BOOL(double_wide);
> >>  
> >>  	PIPE_CONF_CHECK_P(shared_dpll);
> >> -	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);
> >> +	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(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);
> >> @@ -14043,11 +14149,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
> >>  
> >>  	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
> >>  	PIPE_CONF_CHECK_I(dsc.dsc_split);
> >>  	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
> >> -
> >>  	PIPE_CONF_CHECK_I(mst_master_transcoder);
> >>  
> >>  #undef PIPE_CONF_CHECK_X
> >> @@ -14314,6 +14421,7 @@ verify_crtc_state(struct intel_crtc *crtc,
> >>  	struct intel_encoder *encoder;
> >>  	struct intel_crtc_state *pipe_config = old_crtc_state;
> >>  	struct drm_atomic_state *state = old_crtc_state->uapi.state;
> >> +	struct intel_crtc *master = crtc;
> >>  	bool active;
> >>  
> >>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> >> @@ -14340,7 +14448,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);
> >> @@ -14349,12 +14460,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);
> >> @@ -15376,7 +15487,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> >>  {
> >>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> >>  
> >> +	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
> >> +
> >>  	intel_crtc_disable_planes(state, crtc);
> >> +	if (old_crtc_state->bigjoiner)
> >> +		intel_crtc_disable_planes(state,
> >> +					  old_crtc_state->bigjoiner_linked_crtc);
> >>  
> >>  	/*
> >>  	 * We need to disable pipe CRC before disabling the pipe,
> >> @@ -15406,7 +15522,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> >>  	/* Only disable port sync and MST slaves */
> >>  	for_each_oldnew_intel_crtc_in_state(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;
> >>  
> >>  		if (!old_crtc_state->hw.active)
> >> @@ -15421,7 +15537,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> >>  		    !intel_dp_mst_is_slave_trans(old_crtc_state))
> >>  			continue;
> >>  
> >> -		intel_pre_plane_update(state, crtc);
> >>  		intel_old_crtc_state_disables(state, old_crtc_state,
> >>  					      new_crtc_state, crtc);
> >>  		handled |= BIT(crtc->pipe);
> >> @@ -15431,10 +15546,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> >>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> >>  					    new_crtc_state, i) {
> >>  		if (!needs_modeset(new_crtc_state) ||
> >> -		    (handled & BIT(crtc->pipe)))
> >> +		    (handled & BIT(crtc->pipe)) ||
> >> +		    old_crtc_state->bigjoiner_slave)
> >>  			continue;
> >>  
> >>  		intel_pre_plane_update(state, crtc);
> >> +		if (old_crtc_state->bigjoiner) {
> >> +			struct intel_crtc *slave =
> >> +				old_crtc_state->bigjoiner_linked_crtc;
> >> +
> >> +			intel_pre_plane_update(state, slave);
> >> +		}
> >> +
> >>  		if (old_crtc_state->hw.active)
> >>  			intel_old_crtc_state_disables(state, old_crtc_state,
> >>  						      new_crtc_state, crtc);
> >> @@ -18063,7 +18186,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;
> >>  
> >>  		/*
> >> @@ -18562,7 +18685,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 4694cfd90a0a..943709f192f7 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> >> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> >> @@ -826,6 +826,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 */
> >> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> >> index 29f45d2206af..41cb9f9c0292 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> >> @@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> >>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
> >>  				  const struct intel_crtc_state *crtc_state)
> >>  {
> >> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> >> -
> >> -	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
> >> +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
> >>  		return false;
> >>  
> >> -	return intel_dsc_source_support(encoder, crtc_state) &&
> >> +	return intel_dsc_source_support(crtc_state) &&
> >>  		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 c5735c365659..2d343ccef497 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> >> @@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
> >>  	return &rc_parameters[row_index][column_index];
> >>  }
> >>  
> >> -bool intel_dsc_source_support(struct intel_encoder *encoder,
> >> -			      const struct intel_crtc_state *crtc_state)
> >> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
> >>  {
> >>  	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >> -	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> >> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
> >>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> >>  	enum pipe pipe = crtc->pipe;
> >>  
> >> @@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
> >>  		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
> >>  }
> >>  
> >> -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;
> >>  	u32 pps_val = 0;
> >> @@ -503,6 +501,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 |
> >> @@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
> >>  	}
> >>  }
> >>  
> >> -void intel_dsc_get_config(struct intel_encoder *encoder,
> >> -			  struct intel_crtc_state *crtc_state)
> >> -{
> >> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> >> -	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
> >> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >> -	enum pipe pipe = crtc->pipe;
> >> -	enum intel_display_power_domain power_domain;
> >> -	intel_wakeref_t wakeref;
> >> -	u32 dss_ctl1, dss_ctl2, val;
> >> -
> >> -	if (!intel_dsc_source_support(encoder, crtc_state))
> >> -		return;
> >> -
> >> -	power_domain = intel_dsc_power_domain(crtc_state);
> >> -
> >> -	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> >> -	if (!wakeref)
> >> -		return;
> >> -
> >> -	if (!is_pipe_dsc(crtc_state)) {
> >> -		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
> >> -		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
> >> -	} else {
> >> -		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
> >> -		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
> >> -	}
> >> -
> >> -	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
> >> -	if (!crtc_state->dsc.compression_enable)
> >> -		goto out;
> >> -
> >> -	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
> >> -		(dss_ctl1 & JOINER_ENABLE);
> >> -
> >> -	/* FIXME: add more state readout as needed */
> >> -
> >> -	/* PPS1 */
> >> -	if (!is_pipe_dsc(crtc_state))
> >> -		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
> >> -	else
> >> -		val = intel_de_read(dev_priv,
> >> -				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
> >> -	vdsc_cfg->bits_per_pixel = val;
> >> -	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
> >> -out:
> >> -	intel_display_power_put(dev_priv, power_domain, wakeref);
> >> -}
> >> -
> >>  static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
> >>  				    const struct intel_crtc_state *crtc_state)
> >>  {
> >> @@ -1060,77 +1012,130 @@ 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));
> > Why do we remove the power get for dsc_power_domains here? IMO this is causing the CI error since 
> > in dsc_disables we do try to put the dsc_power_domains but we error out saying on dsc disable:
> >
> > "Use count on VDSC POWER DOMAIN already 0"
> >
> > we need to get power domains here since for Pipe A/eDP on TGL, we do need a separate PW2 for VDSC.
> 
> It's the other way around, we need to remove it from dsc_disable.
> 
> get_crtc_power_domains() ensures we always have the dsc power domain correct, even when reading out from the original hw state. It had to be decoupled from the encoder as the slave pipe doesn't have an encoder, and we still want the DSC power domain in that case. :)
> 

Yes, I tried putting this power get call in intel_dsc_enable since I had put it originally while enabling DSC.
But that didnt fix it, so yes may be removing the put call from dsc_disable makes sense.
I will change that and resend the patches. Lets hope that fixes this CI error.

Manasi

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

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

* [Intel-gfx] [PATCH v8 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-07-16 21:12   ` [Intel-gfx] [PATCH v7 " Manasi Navare
@ 2020-08-10 23:28     ` Manasi Navare
  2020-08-27 23:35       ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Manasi Navare @ 2020-08-10 23:28 UTC (permalink / raw)
  To: intel-gfx

From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>

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.

v2:
* Manual rebase (Manasi)

v3:
* Rebase (Manasi)

v4:
* Rebase (Manasi)

v5:
* Get dsc power domain in ddi_init (Manasi)

v6:
* Remove dsc power put from dsc_disable (Maarten)

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
 drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
 drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |   1 +
 drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 201 +++++-----
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
 7 files changed, 413 insertions(+), 249 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 8c55f5bee9ab..26f7372b4c25 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
 	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
 	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 
-	intel_dsc_get_config(encoder, pipe_config);
-
 	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
 	pipe_config->port_clock = intel_dpll_get_freq(i915,
 						      pipe_config->shared_dpll);
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index de5b216561d8..6de13c67f5b8 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -28,6 +28,7 @@
 #include <drm/drm_scdc_helper.h>
 
 #include "i915_drv.h"
+#include "i915_trace.h"
 #include "intel_audio.h"
 #include "intel_combo_phy.h"
 #include "intel_connector.h"
@@ -2093,12 +2094,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 		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(struct intel_encoder *encoder,
@@ -3387,7 +3382,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
 
 	/* 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_atomic_state *state,
@@ -3458,7 +3454,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
 	if (!is_mst)
 		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
@@ -3713,6 +3710,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
 			ilk_pfit_disable(old_crtc_state);
 	}
 
+	if (old_crtc_state->bigjoiner_linked_crtc) {
+		struct intel_atomic_state *state =
+			to_intel_atomic_state(old_crtc_state->uapi.state);
+		struct intel_crtc *slave =
+			old_crtc_state->bigjoiner_linked_crtc;
+		const struct intel_crtc_state *old_slave_crtc_state =
+			intel_atomic_get_old_crtc_state(state, slave);
+
+		intel_crtc_vblank_off(old_slave_crtc_state);
+		trace_intel_pipe_disable(slave);
+
+		intel_dsc_disable(old_slave_crtc_state);
+		skl_scaler_disable(old_slave_crtc_state);
+	}
+
 	/*
 	 * When called from DP MST code:
 	 * - old_conn_state will be NULL
@@ -3927,7 +3939,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
 {
 	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
 
-	intel_ddi_enable_transcoder_func(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_slave)
+		intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
 	intel_enable_pipe(crtc_state);
 
@@ -4274,8 +4287,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
 		    crtc_state->sync_mode_slaves_mask);
 }
 
-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);
@@ -4283,13 +4296,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 	u32 temp, flags = 0;
 
-	/* XXX: DSI transcoder paranoia */
-	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
+	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
+	if (!(temp & TRANS_DDI_FUNC_ENABLE))
 		return;
 
-	intel_dsc_get_config(encoder, pipe_config);
-
-	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
 		flags |= DRM_MODE_FLAG_PHSYNC;
 	else
@@ -4397,6 +4407,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
 		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
 	}
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+
+	/* XXX: DSI transcoder paranoia */
+	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
+		return;
+
+	intel_ddi_read_func_ctl(encoder, pipe_config);
+	if (pipe_config->bigjoiner_slave) {
+		/* read out pipe settings from master */
+		enum transcoder save = pipe_config->cpu_transcoder;
+
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
+		WARN_ON(pipe_config->output_types);
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
+		intel_ddi_read_func_ctl(encoder, pipe_config);
+		pipe_config->cpu_transcoder = save;
+	}
 
 	pipe_config->has_audio =
 		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
@@ -4422,7 +4455,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 41af7f1011fd..7223b6d916e7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7024,6 +7024,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 	intel_de_write(dev_priv, reg, val);
 }
 
+static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
+					 const 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(state, master);
+		intel_enable_shared_dpll(master_crtc_state);
+		intel_encoders_pre_enable(state, master);
+
+		/* and DSC on slave */
+		intel_dsc_enable(NULL, crtc_state);
+	}
+}
+
 static void hsw_crtc_enable(struct intel_atomic_state *state,
 			    struct intel_crtc *crtc)
 {
@@ -7037,34 +7076,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
 		return;
 
-	intel_encoders_pre_pll_enable(state, crtc);
-
-	if (new_crtc_state->shared_dpll)
-		intel_enable_shared_dpll(new_crtc_state);
+	if (!new_crtc_state->bigjoiner) {
+		intel_encoders_pre_pll_enable(state, crtc);
 
-	intel_encoders_pre_enable(state, crtc);
+		if (new_crtc_state->shared_dpll)
+			intel_enable_shared_dpll(new_crtc_state);
 
-	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_set_transcoder_timings(new_crtc_state);
+		intel_encoders_pre_enable(state, crtc);
+	} else {
+		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
+	}
 
 	intel_set_pipe_src_size(new_crtc_state);
+	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
+		bdw_set_pipemisc(new_crtc_state);
 
-	if (cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(cpu_transcoder))
-		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
-			       new_crtc_state->pixel_multiplier - 1);
+	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
+		if (!transcoder_is_dsi(cpu_transcoder))
+			intel_set_transcoder_timings(new_crtc_state);
 
-	if (new_crtc_state->has_pch_encoder)
-		intel_cpu_transcoder_set_m_n(new_crtc_state,
-					     &new_crtc_state->fdi_m_n, NULL);
+		if (cpu_transcoder != TRANSCODER_EDP &&
+		    !transcoder_is_dsi(cpu_transcoder))
+			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
+				       new_crtc_state->pixel_multiplier - 1);
+
+		if (new_crtc_state->has_pch_encoder)
+			intel_cpu_transcoder_set_m_n(new_crtc_state,
+						     &new_crtc_state->fdi_m_n, NULL);
 
-	if (!transcoder_is_dsi(cpu_transcoder)) {
 		hsw_set_frame_start_delay(new_crtc_state);
-		hsw_set_pipeconf(new_crtc_state);
 	}
 
-	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
-		bdw_set_pipemisc(new_crtc_state);
+	if (!transcoder_is_dsi(cpu_transcoder))
+		hsw_set_pipeconf(new_crtc_state);
 
 	crtc->active = true;
 
@@ -7100,6 +7144,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_pipe_mbus_enable(crtc);
 
+	if (new_crtc_state->bigjoiner_slave) {
+		trace_intel_pipe_enable(crtc);
+		intel_crtc_vblank_on(new_crtc_state);
+	}
+
 	intel_encoders_enable(state, crtc);
 
 	if (psl_clkgate_wa) {
@@ -7382,6 +7431,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;
 }
 
@@ -8000,6 +8052,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
 		       pfit_w * pfit_h);
 }
 
+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 pipe timings are half of the transcoder mode
+		 */
+		pipe_mode->crtc_hdisplay /= 2;
+		pipe_mode->crtc_hblank_start /= 2;
+		pipe_mode->crtc_hblank_end /= 2;
+		pipe_mode->crtc_hsync_start /= 2;
+		pipe_mode->crtc_hsync_end /= 2;
+		pipe_mode->crtc_htotal /= 2;
+		pipe_mode->crtc_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);
@@ -8911,20 +8987,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
-	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
-	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
-	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
+	mode->hdisplay = hw_mode->crtc_hdisplay;
+	mode->htotal = hw_mode->crtc_htotal;
+	mode->hsync_start = hw_mode->crtc_hsync_start;
+	mode->hsync_end = hw_mode->crtc_hsync_end;
 
-	mode->flags = pipe_config->hw.adjusted_mode.flags;
+	mode->vdisplay = hw_mode->crtc_vdisplay;
+	mode->vtotal = hw_mode->crtc_vtotal;
+	mode->vsync_start = hw_mode->crtc_vsync_start;
+	mode->vsync_end = hw_mode->crtc_vsync_end;
+
+	mode->flags = hw_mode->flags;
 	mode->type = DRM_MODE_TYPE_DRIVER;
 
-	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
+	mode->clock = hw_mode->crtc_clock;
 
 	drm_mode_set_name(mode);
 }
@@ -11091,6 +11169,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
 	} else {
 		tmp = intel_de_read(dev_priv,
 				    TRANS_DDI_FUNC_CTL(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);
 		else
@@ -11163,12 +11244,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		drm_WARN_ON(&dev_priv->drm, 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) ||
-	    INTEL_GEN(dev_priv) >= 11) {
+		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) {
 		hsw_get_ddi_port_state(crtc, pipe_config);
 		intel_get_transcoder_timings(crtc, pipe_config);
 	}
@@ -11254,8 +11343,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
-	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
-	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
+	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 =
 			intel_de_read(dev_priv,
 				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
@@ -12270,7 +12362,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);
 
@@ -13262,10 +13354,12 @@ 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;
-	drm_WARN_ON(crtc_state->uapi.crtc->dev,
-		    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;
+		drm_WARN_ON(crtc_state->uapi.crtc->dev,
+			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
+	}
 
 	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
 
@@ -13912,21 +14006,42 @@ 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_BOOL(has_hdmi_sink);
 	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
@@ -13936,24 +14051,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)
@@ -13979,7 +14081,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))
@@ -14000,48 +14103,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 	PIPE_CONF_CHECK_BOOL(double_wide);
 
 	PIPE_CONF_CHECK_P(shared_dpll);
-	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);
+	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(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);
@@ -14053,11 +14159,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
 
 	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
 	PIPE_CONF_CHECK_I(dsc.dsc_split);
 	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
-
 	PIPE_CONF_CHECK_I(mst_master_transcoder);
 
 #undef PIPE_CONF_CHECK_X
@@ -14324,6 +14431,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 	struct intel_encoder *encoder;
 	struct intel_crtc_state *pipe_config = old_crtc_state;
 	struct drm_atomic_state *state = old_crtc_state->uapi.state;
+	struct intel_crtc *master = crtc;
 	bool active;
 
 	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
@@ -14350,7 +14458,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);
@@ -14359,12 +14470,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);
@@ -15386,7 +15497,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
 {
 	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 
+	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
+
 	intel_crtc_disable_planes(state, crtc);
+	if (old_crtc_state->bigjoiner)
+		intel_crtc_disable_planes(state,
+					  old_crtc_state->bigjoiner_linked_crtc);
 
 	/*
 	 * We need to disable pipe CRC before disabling the pipe,
@@ -15416,7 +15532,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	/* Only disable port sync and MST slaves */
 	for_each_oldnew_intel_crtc_in_state(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;
 
 		if (!old_crtc_state->hw.active)
@@ -15431,7 +15547,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 		    !intel_dp_mst_is_slave_trans(old_crtc_state))
 			continue;
 
-		intel_pre_plane_update(state, crtc);
 		intel_old_crtc_state_disables(state, old_crtc_state,
 					      new_crtc_state, crtc);
 		handled |= BIT(crtc->pipe);
@@ -15441,10 +15556,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
 		if (!needs_modeset(new_crtc_state) ||
-		    (handled & BIT(crtc->pipe)))
+		    (handled & BIT(crtc->pipe)) ||
+		    old_crtc_state->bigjoiner_slave)
 			continue;
 
 		intel_pre_plane_update(state, crtc);
+		if (old_crtc_state->bigjoiner) {
+			struct intel_crtc *slave =
+				old_crtc_state->bigjoiner_linked_crtc;
+
+			intel_pre_plane_update(state, slave);
+		}
+
 		if (old_crtc_state->hw.active)
 			intel_old_crtc_state_disables(state, old_crtc_state,
 						      new_crtc_state, crtc);
@@ -18080,7 +18203,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;
 
 		/*
@@ -18579,7 +18702,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 d9d56f15bff1..e93493757cbf 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -826,6 +826,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 */
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 29f45d2206af..41cb9f9c0292 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
 static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
 				  const struct intel_crtc_state *crtc_state)
 {
-	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
-
-	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
+	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
 		return false;
 
-	return intel_dsc_source_support(encoder, crtc_state) &&
+	return intel_dsc_source_support(crtc_state) &&
 		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 c5735c365659..e2716a67b281 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
 	return &rc_parameters[row_index][column_index];
 }
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state)
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
 {
 	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 	enum pipe pipe = crtc->pipe;
 
@@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
 }
 
-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;
 	u32 pps_val = 0;
@@ -503,6 +501,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 |
@@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
 	}
 }
 
-void intel_dsc_get_config(struct intel_encoder *encoder,
-			  struct intel_crtc_state *crtc_state)
-{
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
-	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	enum pipe pipe = crtc->pipe;
-	enum intel_display_power_domain power_domain;
-	intel_wakeref_t wakeref;
-	u32 dss_ctl1, dss_ctl2, val;
-
-	if (!intel_dsc_source_support(encoder, crtc_state))
-		return;
-
-	power_domain = intel_dsc_power_domain(crtc_state);
-
-	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
-	if (!wakeref)
-		return;
-
-	if (!is_pipe_dsc(crtc_state)) {
-		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
-		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
-	} else {
-		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
-		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
-	}
-
-	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
-	if (!crtc_state->dsc.compression_enable)
-		goto out;
-
-	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
-		(dss_ctl1 & JOINER_ENABLE);
-
-	/* FIXME: add more state readout as needed */
-
-	/* PPS1 */
-	if (!is_pipe_dsc(crtc_state))
-		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
-	else
-		val = intel_de_read(dev_priv,
-				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
-	vdsc_cfg->bits_per_pixel = val;
-	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
-out:
-	intel_display_power_put(dev_priv, power_domain, wakeref);
-}
-
 static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
 				    const struct intel_crtc_state *crtc_state)
 {
@@ -1060,77 +1012,126 @@ 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(encoder, crtc_state);
+	intel_dsc_pps_configure(crtc_state);
 
-	if (encoder->type == INTEL_OUTPUT_DSI)
-		intel_dsc_dsi_pps_write(encoder, crtc_state);
-	else
-		intel_dsc_dp_pps_write(encoder, crtc_state);
-
-	if (!is_pipe_dsc(crtc_state)) {
-		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);
+	if (!crtc_state->bigjoiner_slave) {
+		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
+			intel_dsc_dsi_pps_write(encoder, crtc_state);
+		else
+			intel_dsc_dp_pps_write(encoder, crtc_state);
 	}
+
 	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;
 	}
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-	intel_de_write(dev_priv, 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;
+	}
+	intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
+	intel_de_write(dev_priv, 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 (!is_pipe_dsc(old_crtc_state)) {
-		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);
+	intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
+	intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
+}
+
+void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
+{
+	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	enum pipe pipe = crtc->pipe;
+	enum intel_display_power_domain power_domain;
+	intel_wakeref_t wakeref;
+	u32 dss_ctl1, dss_ctl2, val;
+
+	if (!intel_dsc_source_support(crtc_state))
+		return;
+
+	power_domain = intel_dsc_power_domain(crtc_state);
+
+	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
+	if (!wakeref)
+		return;
+
+	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
+	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
+
+	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
+	if (!crtc_state->dsc.compression_enable)
+		goto out;
+
+	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
+		(dss_ctl1 & JOINER_ENABLE);
+
+	if (dss_ctl1 & BIG_JOINER_ENABLE) {
+		crtc_state->bigjoiner = true;
+
+		if (!(dss_ctl1 & 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 = intel_de_read(dev_priv, dss_ctl1_reg);
-	if (dss_ctl1_val & JOINER_ENABLE)
-		dss_ctl1_val &= ~JOINER_ENABLE;
-	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
-
-	dss_ctl2_val = intel_de_read(dev_priv, 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);
-	intel_de_write(dev_priv, 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));
+
+	/* FIXME: add more state readout as needed */
+
+	/* PPS1 */
+	if (!is_pipe_dsc(crtc_state))
+		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
+	else
+		val = intel_de_read(dev_priv,
+				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
+	vdsc_cfg->bits_per_pixel = val;
+	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
+out:
+	intel_display_power_put(dev_priv, power_domain, wakeref);
 }
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
index e56a3254c214..5301345ac5e7 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -11,15 +11,14 @@
 struct intel_encoder;
 struct intel_crtc_state;
 
-bool intel_dsc_source_support(struct intel_encoder *encoder,
-			      const struct intel_crtc_state *crtc_state);
+bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
 void intel_dsc_enable(struct intel_encoder *encoder,
 		      const struct intel_crtc_state *crtc_state);
 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_encoder *encoder,
-			  struct intel_crtc_state *crtc_state);
+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.19.1

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (17 preceding siblings ...)
  2020-07-17  1:04 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
@ 2020-08-10 23:47 ` Patchwork
  2020-08-10 23:48 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-10 23:47 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim checkpatch origin/drm-tip
94f4928909c8 HAX to make DSC work on the icelake test system
3b320ffb4bc2 drm/i915: Remove hw.mode
167ba475cb68 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:216: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#216: FILE: drivers/gpu/drm/i915/display/intel_display.c:13229:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 0 warnings, 1 checks, 445 lines checked
59fbefeedaa6 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
354e47b3d9eb drm/i915: Try to make bigjoiner work in atomic check
-:143: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#143: FILE: drivers/gpu/drm/i915/display/intel_display.c:13242:
+								  crtc_state->bigjoiner_linked_crtc);

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

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

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

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

-:332: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#332: FILE: drivers/gpu/drm/i915/display/intel_display.c:14966:
+		slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

-:387: WARNING:BRACES: braces {} are not necessary for any arm of this statement
#387: FILE: drivers/gpu/drm/i915/display/intel_display.c:15361:
+	if (new_crtc_state->bigjoiner) {
[...]
+	} else if (INTEL_GEN(dev_priv) >= 9)
[...]
 	else
[...]

total: 0 errors, 3 warnings, 5 checks, 401 lines checked
54000a12eca0 drm/i915: Enable big joiner support in enable and disable sequences.
-:178: WARNING:LONG_LINE_COMMENT: line length of 106 exceeds 100 columns
#178: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4427:
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

-:180: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#180: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4429:
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;

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

total: 0 errors, 2 warnings, 1 checks, 995 lines checked
6adc9031acd5 drm/i915: Make hardware readout work on i915.
-:33: WARNING:TABSTOP: Statements should start on a tabstop
#33: FILE: drivers/gpu/drm/i915/display/intel_display.c:3610:
+	 struct intel_crtc_state *crtc_state =

-:76: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#76: FILE: drivers/gpu/drm/i915/display/intel_display.c:10695:
+		    (intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000) == plane_config->base) {

total: 0 errors, 2 warnings, 0 checks, 118 lines checked
0aebc7f853d3 drm/i915: Link planes in a bigjoiner configuration, v3.
-:203: ERROR:CODE_INDENT: code indent should use tabs where possible
#203: FILE: drivers/gpu/drm/i915/display/intel_display.c:12636:
+         * Setup and teardown the new bigjoiner plane mappings.$

-:204: ERROR:CODE_INDENT: code indent should use tabs where possible
#204: FILE: drivers/gpu/drm/i915/display/intel_display.c:12637:
+         */$

-:289: ERROR:CODE_INDENT: code indent should use tabs where possible
#289: FILE: drivers/gpu/drm/i915/display/intel_display.c:12718:
+         *$

-:305: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#305: FILE: drivers/gpu/drm/i915/display/intel_display.c:12732:
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {

-:321: ERROR:CODE_INDENT: code indent should use tabs where possible
#321: FILE: drivers/gpu/drm/i915/display/intel_display.c:12748:
+         * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically$

-:322: ERROR:CODE_INDENT: code indent should use tabs where possible
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:12749:
+         * when adding slave planes, because plane_state->crtc is null.$

-:323: ERROR:CODE_INDENT: code indent should use tabs where possible
#323: FILE: drivers/gpu/drm/i915/display/intel_display.c:12750:
+         */$

-:435: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#435: FILE: drivers/gpu/drm/i915/display/intel_display.h:472:
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
[...]
+	for_each_if ((((plane_state) = \

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

-:442: WARNING:LONG_LINE: line length of 124 exceeds 100 columns
#442: FILE: drivers/gpu/drm/i915/display/intel_display.h:479:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \

-:443: WARNING:LONG_LINE: line length of 109 exceeds 100 columns
#443: FILE: drivers/gpu/drm/i915/display/intel_display.h:480:
+		      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

-:445: WARNING:LONG_LINE: line length of 125 exceeds 100 columns
#445: FILE: drivers/gpu/drm/i915/display/intel_display.h:482:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \

total: 6 errors, 6 warnings, 0 checks, 481 lines checked
83120ea46d35 drm/i915: Add bigjoiner aware plane clipping checks
e0a96e6c643e drm/i915: Add intel_update_bigjoiner handling.
d598c90ba017 drm/i915: Add debugfs dumping for bigjoiner, v3.
-:46: WARNING:LONG_LINE: line length of 123 exceeds 100 columns
#46: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:777:
+	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",

-:56: WARNING:LONG_LINE: line length of 119 exceeds 100 columns
#56: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:787:
+			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,

-:60: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#60: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:791:
+			   plane_state->bigjoiner_plane->base.base.id, plane_state->bigjoiner_plane->base.name,

total: 0 errors, 3 warnings, 0 checks, 52 lines checked


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

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (18 preceding siblings ...)
  2020-08-10 23:47 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3) Patchwork
@ 2020-08-10 23:48 ` Patchwork
  2020-08-11  0:09 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-10 23:48 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.0
Fast mode used, each commit won't be checked separately.


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

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

* [Intel-gfx] ✗ Fi.CI.BAT: failure for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (19 preceding siblings ...)
  2020-08-10 23:48 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-08-11  0:09 ` Patchwork
  2020-08-11 18:33 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4) Patchwork
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-11  0:09 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 8059 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8866 -> Patchwork_18338
====================================================

Summary
-------

  **FAILURE**

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

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

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

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

### IGT changes ###

#### Possible regressions ####

  * igt@gem_exec_parallel@engines@contexts:
    - fi-bdw-gvtdvm:      [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-bdw-gvtdvm/igt@gem_exec_parallel@engines@contexts.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-bdw-gvtdvm/igt@gem_exec_parallel@engines@contexts.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-tgl-u2:          [PASS][3] -> [FAIL][4] ([i915#1888])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-tgl-u2/igt@gem_exec_suspend@basic-s0.html

  * igt@kms_busy@basic@flip:
    - fi-kbl-x1275:       [PASS][5] -> [DMESG-WARN][6] ([i915#62] / [i915#92] / [i915#95])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-kbl-x1275/igt@kms_busy@basic@flip.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-kbl-x1275/igt@kms_busy@basic@flip.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-byt-j1900:       [PASS][7] -> [DMESG-WARN][8] ([i915#1982])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-byt-j1900/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-byt-j1900/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
    - fi-bsw-kefka:       [PASS][9] -> [DMESG-WARN][10] ([i915#1982])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-bsw-kefka/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
    - fi-icl-u2:          [PASS][11] -> [DMESG-WARN][12] ([i915#1982])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html

  
#### Possible fixes ####

  * igt@i915_pm_rpm@basic-pci-d3-state:
    - fi-bsw-kefka:       [DMESG-WARN][13] ([i915#1982]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-bsw-kefka/igt@i915_pm_rpm@basic-pci-d3-state.html

  * igt@i915_pm_rpm@module-reload:
    - fi-byt-j1900:       [DMESG-WARN][15] ([i915#1982]) -> [PASS][16]
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-byt-j1900/igt@i915_pm_rpm@module-reload.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-byt-j1900/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@execlists:
    - fi-icl-y:           [INCOMPLETE][17] ([i915#2276]) -> [PASS][18]
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-icl-y/igt@i915_selftest@live@execlists.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-icl-y/igt@i915_selftest@live@execlists.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - {fi-kbl-7560u}:     [DMESG-WARN][19] ([i915#1982]) -> [PASS][20]
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-kbl-7560u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-kbl-7560u/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - fi-icl-u2:          [DMESG-WARN][21] ([i915#1982]) -> [PASS][22]
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  
#### Warnings ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-kbl-x1275:       [DMESG-WARN][23] ([i915#62] / [i915#92]) -> [DMESG-WARN][24] ([i915#62] / [i915#92] / [i915#95]) +1 similar issue
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-kbl-x1275/igt@gem_exec_suspend@basic-s3.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-kbl-x1275/igt@gem_exec_suspend@basic-s3.html

  * igt@kms_force_connector_basic@prune-stale-modes:
    - fi-kbl-x1275:       [DMESG-WARN][25] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][26] ([i915#62] / [i915#92]) +5 similar issues
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8866/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18338/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html

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

  [i915#1602]: https://gitlab.freedesktop.org/drm/intel/issues/1602
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2276]: https://gitlab.freedesktop.org/drm/intel/issues/2276
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (44 -> 37)
------------------------------

  Missing    (7): fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-byt-clapper fi-bdw-samus 


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

  * Linux: CI_DRM_8866 -> Patchwork_18338

  CI-20190529: 20190529
  CI_DRM_8866: 14e46145f8add798ffc8d63a53e803749ccd3286 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5766: fc9f95086fc23f7f2226f7603241fbad3a214ee1 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18338: d598c90ba01765c562675a7ec902230a1ef7066f @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

d598c90ba017 drm/i915: Add debugfs dumping for bigjoiner, v3.
e0a96e6c643e drm/i915: Add intel_update_bigjoiner handling.
83120ea46d35 drm/i915: Add bigjoiner aware plane clipping checks
0aebc7f853d3 drm/i915: Link planes in a bigjoiner configuration, v3.
6adc9031acd5 drm/i915: Make hardware readout work on i915.
54000a12eca0 drm/i915: Enable big joiner support in enable and disable sequences.
354e47b3d9eb drm/i915: Try to make bigjoiner work in atomic check
59fbefeedaa6 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
167ba475cb68 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
3b320ffb4bc2 drm/i915: Remove hw.mode
94f4928909c8 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_18338/index.html

[-- Attachment #1.2: Type: text/html, Size: 9972 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (20 preceding siblings ...)
  2020-08-11  0:09 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
@ 2020-08-11 18:33 ` Patchwork
  2020-08-11 18:35 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-11 18:33 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim checkpatch origin/drm-tip
292437cfd978 HAX to make DSC work on the icelake test system
23ada98c4ac5 drm/i915: Remove hw.mode
5a8a7f2434e9 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:216: CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#216: FILE: drivers/gpu/drm/i915/display/intel_display.c:13232:
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;

total: 0 errors, 0 warnings, 1 checks, 445 lines checked
d87e5294d7d0 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
923a00142e46 drm/i915: Try to make bigjoiner work in atomic check
-:143: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#143: FILE: drivers/gpu/drm/i915/display/intel_display.c:13245:
+								  crtc_state->bigjoiner_linked_crtc);

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

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

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

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

-:332: WARNING:LONG_LINE: line length of 106 exceeds 100 columns
#332: FILE: drivers/gpu/drm/i915/display/intel_display.c:14969:
+		slave_crtc_state->bigjoiner_linked_crtc = master_crtc_state->bigjoiner_linked_crtc = NULL;

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

-:387: WARNING:BRACES: braces {} are not necessary for any arm of this statement
#387: FILE: drivers/gpu/drm/i915/display/intel_display.c:15366:
+	if (new_crtc_state->bigjoiner) {
[...]
+	} else if (INTEL_GEN(dev_priv) >= 9)
[...]
 	else
[...]

total: 0 errors, 3 warnings, 5 checks, 401 lines checked
46581bdd9af5 drm/i915: Enable big joiner support in enable and disable sequences.
-:178: WARNING:LONG_LINE_COMMENT: line length of 106 exceeds 100 columns
#178: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4427:
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

-:180: WARNING:LONG_LINE: line length of 104 exceeds 100 columns
#180: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4429:
+		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;

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

total: 0 errors, 2 warnings, 1 checks, 995 lines checked
7a0b9db39261 drm/i915: Make hardware readout work on i915.
-:33: WARNING:TABSTOP: Statements should start on a tabstop
#33: FILE: drivers/gpu/drm/i915/display/intel_display.c:3610:
+	 struct intel_crtc_state *crtc_state =

-:76: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#76: FILE: drivers/gpu/drm/i915/display/intel_display.c:10695:
+		    (intel_de_read(dev_priv, PLANE_SURF(pipe, plane_id)) & 0xfffff000) == plane_config->base) {

total: 0 errors, 2 warnings, 0 checks, 118 lines checked
450fc3667d12 drm/i915: Link planes in a bigjoiner configuration, v3.
-:203: ERROR:CODE_INDENT: code indent should use tabs where possible
#203: FILE: drivers/gpu/drm/i915/display/intel_display.c:12636:
+         * Setup and teardown the new bigjoiner plane mappings.$

-:204: ERROR:CODE_INDENT: code indent should use tabs where possible
#204: FILE: drivers/gpu/drm/i915/display/intel_display.c:12637:
+         */$

-:289: ERROR:CODE_INDENT: code indent should use tabs where possible
#289: FILE: drivers/gpu/drm/i915/display/intel_display.c:12718:
+         *$

-:305: WARNING:LONG_LINE: line length of 105 exceeds 100 columns
#305: FILE: drivers/gpu/drm/i915/display/intel_display.c:12732:
+		for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {

-:321: ERROR:CODE_INDENT: code indent should use tabs where possible
#321: FILE: drivers/gpu/drm/i915/display/intel_display.c:12748:
+         * Make sure bigjoiner slave crtc's are also pulled in. This is not done automatically$

-:322: ERROR:CODE_INDENT: code indent should use tabs where possible
#322: FILE: drivers/gpu/drm/i915/display/intel_display.c:12749:
+         * when adding slave planes, because plane_state->crtc is null.$

-:323: ERROR:CODE_INDENT: code indent should use tabs where possible
#323: FILE: drivers/gpu/drm/i915/display/intel_display.c:12750:
+         */$

-:435: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (8, 8)
#435: FILE: drivers/gpu/drm/i915/display/intel_display.h:472:
+	for_each_intel_plane_mask(((crtc_state)->uapi.state->dev), (iter), \
[...]
+	for_each_if ((((plane_state) = \

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

-:442: WARNING:LONG_LINE: line length of 124 exceeds 100 columns
#442: FILE: drivers/gpu/drm/i915/display/intel_display.h:479:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &iter->base))), \

-:443: WARNING:LONG_LINE: line length of 109 exceeds 100 columns
#443: FILE: drivers/gpu/drm/i915/display/intel_display.h:480:
+		      ((plane) = (plane_state)->bigjoiner_slave ? (plane_state)->bigjoiner_plane : (iter)), \

-:445: WARNING:LONG_LINE: line length of 125 exceeds 100 columns
#445: FILE: drivers/gpu/drm/i915/display/intel_display.h:482:
+		       to_intel_plane_state(__drm_atomic_get_current_plane_state((crtc_state)->uapi.state, &plane->base)) : \

total: 6 errors, 6 warnings, 0 checks, 481 lines checked
276c25c8a083 drm/i915: Add bigjoiner aware plane clipping checks
e7946df95b2c drm/i915: Add intel_update_bigjoiner handling.
583f5c86bb83 drm/i915: Add debugfs dumping for bigjoiner, v3.
-:46: WARNING:LONG_LINE: line length of 123 exceeds 100 columns
#46: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:780:
+	seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",

-:56: WARNING:LONG_LINE: line length of 119 exceeds 100 columns
#56: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:790:
+			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,

-:60: WARNING:LONG_LINE: line length of 111 exceeds 100 columns
#60: FILE: drivers/gpu/drm/i915/display/intel_display_debugfs.c:794:
+			   plane_state->bigjoiner_plane->base.base.id, plane_state->bigjoiner_plane->base.name,

total: 0 errors, 3 warnings, 0 checks, 52 lines checked


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

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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (21 preceding siblings ...)
  2020-08-11 18:33 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4) Patchwork
@ 2020-08-11 18:35 ` Patchwork
  2020-08-11 18:56 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
  2020-08-11 20:15 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-11 18:35 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

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

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.
-
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47:    expected unsigned int [addressable] [usertype] ulClockParams
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47:    got restricted __le32 [usertype]
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1019:47: warning: incorrect type in assignment (different base types)
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1028:50: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1029:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:1037:47: warning: too many warnings
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:184:44: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:283:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:320:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:323:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:326:14: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:329:18: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:330:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:338:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:340:38: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:342:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:346:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:348:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:353:33: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:367:43: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:369:38: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:374:67: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:375:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:378:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:389:80: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:395:57: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:402:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:403:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:406:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:414:66: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:423:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:424:69: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:473:30: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:476:45: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:477:45: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:484:54: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:52:28: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:531:35: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:53:29: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:533:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:54:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:55:27: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:56:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:57:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:577:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:581:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:58:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:583:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:586:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:590:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:59:26: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:598:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:600:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:617:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:621:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:623:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:630:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:632:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:644:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:648:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:650:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:657:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:659:21: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:662:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:664:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:676:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:688:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:691:47: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:697:25: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:796:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:797:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:800:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:801:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:804:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:805:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:812:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:813:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:816:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:817:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:820:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:821:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:828:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:829:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:832:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:833:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:836:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:837:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:844:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:845:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:848:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:849:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:852:46: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:853:40: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:916:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:918:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:920:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:934:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:936:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:938:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:956:47: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:958:49: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c:960:52: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:328:34: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:365:34: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:395:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:397:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:404:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:418:40: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:441:40: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:44:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:482:53: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:486:33: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:489:61: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:490:64: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:492:54: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:518:17: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:521:21: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:64:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:80:17: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:85:30: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:86:24: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c:98:39: warning: cast to restricted __le16
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:222:29: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:226:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:227:37: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:233:43: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:236:44: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:239:51: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:458:41: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:464:39: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:465:30: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:466:39: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c:468:24: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26:    expected unsigned long long [usertype] *chunk_array_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:140:26: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41:    got unsigned long long [usertype] *chunk_array_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:141:41: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27:    expected struct drm_amdgpu_cs_chunk [noderef] __user **chunk_ptr
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:160:27: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21:    expected struct drm_amdgpu_fence *fences_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21:    got void [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1613:21: warning: incorrect type in assignment (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36:    got struct drm_amdgpu_fence *fences_user
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:1614:36: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49:    expected void const [noderef] __user *from
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49:    got struct drm_amdgpu_cs_chunk [noderef] __user **chunk_ptr
+drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c:161:49: warning: incorrect type in argument 2 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1357:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1357:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1357:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1358:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1358:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1358:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17:    expected restricted __poll_t ( *poll )( ... )
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17:    got unsigned int ( * )( ... )
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:138:17: warning: incorrect type in initializer (different base types)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1417:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1417:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1417:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:261:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:263:29: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:354:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:412:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:473:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:531:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:592:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:650:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21:    expected void const volatile [noderef] __user *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21:    got unsigned int [usertype] *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: cast removes address space '__user' of expression
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: incorrect type in argument 1 (different address spaces)
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:747:21: warning: too many warnings
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1666:65: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1674:55: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1675:50: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1676:50: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1677:56: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1679:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1680:45: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1681:51: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1682:55: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1683:57: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1685:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1686:53: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1688:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1690:25: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1691:46: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1695:73: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1697:33: warning: cast to restricted __le32
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:1699:33: warning: cast to restricted __le32
+drivers/gpu/drm/amd/


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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (22 preceding siblings ...)
  2020-08-11 18:35 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-08-11 18:56 ` Patchwork
  2020-08-11 20:15 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-11 18:56 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 7068 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8871 -> Patchwork_18345
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_suspend@basic-s0:
    - fi-cfl-8109u:       [PASS][1] -> [DMESG-WARN][2] ([i915#295]) +1 similar issue
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-cfl-8109u/igt@gem_exec_suspend@basic-s0.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-cfl-8109u/igt@gem_exec_suspend@basic-s0.html

  * igt@i915_selftest@live@execlists:
    - fi-icl-y:           [PASS][3] -> [INCOMPLETE][4] ([i915#2276])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-icl-y/igt@i915_selftest@live@execlists.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-icl-y/igt@i915_selftest@live@execlists.html

  * igt@i915_selftest@live@gt_lrc:
    - fi-tgl-u2:          [PASS][5] -> [DMESG-FAIL][6] ([i915#1233])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-tgl-u2/igt@i915_selftest@live@gt_lrc.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-tgl-u2/igt@i915_selftest@live@gt_lrc.html

  * igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1:
    - fi-icl-u2:          [PASS][7] -> [DMESG-WARN][8] ([i915#1982])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-icl-u2/igt@kms_flip@basic-flip-vs-wf_vblank@b-edp1.html

  
#### Possible fixes ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-soraka:      [DMESG-WARN][9] ([i915#1982]) -> [PASS][10]
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-kbl-soraka/igt@i915_pm_rpm@module-reload.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-kbl-soraka/igt@i915_pm_rpm@module-reload.html

  * igt@i915_selftest@live@execlists:
    - fi-icl-u2:          [INCOMPLETE][11] ([i915#2089] / [i915#2276]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-icl-u2/igt@i915_selftest@live@execlists.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-icl-u2/igt@i915_selftest@live@execlists.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - fi-bsw-n3050:       [DMESG-WARN][13] ([i915#1982]) -> [PASS][14]
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-bsw-n3050/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy:
    - fi-icl-u2:          [DMESG-WARN][15] ([i915#1982]) -> [PASS][16] +1 similar issue
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-icl-u2/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-legacy.html

  
#### Warnings ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-x1275:       [DMESG-FAIL][17] ([i915#62] / [i915#95]) -> [SKIP][18] ([fdo#109271])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-kbl-x1275/igt@i915_pm_rpm@module-reload.html

  * igt@kms_force_connector_basic@prune-stale-modes:
    - fi-kbl-x1275:       [DMESG-WARN][19] ([i915#62] / [i915#92] / [i915#95]) -> [DMESG-WARN][20] ([i915#62] / [i915#92]) +8 similar issues
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-kbl-x1275/igt@kms_force_connector_basic@prune-stale-modes.html

  * igt@prime_vgem@basic-fence-flip:
    - fi-kbl-x1275:       [DMESG-WARN][21] ([i915#62] / [i915#92]) -> [DMESG-WARN][22] ([i915#62] / [i915#92] / [i915#95]) +2 similar issues
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/fi-kbl-x1275/igt@prime_vgem@basic-fence-flip.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/fi-kbl-x1275/igt@prime_vgem@basic-fence-flip.html

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

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#1233]: https://gitlab.freedesktop.org/drm/intel/issues/1233
  [i915#1602]: https://gitlab.freedesktop.org/drm/intel/issues/1602
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2089]: https://gitlab.freedesktop.org/drm/intel/issues/2089
  [i915#2276]: https://gitlab.freedesktop.org/drm/intel/issues/2276
  [i915#295]: https://gitlab.freedesktop.org/drm/intel/issues/295
  [i915#456]: https://gitlab.freedesktop.org/drm/intel/issues/456
  [i915#62]: https://gitlab.freedesktop.org/drm/intel/issues/62
  [i915#92]: https://gitlab.freedesktop.org/drm/intel/issues/92
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (43 -> 37)
------------------------------

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


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

  * Linux: CI_DRM_8871 -> Patchwork_18345

  CI-20190529: 20190529
  CI_DRM_8871: ca35526cf770cf90faacceda5f0d03e1518d5585 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5767: 39e9aa1032a4e60f776f34b3ccf4fb728abbfe5c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18345: 583f5c86bb83dec8e6177940a0dbe28147778d16 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

583f5c86bb83 drm/i915: Add debugfs dumping for bigjoiner, v3.
e7946df95b2c drm/i915: Add intel_update_bigjoiner handling.
276c25c8a083 drm/i915: Add bigjoiner aware plane clipping checks
450fc3667d12 drm/i915: Link planes in a bigjoiner configuration, v3.
7a0b9db39261 drm/i915: Make hardware readout work on i915.
46581bdd9af5 drm/i915: Enable big joiner support in enable and disable sequences.
923a00142e46 drm/i915: Try to make bigjoiner work in atomic check
d87e5294d7d0 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
5a8a7f2434e9 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
23ada98c4ac5 drm/i915: Remove hw.mode
292437cfd978 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_18345/index.html

[-- Attachment #1.2: Type: text/html, Size: 8720 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4)
  2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (23 preceding siblings ...)
  2020-08-11 18:56 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-08-11 20:15 ` Patchwork
  24 siblings, 0 replies; 80+ messages in thread
From: Patchwork @ 2020-08-11 20:15 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 13477 bytes --]

== Series Details ==

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

== Summary ==

CI Bug Log - changes from CI_DRM_8871_full -> Patchwork_18345_full
====================================================

Summary
-------

  **FAILURE**

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

### IGT changes ###

#### Possible regressions ####

  * igt@gem_exec_whisper@basic-contexts:
    - shard-glk:          [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-glk8/igt@gem_exec_whisper@basic-contexts.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-glk6/igt@gem_exec_whisper@basic-contexts.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-skl:          [PASS][3] -> [INCOMPLETE][4]
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl9/igt@gem_workarounds@suspend-resume-fd.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl1/igt@gem_workarounds@suspend-resume-fd.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_shared@q-smoketest-all:
    - shard-glk:          [PASS][5] -> [DMESG-WARN][6] ([i915#118] / [i915#95]) +2 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-glk8/igt@gem_ctx_shared@q-smoketest-all.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-glk3/igt@gem_ctx_shared@q-smoketest-all.html

  * igt@gem_huc_copy@huc-copy:
    - shard-tglb:         [PASS][7] -> [SKIP][8] ([i915#2190])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-tglb2/igt@gem_huc_copy@huc-copy.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-tglb6/igt@gem_huc_copy@huc-copy.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-apl:          [PASS][9] -> [DMESG-WARN][10] ([i915#1436] / [i915#1635] / [i915#716])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-apl6/igt@gen9_exec_parse@allowed-all.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-apl2/igt@gen9_exec_parse@allowed-all.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-0:
    - shard-glk:          [PASS][11] -> [DMESG-FAIL][12] ([i915#118] / [i915#95]) +1 similar issue
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-glk1/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-glk8/igt@kms_big_fb@x-tiled-64bpp-rotate-0.html

  * igt@kms_big_fb@x-tiled-64bpp-rotate-180:
    - shard-kbl:          [PASS][13] -> [DMESG-WARN][14] ([i915#1982])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-kbl4/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-kbl1/igt@kms_big_fb@x-tiled-64bpp-rotate-180.html

  * igt@kms_cursor_edge_walk@pipe-a-256x256-right-edge:
    - shard-skl:          [PASS][15] -> [DMESG-WARN][16] ([i915#1982]) +13 similar issues
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl4/igt@kms_cursor_edge_walk@pipe-a-256x256-right-edge.html
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl8/igt@kms_cursor_edge_walk@pipe-a-256x256-right-edge.html

  * igt@kms_flip@dpms-vs-vblank-race-interruptible@c-hdmi-a1:
    - shard-glk:          [PASS][17] -> [FAIL][18] ([i915#407])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-glk9/igt@kms_flip@dpms-vs-vblank-race-interruptible@c-hdmi-a1.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-glk2/igt@kms_flip@dpms-vs-vblank-race-interruptible@c-hdmi-a1.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render:
    - shard-tglb:         [PASS][19] -> [DMESG-WARN][20] ([i915#1982]) +1 similar issue
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-tglb6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render.html
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-tglb5/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-suspend:
    - shard-iclb:         [PASS][21] -> [INCOMPLETE][22] ([i915#1185] / [i915#123])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-iclb8/igt@kms_frontbuffer_tracking@psr-suspend.html
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-iclb3/igt@kms_frontbuffer_tracking@psr-suspend.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-kbl:          [PASS][23] -> [DMESG-WARN][24] ([i915#180]) +8 similar issues
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-kbl3/igt@kms_hdr@bpc-switch-suspend.html
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-kbl2/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][25] -> [DMESG-FAIL][26] ([fdo#108145] / [i915#1982])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl1/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl2/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_plane_alpha_blend@pipe-c-coverage-7efc:
    - shard-skl:          [PASS][27] -> [FAIL][28] ([fdo#108145] / [i915#265]) +2 similar issues
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl7/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl6/igt@kms_plane_alpha_blend@pipe-c-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         [PASS][29] -> [SKIP][30] ([fdo#109441]) +2 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-iclb1/igt@kms_psr@psr2_cursor_render.html

  
#### Possible fixes ####

  * igt@gem_ctx_persistence@smoketest:
    - shard-skl:          [DMESG-WARN][31] ([i915#1982]) -> [PASS][32] +6 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl4/igt@gem_ctx_persistence@smoketest.html
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl8/igt@gem_ctx_persistence@smoketest.html

  * igt@gem_exec_schedule@pi-common@bcs0:
    - shard-apl:          [INCOMPLETE][33] ([i915#1635]) -> [PASS][34]
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-apl4/igt@gem_exec_schedule@pi-common@bcs0.html
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-apl2/igt@gem_exec_schedule@pi-common@bcs0.html

  * igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic:
    - shard-tglb:         [DMESG-WARN][35] ([i915#1982]) -> [PASS][36] +1 similar issue
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-tglb5/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-tglb5/igt@kms_cursor_legacy@basic-busy-flip-before-cursor-atomic.html

  * igt@kms_flip@flip-vs-suspend-interruptible@b-edp1:
    - shard-skl:          [INCOMPLETE][37] ([i915#198]) -> [PASS][38] +1 similar issue
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl8/igt@kms_flip@flip-vs-suspend-interruptible@b-edp1.html
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl9/igt@kms_flip@flip-vs-suspend-interruptible@b-edp1.html

  * igt@kms_flip@flip-vs-suspend-interruptible@c-dp1:
    - shard-kbl:          [DMESG-WARN][39] ([i915#180]) -> [PASS][40] +5 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-kbl4/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-kbl1/igt@kms_flip@flip-vs-suspend-interruptible@c-dp1.html

  * igt@kms_flip@plain-flip-fb-recreate@a-dp1:
    - shard-kbl:          [DMESG-WARN][41] ([i915#1982]) -> [PASS][42]
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-kbl6/igt@kms_flip@plain-flip-fb-recreate@a-dp1.html
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-kbl3/igt@kms_flip@plain-flip-fb-recreate@a-dp1.html

  * igt@kms_hdr@bpc-switch:
    - shard-skl:          [FAIL][43] ([i915#1188]) -> [PASS][44]
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl1/igt@kms_hdr@bpc-switch.html
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl2/igt@kms_hdr@bpc-switch.html

  * igt@kms_psr@psr2_sprite_blt:
    - shard-iclb:         [SKIP][45] ([fdo#109441]) -> [PASS][46]
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-iclb8/igt@kms_psr@psr2_sprite_blt.html
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-iclb2/igt@kms_psr@psr2_sprite_blt.html

  * igt@perf_pmu@module-unload:
    - shard-iclb:         [DMESG-WARN][47] ([i915#1982]) -> [PASS][48]
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-iclb7/igt@perf_pmu@module-unload.html
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-iclb3/igt@perf_pmu@module-unload.html

  
#### Warnings ####

  * igt@gem_exec_reloc@basic-concurrent16:
    - shard-glk:          [TIMEOUT][49] ([i915#1958]) -> [INCOMPLETE][50] ([i915#1958])
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-glk2/igt@gem_exec_reloc@basic-concurrent16.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-glk8/igt@gem_exec_reloc@basic-concurrent16.html

  * igt@kms_content_protection@atomic-dpms:
    - shard-kbl:          [TIMEOUT][51] ([i915#1319] / [i915#1958]) -> [TIMEOUT][52] ([i915#1319])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-kbl3/igt@kms_content_protection@atomic-dpms.html
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-kbl2/igt@kms_content_protection@atomic-dpms.html

  * igt@runner@aborted:
    - shard-apl:          [FAIL][53] ([i915#1610] / [i915#1635]) -> [FAIL][54] ([fdo#109271] / [i915#1635] / [i915#716])
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-apl4/igt@runner@aborted.html
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-apl2/igt@runner@aborted.html
    - shard-skl:          [FAIL][55] ([i915#1611] / [i915#2029]) -> [FAIL][56] ([i915#1436])
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_8871/shard-skl3/igt@runner@aborted.html
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/shard-skl3/igt@runner@aborted.html

  
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [i915#118]: https://gitlab.freedesktop.org/drm/intel/issues/118
  [i915#1185]: https://gitlab.freedesktop.org/drm/intel/issues/1185
  [i915#1188]: https://gitlab.freedesktop.org/drm/intel/issues/1188
  [i915#123]: https://gitlab.freedesktop.org/drm/intel/issues/123
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#1436]: https://gitlab.freedesktop.org/drm/intel/issues/1436
  [i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610
  [i915#1611]: https://gitlab.freedesktop.org/drm/intel/issues/1611
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#1958]: https://gitlab.freedesktop.org/drm/intel/issues/1958
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2029]: https://gitlab.freedesktop.org/drm/intel/issues/2029
  [i915#2190]: https://gitlab.freedesktop.org/drm/intel/issues/2190
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#407]: https://gitlab.freedesktop.org/drm/intel/issues/407
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


Participating hosts (11 -> 11)
------------------------------

  No changes in participating hosts


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

  * Linux: CI_DRM_8871 -> Patchwork_18345

  CI-20190529: 20190529
  CI_DRM_8871: ca35526cf770cf90faacceda5f0d03e1518d5585 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5767: 39e9aa1032a4e60f776f34b3ccf4fb728abbfe5c @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18345: 583f5c86bb83dec8e6177940a0dbe28147778d16 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18345/index.html

[-- Attachment #1.2: Type: text/html, Size: 16095 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
@ 2020-08-17  7:26   ` Manna, Animesh
  2020-09-03 17:49   ` Ville Syrjälä
  1 sibling, 0 replies; 80+ messages in thread
From: Manna, Animesh @ 2020-08-17  7:26 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 9781 bytes --]


On 16-07-2020 04:12, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> 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.
>
> v2:
> * Manual rebase (Manasi)
> * remove the use of pipe_mode defined in patch 3 (Manasi)
>
> v3:
> * Rebase on drm-tip (Manasi)
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

Changes looks ok to me.
Reviewed-by: Animesh Manna <animesh.manna@intel.com>

> ---
>   drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
>   .../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, 23 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 729ec6e0d43a..8652a7c6bf11 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>   	tmp = intel_de_read(dev_priv, 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,
> @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>   		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
>   
>   	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>   	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
>   	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>   	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> @@ -13221,17 +13218,17 @@ 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;
>   	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>   
>   	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>   
> @@ -13277,6 +13274,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;
> @@ -13324,7 +13325,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.adjusted_mode,
>   			       &pipe_config->pipe_src_w,
>   			       &pipe_config->pipe_src_h);
>   
> @@ -18461,15 +18462,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
> @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>   			 */
>   			crtc_state->inherited = true;
>   
> +			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 e8f809161c75..f1e29d9a75d0 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
>   	u32 temp = intel_de_read(dev_priv, 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);
>   
>   	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1223,7 +1223,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;
> @@ -1234,9 +1233,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,
> @@ -1308,7 +1307,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;
> @@ -1324,12 +1322,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)) {
> @@ -1339,7 +1337,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);
>   	}
>   
> @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
>   		to_intel_sdvo_connector_state(conn_state);
>   	const struct intel_sdvo_connector *intel_sdvo_connector =
>   		to_intel_sdvo_connector(conn_state->connector);
> -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
>   	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>   	u32 sdvox;
>   	struct intel_sdvo_in_out_map in_out;
> @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
>   		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(&dev_priv->drm,
>   			 "Setting output timings on %s failed\n",

[-- Attachment #1.2: Type: text/html, Size: 10462 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
  2020-08-10 12:38   ` Maarten Lankhorst
@ 2020-08-17  7:32   ` Manna, Animesh
  2020-09-03 17:54   ` Ville Syrjälä
  2 siblings, 0 replies; 80+ messages in thread
From: Manna, Animesh @ 2020-08-17  7:32 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 22165 bytes --]

On 16-07-2020 04:12, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> v4:
> * Manual rebase (Manasi)
> v3:
> * Change state to crtc_state, fix rebase err  (Manasi)
> v2:
> * Manual Rebase (Manasi)
>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

Changes looks ok to me.
Reviewed-by: Animesh Manna <animesh.manna@intel.com>

> ---
>   drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
>   .../drm/i915/display/intel_display_types.h    | 11 ++-
>   drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
>   3 files changed, 79 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8652a7c6bf11..78cbfefbfa62 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -152,7 +152,7 @@ static void ilk_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,
> @@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>   
>   static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
>   	int width, height;
>   
>   	if (crtc_state->pch_pfit.enabled) {
>   		width = drm_rect_width(&crtc_state->pch_pfit.dst);
>   		height = drm_rect_height(&crtc_state->pch_pfit.dst);
>   	} else {
> -		width = adjusted_mode->crtc_hdisplay;
> -		height = adjusted_mode->crtc_vdisplay;
> +		width = pipe_mode->crtc_hdisplay;
> +		height = pipe_mode->crtc_vdisplay;
>   	}
> -
>   	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
>   				 SKL_CRTC_INDEX,
>   				 &crtc_state->scaler_state.scaler_id,
> @@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
>   	if (intel_crtc_has_dp_encoder(new_crtc_state))
>   		intel_dp_set_m_n(new_crtc_state, M1_N1);
>   
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>   	intel_set_pipe_src_size(new_crtc_state);
>   
>   	if (new_crtc_state->has_pch_encoder)
> @@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>   	intel_encoders_pre_enable(state, crtc);
>   
>   	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_pipe_timings(new_crtc_state);
> +		intel_set_transcoder_timings(new_crtc_state);
>   
>   	intel_set_pipe_src_size(new_crtc_state);
>   
> @@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
>   	if (intel_crtc_has_dp_encoder(new_crtc_state))
>   		intel_dp_set_m_n(new_crtc_state, M1_N1);
>   
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>   	intel_set_pipe_src_size(new_crtc_state);
>   
>   	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> @@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
>   	if (intel_crtc_has_dp_encoder(new_crtc_state))
>   		intel_dp_set_m_n(new_crtc_state, M1_N1);
>   
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>   	intel_set_pipe_src_size(new_crtc_state);
>   
>   	i9xx_set_pipeconf(new_crtc_state);
> @@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
>   
>   static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>   {
> -	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
> +	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
>   	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
>   
>   	/*
> @@ -8008,7 +8006,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);
> @@ -8018,7 +8016,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) {
> @@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
>   			    "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;
>   	}
> @@ -8081,7 +8079,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);
> @@ -8751,7 +8749,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);
> @@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
>   		return intel_de_read(dev_priv, 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);
> @@ -9458,7 +9456,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(pipe_config);
> @@ -10739,7 +10737,7 @@ static bool ilk_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);
>   
>   	ilk_get_pfit_config(pipe_config);
> @@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>   	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>   	    INTEL_GEN(dev_priv) >= 11) {
>   		hsw_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);
> @@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
>   
>   static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
>   	int linetime_wm;
>   
>   	if (!crtc_state->hw.enable)
>   		return 0;
>   
> -	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
> -					adjusted_mode->crtc_clock);
> +	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
> +					pipe_mode->crtc_clock);
>   
>   	return min(linetime_wm, 0x1ff);
>   }
> @@ -13218,7 +13216,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);
>   }
>   
> @@ -13325,7 +13323,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.adjusted_mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>   			       &pipe_config->pipe_src_w,
>   			       &pipe_config->pipe_src_h);
>   
> @@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>   	 * drm_atomic_helper_update_legacy_modeset_state() happy
>   	 */
>   	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;
>   }
> @@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>   			 */
>   			crtc_state->inherited = true;
>   
> +			/* 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 f1e29d9a75d0..c52c8f42df68 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
> @@ -1141,8 +1141,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;
>   
> @@ -1169,8 +1169,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);
>   
> @@ -1666,8 +1666,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)
> @@ -1677,8 +1677,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) {
> @@ -2267,12 +2267,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;
> @@ -2351,8 +2351,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;
> @@ -2362,7 +2362,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;
> @@ -2378,8 +2378,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;
> @@ -2389,7 +2389,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)
> @@ -2427,12 +2427,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;
> @@ -2480,7 +2480,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;
>   
> @@ -2488,8 +2488,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);
> @@ -2579,7 +2579,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);
>   
> @@ -2607,7 +2607,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);
> @@ -2632,7 +2632,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);
>   }
> @@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>   	if (!crtc_state->hw.active)
>   		return true;
>   
> -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
>   		return false;
>   
>   	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> @@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>   	 */
>   	total_slice_mask = dbuf_slice_mask;
>   	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;
>   		u32 pipe_dbuf_slice_mask;
> @@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>   		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
>   			continue;
>   
> -		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> +		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
>   
>   		total_width_in_range += hdisplay;
>   
> @@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>   	if (drm_WARN_ON(&dev_priv->drm, 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;
> @@ -5288,14 +5288,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;

[-- Attachment #1.2: Type: text/html, Size: 22597 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
  2020-08-10 12:40   ` Maarten Lankhorst
@ 2020-08-21  9:41   ` Manna, Animesh
  2020-08-21 21:51     ` Navare, Manasi
  2020-09-07 11:20   ` Ville Syrjälä
  2 siblings, 1 reply; 80+ messages in thread
From: Manna, Animesh @ 2020-08-21  9:41 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx


[-- Attachment #1.1: Type: text/plain, Size: 9682 bytes --]


On 16-07-2020 04:12, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
> 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.
>
> v5:
> * Increase max plane width to support 8K with bigjoiner (Maarten)
> v4:
> * Rebase (Manasi)
>
> 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)
> v3:
> * Rebase (Manasi)
>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>   drivers/gpu/drm/i915/display/intel_display.c |   2 +-
>   drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
>   2 files changed, 91 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 78cbfefbfa62..3ecb642805a6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
>   	 * too big for that.
>   	 */
>   	if (INTEL_GEN(dev_priv) >= 11) {
> -		plane_width_max = 5120;
> +		plane_width_max = 7680;


Other encoder also use this function and big joiner on DP only need this change. Is it good idea to add encoder check? Maybe in a cover-letter can we add some description about big-joiner
feature and current limitation.
Overall changes looks good to me, for dsc related code better get a review from someone who has worked before.

Regards,
Animesh
  

>   		plane_height_max = 4320;
>   	} else {
>   		plane_width_max = 5120;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d6295eb20b63..fbfea99fd804 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> -	struct intel_encoder *encoder = &dig_port->base;
> +	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;
>   
> +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> +		return 2 * dev_priv->max_dotclk_freq;
> +
> +	return dev_priv->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;
>   }
> @@ -527,7 +539,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;
> @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
>   		    max_bpp_small_joiner_ram);
>   
> @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> @@ -576,7 +602,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)
>   {
>   	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>   	u8 min_slice_count, i;
> @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> @@ -648,11 +683,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)
> @@ -664,6 +703,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);
>   
> @@ -691,23 +745,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);
>   }
> @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
>   				    "Compressed BPP/Slice Count not supported\n");

[-- Attachment #1.2: Type: text/html, Size: 10192 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

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

* Re: [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check Manasi Navare
@ 2020-08-21 10:16   ` Manna, Animesh
  2020-08-21 18:22     ` Navare, Manasi
  2020-09-03 18:38   ` Ville Syrjälä
  1 sibling, 1 reply; 80+ messages in thread
From: Manna, Animesh @ 2020-08-21 10:16 UTC (permalink / raw)
  To: Manasi Navare, intel-gfx


On 16-07-2020 04:12, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>
>   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.
>
> v3:
> * Manual Rebase (Manasi)
>   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>
> Signed-off-by: Manasi Navare <manasi.d.navare@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  | 201 ++++++++++++++++--
>   .../drm/i915/display/intel_display_types.h    |   9 +
>   drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
>   5 files changed, 211 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 630f49b7aa01..b9dcdc74a10d 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -270,14 +270,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)

can we use primary_crtc_state instead of 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 11146292b06f..fc556c032c8f 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -43,7 +43,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_free(struct drm_atomic_state *state);
>   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 3ecb642805a6..955e19abb563 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8016,9 +8016,24 @@ 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;
>   
> @@ -8079,7 +8094,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);
> @@ -12433,7 +12448,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,

we may not need it.

>   					 struct intel_crtc *crtc,
>   					 struct intel_encoder *encoder)
>   {
> @@ -12442,7 +12457,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;
>   
> @@ -12682,6 +12697,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 &&

based on recent direction better to use primary/secondary keyword instead of master/slave.

>   	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
>   		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>   		if (ret)
> @@ -13206,18 +13222,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,
> @@ -13240,7 +13269,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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>   	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> @@ -13276,16 +13347,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 drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
>   	struct drm_connector *connector;
>   	struct drm_connector_state *connector_state;
> @@ -13327,7 +13398,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) {
>   		struct intel_encoder *encoder =
>   			to_intel_encoder(connector_state->best_encoder);
>   
> @@ -13365,7 +13436,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) {
>   		struct intel_encoder *encoder =
>   			to_intel_encoder(connector_state->best_encoder);
>   
> @@ -13422,8 +13493,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>   	 * drm_atomic_helper_update_legacy_modeset_state() happy
>   	 */
>   	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;
>   }
> @@ -14820,6 +14889,75 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
>   	return false;
>   }
>   
> +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
> @@ -14849,19 +14987,36 @@ 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;
>   		}
>   
> -		ret = intel_crtc_prepare_cleared_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;
> +		}
> +
> +		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(state, new_crtc_state);
>   		if (ret)
>   			goto fail;
>   
> -		if (!new_crtc_state->hw.enable)
> -			continue;
> +		ret = intel_modeset_pipe_config(state, new_crtc_state);
> +		if (ret)
> +			goto fail;
>   
> -		ret = intel_modeset_pipe_config(new_crtc_state);
> +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
> +						   new_crtc_state);
>   		if (ret)
>   			goto fail;
>   	}
> @@ -15193,7 +15348,9 @@ static void intel_update_crtc(struct intel_atomic_state *state,
>   
>   	commit_pipe_config(state, crtc);
>   
> -	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 c52c8f42df68..4694cfd90a0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1053,6 +1053,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 fbfea99fd804..29f45d2206af 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2247,6 +2247,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");
> +	}
> +

Adding a flag for big-joiner and setting it can be part of previous patch and instead of using true/false directly it can be used in dsc functions. Other changes looks fine to me.

Regards,
Animesh

>   	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,
> @@ -2264,12 +2273,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_dbg_kms(&dev_priv->drm,
>   				    "Compressed BPP/Slice Count not supported\n");
> @@ -2285,14 +2294,15 @@ 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_dbg_kms(&dev_priv->drm,
>   				    "Cannot split stream to use 2 VDSC instances\n");
>   			return -EINVAL;
>   		}
> +
> +		pipe_config->dsc.dsc_split = true;
>   	}
>   
>   	ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check
  2020-08-21 10:16   ` Manna, Animesh
@ 2020-08-21 18:22     ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-08-21 18:22 UTC (permalink / raw)
  To: Manna, Animesh; +Cc: intel-gfx

On Fri, Aug 21, 2020 at 03:46:48PM +0530, Manna, Animesh wrote:
> 
> On 16-07-2020 04:12, Manasi Navare wrote:
> >From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >
> >  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.
> >
> >v3:
> >* Manual Rebase (Manasi)
> >  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>
> >Signed-off-by: Manasi Navare <manasi.d.navare@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  | 201 ++++++++++++++++--
> >  .../drm/i915/display/intel_display_types.h    |   9 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
> >  5 files changed, 211 insertions(+), 33 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> >index 630f49b7aa01..b9dcdc74a10d 100644
> >--- a/drivers/gpu/drm/i915/display/intel_atomic.c
> >+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> >@@ -270,14 +270,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)
> 
> can we use primary_crtc_state instead of from_crtc_state?

You mean more intiutive naming instead of from_crtc_state ?
I feel primary_crtc_state might be confusing with primary/secondary planes naming
But may be we call it master_crtc_state or primary_big_joiner_crtc_state ?

@Maarten @Ville, any thoughts on better naming here?

> 
> >  {
> >  	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 11146292b06f..fc556c032c8f 100644
> >--- a/drivers/gpu/drm/i915/display/intel_atomic.h
> >+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> >@@ -43,7 +43,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_free(struct drm_atomic_state *state);
> >  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 3ecb642805a6..955e19abb563 100644
> >--- a/drivers/gpu/drm/i915/display/intel_display.c
> >+++ b/drivers/gpu/drm/i915/display/intel_display.c
> >@@ -8016,9 +8016,24 @@ 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;
> >@@ -8079,7 +8094,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);
> >@@ -12433,7 +12448,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,
> 
> we may not need it.

What do you mean we may not need it? Do you mean making it static not needed?

> 
> >  					 struct intel_crtc *crtc,
> >  					 struct intel_encoder *encoder)
> >  {
> >@@ -12442,7 +12457,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;
> >@@ -12682,6 +12697,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 &&
> 
> based on recent direction better to use primary/secondary keyword instead of master/slave.

Hmm, but in terms of big joiner terminology, we still call it master and slave. But we can discuss
offline on the recent direction and figure out the best naming.

Manasi

> 
> >  	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
> >  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
> >  		if (ret)
> >@@ -13206,18 +13222,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,
> >@@ -13240,7 +13269,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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> >@@ -13276,16 +13347,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 drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
> >  	struct drm_connector *connector;
> >  	struct drm_connector_state *connector_state;
> >@@ -13327,7 +13398,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) {
> >  		struct intel_encoder *encoder =
> >  			to_intel_encoder(connector_state->best_encoder);
> >@@ -13365,7 +13436,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) {
> >  		struct intel_encoder *encoder =
> >  			to_intel_encoder(connector_state->best_encoder);
> >@@ -13422,8 +13493,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> >  	 * drm_atomic_helper_update_legacy_modeset_state() happy
> >  	 */
> >  	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;
> >  }
> >@@ -14820,6 +14889,75 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
> >  	return false;
> >  }
> >+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
> >@@ -14849,19 +14987,36 @@ 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;
> >  		}
> >-		ret = intel_crtc_prepare_cleared_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;
> >+		}
> >+
> >+		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(state, new_crtc_state);
> >  		if (ret)
> >  			goto fail;
> >-		if (!new_crtc_state->hw.enable)
> >-			continue;
> >+		ret = intel_modeset_pipe_config(state, new_crtc_state);
> >+		if (ret)
> >+			goto fail;
> >-		ret = intel_modeset_pipe_config(new_crtc_state);
> >+		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
> >+						   new_crtc_state);
> >  		if (ret)
> >  			goto fail;
> >  	}
> >@@ -15193,7 +15348,9 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> >  	commit_pipe_config(state, crtc);
> >-	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 c52c8f42df68..4694cfd90a0a 100644
> >--- a/drivers/gpu/drm/i915/display/intel_display_types.h
> >+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> >@@ -1053,6 +1053,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 fbfea99fd804..29f45d2206af 100644
> >--- a/drivers/gpu/drm/i915/display/intel_dp.c
> >+++ b/drivers/gpu/drm/i915/display/intel_dp.c
> >@@ -2247,6 +2247,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");
> >+	}
> >+
> 
> Adding a flag for big-joiner and setting it can be part of previous patch and instead of using true/false directly it can be used in dsc functions. Other changes looks fine to me.
> 
> Regards,
> Animesh
> 
> >  	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,
> >@@ -2264,12 +2273,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_dbg_kms(&dev_priv->drm,
> >  				    "Compressed BPP/Slice Count not supported\n");
> >@@ -2285,14 +2294,15 @@ 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_dbg_kms(&dev_priv->drm,
> >  				    "Cannot split stream to use 2 VDSC instances\n");
> >  			return -EINVAL;
> >  		}
> >+
> >+		pipe_config->dsc.dsc_split = true;
> >  	}
> >  	ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-08-21  9:41   ` Manna, Animesh
@ 2020-08-21 21:51     ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-08-21 21:51 UTC (permalink / raw)
  To: Manna, Animesh; +Cc: intel-gfx

On Fri, Aug 21, 2020 at 03:11:45PM +0530, Manna, Animesh wrote:
> 
> On 16-07-2020 04:12, Manasi Navare wrote:
> >From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >
> >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.
> >
> >v5:
> >* Increase max plane width to support 8K with bigjoiner (Maarten)
> >v4:
> >* Rebase (Manasi)
> >
> >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)
> >v3:
> >* Rebase (Manasi)
> >
> >Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> >Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> >---
> >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> >  2 files changed, 91 insertions(+), 30 deletions(-)
> >
> >diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> >index 78cbfefbfa62..3ecb642805a6 100644
> >--- a/drivers/gpu/drm/i915/display/intel_display.c
> >+++ b/drivers/gpu/drm/i915/display/intel_display.c
> >@@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> >  	 * too big for that.
> >  	 */
> >  	if (INTEL_GEN(dev_priv) >= 11) {
> >-		plane_width_max = 5120;
> >+		plane_width_max = 7680;
> 
> 
> Other encoder also use this function and big joiner on DP only need this change. Is it good idea to add encoder check? Maybe in a cover-letter can we add some description about big-joiner
> feature and current limitation.
> Overall changes looks good to me, for dsc related code better get a review from someone who has worked before.

Yes I think the plane width max also should only be changed to 7680 if big joiner is supported so this needs
some tweak anyways. I will take a look into this.
Also will sync with Maarten on what might be the best approach.

Manasi

> 
> Regards,
> Animesh
> 
> >  		plane_height_max = 4320;
> >  	} else {
> >  		plane_width_max = 5120;
> >diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> >index d6295eb20b63..fbfea99fd804 100644
> >--- a/drivers/gpu/drm/i915/display/intel_dp.c
> >+++ b/drivers/gpu/drm/i915/display/intel_dp.c
> >@@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> >-	struct intel_encoder *encoder = &dig_port->base;
> >+	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;
> >+	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> >+		return 2 * dev_priv->max_dotclk_freq;
> >+
> >+	return dev_priv->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;
> >  }
> >@@ -527,7 +539,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;
> >@@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> >  		    max_bpp_small_joiner_ram);
> >@@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> >@@ -576,7 +602,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)
> >  {
> >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> >  	u8 min_slice_count, i;
> >@@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> >@@ -648,11 +683,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)
> >@@ -664,6 +703,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);
> >@@ -691,23 +745,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);
> >  }
> >@@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> >  				    "Compressed BPP/Slice Count not supported\n");
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling Manasi Navare
@ 2020-08-24 22:15   ` Navare, Manasi
  2020-09-03 19:23   ` Ville Syrjälä
  1 sibling, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-08-24 22:15 UTC (permalink / raw)
  To: intel-gfx

On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> ****This needs to be checked if it still works since lot of refactoring
> in skl_commit_modeset_enables
> 
> v2:
> * Manual Rebase (Manasi)
> * Refactoring on intel_update_crtc and enable_crtc and removing
> special trans_port_sync_update (Manasi)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>

This looks good to me in terms of modeset enable sequence as per Bspec
but would be good to get an ack from Ville/Maarten just to double
check I didnt break anything while rebase

Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>

Manasi

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
>  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
>  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
>  3 files changed, 129 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index a1011414da6d..00b26863ffc6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
>  	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
> @@ -15754,6 +15754,52 @@ 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);
> +
> +	if (modeset) {
> +		/* Enable slave first */
> +		intel_crtc_update_active_timings(new_slave_crtc_state);
> +		dev_priv->display.crtc_enable(state, slave);
> +
> +		/* Then master */
> +		intel_crtc_update_active_timings(new_crtc_state);
> +		dev_priv->display.crtc_enable(state, crtc);
> +
> +		/* vblanks work again, re-enable pipe CRC. */
> +		intel_crtc_enable_pipe_crc(crtc);
> +
> +	} else {
> +		intel_pre_plane_update(state, crtc);
> +		intel_pre_plane_update(state, slave);
> +
> +		if (new_crtc_state->update_pipe)
> +			intel_encoders_update_pipe(state, crtc);
> +	}
> +
> +	/*
> +	 * 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, crtc);
> +	commit_pipe_config(state, slave);
> +
> +	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_state *new_crtc_state;
> @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
>  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> -	struct intel_crtc *crtc;
> +	struct intel_crtc *crtc, *slave;
>  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
>  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
>  	u8 update_pipes = 0, modeset_pipes = 0;
> +	const struct intel_crtc_state *slave_crtc_state;
>  	int i;
>  
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
>  		enum pipe pipe = crtc->pipe;
>  
> +		if (new_crtc_state->bigjoiner_slave) {
> +			/* We're updated from master */
> +			continue;
> +		}
> +
>  		if (!new_crtc_state->hw.active)
>  			continue;
>  
> @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		} else {
>  			modeset_pipes |= BIT(pipe);
>  		}
> +
> +		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;
> +		}
> +
> +		/* ignore allocations for crtc's that have been turned off during modeset. */
> +		if (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;
> +		}
>  	}
>  
>  	/*
> @@ -15806,28 +15887,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  						    new_crtc_state, i) {
>  			enum pipe pipe = crtc->pipe;
> +			bool ddb_changed;
>  
>  			if ((update_pipes & BIT(pipe)) == 0)
>  				continue;
>  
> -			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> +			if (skl_ddb_allocation_overlaps(&new_entries[pipe],
>  							entries, I915_MAX_PIPES, pipe))
>  				continue;
>  
> -			entries[pipe] = new_crtc_state->wm.skl.ddb;
> +			ddb_changed = !skl_ddb_entry_equal(&new_entries[pipe], &entries[pipe]);
> +			entries[pipe] = new_entries[pipe];
>  			update_pipes &= ~BIT(pipe);
>  
> -			intel_update_crtc(state, crtc);
> -
>  			/*
>  			 * If this is an already active pipe, it's DDB changed,
>  			 * and this isn't the last pipe that needs updating
>  			 * 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) &&
> -			    (update_pipes | modeset_pipes))
> +			if (new_crtc_state->bigjoiner) {
> +				intel_update_bigjoiner(crtc, state,
> +						       old_crtc_state,
> +						       new_crtc_state);
> +			} else {
> +				intel_update_crtc(state, crtc);
> +			}
> +
> +			if (ddb_changed && (update_pipes | modeset_pipes))
>  				intel_wait_for_vblank(dev_priv, pipe);
>  		}
>  	}
> @@ -15863,9 +15950,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		if ((modeset_pipes & BIT(pipe)) == 0)
>  			continue;
>  
> +		WARN_ON(skl_ddb_allocation_overlaps(&new_entries[pipe],
> +						    entries, I915_MAX_PIPES, pipe));
> +
> +		entries[pipe] = new_entries[pipe];
>  		modeset_pipes &= ~BIT(pipe);
>  
> -		intel_enable_crtc(state, crtc);
> +		if (new_crtc_state->bigjoiner)
> +			intel_update_bigjoiner(crtc, state,
> +					       old_crtc_state,
> +					       new_crtc_state);
> +		else
> +			intel_enable_crtc(state, crtc);
>  	}
>  
>  	/*
> @@ -15877,10 +15973,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		if ((update_pipes & BIT(pipe)) == 0)
>  			continue;
>  
> -		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> +		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_entries[pipe],
>  									entries, I915_MAX_PIPES, pipe));
>  
> -		entries[pipe] = new_crtc_state->wm.skl.ddb;
> +		entries[pipe] = new_entries[pipe];
>  		update_pipes &= ~BIT(pipe);
>  
>  		intel_update_crtc(state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 60eeed06a780..eaae5df546fe 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -99,6 +99,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;
>  
> @@ -191,7 +193,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;
> @@ -206,16 +209,26 @@ 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) {
> -		drm_WARN_ON(&dev_priv->drm,
> -			    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)
> +			drm_WARN_ON(&dev_priv->drm,
> +				    drm_crtc_vblank_get(&crtc->base) != 0);
> +		if (slave_crtc_state && slave_crtc_state->uapi.event)
> +			drm_WARN_ON(&dev_priv->drm,
> +				    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 cd2104ba1ca1..15e7c112ec77 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.19.1
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v8 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-08-10 23:28     ` [Intel-gfx] [PATCH v8 " Manasi Navare
@ 2020-08-27 23:35       ` Navare, Manasi
  2020-08-28  6:26         ` Maarten Lankhorst
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-08-27 23:35 UTC (permalink / raw)
  To: intel-gfx

On Mon, Aug 10, 2020 at 04:28:28PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> v2:
> * Manual rebase (Manasi)
> 
> v3:
> * Rebase (Manasi)
> 
> v4:
> * Rebase (Manasi)
> 
> v5:
> * Get dsc power domain in ddi_init (Manasi)
> 
> v6:
> * Remove dsc power put from dsc_disable (Maarten)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
>  drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |   1 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 201 +++++-----
>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
>  7 files changed, 413 insertions(+), 249 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 8c55f5bee9ab..26f7372b4c25 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>  	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
>  
> -	intel_dsc_get_config(encoder, pipe_config);

Maarten,
Why do we need to remove this from dsi_get_config()?

> -
>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
>  						      pipe_config->shared_dpll);
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index de5b216561d8..6de13c67f5b8 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -28,6 +28,7 @@
>  #include <drm/drm_scdc_helper.h>
>  
>  #include "i915_drv.h"
> +#include "i915_trace.h"
>  #include "intel_audio.h"
>  #include "intel_combo_phy.h"
>  #include "intel_connector.h"
> @@ -2093,12 +2094,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>  		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(struct intel_encoder *encoder,
> @@ -3387,7 +3382,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
>  
>  	/* 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_atomic_state *state,
> @@ -3458,7 +3454,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
>  	if (!is_mst)
>  		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
> @@ -3713,6 +3710,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
>  			ilk_pfit_disable(old_crtc_state);
>  	}
>  
> +	if (old_crtc_state->bigjoiner_linked_crtc) {
> +		struct intel_atomic_state *state =
> +			to_intel_atomic_state(old_crtc_state->uapi.state);
> +		struct intel_crtc *slave =
> +			old_crtc_state->bigjoiner_linked_crtc;
> +		const struct intel_crtc_state *old_slave_crtc_state =
> +			intel_atomic_get_old_crtc_state(state, slave);
> +
> +		intel_crtc_vblank_off(old_slave_crtc_state);
> +		trace_intel_pipe_disable(slave);
> +
> +		intel_dsc_disable(old_slave_crtc_state);
> +		skl_scaler_disable(old_slave_crtc_state);
> +	}
> +
>  	/*
>  	 * When called from DP MST code:
>  	 * - old_conn_state will be NULL
> @@ -3927,7 +3939,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
>  {
>  	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
>  
> -	intel_ddi_enable_transcoder_func(encoder, crtc_state);
> +	if (!crtc_state->bigjoiner_slave)
> +		intel_ddi_enable_transcoder_func(encoder, crtc_state);
>  
>  	intel_enable_pipe(crtc_state);
>  
> @@ -4274,8 +4287,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
>  		    crtc_state->sync_mode_slaves_mask);
>  }
>  
> -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);
> @@ -4283,13 +4296,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>  	u32 temp, flags = 0;
>  
> -	/* XXX: DSI transcoder paranoia */
> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> +	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>  		return;
>  
> -	intel_dsc_get_config(encoder, pipe_config);
> -
> -	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
>  		flags |= DRM_MODE_FLAG_PHSYNC;
>  	else
> @@ -4397,6 +4407,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
>  		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
>  	}
> +}
> +
> +void intel_ddi_get_config(struct intel_encoder *encoder,
> +			  struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +
> +	/* XXX: DSI transcoder paranoia */
> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
> +		return;
> +
> +	intel_ddi_read_func_ctl(encoder, pipe_config);
> +	if (pipe_config->bigjoiner_slave) {
> +		/* read out pipe settings from master */
> +		enum transcoder save = pipe_config->cpu_transcoder;
> +
> +		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
> +		WARN_ON(pipe_config->output_types);
> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
> +		intel_ddi_read_func_ctl(encoder, pipe_config);
> +		pipe_config->cpu_transcoder = save;
> +	}
>  
>  	pipe_config->has_audio =
>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
> @@ -4422,7 +4455,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 41af7f1011fd..7223b6d916e7 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7024,6 +7024,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
>  	intel_de_write(dev_priv, reg, val);
>  }
>  
> +static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
> +					 const 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(state, master);
> +		intel_enable_shared_dpll(master_crtc_state);
> +		intel_encoders_pre_enable(state, master);
> +
> +		/* and DSC on slave */

Also here fec_enable never gets called for the slave since we call intel_encoders_pre_enable
only for the master. So essentially on slave we are just doing dsc enable without FEC which is wrong.

Regards
Manasi


> +		intel_dsc_enable(NULL, crtc_state);
> +	}
> +}
> +
>  static void hsw_crtc_enable(struct intel_atomic_state *state,
>  			    struct intel_crtc *crtc)
>  {
> @@ -7037,34 +7076,39 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
>  		return;
>  
> -	intel_encoders_pre_pll_enable(state, crtc);
> -
> -	if (new_crtc_state->shared_dpll)
> -		intel_enable_shared_dpll(new_crtc_state);
> +	if (!new_crtc_state->bigjoiner) {
> +		intel_encoders_pre_pll_enable(state, crtc);
>  
> -	intel_encoders_pre_enable(state, crtc);
> +		if (new_crtc_state->shared_dpll)
> +			intel_enable_shared_dpll(new_crtc_state);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_transcoder_timings(new_crtc_state);
> +		intel_encoders_pre_enable(state, crtc);
> +	} else {
> +		tgl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
> +	}
>  
>  	intel_set_pipe_src_size(new_crtc_state);
> +	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> +		bdw_set_pipemisc(new_crtc_state);
>  
> -	if (cpu_transcoder != TRANSCODER_EDP &&
> -	    !transcoder_is_dsi(cpu_transcoder))
> -		intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> -			       new_crtc_state->pixel_multiplier - 1);
> +	if (!new_crtc_state->bigjoiner_slave && !transcoder_is_dsi(cpu_transcoder)) {
> +		if (!transcoder_is_dsi(cpu_transcoder))
> +			intel_set_transcoder_timings(new_crtc_state);
>  
> -	if (new_crtc_state->has_pch_encoder)
> -		intel_cpu_transcoder_set_m_n(new_crtc_state,
> -					     &new_crtc_state->fdi_m_n, NULL);
> +		if (cpu_transcoder != TRANSCODER_EDP &&
> +		    !transcoder_is_dsi(cpu_transcoder))
> +			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
> +				       new_crtc_state->pixel_multiplier - 1);
> +
> +		if (new_crtc_state->has_pch_encoder)
> +			intel_cpu_transcoder_set_m_n(new_crtc_state,
> +						     &new_crtc_state->fdi_m_n, NULL);
>  
> -	if (!transcoder_is_dsi(cpu_transcoder)) {
>  		hsw_set_frame_start_delay(new_crtc_state);
> -		hsw_set_pipeconf(new_crtc_state);
>  	}
>  
> -	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> -		bdw_set_pipemisc(new_crtc_state);
> +	if (!transcoder_is_dsi(cpu_transcoder))
> +		hsw_set_pipeconf(new_crtc_state);
>  
>  	crtc->active = true;
>  
> @@ -7100,6 +7144,11 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	if (INTEL_GEN(dev_priv) >= 11)
>  		icl_pipe_mbus_enable(crtc);
>  
> +	if (new_crtc_state->bigjoiner_slave) {
> +		trace_intel_pipe_enable(crtc);
> +		intel_crtc_vblank_on(new_crtc_state);
> +	}
> +
>  	intel_encoders_enable(state, crtc);
>  
>  	if (psl_clkgate_wa) {
> @@ -7382,6 +7431,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;
>  }
>  
> @@ -8000,6 +8052,30 @@ static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>  		       pfit_w * pfit_h);
>  }
>  
> +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 pipe timings are half of the transcoder mode
> +		 */
> +		pipe_mode->crtc_hdisplay /= 2;
> +		pipe_mode->crtc_hblank_start /= 2;
> +		pipe_mode->crtc_hblank_end /= 2;
> +		pipe_mode->crtc_hsync_start /= 2;
> +		pipe_mode->crtc_hsync_end /= 2;
> +		pipe_mode->crtc_htotal /= 2;
> +		pipe_mode->crtc_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);
> @@ -8911,20 +8987,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->vdisplay = pipe_config->hw.adjusted_mode.crtc_vdisplay;
> -	mode->vtotal = pipe_config->hw.adjusted_mode.crtc_vtotal;
> -	mode->vsync_start = pipe_config->hw.adjusted_mode.crtc_vsync_start;
> -	mode->vsync_end = pipe_config->hw.adjusted_mode.crtc_vsync_end;
> +	mode->hdisplay = hw_mode->crtc_hdisplay;
> +	mode->htotal = hw_mode->crtc_htotal;
> +	mode->hsync_start = hw_mode->crtc_hsync_start;
> +	mode->hsync_end = hw_mode->crtc_hsync_end;
>  
> -	mode->flags = pipe_config->hw.adjusted_mode.flags;
> +	mode->vdisplay = hw_mode->crtc_vdisplay;
> +	mode->vtotal = hw_mode->crtc_vtotal;
> +	mode->vsync_start = hw_mode->crtc_vsync_start;
> +	mode->vsync_end = hw_mode->crtc_vsync_end;
> +
> +	mode->flags = hw_mode->flags;
>  	mode->type = DRM_MODE_TYPE_DRIVER;
>  
> -	mode->clock = pipe_config->hw.adjusted_mode.crtc_clock;
> +	mode->clock = hw_mode->crtc_clock;
>  
>  	drm_mode_set_name(mode);
>  }
> @@ -11091,6 +11169,9 @@ static void hsw_get_ddi_port_state(struct intel_crtc *crtc,
>  	} else {
>  		tmp = intel_de_read(dev_priv,
>  				    TRANS_DDI_FUNC_CTL(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);
>  		else
> @@ -11163,12 +11244,20 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		drm_WARN_ON(&dev_priv->drm, 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) ||
> -	    INTEL_GEN(dev_priv) >= 11) {
> +		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) {
>  		hsw_get_ddi_port_state(crtc, pipe_config);
>  		intel_get_transcoder_timings(crtc, pipe_config);
>  	}
> @@ -11254,8 +11343,11 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> -	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> +	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 =
>  			intel_de_read(dev_priv,
>  				      PIPE_MULT(pipe_config->cpu_transcoder)) + 1;
> @@ -12270,7 +12362,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);
>  
> @@ -13262,10 +13354,12 @@ 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;
> -	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> -		    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;
> +		drm_WARN_ON(crtc_state->uapi.crtc->dev,
> +			    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> +	}
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -13912,21 +14006,42 @@ 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_BOOL(has_hdmi_sink);
>  	if ((INTEL_GEN(dev_priv) < 8 && !IS_HASWELL(dev_priv)) ||
> @@ -13936,24 +14051,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)
> @@ -13979,7 +14081,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))
> @@ -14000,48 +14103,51 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  	PIPE_CONF_CHECK_BOOL(double_wide);
>  
>  	PIPE_CONF_CHECK_P(shared_dpll);
> -	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);
> +	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(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);
> @@ -14053,11 +14159,12 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
>  
>  	PIPE_CONF_CHECK_X(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_I(dsc.compression_enable);
>  	PIPE_CONF_CHECK_I(dsc.dsc_split);
>  	PIPE_CONF_CHECK_I(dsc.compressed_bpp);
> -
>  	PIPE_CONF_CHECK_I(mst_master_transcoder);
>  
>  #undef PIPE_CONF_CHECK_X
> @@ -14324,6 +14431,7 @@ verify_crtc_state(struct intel_crtc *crtc,
>  	struct intel_encoder *encoder;
>  	struct intel_crtc_state *pipe_config = old_crtc_state;
>  	struct drm_atomic_state *state = old_crtc_state->uapi.state;
> +	struct intel_crtc *master = crtc;
>  	bool active;
>  
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> @@ -14350,7 +14458,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);
> @@ -14359,12 +14470,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);
> @@ -15386,7 +15497,12 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
>  
> +	drm_WARN_ON(&dev_priv->drm, old_crtc_state->bigjoiner_slave);
> +
>  	intel_crtc_disable_planes(state, crtc);
> +	if (old_crtc_state->bigjoiner)
> +		intel_crtc_disable_planes(state,
> +					  old_crtc_state->bigjoiner_linked_crtc);
>  
>  	/*
>  	 * We need to disable pipe CRC before disabling the pipe,
> @@ -15416,7 +15532,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	/* Only disable port sync and MST slaves */
>  	for_each_oldnew_intel_crtc_in_state(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;
>  
>  		if (!old_crtc_state->hw.active)
> @@ -15431,7 +15547,6 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  		    !intel_dp_mst_is_slave_trans(old_crtc_state))
>  			continue;
>  
> -		intel_pre_plane_update(state, crtc);
>  		intel_old_crtc_state_disables(state, old_crtc_state,
>  					      new_crtc_state, crtc);
>  		handled |= BIT(crtc->pipe);
> @@ -15441,10 +15556,18 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  					    new_crtc_state, i) {
>  		if (!needs_modeset(new_crtc_state) ||
> -		    (handled & BIT(crtc->pipe)))
> +		    (handled & BIT(crtc->pipe)) ||
> +		    old_crtc_state->bigjoiner_slave)
>  			continue;
>  
>  		intel_pre_plane_update(state, crtc);
> +		if (old_crtc_state->bigjoiner) {
> +			struct intel_crtc *slave =
> +				old_crtc_state->bigjoiner_linked_crtc;
> +
> +			intel_pre_plane_update(state, slave);
> +		}
> +
>  		if (old_crtc_state->hw.active)
>  			intel_old_crtc_state_disables(state, old_crtc_state,
>  						      new_crtc_state, crtc);
> @@ -18080,7 +18203,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;
>  
>  		/*
> @@ -18579,7 +18702,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 d9d56f15bff1..e93493757cbf 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -826,6 +826,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 */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 29f45d2206af..41cb9f9c0292 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2004,12 +2004,10 @@ static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
>  				  const struct intel_crtc_state *crtc_state)
>  {
> -	struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
> -
> -	if (!intel_dp_is_edp(intel_dp) && !crtc_state->fec_enable)
> +	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
>  		return false;
>  
> -	return intel_dsc_source_support(encoder, crtc_state) &&
> +	return intel_dsc_source_support(crtc_state) &&
>  		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 c5735c365659..e2716a67b281 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.c
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
> @@ -332,11 +332,10 @@ static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
>  	return &rc_parameters[row_index][column_index];
>  }
>  
> -bool intel_dsc_source_support(struct intel_encoder *encoder,
> -			      const struct intel_crtc_state *crtc_state)
> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
>  {
>  	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
>  	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>  	enum pipe pipe = crtc->pipe;
>  
> @@ -490,11 +489,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
>  		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
>  }
>  
> -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;
>  	u32 pps_val = 0;
> @@ -503,6 +501,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 |
> @@ -973,55 +974,6 @@ static void intel_dsc_pps_configure(struct intel_encoder *encoder,
>  	}
>  }
>  
> -void intel_dsc_get_config(struct intel_encoder *encoder,
> -			  struct intel_crtc_state *crtc_state)
> -{
> -	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> -	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
> -	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -	enum pipe pipe = crtc->pipe;
> -	enum intel_display_power_domain power_domain;
> -	intel_wakeref_t wakeref;
> -	u32 dss_ctl1, dss_ctl2, val;
> -
> -	if (!intel_dsc_source_support(encoder, crtc_state))
> -		return;
> -
> -	power_domain = intel_dsc_power_domain(crtc_state);
> -
> -	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> -	if (!wakeref)
> -		return;
> -
> -	if (!is_pipe_dsc(crtc_state)) {
> -		dss_ctl1 = intel_de_read(dev_priv, DSS_CTL1);
> -		dss_ctl2 = intel_de_read(dev_priv, DSS_CTL2);
> -	} else {
> -		dss_ctl1 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL1(pipe));
> -		dss_ctl2 = intel_de_read(dev_priv, ICL_PIPE_DSS_CTL2(pipe));
> -	}
> -
> -	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
> -	if (!crtc_state->dsc.compression_enable)
> -		goto out;
> -
> -	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
> -		(dss_ctl1 & JOINER_ENABLE);
> -
> -	/* FIXME: add more state readout as needed */
> -
> -	/* PPS1 */
> -	if (!is_pipe_dsc(crtc_state))
> -		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
> -	else
> -		val = intel_de_read(dev_priv,
> -				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
> -	vdsc_cfg->bits_per_pixel = val;
> -	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
> -out:
> -	intel_display_power_put(dev_priv, power_domain, wakeref);
> -}
> -
>  static void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
>  				    const struct intel_crtc_state *crtc_state)
>  {
> @@ -1060,77 +1012,126 @@ 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(encoder, crtc_state);
> +	intel_dsc_pps_configure(crtc_state);
>  
> -	if (encoder->type == INTEL_OUTPUT_DSI)
> -		intel_dsc_dsi_pps_write(encoder, crtc_state);
> -	else
> -		intel_dsc_dp_pps_write(encoder, crtc_state);
> -
> -	if (!is_pipe_dsc(crtc_state)) {
> -		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);
> +	if (!crtc_state->bigjoiner_slave) {
> +		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
> +			intel_dsc_dsi_pps_write(encoder, crtc_state);
> +		else
> +			intel_dsc_dp_pps_write(encoder, crtc_state);
>  	}
> +
>  	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;
>  	}
> -	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
> -	intel_de_write(dev_priv, 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;
> +	}
> +	intel_de_write(dev_priv, dss_ctl1_reg(crtc_state), dss_ctl1_val);
> +	intel_de_write(dev_priv, 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 (!is_pipe_dsc(old_crtc_state)) {
> -		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);
> +	intel_de_write(dev_priv, dss_ctl1_reg(old_crtc_state), 0);
> +	intel_de_write(dev_priv, dss_ctl2_reg(old_crtc_state), 0);
> +}
> +
> +void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
> +{
> +	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> +	enum pipe pipe = crtc->pipe;
> +	enum intel_display_power_domain power_domain;
> +	intel_wakeref_t wakeref;
> +	u32 dss_ctl1, dss_ctl2, val;
> +
> +	if (!intel_dsc_source_support(crtc_state))
> +		return;
> +
> +	power_domain = intel_dsc_power_domain(crtc_state);
> +
> +	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> +	if (!wakeref)
> +		return;
> +
> +	dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc_state));
> +	dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc_state));
> +
> +	crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
> +	if (!crtc_state->dsc.compression_enable)
> +		goto out;
> +
> +	crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
> +		(dss_ctl1 & JOINER_ENABLE);
> +
> +	if (dss_ctl1 & BIG_JOINER_ENABLE) {
> +		crtc_state->bigjoiner = true;
> +
> +		if (!(dss_ctl1 & 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 = intel_de_read(dev_priv, dss_ctl1_reg);
> -	if (dss_ctl1_val & JOINER_ENABLE)
> -		dss_ctl1_val &= ~JOINER_ENABLE;
> -	intel_de_write(dev_priv, dss_ctl1_reg, dss_ctl1_val);
> -
> -	dss_ctl2_val = intel_de_read(dev_priv, 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);
> -	intel_de_write(dev_priv, 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));
> +
> +	/* FIXME: add more state readout as needed */
> +
> +	/* PPS1 */
> +	if (!is_pipe_dsc(crtc_state))
> +		val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
> +	else
> +		val = intel_de_read(dev_priv,
> +				    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
> +	vdsc_cfg->bits_per_pixel = val;
> +	crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
> +out:
> +	intel_display_power_put(dev_priv, power_domain, wakeref);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h
> index e56a3254c214..5301345ac5e7 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -11,15 +11,14 @@
>  struct intel_encoder;
>  struct intel_crtc_state;
>  
> -bool intel_dsc_source_support(struct intel_encoder *encoder,
> -			      const struct intel_crtc_state *crtc_state);
> +bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state);
>  void intel_dsc_enable(struct intel_encoder *encoder,
>  		      const struct intel_crtc_state *crtc_state);
>  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_encoder *encoder,
> -			  struct intel_crtc_state *crtc_state);
> +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.19.1
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v8 06/11] drm/i915: Enable big joiner support in enable and disable sequences.
  2020-08-27 23:35       ` Navare, Manasi
@ 2020-08-28  6:26         ` Maarten Lankhorst
  0 siblings, 0 replies; 80+ messages in thread
From: Maarten Lankhorst @ 2020-08-28  6:26 UTC (permalink / raw)
  To: Navare, Manasi, intel-gfx

Op 28-08-2020 om 01:35 schreef Navare, Manasi:
> On Mon, Aug 10, 2020 at 04:28:28PM -0700, Manasi Navare wrote:
>> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>>
>> 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.
>>
>> v2:
>> * Manual rebase (Manasi)
>>
>> v3:
>> * Rebase (Manasi)
>>
>> v4:
>> * Rebase (Manasi)
>>
>> v5:
>> * Get dsc power domain in ddi_init (Manasi)
>>
>> v6:
>> * Remove dsc power put from dsc_disable (Maarten)
>>
>> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
>> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
>> ---
>>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>>  drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +++-
>>  drivers/gpu/drm/i915/display/intel_display.c  | 377 ++++++++++++------
>>  .../drm/i915/display/intel_display_types.h    |   1 +
>>  drivers/gpu/drm/i915/display/intel_dp.c       |   6 +-
>>  drivers/gpu/drm/i915/display/intel_vdsc.c     | 201 +++++-----
>>  drivers/gpu/drm/i915/display/intel_vdsc.h     |   7 +-
>>  7 files changed, 413 insertions(+), 249 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
>> index 8c55f5bee9ab..26f7372b4c25 100644
>> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
>> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
>> @@ -1454,8 +1454,6 @@ static void gen11_dsi_get_config(struct intel_encoder *encoder,
>>  	struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>>  	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
>>  
>> -	intel_dsc_get_config(encoder, pipe_config);
> Maarten,
> Why do we need to remove this from dsi_get_config()?
This is read by the pipe now, which is the only place that does get_config().
>
>> -
>>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
>>  						      pipe_config->shared_dpll);
>> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
>> index de5b216561d8..6de13c67f5b8 100644
>> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
>> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
>> @@ -28,6 +28,7 @@
>>  #include <drm/drm_scdc_helper.h>
>>  
>>  #include "i915_drv.h"
>> +#include "i915_trace.h"
>>  #include "intel_audio.h"
>>  #include "intel_combo_phy.h"
>>  #include "intel_connector.h"
>> @@ -2093,12 +2094,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>>  		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(struct intel_encoder *encoder,
>> @@ -3387,7 +3382,8 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
>>  
>>  	/* 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_atomic_state *state,
>> @@ -3458,7 +3454,8 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
>>  	if (!is_mst)
>>  		intel_ddi_enable_pipe_clock(encoder, 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_atomic_state *state,
>> @@ -3713,6 +3710,21 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state,
>>  			ilk_pfit_disable(old_crtc_state);
>>  	}
>>  
>> +	if (old_crtc_state->bigjoiner_linked_crtc) {
>> +		struct intel_atomic_state *state =
>> +			to_intel_atomic_state(old_crtc_state->uapi.state);
>> +		struct intel_crtc *slave =
>> +			old_crtc_state->bigjoiner_linked_crtc;
>> +		const struct intel_crtc_state *old_slave_crtc_state =
>> +			intel_atomic_get_old_crtc_state(state, slave);
>> +
>> +		intel_crtc_vblank_off(old_slave_crtc_state);
>> +		trace_intel_pipe_disable(slave);
>> +
>> +		intel_dsc_disable(old_slave_crtc_state);
>> +		skl_scaler_disable(old_slave_crtc_state);
>> +	}
>> +
>>  	/*
>>  	 * When called from DP MST code:
>>  	 * - old_conn_state will be NULL
>> @@ -3927,7 +3939,8 @@ static void intel_enable_ddi(struct intel_atomic_state *state,
>>  {
>>  	drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
>>  
>> -	intel_ddi_enable_transcoder_func(encoder, crtc_state);
>> +	if (!crtc_state->bigjoiner_slave)
>> +		intel_ddi_enable_transcoder_func(encoder, crtc_state);
>>  
>>  	intel_enable_pipe(crtc_state);
>>  
>> @@ -4274,8 +4287,8 @@ static void bdw_get_trans_port_sync_config(struct intel_crtc_state *crtc_state)
>>  		    crtc_state->sync_mode_slaves_mask);
>>  }
>>  
>> -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);
>> @@ -4283,13 +4296,10 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
>>  	u32 temp, flags = 0;
>>  
>> -	/* XXX: DSI transcoder paranoia */
>> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
>> +	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>> +	if (!(temp & TRANS_DDI_FUNC_ENABLE))
>>  		return;
>>  
>> -	intel_dsc_get_config(encoder, pipe_config);
>> -
>> -	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>>  	if (temp & TRANS_DDI_PHSYNC)
>>  		flags |= DRM_MODE_FLAG_PHSYNC;
>>  	else
>> @@ -4397,6 +4407,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>>  		intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(transcoder);
>>  		intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(transcoder);
>>  	}
>> +}
>> +
>> +void intel_ddi_get_config(struct intel_encoder *encoder,
>> +			  struct intel_crtc_state *pipe_config)
>> +{
>> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>> +
>> +	/* XXX: DSI transcoder paranoia */
>> +	if (WARN_ON(transcoder_is_dsi(cpu_transcoder)))
>> +		return;
>> +
>> +	intel_ddi_read_func_ctl(encoder, pipe_config);
>> +	if (pipe_config->bigjoiner_slave) {
>> +		/* read out pipe settings from master */
>> +		enum transcoder save = pipe_config->cpu_transcoder;
>> +
>> +		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */
>> +		WARN_ON(pipe_config->output_types);
>> +		pipe_config->cpu_transcoder = (enum transcoder)pipe_config->bigjoiner_linked_crtc->pipe;
>> +		intel_ddi_read_func_ctl(encoder, pipe_config);
>> +		pipe_config->cpu_transcoder = save;
>> +	}
>>  
>>  	pipe_config->has_audio =
>>  		intel_ddi_is_audio_enabled(dev_priv, cpu_transcoder);
>> @@ -4422,7 +4455,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 41af7f1011fd..7223b6d916e7 100644
>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>> @@ -7024,6 +7024,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
>>  	intel_de_write(dev_priv, reg, val);
>>  }
>>  
>> +static void tgl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
>> +					 const 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(state, master);
>> +		intel_enable_shared_dpll(master_crtc_state);
>> +		intel_encoders_pre_enable(state, master);
>> +
>> +		/* and DSC on slave */
> Also here fec_enable never gets called for the slave since we call intel_encoders_pre_enable
> only for the master. So essentially on slave we are just doing dsc enable without FEC which is wrong.
>
> Regard

It is? I thought FEC was only required for the master when I was carefully reading the spec.

The DP encoder on the slave is completely unused, so no fec should be needed there.

~Maarten

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
  2020-08-17  7:26   ` Manna, Animesh
@ 2020-09-03 17:49   ` Ville Syrjälä
  2020-09-03 18:04     ` Navare, Manasi
  1 sibling, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 17:49 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> v2:
> * Manual rebase (Manasi)
> * remove the use of pipe_mode defined in patch 3 (Manasi)
> 
> v3:
> * Rebase on drm-tip (Manasi)

Previous review was apparently ignored. Or is there a better version
somewhere? If not, this still looks very wrong.

> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
>  .../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, 23 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 729ec6e0d43a..8652a7c6bf11 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
>  	tmp = intel_de_read(dev_priv, 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,
> @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
>  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
>  
>  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
>  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
>  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
>  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> @@ -13221,17 +13218,17 @@ 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;
>  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
>  
>  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
>  
> @@ -13277,6 +13274,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;
> @@ -13324,7 +13325,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.adjusted_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -18461,15 +18462,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
> @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			 */
>  			crtc_state->inherited = true;
>  
> +			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 e8f809161c75..f1e29d9a75d0 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
>  	u32 temp = intel_de_read(dev_priv, 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);
>  
>  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> @@ -1223,7 +1223,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;
> @@ -1234,9 +1233,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,
> @@ -1308,7 +1307,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;
> @@ -1324,12 +1322,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)) {
> @@ -1339,7 +1337,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);
>  	}
>  
> @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
>  		to_intel_sdvo_connector_state(conn_state);
>  	const struct intel_sdvo_connector *intel_sdvo_connector =
>  		to_intel_sdvo_connector(conn_state->connector);
> -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
>  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
>  	u32 sdvox;
>  	struct intel_sdvo_in_out_map in_out;
> @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
>  		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(&dev_priv->drm,
>  			 "Setting output timings on %s failed\n",
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
  2020-08-10 12:38   ` Maarten Lankhorst
  2020-08-17  7:32   ` Manna, Animesh
@ 2020-09-03 17:54   ` Ville Syrjälä
  2020-09-14 18:45     ` Navare, Manasi
  2 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 17:54 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:14PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> v4:
> * Manual rebase (Manasi)
> v3:
> * Change state to crtc_state, fix rebase err  (Manasi)
> v2:
> * Manual Rebase (Manasi)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
>  .../drm/i915/display/intel_display_types.h    | 11 ++-
>  drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
>  3 files changed, 79 insertions(+), 69 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 8652a7c6bf11..78cbfefbfa62 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -152,7 +152,7 @@ static void ilk_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);

These renames make it hard to see what changed. Should be split out.

>  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,
> @@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
>  
>  static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
>  	int width, height;
>  
>  	if (crtc_state->pch_pfit.enabled) {
>  		width = drm_rect_width(&crtc_state->pch_pfit.dst);
>  		height = drm_rect_height(&crtc_state->pch_pfit.dst);
>  	} else {
> -		width = adjusted_mode->crtc_hdisplay;
> -		height = adjusted_mode->crtc_vdisplay;
> +		width = pipe_mode->crtc_hdisplay;
> +		height = pipe_mode->crtc_vdisplay;
>  	}
> -
>  	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
>  				 SKL_CRTC_INDEX,
>  				 &crtc_state->scaler_state.scaler_id,
> @@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	if (new_crtc_state->has_pch_encoder)
> @@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
>  	intel_encoders_pre_enable(state, crtc);
>  
>  	if (!transcoder_is_dsi(cpu_transcoder))
> -		intel_set_pipe_timings(new_crtc_state);
> +		intel_set_transcoder_timings(new_crtc_state);
>  
>  	intel_set_pipe_src_size(new_crtc_state);
>  
> @@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> @@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
>  	if (intel_crtc_has_dp_encoder(new_crtc_state))
>  		intel_dp_set_m_n(new_crtc_state, M1_N1);
>  
> -	intel_set_pipe_timings(new_crtc_state);
> +	intel_set_transcoder_timings(new_crtc_state);
>  	intel_set_pipe_src_size(new_crtc_state);
>  
>  	i9xx_set_pipeconf(new_crtc_state);
> @@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
>  
>  static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
>  {
> -	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
> +	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
>  	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
>  
>  	/*
> @@ -8008,7 +8006,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);
> @@ -8018,7 +8016,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) {
> @@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
>  			    "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;
>  	}
> @@ -8081,7 +8079,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);
> @@ -8751,7 +8749,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);
> @@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
>  		return intel_de_read(dev_priv, 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);
> @@ -9458,7 +9456,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(pipe_config);
> @@ -10739,7 +10737,7 @@ static bool ilk_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);
>  
>  	ilk_get_pfit_config(pipe_config);
> @@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
>  	    INTEL_GEN(dev_priv) >= 11) {
>  		hsw_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);
> @@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
>  
>  static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
>  	int linetime_wm;
>  
>  	if (!crtc_state->hw.enable)
>  		return 0;
>  
> -	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
> -					adjusted_mode->crtc_clock);
> +	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
> +					pipe_mode->crtc_clock);
>  
>  	return min(linetime_wm, 0x1ff);
>  }
> @@ -13218,7 +13216,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);
>  }
>  
> @@ -13325,7 +13323,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.adjusted_mode,
> +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
>  			       &pipe_config->pipe_src_w,
>  			       &pipe_config->pipe_src_h);
>  
> @@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * drm_atomic_helper_update_legacy_modeset_state() happy
>  	 */
>  	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;
>  }
> @@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			 */
>  			crtc_state->inherited = true;
>  
> +			/* 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 f1e29d9a75d0..c52c8f42df68 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
> @@ -1141,8 +1141,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;
>  
> @@ -1169,8 +1169,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);
>  
> @@ -1666,8 +1666,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)
> @@ -1677,8 +1677,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) {
> @@ -2267,12 +2267,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;
> @@ -2351,8 +2351,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;
> @@ -2362,7 +2362,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;
> @@ -2378,8 +2378,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;
> @@ -2389,7 +2389,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)
> @@ -2427,12 +2427,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;
> @@ -2480,7 +2480,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;
>  
> @@ -2488,8 +2488,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);
> @@ -2579,7 +2579,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);
>  
> @@ -2607,7 +2607,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);
> @@ -2632,7 +2632,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);
>  }
> @@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>  	if (!crtc_state->hw.active)
>  		return true;
>  
> -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> +	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		return false;
>  
>  	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> @@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  	 */
>  	total_slice_mask = dbuf_slice_mask;
>  	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;
>  		u32 pipe_dbuf_slice_mask;
> @@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
>  		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
>  			continue;
>  
> -		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> +		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
>  
>  		total_width_in_range += hdisplay;
>  
> @@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
>  	if (drm_WARN_ON(&dev_priv->drm, 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;
> @@ -5288,14 +5288,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.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-03 17:49   ` Ville Syrjälä
@ 2020-09-03 18:04     ` Navare, Manasi
  2020-09-03 18:40       ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-03 18:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> > 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.
> > 
> > v2:
> > * Manual rebase (Manasi)
> > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > 
> > v3:
> > * Rebase on drm-tip (Manasi)
> 
> Previous review was apparently ignored. Or is there a better version
> somewhere? If not, this still looks very wrong.

This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
What in particular looks wrong or what review comments were unaddressed here?

@Maarten any feedback on Ville's unaddressed comments?

Manasi

> 
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> >  .../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, 23 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 729ec6e0d43a..8652a7c6bf11 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> >  	tmp = intel_de_read(dev_priv, 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,
> > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> >  
> >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > @@ -13221,17 +13218,17 @@ 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;
> >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> >  
> >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> >  
> > @@ -13277,6 +13274,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;
> > @@ -13324,7 +13325,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.adjusted_mode,
> >  			       &pipe_config->pipe_src_w,
> >  			       &pipe_config->pipe_src_h);
> >  
> > @@ -18461,15 +18462,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
> > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  			 */
> >  			crtc_state->inherited = true;
> >  
> > +			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 e8f809161c75..f1e29d9a75d0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> >  	u32 temp = intel_de_read(dev_priv, 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);
> >  
> >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > @@ -1223,7 +1223,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;
> > @@ -1234,9 +1233,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,
> > @@ -1308,7 +1307,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;
> > @@ -1324,12 +1322,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)) {
> > @@ -1339,7 +1337,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);
> >  	}
> >  
> > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> >  		to_intel_sdvo_connector_state(conn_state);
> >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> >  		to_intel_sdvo_connector(conn_state->connector);
> > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> >  	u32 sdvox;
> >  	struct intel_sdvo_in_out_map in_out;
> > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> >  		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(&dev_priv->drm,
> >  			 "Setting output timings on %s failed\n",
> > -- 
> > 2.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check Manasi Navare
  2020-08-21 10:16   ` Manna, Animesh
@ 2020-09-03 18:38   ` Ville Syrjälä
  2020-09-23 22:58     ` Navare, Manasi
  1 sibling, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 18:38 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:16PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
>  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.
> 
> v3:
> * Manual Rebase (Manasi)
>  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>
> Signed-off-by: Manasi Navare <manasi.d.navare@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  | 201 ++++++++++++++++--
>  .../drm/i915/display/intel_display_types.h    |   9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
>  5 files changed, 211 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> index 630f49b7aa01..b9dcdc74a10d 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> @@ -270,14 +270,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 11146292b06f..fc556c032c8f 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> @@ -43,7 +43,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_free(struct drm_atomic_state *state);
>  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 3ecb642805a6..955e19abb563 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8016,9 +8016,24 @@ 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;
>  
> @@ -8079,7 +8094,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)

What's the deal here? I think I asked this same question ages ago
already...

>  		return -EINVAL;
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -12433,7 +12448,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)
>  {
> @@ -12442,7 +12457,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;
>  
> @@ -12682,6 +12697,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 &&
>  	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
>  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
>  		if (ret)
> @@ -13206,18 +13222,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,
> @@ -13240,7 +13269,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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> @@ -13276,16 +13347,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 drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
>  	struct drm_connector *connector;
>  	struct drm_connector_state *connector_state;
> @@ -13327,7 +13398,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) {
>  		struct intel_encoder *encoder =
>  			to_intel_encoder(connector_state->best_encoder);
>  
> @@ -13365,7 +13436,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) {
>  		struct intel_encoder *encoder =
>  			to_intel_encoder(connector_state->best_encoder);
>  
> @@ -13422,8 +13493,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  	 * drm_atomic_helper_update_legacy_modeset_state() happy
>  	 */
>  	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;
>  }
> @@ -14820,6 +14889,75 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
>  	return false;
>  }
>  
> +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
> @@ -14849,19 +14987,36 @@ 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;
>  		}
>  
> -		ret = intel_crtc_prepare_cleared_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;
> +		}
> +
> +		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;
> +			}

I'm confused. Where do we add the other pipe to the state if there are no
modesets involved?

> +			continue;
> +		}
> +
> +		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
>  		if (ret)
>  			goto fail;
>  
> -		if (!new_crtc_state->hw.enable)
> -			continue;
> +		ret = intel_modeset_pipe_config(state, new_crtc_state);
> +		if (ret)
> +			goto fail;
>  
> -		ret = intel_modeset_pipe_config(new_crtc_state);
> +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
> +						   new_crtc_state);
>  		if (ret)
>  			goto fail;
>  	}
> @@ -15193,7 +15348,9 @@ static void intel_update_crtc(struct intel_atomic_state *state,
>  
>  	commit_pipe_config(state, crtc);
>  
> -	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 c52c8f42df68..4694cfd90a0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1053,6 +1053,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 fbfea99fd804..29f45d2206af 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2247,6 +2247,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,
> @@ -2264,12 +2273,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_dbg_kms(&dev_priv->drm,
>  				    "Compressed BPP/Slice Count not supported\n");
> @@ -2285,14 +2294,15 @@ 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_dbg_kms(&dev_priv->drm,
>  				    "Cannot split stream to use 2 VDSC instances\n");
>  			return -EINVAL;
>  		}
> +
> +		pipe_config->dsc.dsc_split = true;
>  	}
>  
>  	ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-03 18:04     ` Navare, Manasi
@ 2020-09-03 18:40       ` Ville Syrjälä
  2020-09-07 12:35         ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 18:40 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > 
> > > 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.
> > > 
> > > v2:
> > > * Manual rebase (Manasi)
> > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > 
> > > v3:
> > > * Rebase on drm-tip (Manasi)
> > 
> > Previous review was apparently ignored. Or is there a better version
> > somewhere? If not, this still looks very wrong.
> 
> This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> What in particular looks wrong or what review comments were unaddressed here?

The dvo/sdvo changes.

> 
> @Maarten any feedback on Ville's unaddressed comments?
> 
> Manasi
> 
> > 
> > > 
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> > >  .../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, 23 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 729ec6e0d43a..8652a7c6bf11 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > >  	tmp = intel_de_read(dev_priv, 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,
> > > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> > >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> > >  
> > >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> > >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> > >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> > >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > > @@ -13221,17 +13218,17 @@ 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;
> > >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> > >  
> > >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> > >  
> > > @@ -13277,6 +13274,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;
> > > @@ -13324,7 +13325,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.adjusted_mode,
> > >  			       &pipe_config->pipe_src_w,
> > >  			       &pipe_config->pipe_src_h);
> > >  
> > > @@ -18461,15 +18462,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
> > > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > >  			 */
> > >  			crtc_state->inherited = true;
> > >  
> > > +			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 e8f809161c75..f1e29d9a75d0 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> > >  	u32 temp = intel_de_read(dev_priv, 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);
> > >  
> > >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > @@ -1223,7 +1223,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;
> > > @@ -1234,9 +1233,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,
> > > @@ -1308,7 +1307,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;
> > > @@ -1324,12 +1322,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)) {
> > > @@ -1339,7 +1337,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);
> > >  	}
> > >  
> > > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > >  		to_intel_sdvo_connector_state(conn_state);
> > >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> > >  		to_intel_sdvo_connector(conn_state->connector);
> > > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> > >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> > >  	u32 sdvox;
> > >  	struct intel_sdvo_in_out_map in_out;
> > > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > >  		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(&dev_priv->drm,
> > >  			 "Setting output timings on %s failed\n",
> > > -- 
> > > 2.19.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
@ 2020-09-03 19:19   ` Ville Syrjälä
  2020-09-14 19:14     ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 19:19 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
>  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.
> 
> v5:
> * Rebase after adding sagv support (Manasi)
> v4:
> * Manual rebase (Manasi)
> 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>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
>  .../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  |  20 +-
>  .../drm/i915/display/intel_display_types.h    |  11 +
>  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
>  6 files changed, 274 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 79032701873a..5c6e72063fac 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -246,11 +246,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);
>  
> +	if (from_plane_state->uapi.crtc)
> +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> +	else
> +		plane_state->hw.crtc = NULL;
> +
>  	plane_state->hw.crtc = from_plane_state->uapi.crtc;

eh?

>  	plane_state->hw.fb = from_plane_state->uapi.fb;
>  	if (plane_state->hw.fb)
> @@ -319,15 +325,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;
>  }
>  
> @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
>  		intel_atomic_get_new_plane_state(state, plane);
>  	const struct intel_plane_state *old_plane_state =
>  		intel_atomic_get_old_plane_state(state, plane);
> +	const struct intel_plane_state *new_master_plane_state;
>  	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;
>  
> -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> +	if (crtc)
> +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> +	else
> +		new_crtc_state = NULL;
> +
> +	new_master_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);
> +
>  	new_plane_state->uapi.visible = false;
>  	if (!crtc)
>  		return 0;
>  
>  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
>  
>  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
>  
>  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 bfc5c890ab4e..6f4a2845674d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  	drm_framebuffer_get(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);
>  
>  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>  
> @@ -12582,26 +12582,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.

Feels like this has become super complicated by mixing up the bigjoiner
and Y plane cases. Can't we just handle them separately. First deal with
bigjoiner planes, then let each crtc handle its Y-planes independently?

> +	 *
> +	 * 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);
>  
> -		drm_WARN_ON(state->base.dev,
> -			    linked_plane_state->planar_linked_plane != plane);
> -		drm_WARN_ON(state->base.dev,
> -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> +			if (IS_ERR(linked_crtc_state))
> +				return PTR_ERR(linked_crtc_state);
> +		}
>  	}
>  
>  	return 0;
> @@ -12641,6 +12795,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)))
> @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
>  		memcpy(linked_state->color_plane, plane_state->color_plane,
>  		       sizeof(linked_state->color_plane));
>  
> -		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;
>  
> @@ -15028,6 +15190,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) {
> @@ -15038,6 +15201,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;
>  
> @@ -15062,7 +15231,11 @@ 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 "
> @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>  	new_plane_state->uapi.crtc_w = crtc_w;
>  	new_plane_state->uapi.crtc_h = crtc_h;
>  
> -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
>  
>  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
>  						  old_plane_state, new_plane_state);
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index e890c8fb779b..78010ee364f3 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -467,12 +467,20 @@ enum phy_fia {
>  		for_each_if(crtc)
>  
>  #define intel_atomic_crtc_state_for_each_plane_state( \
> -		  plane, 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))))
> +	plane, iter, plane_state, \
> +	crtc_state) \
> +	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 943709f192f7..6957eac140cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3150,7 +3150,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 *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;
> @@ -3160,7 +3160,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)
> @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>  {
>  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -	struct intel_plane *plane;
> +	struct intel_plane *plane, *iter;
>  	const struct intel_plane_state *plane_state;
>  	int level, latency;
>  
> @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
>  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
>  		return false;
>  
> -	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) {
>  		const struct skl_plane_wm *wm =
>  			&crtc_state->wm.skl.optimal.planes[plane->id];
>  
> @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
>  				 u64 *plane_data_rate,
>  				 u64 *uv_plane_data_rate)
>  {
> -	struct intel_plane *plane;
> +	struct intel_plane *plane, *iter;
>  	const struct intel_plane_state *plane_state;
>  	u64 total_data_rate = 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;
>  
> @@ -4741,12 +4741,12 @@ 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;
>  
>  	/* 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;
>  
> @@ -5593,7 +5593,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;
>  
> @@ -5603,7 +5603,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.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling Manasi Navare
  2020-08-24 22:15   ` Navare, Manasi
@ 2020-09-03 19:23   ` Ville Syrjälä
  2020-09-14 19:21     ` Navare, Manasi
  1 sibling, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-03 19:23 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> ****This needs to be checked if it still works since lot of refactoring
> in skl_commit_modeset_enables
> 
> v2:
> * Manual Rebase (Manasi)
> * Refactoring on intel_update_crtc and enable_crtc and removing
> special trans_port_sync_update (Manasi)
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
>  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
>  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
>  3 files changed, 129 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index a1011414da6d..00b26863ffc6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
>  	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
> @@ -15754,6 +15754,52 @@ 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);
> +
> +	if (modeset) {
> +		/* Enable slave first */
> +		intel_crtc_update_active_timings(new_slave_crtc_state);
> +		dev_priv->display.crtc_enable(state, slave);
> +
> +		/* Then master */
> +		intel_crtc_update_active_timings(new_crtc_state);
> +		dev_priv->display.crtc_enable(state, crtc);
> +
> +		/* vblanks work again, re-enable pipe CRC. */
> +		intel_crtc_enable_pipe_crc(crtc);
> +
> +	} else {
> +		intel_pre_plane_update(state, crtc);
> +		intel_pre_plane_update(state, slave);
> +
> +		if (new_crtc_state->update_pipe)
> +			intel_encoders_update_pipe(state, crtc);
> +	}
> +
> +	/*
> +	 * 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, crtc);
> +	commit_pipe_config(state, slave);
> +
> +	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);
> +}

I think this should ideally all go away and just the normal logic
in commit_modeset_enables() should deal with it. Just like it does
for port sync/mst pipe dependencies.

> +
>  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
>  {
>  	struct intel_crtc_state *new_crtc_state;
> @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
>  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  {
>  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> -	struct intel_crtc *crtc;
> +	struct intel_crtc *crtc, *slave;
>  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
>  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
>  	u8 update_pipes = 0, modeset_pipes = 0;
> +	const struct intel_crtc_state *slave_crtc_state;
>  	int i;
>  
>  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
>  		enum pipe pipe = crtc->pipe;
>  
> +		if (new_crtc_state->bigjoiner_slave) {
> +			/* We're updated from master */
> +			continue;
> +		}
> +
>  		if (!new_crtc_state->hw.active)
>  			continue;
>  
> @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		} else {
>  			modeset_pipes |= BIT(pipe);
>  		}
> +
> +		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;
> +		}
> +
> +		/* ignore allocations for crtc's that have been turned off during modeset. */
> +		if (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;
> +		}

Why is this here? Can't see why the current code wouldn't work just fine
for bigjoiner too.

>  	}
>  
>  	/*
> @@ -15806,28 +15887,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>  						    new_crtc_state, i) {
>  			enum pipe pipe = crtc->pipe;
> +			bool ddb_changed;
>  
>  			if ((update_pipes & BIT(pipe)) == 0)
>  				continue;
>  
> -			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> +			if (skl_ddb_allocation_overlaps(&new_entries[pipe],
>  							entries, I915_MAX_PIPES, pipe))
>  				continue;
>  
> -			entries[pipe] = new_crtc_state->wm.skl.ddb;
> +			ddb_changed = !skl_ddb_entry_equal(&new_entries[pipe], &entries[pipe]);
> +			entries[pipe] = new_entries[pipe];
>  			update_pipes &= ~BIT(pipe);
>  
> -			intel_update_crtc(state, crtc);
> -
>  			/*
>  			 * If this is an already active pipe, it's DDB changed,
>  			 * and this isn't the last pipe that needs updating
>  			 * 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) &&
> -			    (update_pipes | modeset_pipes))
> +			if (new_crtc_state->bigjoiner) {
> +				intel_update_bigjoiner(crtc, state,
> +						       old_crtc_state,
> +						       new_crtc_state);
> +			} else {
> +				intel_update_crtc(state, crtc);
> +			}
> +
> +			if (ddb_changed && (update_pipes | modeset_pipes))
>  				intel_wait_for_vblank(dev_priv, pipe);
>  		}
>  	}
> @@ -15863,9 +15950,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		if ((modeset_pipes & BIT(pipe)) == 0)
>  			continue;
>  
> +		WARN_ON(skl_ddb_allocation_overlaps(&new_entries[pipe],
> +						    entries, I915_MAX_PIPES, pipe));
> +
> +		entries[pipe] = new_entries[pipe];
>  		modeset_pipes &= ~BIT(pipe);
>  
> -		intel_enable_crtc(state, crtc);
> +		if (new_crtc_state->bigjoiner)
> +			intel_update_bigjoiner(crtc, state,
> +					       old_crtc_state,
> +					       new_crtc_state);
> +		else
> +			intel_enable_crtc(state, crtc);
>  	}
>  
>  	/*
> @@ -15877,10 +15973,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  		if ((update_pipes & BIT(pipe)) == 0)
>  			continue;
>  
> -		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> +		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_entries[pipe],
>  									entries, I915_MAX_PIPES, pipe));
>  
> -		entries[pipe] = new_crtc_state->wm.skl.ddb;
> +		entries[pipe] = new_entries[pipe];
>  		update_pipes &= ~BIT(pipe);
>  
>  		intel_update_crtc(state, crtc);
> diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> index 60eeed06a780..eaae5df546fe 100644
> --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> @@ -99,6 +99,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;
>  
> @@ -191,7 +193,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;
> @@ -206,16 +209,26 @@ 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) {
> -		drm_WARN_ON(&dev_priv->drm,
> -			    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)
> +			drm_WARN_ON(&dev_priv->drm,
> +				    drm_crtc_vblank_get(&crtc->base) != 0);
> +		if (slave_crtc_state && slave_crtc_state->uapi.event)
> +			drm_WARN_ON(&dev_priv->drm,
> +				    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 cd2104ba1ca1..15e7c112ec77 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.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
  2020-08-10 12:40   ` Maarten Lankhorst
  2020-08-21  9:41   ` Manna, Animesh
@ 2020-09-07 11:20   ` Ville Syrjälä
  2020-09-14 19:00     ` Navare, Manasi
  2 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-07 11:20 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> 
> 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.
> 
> v5:
> * Increase max plane width to support 8K with bigjoiner (Maarten)
> v4:
> * Rebase (Manasi)
> 
> 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)
> v3:
> * Rebase (Manasi)
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
>  2 files changed, 91 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 78cbfefbfa62..3ecb642805a6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
>  	 * too big for that.
>  	 */
>  	if (INTEL_GEN(dev_priv) >= 11) {
> -		plane_width_max = 5120;
> +		plane_width_max = 7680;

This looks misplaced. Planes do no know whether bigjoiner can be used or
not. They should not care in fact. The caller should have that knowledge
and can deal with it properly.

>  		plane_height_max = 4320;
>  	} else {
>  		plane_width_max = 5120;
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index d6295eb20b63..fbfea99fd804 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> -	struct intel_encoder *encoder = &dig_port->base;
> +	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;
>  
> +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> +		return 2 * dev_priv->max_dotclk_freq;
> +
> +	return dev_priv->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;
>  }
> @@ -527,7 +539,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;
> @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
>  		    max_bpp_small_joiner_ram);
>  
> @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> @@ -576,7 +602,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)
>  {
>  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  	u8 min_slice_count, i;
> @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> @@ -648,11 +683,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)
> @@ -664,6 +703,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);
>  
> @@ -691,23 +745,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);
>  }
> @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
>  				    "Compressed BPP/Slice Count not supported\n");
> -- 
> 2.19.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-03 18:40       ` Ville Syrjälä
@ 2020-09-07 12:35         ` Ville Syrjälä
  2020-09-14 18:32           ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-07 12:35 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > 
> > > > 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.
> > > > 
> > > > v2:
> > > > * Manual rebase (Manasi)
> > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > 
> > > > v3:
> > > > * Rebase on drm-tip (Manasi)
> > > 
> > > Previous review was apparently ignored. Or is there a better version
> > > somewhere? If not, this still looks very wrong.
> > 
> > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > What in particular looks wrong or what review comments were unaddressed here?
> 
> The dvo/sdvo changes.

I recommend just dropping this patch entirely. It doesn't seem to have
anything to do with the bigjoiner anyway.

> 
> > 
> > @Maarten any feedback on Ville's unaddressed comments?
> > 
> > Manasi
> > 
> > > 
> > > > 
> > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> > > >  .../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, 23 insertions(+), 26 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 729ec6e0d43a..8652a7c6bf11 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > > >  	tmp = intel_de_read(dev_priv, 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,
> > > > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> > > >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> > > >  
> > > >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > > > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > > > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> > > >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> > > >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> > > >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > > > @@ -13221,17 +13218,17 @@ 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;
> > > >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > > > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > > > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> > > >  
> > > >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> > > >  
> > > > @@ -13277,6 +13274,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;
> > > > @@ -13324,7 +13325,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.adjusted_mode,
> > > >  			       &pipe_config->pipe_src_w,
> > > >  			       &pipe_config->pipe_src_h);
> > > >  
> > > > @@ -18461,15 +18462,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
> > > > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > > >  			 */
> > > >  			crtc_state->inherited = true;
> > > >  
> > > > +			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 e8f809161c75..f1e29d9a75d0 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> > > >  	u32 temp = intel_de_read(dev_priv, 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);
> > > >  
> > > >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > @@ -1223,7 +1223,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;
> > > > @@ -1234,9 +1233,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,
> > > > @@ -1308,7 +1307,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;
> > > > @@ -1324,12 +1322,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)) {
> > > > @@ -1339,7 +1337,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);
> > > >  	}
> > > >  
> > > > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > >  		to_intel_sdvo_connector_state(conn_state);
> > > >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> > > >  		to_intel_sdvo_connector(conn_state->connector);
> > > > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> > > >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> > > >  	u32 sdvox;
> > > >  	struct intel_sdvo_in_out_map in_out;
> > > > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > >  		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(&dev_priv->drm,
> > > >  			 "Setting output timings on %s failed\n",
> > > > -- 
> > > > 2.19.1
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> Ville Syrjälä
> Intel
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-07 12:35         ` Ville Syrjälä
@ 2020-09-14 18:32           ` Navare, Manasi
  2020-09-14 18:52             ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 18:32 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > 
> > > > > 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.
> > > > > 
> > > > > v2:
> > > > > * Manual rebase (Manasi)
> > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > 
> > > > > v3:
> > > > > * Rebase on drm-tip (Manasi)
> > > > 
> > > > Previous review was apparently ignored. Or is there a better version
> > > > somewhere? If not, this still looks very wrong.
> > > 
> > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > What in particular looks wrong or what review comments were unaddressed here?
> > 
> > The dvo/sdvo changes.
> 
> I recommend just dropping this patch entirely. It doesn't seem to have
> anything to do with the bigjoiner anyway.

So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
+					     struct drm_display_mode *user_mode)

You think we dont need mode as an argument there either?

Manasi
> 
> > 
> > > 
> > > @Maarten any feedback on Ville's unaddressed comments?
> > > 
> > > Manasi
> > > 
> > > > 
> > > > > 
> > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> > > > >  .../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, 23 insertions(+), 26 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index 729ec6e0d43a..8652a7c6bf11 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > > > >  	tmp = intel_de_read(dev_priv, 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,
> > > > > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> > > > >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> > > > >  
> > > > >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > > > > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > > > > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> > > > >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> > > > >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> > > > >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > > > > @@ -13221,17 +13218,17 @@ 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;
> > > > >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > > > > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > > > > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> > > > >  
> > > > >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> > > > >  
> > > > > @@ -13277,6 +13274,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;
> > > > > @@ -13324,7 +13325,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.adjusted_mode,
> > > > >  			       &pipe_config->pipe_src_w,
> > > > >  			       &pipe_config->pipe_src_h);
> > > > >  
> > > > > @@ -18461,15 +18462,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
> > > > > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > > > >  			 */
> > > > >  			crtc_state->inherited = true;
> > > > >  
> > > > > +			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 e8f809161c75..f1e29d9a75d0 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> > > > >  	u32 temp = intel_de_read(dev_priv, 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);
> > > > >  
> > > > >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > @@ -1223,7 +1223,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;
> > > > > @@ -1234,9 +1233,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,
> > > > > @@ -1308,7 +1307,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;
> > > > > @@ -1324,12 +1322,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)) {
> > > > > @@ -1339,7 +1337,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);
> > > > >  	}
> > > > >  
> > > > > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > >  		to_intel_sdvo_connector_state(conn_state);
> > > > >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> > > > >  		to_intel_sdvo_connector(conn_state->connector);
> > > > > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> > > > >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> > > > >  	u32 sdvox;
> > > > >  	struct intel_sdvo_in_out_map in_out;
> > > > > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > >  		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(&dev_priv->drm,
> > > > >  			 "Setting output timings on %s failed\n",
> > > > > -- 
> > > > > 2.19.1
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > 
> > -- 
> > Ville Syrjälä
> > Intel
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-09-03 17:54   ` Ville Syrjälä
@ 2020-09-14 18:45     ` Navare, Manasi
  2020-09-14 18:48       ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 18:45 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 08:54:40PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:14PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> > v4:
> > * Manual rebase (Manasi)
> > v3:
> > * Change state to crtc_state, fix rebase err  (Manasi)
> > v2:
> > * Manual Rebase (Manasi)
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
> >  .../drm/i915/display/intel_display_types.h    | 11 ++-
> >  drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
> >  3 files changed, 79 insertions(+), 69 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 8652a7c6bf11..78cbfefbfa62 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -152,7 +152,7 @@ static void ilk_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);
> 
> These renames make it hard to see what changed. Should be split out.

So just have the renaming in separate patch?

Manasi
> 
> >  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,
> > @@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> >  
> >  static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
> >  	int width, height;
> >  
> >  	if (crtc_state->pch_pfit.enabled) {
> >  		width = drm_rect_width(&crtc_state->pch_pfit.dst);
> >  		height = drm_rect_height(&crtc_state->pch_pfit.dst);
> >  	} else {
> > -		width = adjusted_mode->crtc_hdisplay;
> > -		height = adjusted_mode->crtc_vdisplay;
> > +		width = pipe_mode->crtc_hdisplay;
> > +		height = pipe_mode->crtc_vdisplay;
> >  	}
> > -
> >  	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
> >  				 SKL_CRTC_INDEX,
> >  				 &crtc_state->scaler_state.scaler_id,
> > @@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
> >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> >  
> > -	intel_set_pipe_timings(new_crtc_state);
> > +	intel_set_transcoder_timings(new_crtc_state);
> >  	intel_set_pipe_src_size(new_crtc_state);
> >  
> >  	if (new_crtc_state->has_pch_encoder)
> > @@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
> >  	intel_encoders_pre_enable(state, crtc);
> >  
> >  	if (!transcoder_is_dsi(cpu_transcoder))
> > -		intel_set_pipe_timings(new_crtc_state);
> > +		intel_set_transcoder_timings(new_crtc_state);
> >  
> >  	intel_set_pipe_src_size(new_crtc_state);
> >  
> > @@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
> >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> >  
> > -	intel_set_pipe_timings(new_crtc_state);
> > +	intel_set_transcoder_timings(new_crtc_state);
> >  	intel_set_pipe_src_size(new_crtc_state);
> >  
> >  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> > @@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
> >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> >  
> > -	intel_set_pipe_timings(new_crtc_state);
> > +	intel_set_transcoder_timings(new_crtc_state);
> >  	intel_set_pipe_src_size(new_crtc_state);
> >  
> >  	i9xx_set_pipeconf(new_crtc_state);
> > @@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
> >  
> >  static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
> >  {
> > -	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
> > +	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
> >  	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
> >  
> >  	/*
> > @@ -8008,7 +8006,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);
> > @@ -8018,7 +8016,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) {
> > @@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
> >  			    "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;
> >  	}
> > @@ -8081,7 +8079,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);
> > @@ -8751,7 +8749,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);
> > @@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
> >  		return intel_de_read(dev_priv, 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);
> > @@ -9458,7 +9456,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(pipe_config);
> > @@ -10739,7 +10737,7 @@ static bool ilk_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);
> >  
> >  	ilk_get_pfit_config(pipe_config);
> > @@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> >  	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> >  	    INTEL_GEN(dev_priv) >= 11) {
> >  		hsw_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);
> > @@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
> >  
> >  static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
> >  	int linetime_wm;
> >  
> >  	if (!crtc_state->hw.enable)
> >  		return 0;
> >  
> > -	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
> > -					adjusted_mode->crtc_clock);
> > +	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
> > +					pipe_mode->crtc_clock);
> >  
> >  	return min(linetime_wm, 0x1ff);
> >  }
> > @@ -13218,7 +13216,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);
> >  }
> >  
> > @@ -13325,7 +13323,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.adjusted_mode,
> > +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
> >  			       &pipe_config->pipe_src_w,
> >  			       &pipe_config->pipe_src_h);
> >  
> > @@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> >  	 * drm_atomic_helper_update_legacy_modeset_state() happy
> >  	 */
> >  	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;
> >  }
> > @@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  			 */
> >  			crtc_state->inherited = true;
> >  
> > +			/* 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 f1e29d9a75d0..c52c8f42df68 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
> > @@ -1141,8 +1141,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;
> >  
> > @@ -1169,8 +1169,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);
> >  
> > @@ -1666,8 +1666,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)
> > @@ -1677,8 +1677,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) {
> > @@ -2267,12 +2267,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;
> > @@ -2351,8 +2351,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;
> > @@ -2362,7 +2362,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;
> > @@ -2378,8 +2378,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;
> > @@ -2389,7 +2389,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)
> > @@ -2427,12 +2427,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;
> > @@ -2480,7 +2480,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;
> >  
> > @@ -2488,8 +2488,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);
> > @@ -2579,7 +2579,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);
> >  
> > @@ -2607,7 +2607,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);
> > @@ -2632,7 +2632,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);
> >  }
> > @@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> >  	if (!crtc_state->hw.active)
> >  		return true;
> >  
> > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > +	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> >  		return false;
> >  
> >  	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > @@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
> >  	 */
> >  	total_slice_mask = dbuf_slice_mask;
> >  	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;
> >  		u32 pipe_dbuf_slice_mask;
> > @@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
> >  		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
> >  			continue;
> >  
> > -		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> > +		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
> >  
> >  		total_width_in_range += hdisplay;
> >  
> > @@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
> >  	if (drm_WARN_ON(&dev_priv->drm, 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;
> > @@ -5288,14 +5288,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.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-09-14 18:45     ` Navare, Manasi
@ 2020-09-14 18:48       ` Ville Syrjälä
  0 siblings, 0 replies; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 18:48 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 11:45:37AM -0700, Navare, Manasi wrote:
> On Thu, Sep 03, 2020 at 08:54:40PM +0300, Ville Syrjälä wrote:
> > On Wed, Jul 15, 2020 at 03:42:14PM -0700, Manasi Navare wrote:
> > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > 
> > > v4:
> > > * Manual rebase (Manasi)
> > > v3:
> > > * Change state to crtc_state, fix rebase err  (Manasi)
> > > v2:
> > > * Manual Rebase (Manasi)
> > > 
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c  | 61 ++++++++-------
> > >  .../drm/i915/display/intel_display_types.h    | 11 ++-
> > >  drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
> > >  3 files changed, 79 insertions(+), 69 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 8652a7c6bf11..78cbfefbfa62 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -152,7 +152,7 @@ static void ilk_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);
> > 
> > These renames make it hard to see what changed. Should be split out.
> 
> So just have the renaming in separate patch?

Yeah.

> 
> Manasi
> > 
> > >  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,
> > > @@ -6110,18 +6110,16 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> > >  
> > >  static int skl_update_scaler_crtc(struct intel_crtc_state *crtc_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;
> > >  	int width, height;
> > >  
> > >  	if (crtc_state->pch_pfit.enabled) {
> > >  		width = drm_rect_width(&crtc_state->pch_pfit.dst);
> > >  		height = drm_rect_height(&crtc_state->pch_pfit.dst);
> > >  	} else {
> > > -		width = adjusted_mode->crtc_hdisplay;
> > > -		height = adjusted_mode->crtc_vdisplay;
> > > +		width = pipe_mode->crtc_hdisplay;
> > > +		height = pipe_mode->crtc_vdisplay;
> > >  	}
> > > -
> > >  	return skl_update_scaler(crtc_state, !crtc_state->hw.active,
> > >  				 SKL_CRTC_INDEX,
> > >  				 &crtc_state->scaler_state.scaler_id,
> > > @@ -6901,7 +6899,7 @@ static void ilk_crtc_enable(struct intel_atomic_state *state,
> > >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> > >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> > >  
> > > -	intel_set_pipe_timings(new_crtc_state);
> > > +	intel_set_transcoder_timings(new_crtc_state);
> > >  	intel_set_pipe_src_size(new_crtc_state);
> > >  
> > >  	if (new_crtc_state->has_pch_encoder)
> > > @@ -7046,7 +7044,7 @@ static void hsw_crtc_enable(struct intel_atomic_state *state,
> > >  	intel_encoders_pre_enable(state, crtc);
> > >  
> > >  	if (!transcoder_is_dsi(cpu_transcoder))
> > > -		intel_set_pipe_timings(new_crtc_state);
> > > +		intel_set_transcoder_timings(new_crtc_state);
> > >  
> > >  	intel_set_pipe_src_size(new_crtc_state);
> > >  
> > > @@ -7429,7 +7427,7 @@ static void valleyview_crtc_enable(struct intel_atomic_state *state,
> > >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> > >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> > >  
> > > -	intel_set_pipe_timings(new_crtc_state);
> > > +	intel_set_transcoder_timings(new_crtc_state);
> > >  	intel_set_pipe_src_size(new_crtc_state);
> > >  
> > >  	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> > > @@ -7497,7 +7495,7 @@ static void i9xx_crtc_enable(struct intel_atomic_state *state,
> > >  	if (intel_crtc_has_dp_encoder(new_crtc_state))
> > >  		intel_dp_set_m_n(new_crtc_state, M1_N1);
> > >  
> > > -	intel_set_pipe_timings(new_crtc_state);
> > > +	intel_set_transcoder_timings(new_crtc_state);
> > >  	intel_set_pipe_src_size(new_crtc_state);
> > >  
> > >  	i9xx_set_pipeconf(new_crtc_state);
> > > @@ -7971,7 +7969,7 @@ static bool intel_crtc_supports_double_wide(const struct intel_crtc *crtc)
> > >  
> > >  static u32 ilk_pipe_pixel_rate(const struct intel_crtc_state *crtc_state)
> > >  {
> > > -	u32 pixel_rate = crtc_state->hw.adjusted_mode.crtc_clock;
> > > +	u32 pixel_rate = crtc_state->hw.pipe_mode.crtc_clock;
> > >  	unsigned int pipe_w, pipe_h, pfit_w, pfit_h;
> > >  
> > >  	/*
> > > @@ -8008,7 +8006,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);
> > > @@ -8018,7 +8016,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) {
> > > @@ -8029,16 +8027,16 @@ 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_dbg_kms(&dev_priv->drm,
> > >  			    "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;
> > >  	}
> > > @@ -8081,7 +8079,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);
> > > @@ -8751,7 +8749,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);
> > > @@ -8837,8 +8835,8 @@ static bool intel_pipe_is_interlaced(const struct intel_crtc_state *crtc_state)
> > >  		return intel_de_read(dev_priv, 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);
> > > @@ -9458,7 +9456,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(pipe_config);
> > > @@ -10739,7 +10737,7 @@ static bool ilk_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);
> > >  
> > >  	ilk_get_pfit_config(pipe_config);
> > > @@ -11147,7 +11145,7 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> > >  	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > >  	    INTEL_GEN(dev_priv) >= 11) {
> > >  		hsw_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);
> > > @@ -12593,15 +12591,15 @@ static bool c8_planes_changed(const struct intel_crtc_state *new_crtc_state)
> > >  
> > >  static u16 hsw_linetime_wm(const struct intel_crtc_state *crtc_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;
> > >  	int linetime_wm;
> > >  
> > >  	if (!crtc_state->hw.enable)
> > >  		return 0;
> > >  
> > > -	linetime_wm = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
> > > -					adjusted_mode->crtc_clock);
> > > +	linetime_wm = DIV_ROUND_CLOSEST(pipe_mode->crtc_htotal * 1000 * 8,
> > > +					pipe_mode->crtc_clock);
> > >  
> > >  	return min(linetime_wm, 0x1ff);
> > >  }
> > > @@ -13218,7 +13216,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);
> > >  }
> > >  
> > > @@ -13325,7 +13323,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.adjusted_mode,
> > > +	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
> > >  			       &pipe_config->pipe_src_w,
> > >  			       &pipe_config->pipe_src_h);
> > >  
> > > @@ -13424,6 +13422,8 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> > >  	 * drm_atomic_helper_update_legacy_modeset_state() happy
> > >  	 */
> > >  	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;
> > >  }
> > > @@ -18478,6 +18478,9 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > >  			 */
> > >  			crtc_state->inherited = true;
> > >  
> > > +			/* 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 f1e29d9a75d0..c52c8f42df68 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -799,15 +799,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 cfabbe0481ab..d1263ebd3811 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -905,12 +905,12 @@ static void pnv_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, &pnv_display_wm,
> > > @@ -1141,8 +1141,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;
> > >  
> > > @@ -1169,8 +1169,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);
> > >  
> > > @@ -1666,8 +1666,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)
> > > @@ -1677,8 +1677,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) {
> > > @@ -2267,12 +2267,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;
> > > @@ -2351,8 +2351,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;
> > > @@ -2362,7 +2362,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;
> > > @@ -2378,8 +2378,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;
> > > @@ -2389,7 +2389,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)
> > > @@ -2427,12 +2427,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;
> > > @@ -2480,7 +2480,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;
> > >  
> > > @@ -2488,8 +2488,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);
> > > @@ -2579,7 +2579,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);
> > >  
> > > @@ -2607,7 +2607,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);
> > > @@ -2632,7 +2632,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);
> > >  }
> > > @@ -3889,7 +3889,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > >  	if (!crtc_state->hw.active)
> > >  		return true;
> > >  
> > > -	if (crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > +	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > >  		return false;
> > >  
> > >  	intel_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) {
> > > @@ -4180,8 +4180,8 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
> > >  	 */
> > >  	total_slice_mask = dbuf_slice_mask;
> > >  	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;
> > >  		u32 pipe_dbuf_slice_mask;
> > > @@ -4211,7 +4211,7 @@ skl_ddb_get_pipe_allocation_limits(struct drm_i915_private *dev_priv,
> > >  		if (dbuf_slice_mask != pipe_dbuf_slice_mask)
> > >  			continue;
> > >  
> > > -		drm_mode_get_hv_timing(adjusted_mode, &hdisplay, &vdisplay);
> > > +		drm_mode_get_hv_timing(pipe_mode, &hdisplay, &vdisplay);
> > >  
> > >  		total_width_in_range += hdisplay;
> > >  
> > > @@ -5099,7 +5099,7 @@ intel_get_linetime_us(const struct intel_crtc_state *crtc_state)
> > >  	if (drm_WARN_ON(&dev_priv->drm, 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;
> > > @@ -5288,14 +5288,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.19.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-14 18:32           ` Navare, Manasi
@ 2020-09-14 18:52             ` Ville Syrjälä
  2020-09-21 21:01               ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 18:52 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 11:32:48AM -0700, Navare, Manasi wrote:
> On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> > On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > 
> > > > > > 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.
> > > > > > 
> > > > > > v2:
> > > > > > * Manual rebase (Manasi)
> > > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > > 
> > > > > > v3:
> > > > > > * Rebase on drm-tip (Manasi)
> > > > > 
> > > > > Previous review was apparently ignored. Or is there a better version
> > > > > somewhere? If not, this still looks very wrong.
> > > > 
> > > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > > What in particular looks wrong or what review comments were unaddressed here?
> > > 
> > > The dvo/sdvo changes.
> > 
> > I recommend just dropping this patch entirely. It doesn't seem to have
> > anything to do with the bigjoiner anyway.
> 
> So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
> How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
> static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> +					     struct drm_display_mode *user_mode)
> 
> You think we dont need mode as an argument there either?

Not in this patch if all the other stuff disappears. No idea if some
later patch might need something like it.

> 
> Manasi
> > 
> > > 
> > > > 
> > > > @Maarten any feedback on Ville's unaddressed comments?
> > > > 
> > > > Manasi
> > > > 
> > > > > 
> > > > > > 
> > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> > > > > >  .../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, 23 insertions(+), 26 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index 729ec6e0d43a..8652a7c6bf11 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > > > > >  	tmp = intel_de_read(dev_priv, 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,
> > > > > > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> > > > > >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> > > > > >  
> > > > > >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > > > > > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > > > > > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> > > > > >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> > > > > >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> > > > > >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > > > > > @@ -13221,17 +13218,17 @@ 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;
> > > > > >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > > > > > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > > > > > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> > > > > >  
> > > > > >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> > > > > >  
> > > > > > @@ -13277,6 +13274,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;
> > > > > > @@ -13324,7 +13325,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.adjusted_mode,
> > > > > >  			       &pipe_config->pipe_src_w,
> > > > > >  			       &pipe_config->pipe_src_h);
> > > > > >  
> > > > > > @@ -18461,15 +18462,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
> > > > > > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > > > > >  			 */
> > > > > >  			crtc_state->inherited = true;
> > > > > >  
> > > > > > +			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 e8f809161c75..f1e29d9a75d0 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> > > > > >  	u32 temp = intel_de_read(dev_priv, 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);
> > > > > >  
> > > > > >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > > @@ -1223,7 +1223,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;
> > > > > > @@ -1234,9 +1233,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,
> > > > > > @@ -1308,7 +1307,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;
> > > > > > @@ -1324,12 +1322,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)) {
> > > > > > @@ -1339,7 +1337,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);
> > > > > >  	}
> > > > > >  
> > > > > > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > > >  		to_intel_sdvo_connector_state(conn_state);
> > > > > >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> > > > > >  		to_intel_sdvo_connector(conn_state->connector);
> > > > > > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> > > > > >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> > > > > >  	u32 sdvox;
> > > > > >  	struct intel_sdvo_in_out_map in_out;
> > > > > > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > > >  		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(&dev_priv->drm,
> > > > > >  			 "Setting output timings on %s failed\n",
> > > > > > -- 
> > > > > > 2.19.1
> > > > > > 
> > > > > > _______________________________________________
> > > > > > Intel-gfx mailing list
> > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-07 11:20   ` Ville Syrjälä
@ 2020-09-14 19:00     ` Navare, Manasi
  2020-09-14 19:17       ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:00 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> > 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.
> > 
> > v5:
> > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > v4:
> > * Rebase (Manasi)
> > 
> > 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)
> > v3:
> > * Rebase (Manasi)
> > 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> >  2 files changed, 91 insertions(+), 30 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 78cbfefbfa62..3ecb642805a6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> >  	 * too big for that.
> >  	 */
> >  	if (INTEL_GEN(dev_priv) >= 11) {
> > -		plane_width_max = 5120;
> > +		plane_width_max = 7680;
> 
> This looks misplaced. Planes do no know whether bigjoiner can be used or
> not. They should not care in fact. The caller should have that knowledge
> and can deal with it properly.

Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?

Am still not sure where this should happen? We need to have the plane max width to be 7680
before we prune the 8K mode in intel_mode_valid

Where should this be added according to you?

Manasi
> 
> >  		plane_height_max = 4320;
> >  	} else {
> >  		plane_width_max = 5120;
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index d6295eb20b63..fbfea99fd804 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > -	struct intel_encoder *encoder = &dig_port->base;
> > +	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;
> >  
> > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > +		return 2 * dev_priv->max_dotclk_freq;
> > +
> > +	return dev_priv->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;
> >  }
> > @@ -527,7 +539,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;
> > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> >  		    max_bpp_small_joiner_ram);
> >  
> > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > @@ -576,7 +602,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)
> >  {
> >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> >  	u8 min_slice_count, i;
> > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > @@ -648,11 +683,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)
> > @@ -664,6 +703,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);
> >  
> > @@ -691,23 +745,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);
> >  }
> > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> >  				    "Compressed BPP/Slice Count not supported\n");
> > -- 
> > 2.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-03 19:19   ` Ville Syrjälä
@ 2020-09-14 19:14     ` Navare, Manasi
  2020-09-14 19:20       ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:14 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> >  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.
> > 
> > v5:
> > * Rebase after adding sagv support (Manasi)
> > v4:
> > * Manual rebase (Manasi)
> > 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>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> >  .../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  |  20 +-
> >  .../drm/i915/display/intel_display_types.h    |  11 +
> >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> >  6 files changed, 274 insertions(+), 39 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index 79032701873a..5c6e72063fac 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -246,11 +246,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);
> >  
> > +	if (from_plane_state->uapi.crtc)
> > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > +	else
> > +		plane_state->hw.crtc = NULL;
> > +
> >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> 
> eh?

Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
so this should just be:

 if (from_plane_state->uapi.crtc)
	plane_state->hw.crtc = crtc_state->uapi.crtc;
else
	 plane_state->hw.crtc = NULL;

And the reassignmnet of plane_state->hw.crtc should be removed.

Good?

> 
> >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> >  	if (plane_state->hw.fb)
> > @@ -319,15 +325,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;
> >  }
> >  
> > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> >  		intel_atomic_get_new_plane_state(state, plane);
> >  	const struct intel_plane_state *old_plane_state =
> >  		intel_atomic_get_old_plane_state(state, plane);
> > +	const struct intel_plane_state *new_master_plane_state;
> >  	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;
> >  
> > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > +	if (crtc)
> > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > +	else
> > +		new_crtc_state = NULL;
> > +
> > +	new_master_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);
> > +
> >  	new_plane_state->uapi.visible = false;
> >  	if (!crtc)
> >  		return 0;
> >  
> >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> >  
> >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> >  
> >  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 bfc5c890ab4e..6f4a2845674d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> >  	drm_framebuffer_get(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);
> >  
> >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> >  
> > @@ -12582,26 +12582,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.
> 
> Feels like this has become super complicated by mixing up the bigjoiner
> and Y plane cases. Can't we just handle them separately. First deal with
> bigjoiner planes, then let each crtc handle its Y-planes independently?
>

Yea this is a complex algorithm here. But if functionally it looks right
I dont feel comfortable detangling it since originally written by Maarten.

Manasi
 
> > +	 *
> > +	 * 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);
> >  
> > -		drm_WARN_ON(state->base.dev,
> > -			    linked_plane_state->planar_linked_plane != plane);
> > -		drm_WARN_ON(state->base.dev,
> > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > +			if (IS_ERR(linked_crtc_state))
> > +				return PTR_ERR(linked_crtc_state);
> > +		}
> >  	}
> >  
> >  	return 0;
> > @@ -12641,6 +12795,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)))
> > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> >  		       sizeof(linked_state->color_plane));
> >  
> > -		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;
> >  
> > @@ -15028,6 +15190,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) {
> > @@ -15038,6 +15201,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;
> >  
> > @@ -15062,7 +15231,11 @@ 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 "
> > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> >  	new_plane_state->uapi.crtc_w = crtc_w;
> >  	new_plane_state->uapi.crtc_h = crtc_h;
> >  
> > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> >  
> >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> >  						  old_plane_state, new_plane_state);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > index e890c8fb779b..78010ee364f3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -467,12 +467,20 @@ enum phy_fia {
> >  		for_each_if(crtc)
> >  
> >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > -		  plane, 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))))
> > +	plane, iter, plane_state, \
> > +	crtc_state) \
> > +	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 943709f192f7..6957eac140cd 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3150,7 +3150,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 *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;
> > @@ -3160,7 +3160,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)
> > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> >  {
> >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > -	struct intel_plane *plane;
> > +	struct intel_plane *plane, *iter;
> >  	const struct intel_plane_state *plane_state;
> >  	int level, latency;
> >  
> > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> >  		return false;
> >  
> > -	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) {
> >  		const struct skl_plane_wm *wm =
> >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> >  
> > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> >  				 u64 *plane_data_rate,
> >  				 u64 *uv_plane_data_rate)
> >  {
> > -	struct intel_plane *plane;
> > +	struct intel_plane *plane, *iter;
> >  	const struct intel_plane_state *plane_state;
> >  	u64 total_data_rate = 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;
> >  
> > @@ -4741,12 +4741,12 @@ 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;
> >  
> >  	/* 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;
> >  
> > @@ -5593,7 +5593,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;
> >  
> > @@ -5603,7 +5603,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.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-14 19:00     ` Navare, Manasi
@ 2020-09-14 19:17       ` Ville Syrjälä
  2020-09-14 19:38         ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 19:17 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > 
> > > 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.
> > > 
> > > v5:
> > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > v4:
> > > * Rebase (Manasi)
> > > 
> > > 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)
> > > v3:
> > > * Rebase (Manasi)
> > > 
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 78cbfefbfa62..3ecb642805a6 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > >  	 * too big for that.
> > >  	 */
> > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > -		plane_width_max = 5120;
> > > +		plane_width_max = 7680;
> > 
> > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > not. They should not care in fact. The caller should have that knowledge
> > and can deal with it properly.
> 
> Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> 
> Am still not sure where this should happen? We need to have the plane max width to be 7680
> before we prune the 8K mode in intel_mode_valid
> 
> Where should this be added according to you?

Hmm. I guess we do need to put it into this function given the way this
is structured. However we still can't assume bigjoiner can be used since
it can't be used on DDI A on icl. So we should probably just pass in a
bool here to indicate whether bigjoiner can be used or not.

Personally I'd just write the thing as something like:
intel_mode_valid_max_plane_size(..., bool bigjoiner)
{
	...
	plane_width_max = 5120 << bigjoiner;
	...
}

> 
> Manasi
> > 
> > >  		plane_height_max = 4320;
> > >  	} else {
> > >  		plane_width_max = 5120;
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index d6295eb20b63..fbfea99fd804 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > -	struct intel_encoder *encoder = &dig_port->base;
> > > +	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;
> > >  
> > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > +		return 2 * dev_priv->max_dotclk_freq;
> > > +
> > > +	return dev_priv->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;
> > >  }
> > > @@ -527,7 +539,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;
> > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > >  		    max_bpp_small_joiner_ram);
> > >  
> > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > @@ -576,7 +602,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)
> > >  {
> > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > >  	u8 min_slice_count, i;
> > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > @@ -648,11 +683,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)
> > > @@ -664,6 +703,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);
> > >  
> > > @@ -691,23 +745,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);
> > >  }
> > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > >  				    "Compressed BPP/Slice Count not supported\n");
> > > -- 
> > > 2.19.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 19:14     ` Navare, Manasi
@ 2020-09-14 19:20       ` Ville Syrjälä
  2020-09-14 19:27         ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 19:20 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > 
> > >  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.
> > > 
> > > v5:
> > > * Rebase after adding sagv support (Manasi)
> > > v4:
> > > * Manual rebase (Manasi)
> > > 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>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > >  .../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  |  20 +-
> > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > index 79032701873a..5c6e72063fac 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > @@ -246,11 +246,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);
> > >  
> > > +	if (from_plane_state->uapi.crtc)
> > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > +	else
> > > +		plane_state->hw.crtc = NULL;
> > > +
> > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > 
> > eh?
> 
> Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> so this should just be:
> 
>  if (from_plane_state->uapi.crtc)
> 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> else
> 	 plane_state->hw.crtc = NULL;
> 
> And the reassignmnet of plane_state->hw.crtc should be removed.
> 
> Good?

The if-else seems totally pointless.

> 
> > 
> > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > >  	if (plane_state->hw.fb)
> > > @@ -319,15 +325,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;
> > >  }
> > >  
> > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > >  		intel_atomic_get_new_plane_state(state, plane);
> > >  	const struct intel_plane_state *old_plane_state =
> > >  		intel_atomic_get_old_plane_state(state, plane);
> > > +	const struct intel_plane_state *new_master_plane_state;
> > >  	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;
> > >  
> > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > +	if (crtc)
> > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > +	else
> > > +		new_crtc_state = NULL;
> > > +
> > > +	new_master_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);
> > > +
> > >  	new_plane_state->uapi.visible = false;
> > >  	if (!crtc)
> > >  		return 0;
> > >  
> > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > >  
> > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > >  
> > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > >  	drm_framebuffer_get(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);
> > >  
> > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > >  
> > > @@ -12582,26 +12582,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.
> > 
> > Feels like this has become super complicated by mixing up the bigjoiner
> > and Y plane cases. Can't we just handle them separately. First deal with
> > bigjoiner planes, then let each crtc handle its Y-planes independently?
> >
> 
> Yea this is a complex algorithm here. But if functionally it looks right
> I dont feel comfortable detangling it since originally written by Maarten.
> 
> Manasi
>  
> > > +	 *
> > > +	 * 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);
> > >  
> > > -		drm_WARN_ON(state->base.dev,
> > > -			    linked_plane_state->planar_linked_plane != plane);
> > > -		drm_WARN_ON(state->base.dev,
> > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > +			if (IS_ERR(linked_crtc_state))
> > > +				return PTR_ERR(linked_crtc_state);
> > > +		}
> > >  	}
> > >  
> > >  	return 0;
> > > @@ -12641,6 +12795,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)))
> > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > >  		       sizeof(linked_state->color_plane));
> > >  
> > > -		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;
> > >  
> > > @@ -15028,6 +15190,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) {
> > > @@ -15038,6 +15201,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;
> > >  
> > > @@ -15062,7 +15231,11 @@ 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 "
> > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > >  
> > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > >  
> > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > >  						  old_plane_state, new_plane_state);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > index e890c8fb779b..78010ee364f3 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > @@ -467,12 +467,20 @@ enum phy_fia {
> > >  		for_each_if(crtc)
> > >  
> > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > -		  plane, 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))))
> > > +	plane, iter, plane_state, \
> > > +	crtc_state) \
> > > +	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 943709f192f7..6957eac140cd 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3150,7 +3150,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 *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;
> > > @@ -3160,7 +3160,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)
> > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > >  {
> > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > -	struct intel_plane *plane;
> > > +	struct intel_plane *plane, *iter;
> > >  	const struct intel_plane_state *plane_state;
> > >  	int level, latency;
> > >  
> > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > >  		return false;
> > >  
> > > -	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) {
> > >  		const struct skl_plane_wm *wm =
> > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > >  
> > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > >  				 u64 *plane_data_rate,
> > >  				 u64 *uv_plane_data_rate)
> > >  {
> > > -	struct intel_plane *plane;
> > > +	struct intel_plane *plane, *iter;
> > >  	const struct intel_plane_state *plane_state;
> > >  	u64 total_data_rate = 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;
> > >  
> > > @@ -4741,12 +4741,12 @@ 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;
> > >  
> > >  	/* 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;
> > >  
> > > @@ -5593,7 +5593,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;
> > >  
> > > @@ -5603,7 +5603,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.19.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-09-03 19:23   ` Ville Syrjälä
@ 2020-09-14 19:21     ` Navare, Manasi
  2020-09-21 21:18       ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:21 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 10:23:35PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> > 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.
> > 
> > ****This needs to be checked if it still works since lot of refactoring
> > in skl_commit_modeset_enables
> > 
> > v2:
> > * Manual Rebase (Manasi)
> > * Refactoring on intel_update_crtc and enable_crtc and removing
> > special trans_port_sync_update (Manasi)
> > 
> > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
> >  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
> >  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
> >  3 files changed, 129 insertions(+), 19 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index a1011414da6d..00b26863ffc6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> >  	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
> > @@ -15754,6 +15754,52 @@ 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);
> > +
> > +	if (modeset) {
> > +		/* Enable slave first */
> > +		intel_crtc_update_active_timings(new_slave_crtc_state);
> > +		dev_priv->display.crtc_enable(state, slave);
> > +
> > +		/* Then master */
> > +		intel_crtc_update_active_timings(new_crtc_state);
> > +		dev_priv->display.crtc_enable(state, crtc);
> > +
> > +		/* vblanks work again, re-enable pipe CRC. */
> > +		intel_crtc_enable_pipe_crc(crtc);
> > +
> > +	} else {
> > +		intel_pre_plane_update(state, crtc);
> > +		intel_pre_plane_update(state, slave);
> > +
> > +		if (new_crtc_state->update_pipe)
> > +			intel_encoders_update_pipe(state, crtc);
> > +	}
> > +
> > +	/*
> > +	 * 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, crtc);
> > +	commit_pipe_config(state, slave);
> > +
> > +	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);
> > +}
> 
> I think this should ideally all go away and just the normal logic
> in commit_modeset_enables() should deal with it. Just like it does
> for port sync/mst pipe dependencies.
>

Yes I think so too. Except for the intel_pipe_update_end where
now we send the new_slave_crtc_state() so thats still something I need to figure
how it will work in normal code without special bigjoiner handling.

I think the 2p2p transcoder ports sync code initially had a special trans port sync handling
function and thats why this was written this way but with the new code we just use
the regular modeset_enables function with no special handling

Manasi
 
> > +
> >  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> >  {
> >  	struct intel_crtc_state *new_crtc_state;
> > @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> >  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> >  {
> >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > -	struct intel_crtc *crtc;
> > +	struct intel_crtc *crtc, *slave;
> >  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
> >  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> > +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
> >  	u8 update_pipes = 0, modeset_pipes = 0;
> > +	const struct intel_crtc_state *slave_crtc_state;
> >  	int i;
> >  
> >  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> >  		enum pipe pipe = crtc->pipe;
> >  
> > +		if (new_crtc_state->bigjoiner_slave) {
> > +			/* We're updated from master */
> > +			continue;
> > +		}
> > +
> >  		if (!new_crtc_state->hw.active)
> >  			continue;
> >  
> > @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> >  		} else {
> >  			modeset_pipes |= BIT(pipe);
> >  		}
> > +
> > +		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;
> > +		}
> > +
> > +		/* ignore allocations for crtc's that have been turned off during modeset. */
> > +		if (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;
> > +		}
> 
> Why is this here? Can't see why the current code wouldn't work just fine
> for bigjoiner too.
> 
> >  	}
> >  
> >  	/*
> > @@ -15806,28 +15887,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> >  		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> >  						    new_crtc_state, i) {
> >  			enum pipe pipe = crtc->pipe;
> > +			bool ddb_changed;
> >  
> >  			if ((update_pipes & BIT(pipe)) == 0)
> >  				continue;
> >  
> > -			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> > +			if (skl_ddb_allocation_overlaps(&new_entries[pipe],
> >  							entries, I915_MAX_PIPES, pipe))
> >  				continue;
> >  
> > -			entries[pipe] = new_crtc_state->wm.skl.ddb;
> > +			ddb_changed = !skl_ddb_entry_equal(&new_entries[pipe], &entries[pipe]);
> > +			entries[pipe] = new_entries[pipe];
> >  			update_pipes &= ~BIT(pipe);
> >  
> > -			intel_update_crtc(state, crtc);
> > -
> >  			/*
> >  			 * If this is an already active pipe, it's DDB changed,
> >  			 * and this isn't the last pipe that needs updating
> >  			 * 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) &&
> > -			    (update_pipes | modeset_pipes))
> > +			if (new_crtc_state->bigjoiner) {
> > +				intel_update_bigjoiner(crtc, state,
> > +						       old_crtc_state,
> > +						       new_crtc_state);
> > +			} else {
> > +				intel_update_crtc(state, crtc);
> > +			}
> > +
> > +			if (ddb_changed && (update_pipes | modeset_pipes))
> >  				intel_wait_for_vblank(dev_priv, pipe);
> >  		}
> >  	}
> > @@ -15863,9 +15950,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> >  		if ((modeset_pipes & BIT(pipe)) == 0)
> >  			continue;
> >  
> > +		WARN_ON(skl_ddb_allocation_overlaps(&new_entries[pipe],
> > +						    entries, I915_MAX_PIPES, pipe));
> > +
> > +		entries[pipe] = new_entries[pipe];
> >  		modeset_pipes &= ~BIT(pipe);
> >  
> > -		intel_enable_crtc(state, crtc);
> > +		if (new_crtc_state->bigjoiner)
> > +			intel_update_bigjoiner(crtc, state,
> > +					       old_crtc_state,
> > +					       new_crtc_state);
> > +		else
> > +			intel_enable_crtc(state, crtc);
> >  	}
> >  
> >  	/*
> > @@ -15877,10 +15973,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> >  		if ((update_pipes & BIT(pipe)) == 0)
> >  			continue;
> >  
> > -		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> > +		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_entries[pipe],
> >  									entries, I915_MAX_PIPES, pipe));
> >  
> > -		entries[pipe] = new_crtc_state->wm.skl.ddb;
> > +		entries[pipe] = new_entries[pipe];
> >  		update_pipes &= ~BIT(pipe);
> >  
> >  		intel_update_crtc(state, crtc);
> > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > index 60eeed06a780..eaae5df546fe 100644
> > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > @@ -99,6 +99,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;
> >  
> > @@ -191,7 +193,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;
> > @@ -206,16 +209,26 @@ 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) {
> > -		drm_WARN_ON(&dev_priv->drm,
> > -			    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)
> > +			drm_WARN_ON(&dev_priv->drm,
> > +				    drm_crtc_vblank_get(&crtc->base) != 0);
> > +		if (slave_crtc_state && slave_crtc_state->uapi.event)
> > +			drm_WARN_ON(&dev_priv->drm,
> > +				    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 cd2104ba1ca1..15e7c112ec77 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.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 19:20       ` Ville Syrjälä
@ 2020-09-14 19:27         ` Navare, Manasi
  2020-09-14 19:34           ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:27 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 10:20:41PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> > On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > 
> > > >  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.
> > > > 
> > > > v5:
> > > > * Rebase after adding sagv support (Manasi)
> > > > v4:
> > > > * Manual rebase (Manasi)
> > > > 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>
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > ---
> > > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > > >  .../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  |  20 +-
> > > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > index 79032701873a..5c6e72063fac 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > @@ -246,11 +246,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);
> > > >  
> > > > +	if (from_plane_state->uapi.crtc)
> > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > +	else
> > > > +		plane_state->hw.crtc = NULL;
> > > > +
> > > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > 
> > > eh?
> > 
> > Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> > so this should just be:
> > 
> >  if (from_plane_state->uapi.crtc)
> > 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> > else
> > 	 plane_state->hw.crtc = NULL;
> > 
> > And the reassignmnet of plane_state->hw.crtc should be removed.
> > 
> > Good?
> 
> The if-else seems totally pointless.
>

Hmm yes so we assume that if from_plane_state->uapi.crtc is NULL then crtc_state->uapi.crtc is NULL?
Then just have  plane_state->hw.crtc = crtc_state->uapi.crtc; without if-else?

Manasi
 
> > 
> > > 
> > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > >  	if (plane_state->hw.fb)
> > > > @@ -319,15 +325,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;
> > > >  }
> > > >  
> > > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > > >  		intel_atomic_get_new_plane_state(state, plane);
> > > >  	const struct intel_plane_state *old_plane_state =
> > > >  		intel_atomic_get_old_plane_state(state, plane);
> > > > +	const struct intel_plane_state *new_master_plane_state;
> > > >  	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;
> > > >  
> > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > +	if (crtc)
> > > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > +	else
> > > > +		new_crtc_state = NULL;
> > > > +
> > > > +	new_master_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);
> > > > +
> > > >  	new_plane_state->uapi.visible = false;
> > > >  	if (!crtc)
> > > >  		return 0;
> > > >  
> > > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > >  
> > > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > > >  
> > > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > > >  	drm_framebuffer_get(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);
> > > >  
> > > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > > >  
> > > > @@ -12582,26 +12582,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.
> > > 
> > > Feels like this has become super complicated by mixing up the bigjoiner
> > > and Y plane cases. Can't we just handle them separately. First deal with
> > > bigjoiner planes, then let each crtc handle its Y-planes independently?
> > >
> > 
> > Yea this is a complex algorithm here. But if functionally it looks right
> > I dont feel comfortable detangling it since originally written by Maarten.
> > 
> > Manasi
> >  
> > > > +	 *
> > > > +	 * 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);
> > > >  
> > > > -		drm_WARN_ON(state->base.dev,
> > > > -			    linked_plane_state->planar_linked_plane != plane);
> > > > -		drm_WARN_ON(state->base.dev,
> > > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > > +			if (IS_ERR(linked_crtc_state))
> > > > +				return PTR_ERR(linked_crtc_state);
> > > > +		}
> > > >  	}
> > > >  
> > > >  	return 0;
> > > > @@ -12641,6 +12795,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)))
> > > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > > >  		       sizeof(linked_state->color_plane));
> > > >  
> > > > -		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;
> > > >  
> > > > @@ -15028,6 +15190,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) {
> > > > @@ -15038,6 +15201,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;
> > > >  
> > > > @@ -15062,7 +15231,11 @@ 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 "
> > > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > > >  
> > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > > >  
> > > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > > >  						  old_plane_state, new_plane_state);
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > index e890c8fb779b..78010ee364f3 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > @@ -467,12 +467,20 @@ enum phy_fia {
> > > >  		for_each_if(crtc)
> > > >  
> > > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > > -		  plane, 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))))
> > > > +	plane, iter, plane_state, \
> > > > +	crtc_state) \
> > > > +	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 943709f192f7..6957eac140cd 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > @@ -3150,7 +3150,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 *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;
> > > > @@ -3160,7 +3160,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)
> > > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > >  {
> > > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > > -	struct intel_plane *plane;
> > > > +	struct intel_plane *plane, *iter;
> > > >  	const struct intel_plane_state *plane_state;
> > > >  	int level, latency;
> > > >  
> > > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > >  		return false;
> > > >  
> > > > -	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) {
> > > >  		const struct skl_plane_wm *wm =
> > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > >  
> > > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > > >  				 u64 *plane_data_rate,
> > > >  				 u64 *uv_plane_data_rate)
> > > >  {
> > > > -	struct intel_plane *plane;
> > > > +	struct intel_plane *plane, *iter;
> > > >  	const struct intel_plane_state *plane_state;
> > > >  	u64 total_data_rate = 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;
> > > >  
> > > > @@ -4741,12 +4741,12 @@ 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;
> > > >  
> > > >  	/* 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;
> > > >  
> > > > @@ -5593,7 +5593,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;
> > > >  
> > > > @@ -5603,7 +5603,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.19.1
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 19:27         ` Navare, Manasi
@ 2020-09-14 19:34           ` Ville Syrjälä
  2020-09-14 19:45             ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 19:34 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:27:58PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 10:20:41PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> > > On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > > > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > 
> > > > >  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.
> > > > > 
> > > > > v5:
> > > > > * Rebase after adding sagv support (Manasi)
> > > > > v4:
> > > > > * Manual rebase (Manasi)
> > > > > 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>
> > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > ---
> > > > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > > > >  .../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  |  20 +-
> > > > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > > > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > > > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > index 79032701873a..5c6e72063fac 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > @@ -246,11 +246,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);
> > > > >  
> > > > > +	if (from_plane_state->uapi.crtc)
> > > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > +	else
> > > > > +		plane_state->hw.crtc = NULL;
> > > > > +
> > > > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > 
> > > > eh?
> > > 
> > > Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> > > so this should just be:
> > > 
> > >  if (from_plane_state->uapi.crtc)
> > > 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > else
> > > 	 plane_state->hw.crtc = NULL;
> > > 
> > > And the reassignmnet of plane_state->hw.crtc should be removed.
> > > 
> > > Good?
> > 
> > The if-else seems totally pointless.
> >
> 
> Hmm yes so we assume that if from_plane_state->uapi.crtc is NULL then crtc_state->uapi.crtc is NULL?
> Then just have  plane_state->hw.crtc = crtc_state->uapi.crtc; without if-else?

Actually, re-reading this I don't even understand what this code is doing.

> 
> Manasi
>  
> > > 
> > > > 
> > > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > > >  	if (plane_state->hw.fb)
> > > > > @@ -319,15 +325,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;
> > > > >  }
> > > > >  
> > > > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > > > >  		intel_atomic_get_new_plane_state(state, plane);
> > > > >  	const struct intel_plane_state *old_plane_state =
> > > > >  		intel_atomic_get_old_plane_state(state, plane);
> > > > > +	const struct intel_plane_state *new_master_plane_state;
> > > > >  	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;
> > > > >  
> > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > +	if (crtc)
> > > > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > +	else
> > > > > +		new_crtc_state = NULL;
> > > > > +
> > > > > +	new_master_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);
> > > > > +
> > > > >  	new_plane_state->uapi.visible = false;
> > > > >  	if (!crtc)
> > > > >  		return 0;
> > > > >  
> > > > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > >  
> > > > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > > > >  
> > > > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > > > >  	drm_framebuffer_get(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);
> > > > >  
> > > > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > > > >  
> > > > > @@ -12582,26 +12582,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.
> > > > 
> > > > Feels like this has become super complicated by mixing up the bigjoiner
> > > > and Y plane cases. Can't we just handle them separately. First deal with
> > > > bigjoiner planes, then let each crtc handle its Y-planes independently?
> > > >
> > > 
> > > Yea this is a complex algorithm here. But if functionally it looks right
> > > I dont feel comfortable detangling it since originally written by Maarten.
> > > 
> > > Manasi
> > >  
> > > > > +	 *
> > > > > +	 * 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);
> > > > >  
> > > > > -		drm_WARN_ON(state->base.dev,
> > > > > -			    linked_plane_state->planar_linked_plane != plane);
> > > > > -		drm_WARN_ON(state->base.dev,
> > > > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > > > +			if (IS_ERR(linked_crtc_state))
> > > > > +				return PTR_ERR(linked_crtc_state);
> > > > > +		}
> > > > >  	}
> > > > >  
> > > > >  	return 0;
> > > > > @@ -12641,6 +12795,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)))
> > > > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > > > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > > > >  		       sizeof(linked_state->color_plane));
> > > > >  
> > > > > -		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;
> > > > >  
> > > > > @@ -15028,6 +15190,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) {
> > > > > @@ -15038,6 +15201,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;
> > > > >  
> > > > > @@ -15062,7 +15231,11 @@ 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 "
> > > > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > > > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > > > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > > > >  
> > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > > > >  
> > > > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > > > >  						  old_plane_state, new_plane_state);
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > index e890c8fb779b..78010ee364f3 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > @@ -467,12 +467,20 @@ enum phy_fia {
> > > > >  		for_each_if(crtc)
> > > > >  
> > > > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > > > -		  plane, 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))))
> > > > > +	plane, iter, plane_state, \
> > > > > +	crtc_state) \
> > > > > +	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 943709f192f7..6957eac140cd 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > @@ -3150,7 +3150,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 *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;
> > > > > @@ -3160,7 +3160,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)
> > > > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > >  {
> > > > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > > > -	struct intel_plane *plane;
> > > > > +	struct intel_plane *plane, *iter;
> > > > >  	const struct intel_plane_state *plane_state;
> > > > >  	int level, latency;
> > > > >  
> > > > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > >  		return false;
> > > > >  
> > > > > -	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) {
> > > > >  		const struct skl_plane_wm *wm =
> > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > >  
> > > > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > > > >  				 u64 *plane_data_rate,
> > > > >  				 u64 *uv_plane_data_rate)
> > > > >  {
> > > > > -	struct intel_plane *plane;
> > > > > +	struct intel_plane *plane, *iter;
> > > > >  	const struct intel_plane_state *plane_state;
> > > > >  	u64 total_data_rate = 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;
> > > > >  
> > > > > @@ -4741,12 +4741,12 @@ 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;
> > > > >  
> > > > >  	/* 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;
> > > > >  
> > > > > @@ -5593,7 +5593,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;
> > > > >  
> > > > > @@ -5603,7 +5603,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.19.1
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-14 19:17       ` Ville Syrjälä
@ 2020-09-14 19:38         ` Navare, Manasi
  2020-09-14 19:47           ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:38 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > 
> > > > 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.
> > > > 
> > > > v5:
> > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > v4:
> > > > * Rebase (Manasi)
> > > > 
> > > > 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)
> > > > v3:
> > > > * Rebase (Manasi)
> > > > 
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > >  	 * too big for that.
> > > >  	 */
> > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > -		plane_width_max = 5120;
> > > > +		plane_width_max = 7680;
> > > 
> > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > not. They should not care in fact. The caller should have that knowledge
> > > and can deal with it properly.
> > 
> > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > 
> > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > before we prune the 8K mode in intel_mode_valid
> > 
> > Where should this be added according to you?
> 
> Hmm. I guess we do need to put it into this function given the way this
> is structured. However we still can't assume bigjoiner can be used since
> it can't be used on DDI A on icl. So we should probably just pass in a
> bool here to indicate whether bigjoiner can be used or not.
>

So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)

Sounds good?

> Personally I'd just write the thing as something like:
> intel_mode_valid_max_plane_size(..., bool bigjoiner)
> {
> 	...
> 	plane_width_max = 5120 << bigjoiner;
> 	...
> }
> 
> > 
> > Manasi
> > > 
> > > >  		plane_height_max = 4320;
> > > >  	} else {
> > > >  		plane_width_max = 5120;
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > index d6295eb20b63..fbfea99fd804 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > > -	struct intel_encoder *encoder = &dig_port->base;
> > > > +	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;
> > > >  
> > > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > +
> > > > +	return dev_priv->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;
> > > >  }
> > > > @@ -527,7 +539,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;
> > > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > > >  		    max_bpp_small_joiner_ram);
> > > >  
> > > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > > @@ -576,7 +602,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)
> > > >  {
> > > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > > >  	u8 min_slice_count, i;
> > > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > > @@ -648,11 +683,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)
> > > > @@ -664,6 +703,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);
> > > >  
> > > > @@ -691,23 +745,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);
> > > >  }
> > > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > > >  				    "Compressed BPP/Slice Count not supported\n");
> > > > -- 
> > > > 2.19.1
> > > > 
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 19:34           ` Ville Syrjälä
@ 2020-09-14 19:45             ` Navare, Manasi
  2020-09-14 20:05               ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-14 19:45 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 10:34:12PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 12:27:58PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 10:20:41PM +0300, Ville Syrjälä wrote:
> > > On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> > > > On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > > > > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > 
> > > > > >  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.
> > > > > > 
> > > > > > v5:
> > > > > > * Rebase after adding sagv support (Manasi)
> > > > > > v4:
> > > > > > * Manual rebase (Manasi)
> > > > > > 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>
> > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > ---
> > > > > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > > > > >  .../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  |  20 +-
> > > > > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > > > > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > > > > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > index 79032701873a..5c6e72063fac 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > @@ -246,11 +246,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);
> > > > > >  
> > > > > > +	if (from_plane_state->uapi.crtc)
> > > > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > > +	else
> > > > > > +		plane_state->hw.crtc = NULL;
> > > > > > +
> > > > > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > > 
> > > > > eh?
> > > > 
> > > > Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> > > > so this should just be:
> > > > 
> > > >  if (from_plane_state->uapi.crtc)
> > > > 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > else
> > > > 	 plane_state->hw.crtc = NULL;
> > > > 
> > > > And the reassignmnet of plane_state->hw.crtc should be removed.
> > > > 
> > > > Good?
> > > 
> > > The if-else seems totally pointless.
> > >
> > 
> > Hmm yes so we assume that if from_plane_state->uapi.crtc is NULL then crtc_state->uapi.crtc is NULL?
> > Then just have  plane_state->hw.crtc = crtc_state->uapi.crtc; without if-else?
> 
> Actually, re-reading this I don't even understand what this code is doing.
>

My understanding was that here this gets called by: intel_plane_atomic_check() where from_plane_state
comes from the master_plane_state and then we copy this uapi state to hw state for both master and slave planes.

so now if it has a crtc meaning it is the master crtc then we assign 
plane_state->hw.crtc = crtc_state->uapi.crtc; else it means it is a slave crtc and hence hw.crtc would be NULL?

I donno, may be Maarten needs to clarify this.

@Maarten??

Manasi
 
> > 
> > Manasi
> >  
> > > > 
> > > > > 
> > > > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > > > >  	if (plane_state->hw.fb)
> > > > > > @@ -319,15 +325,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;
> > > > > >  }
> > > > > >  
> > > > > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > > > > >  		intel_atomic_get_new_plane_state(state, plane);
> > > > > >  	const struct intel_plane_state *old_plane_state =
> > > > > >  		intel_atomic_get_old_plane_state(state, plane);
> > > > > > +	const struct intel_plane_state *new_master_plane_state;
> > > > > >  	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;
> > > > > >  
> > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > +	if (crtc)
> > > > > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > +	else
> > > > > > +		new_crtc_state = NULL;
> > > > > > +
> > > > > > +	new_master_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);
> > > > > > +
> > > > > >  	new_plane_state->uapi.visible = false;
> > > > > >  	if (!crtc)
> > > > > >  		return 0;
> > > > > >  
> > > > > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > > > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > >  
> > > > > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > > > > >  
> > > > > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > > > > >  	drm_framebuffer_get(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);
> > > > > >  
> > > > > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > > > > >  
> > > > > > @@ -12582,26 +12582,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.
> > > > > 
> > > > > Feels like this has become super complicated by mixing up the bigjoiner
> > > > > and Y plane cases. Can't we just handle them separately. First deal with
> > > > > bigjoiner planes, then let each crtc handle its Y-planes independently?
> > > > >
> > > > 
> > > > Yea this is a complex algorithm here. But if functionally it looks right
> > > > I dont feel comfortable detangling it since originally written by Maarten.
> > > > 
> > > > Manasi
> > > >  
> > > > > > +	 *
> > > > > > +	 * 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);
> > > > > >  
> > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > -			    linked_plane_state->planar_linked_plane != plane);
> > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > > > > +			if (IS_ERR(linked_crtc_state))
> > > > > > +				return PTR_ERR(linked_crtc_state);
> > > > > > +		}
> > > > > >  	}
> > > > > >  
> > > > > >  	return 0;
> > > > > > @@ -12641,6 +12795,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)))
> > > > > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > > > > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > > > > >  		       sizeof(linked_state->color_plane));
> > > > > >  
> > > > > > -		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;
> > > > > >  
> > > > > > @@ -15028,6 +15190,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) {
> > > > > > @@ -15038,6 +15201,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;
> > > > > >  
> > > > > > @@ -15062,7 +15231,11 @@ 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 "
> > > > > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > > > > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > > > > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > > > > >  
> > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > > > > >  
> > > > > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > > > > >  						  old_plane_state, new_plane_state);
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > index e890c8fb779b..78010ee364f3 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > @@ -467,12 +467,20 @@ enum phy_fia {
> > > > > >  		for_each_if(crtc)
> > > > > >  
> > > > > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > > > > -		  plane, 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))))
> > > > > > +	plane, iter, plane_state, \
> > > > > > +	crtc_state) \
> > > > > > +	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 943709f192f7..6957eac140cd 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > > @@ -3150,7 +3150,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 *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;
> > > > > > @@ -3160,7 +3160,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)
> > > > > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > >  {
> > > > > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > > > > -	struct intel_plane *plane;
> > > > > > +	struct intel_plane *plane, *iter;
> > > > > >  	const struct intel_plane_state *plane_state;
> > > > > >  	int level, latency;
> > > > > >  
> > > > > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > > >  		return false;
> > > > > >  
> > > > > > -	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) {
> > > > > >  		const struct skl_plane_wm *wm =
> > > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > > >  
> > > > > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > > > > >  				 u64 *plane_data_rate,
> > > > > >  				 u64 *uv_plane_data_rate)
> > > > > >  {
> > > > > > -	struct intel_plane *plane;
> > > > > > +	struct intel_plane *plane, *iter;
> > > > > >  	const struct intel_plane_state *plane_state;
> > > > > >  	u64 total_data_rate = 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;
> > > > > >  
> > > > > > @@ -4741,12 +4741,12 @@ 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;
> > > > > >  
> > > > > >  	/* 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;
> > > > > >  
> > > > > > @@ -5593,7 +5593,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;
> > > > > >  
> > > > > > @@ -5603,7 +5603,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.19.1
> > > > > > 
> > > > > > _______________________________________________
> > > > > > Intel-gfx mailing list
> > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-14 19:38         ` Navare, Manasi
@ 2020-09-14 19:47           ` Ville Syrjälä
  2020-09-15 23:03             ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 19:47 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:38:57PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > 
> > > > > 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.
> > > > > 
> > > > > v5:
> > > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > > v4:
> > > > > * Rebase (Manasi)
> > > > > 
> > > > > 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)
> > > > > v3:
> > > > > * Rebase (Manasi)
> > > > > 
> > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > >  	 * too big for that.
> > > > >  	 */
> > > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > > -		plane_width_max = 5120;
> > > > > +		plane_width_max = 7680;
> > > > 
> > > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > > not. They should not care in fact. The caller should have that knowledge
> > > > and can deal with it properly.
> > > 
> > > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > > 
> > > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > > before we prune the 8K mode in intel_mode_valid
> > > 
> > > Where should this be added according to you?
> > 
> > Hmm. I guess we do need to put it into this function given the way this
> > is structured. However we still can't assume bigjoiner can be used since
> > it can't be used on DDI A on icl. So we should probably just pass in a
> > bool here to indicate whether bigjoiner can be used or not.
> >
> 
> So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
> I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
> where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
> to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)

can_bigjoiner() {
	return gen >= 12 || (gen==11 && port!=A);
}

or something.

> 
> Sounds good?
> 
> > Personally I'd just write the thing as something like:
> > intel_mode_valid_max_plane_size(..., bool bigjoiner)
> > {
> > 	...
> > 	plane_width_max = 5120 << bigjoiner;
> > 	...
> > }
> > 
> > > 
> > > Manasi
> > > > 
> > > > >  		plane_height_max = 4320;
> > > > >  	} else {
> > > > >  		plane_width_max = 5120;
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > index d6295eb20b63..fbfea99fd804 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > > > -	struct intel_encoder *encoder = &dig_port->base;
> > > > > +	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;
> > > > >  
> > > > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > > +
> > > > > +	return dev_priv->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;
> > > > >  }
> > > > > @@ -527,7 +539,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;
> > > > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > > > >  		    max_bpp_small_joiner_ram);
> > > > >  
> > > > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > > > @@ -576,7 +602,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)
> > > > >  {
> > > > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > > > >  	u8 min_slice_count, i;
> > > > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > > > @@ -648,11 +683,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)
> > > > > @@ -664,6 +703,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);
> > > > >  
> > > > > @@ -691,23 +745,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);
> > > > >  }
> > > > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > > > >  				    "Compressed BPP/Slice Count not supported\n");
> > > > > -- 
> > > > > 2.19.1
> > > > > 
> > > > > _______________________________________________
> > > > > Intel-gfx mailing list
> > > > > Intel-gfx@lists.freedesktop.org
> > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 19:45             ` Navare, Manasi
@ 2020-09-14 20:05               ` Ville Syrjälä
  2020-09-15 22:40                 ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-14 20:05 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:45:59PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 10:34:12PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 14, 2020 at 12:27:58PM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 14, 2020 at 10:20:41PM +0300, Ville Syrjälä wrote:
> > > > On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> > > > > On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > > > > > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > 
> > > > > > >  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.
> > > > > > > 
> > > > > > > v5:
> > > > > > > * Rebase after adding sagv support (Manasi)
> > > > > > > v4:
> > > > > > > * Manual rebase (Manasi)
> > > > > > > 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>
> > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > ---
> > > > > > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > > > > > >  .../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  |  20 +-
> > > > > > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > > > > > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > > > > > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > index 79032701873a..5c6e72063fac 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > @@ -246,11 +246,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);
> > > > > > >  
> > > > > > > +	if (from_plane_state->uapi.crtc)
> > > > > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > > > +	else
> > > > > > > +		plane_state->hw.crtc = NULL;
> > > > > > > +
> > > > > > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > > > 
> > > > > > eh?
> > > > > 
> > > > > Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> > > > > so this should just be:
> > > > > 
> > > > >  if (from_plane_state->uapi.crtc)
> > > > > 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > else
> > > > > 	 plane_state->hw.crtc = NULL;
> > > > > 
> > > > > And the reassignmnet of plane_state->hw.crtc should be removed.
> > > > > 
> > > > > Good?
> > > > 
> > > > The if-else seems totally pointless.
> > > >
> > > 
> > > Hmm yes so we assume that if from_plane_state->uapi.crtc is NULL then crtc_state->uapi.crtc is NULL?
> > > Then just have  plane_state->hw.crtc = crtc_state->uapi.crtc; without if-else?
> > 
> > Actually, re-reading this I don't even understand what this code is doing.
> >
> 
> My understanding was that here this gets called by: intel_plane_atomic_check() where from_plane_state
> comes from the master_plane_state and then we copy this uapi state to hw state for both master and slave planes.
> 
> so now if it has a crtc meaning it is the master crtc then we assign 
> plane_state->hw.crtc = crtc_state->uapi.crtc; else it means it is a slave crtc and hence hw.crtc would be NULL?

Hmm. I guess I understand what it's doing now. Just feels like a
strange way to do it. Might be simpler to leave this part to the
caller. But then we're perhaps going to have to update several callers
which isn't so great either. Not sure. At least it needs a comment
of some sort to explain wtf is going on.

> 
> I donno, may be Maarten needs to clarify this.
> 
> @Maarten??
> 
> Manasi
>  
> > > 
> > > Manasi
> > >  
> > > > > 
> > > > > > 
> > > > > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > > > > >  	if (plane_state->hw.fb)
> > > > > > > @@ -319,15 +325,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;
> > > > > > >  }
> > > > > > >  
> > > > > > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > > > > > >  		intel_atomic_get_new_plane_state(state, plane);
> > > > > > >  	const struct intel_plane_state *old_plane_state =
> > > > > > >  		intel_atomic_get_old_plane_state(state, plane);
> > > > > > > +	const struct intel_plane_state *new_master_plane_state;
> > > > > > >  	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;
> > > > > > >  
> > > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > > +	if (crtc)
> > > > > > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > > +	else
> > > > > > > +		new_crtc_state = NULL;
> > > > > > > +
> > > > > > > +	new_master_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);
> > > > > > > +
> > > > > > >  	new_plane_state->uapi.visible = false;
> > > > > > >  	if (!crtc)
> > > > > > >  		return 0;
> > > > > > >  
> > > > > > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > > > > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > >  
> > > > > > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > > > > > >  
> > > > > > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > > > > > >  	drm_framebuffer_get(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);
> > > > > > >  
> > > > > > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > > > > > >  
> > > > > > > @@ -12582,26 +12582,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.
> > > > > > 
> > > > > > Feels like this has become super complicated by mixing up the bigjoiner
> > > > > > and Y plane cases. Can't we just handle them separately. First deal with
> > > > > > bigjoiner planes, then let each crtc handle its Y-planes independently?
> > > > > >
> > > > > 
> > > > > Yea this is a complex algorithm here. But if functionally it looks right
> > > > > I dont feel comfortable detangling it since originally written by Maarten.
> > > > > 
> > > > > Manasi
> > > > >  
> > > > > > > +	 *
> > > > > > > +	 * 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);
> > > > > > >  
> > > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > > -			    linked_plane_state->planar_linked_plane != plane);
> > > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > > > > > +			if (IS_ERR(linked_crtc_state))
> > > > > > > +				return PTR_ERR(linked_crtc_state);
> > > > > > > +		}
> > > > > > >  	}
> > > > > > >  
> > > > > > >  	return 0;
> > > > > > > @@ -12641,6 +12795,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)))
> > > > > > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > > > > > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > > > > > >  		       sizeof(linked_state->color_plane));
> > > > > > >  
> > > > > > > -		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;
> > > > > > >  
> > > > > > > @@ -15028,6 +15190,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) {
> > > > > > > @@ -15038,6 +15201,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;
> > > > > > >  
> > > > > > > @@ -15062,7 +15231,11 @@ 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 "
> > > > > > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > > > > > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > > > > > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > > > > > >  
> > > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > > > > > >  
> > > > > > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > > > > > >  						  old_plane_state, new_plane_state);
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > index e890c8fb779b..78010ee364f3 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > @@ -467,12 +467,20 @@ enum phy_fia {
> > > > > > >  		for_each_if(crtc)
> > > > > > >  
> > > > > > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > > > > > -		  plane, 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))))
> > > > > > > +	plane, iter, plane_state, \
> > > > > > > +	crtc_state) \
> > > > > > > +	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 943709f192f7..6957eac140cd 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > > > @@ -3150,7 +3150,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 *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;
> > > > > > > @@ -3160,7 +3160,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)
> > > > > > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > > >  {
> > > > > > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > > > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > > > > > -	struct intel_plane *plane;
> > > > > > > +	struct intel_plane *plane, *iter;
> > > > > > >  	const struct intel_plane_state *plane_state;
> > > > > > >  	int level, latency;
> > > > > > >  
> > > > > > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > >  		return false;
> > > > > > >  
> > > > > > > -	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) {
> > > > > > >  		const struct skl_plane_wm *wm =
> > > > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > > > >  
> > > > > > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > > > > > >  				 u64 *plane_data_rate,
> > > > > > >  				 u64 *uv_plane_data_rate)
> > > > > > >  {
> > > > > > > -	struct intel_plane *plane;
> > > > > > > +	struct intel_plane *plane, *iter;
> > > > > > >  	const struct intel_plane_state *plane_state;
> > > > > > >  	u64 total_data_rate = 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;
> > > > > > >  
> > > > > > > @@ -4741,12 +4741,12 @@ 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;
> > > > > > >  
> > > > > > >  	/* 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;
> > > > > > >  
> > > > > > > @@ -5593,7 +5593,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;
> > > > > > >  
> > > > > > > @@ -5603,7 +5603,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.19.1
> > > > > > > 
> > > > > > > _______________________________________________
> > > > > > > Intel-gfx mailing list
> > > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > > 
> > > > > > -- 
> > > > > > Ville Syrjälä
> > > > > > Intel
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-09-14 20:05               ` Ville Syrjälä
@ 2020-09-15 22:40                 ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-09-15 22:40 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 11:05:42PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 12:45:59PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 10:34:12PM +0300, Ville Syrjälä wrote:
> > > On Mon, Sep 14, 2020 at 12:27:58PM -0700, Navare, Manasi wrote:
> > > > On Mon, Sep 14, 2020 at 10:20:41PM +0300, Ville Syrjälä wrote:
> > > > > On Mon, Sep 14, 2020 at 12:14:10PM -0700, Navare, Manasi wrote:
> > > > > > On Thu, Sep 03, 2020 at 10:19:45PM +0300, Ville Syrjälä wrote:
> > > > > > > On Wed, Jul 15, 2020 at 03:42:19PM -0700, Manasi Navare wrote:
> > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > 
> > > > > > > >  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.
> > > > > > > > 
> > > > > > > > v5:
> > > > > > > > * Rebase after adding sagv support (Manasi)
> > > > > > > > v4:
> > > > > > > > * Manual rebase (Manasi)
> > > > > > > > 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>
> > > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > > ---
> > > > > > > >  .../gpu/drm/i915/display/intel_atomic_plane.c |  52 ++++-
> > > > > > > >  .../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  |  20 +-
> > > > > > > >  .../drm/i915/display/intel_display_types.h    |  11 +
> > > > > > > >  drivers/gpu/drm/i915/intel_pm.c               |  20 +-
> > > > > > > >  6 files changed, 274 insertions(+), 39 deletions(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > > index 79032701873a..5c6e72063fac 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > > > > @@ -246,11 +246,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);
> > > > > > > >  
> > > > > > > > +	if (from_plane_state->uapi.crtc)
> > > > > > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > > > > +	else
> > > > > > > > +		plane_state->hw.crtc = NULL;
> > > > > > > > +
> > > > > > > >  	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > > > > 
> > > > > > > eh?
> > > > > > 
> > > > > > Hmm good catch here, this one definitely looks fishy probably got messed up in the rebase
> > > > > > so this should just be:
> > > > > > 
> > > > > >  if (from_plane_state->uapi.crtc)
> > > > > > 	plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > > else
> > > > > > 	 plane_state->hw.crtc = NULL;
> > > > > > 
> > > > > > And the reassignmnet of plane_state->hw.crtc should be removed.
> > > > > > 
> > > > > > Good?
> > > > > 
> > > > > The if-else seems totally pointless.
> > > > >
> > > > 
> > > > Hmm yes so we assume that if from_plane_state->uapi.crtc is NULL then crtc_state->uapi.crtc is NULL?
> > > > Then just have  plane_state->hw.crtc = crtc_state->uapi.crtc; without if-else?
> > > 
> > > Actually, re-reading this I don't even understand what this code is doing.
> > >
> > 
> > My understanding was that here this gets called by: intel_plane_atomic_check() where from_plane_state
> > comes from the master_plane_state and then we copy this uapi state to hw state for both master and slave planes.
> > 
> > so now if it has a crtc meaning it is the master crtc then we assign 
> > plane_state->hw.crtc = crtc_state->uapi.crtc; else it means it is a slave crtc and hence hw.crtc would be NULL?
> 
> Hmm. I guess I understand what it's doing now. Just feels like a
> strange way to do it. Might be simpler to leave this part to the
> caller. But then we're perhaps going to have to update several callers
> which isn't so great either. Not sure. At least it needs a comment
> of some sort to explain wtf is going on.
>

So will my above explanation suffice in the comment?

Manasi
 
> > 
> > I donno, may be Maarten needs to clarify this.
> > 
> > @Maarten??
> > 
> > Manasi
> >  
> > > > 
> > > > Manasi
> > > >  
> > > > > > 
> > > > > > > 
> > > > > > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > > > > > >  	if (plane_state->hw.fb)
> > > > > > > > @@ -319,15 +325,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;
> > > > > > > >  }
> > > > > > > >  
> > > > > > > > @@ -338,18 +365,33 @@ int intel_plane_atomic_check(struct intel_atomic_state *state,
> > > > > > > >  		intel_atomic_get_new_plane_state(state, plane);
> > > > > > > >  	const struct intel_plane_state *old_plane_state =
> > > > > > > >  		intel_atomic_get_old_plane_state(state, plane);
> > > > > > > > +	const struct intel_plane_state *new_master_plane_state;
> > > > > > > >  	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;
> > > > > > > >  
> > > > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > > > +	if (crtc)
> > > > > > > > +		new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > > > +	else
> > > > > > > > +		new_crtc_state = NULL;
> > > > > > > > +
> > > > > > > > +	new_master_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);
> > > > > > > > +
> > > > > > > >  	new_plane_state->uapi.visible = false;
> > > > > > > >  	if (!crtc)
> > > > > > > >  		return 0;
> > > > > > > >  
> > > > > > > >  	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> > > > > > > > -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > > > > > > >  
> > > > > > > >  	return intel_plane_atomic_check_with_state(old_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 59dd1fbb02ea..c2a1e7c86e6c 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> > > > > > > > @@ -23,7 +23,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
> > > > > > > >  
> > > > > > > >  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 bfc5c890ab4e..6f4a2845674d 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > @@ -3693,7 +3693,7 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
> > > > > > > >  	drm_framebuffer_get(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);
> > > > > > > >  
> > > > > > > >  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
> > > > > > > >  
> > > > > > > > @@ -12582,26 +12582,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.
> > > > > > > 
> > > > > > > Feels like this has become super complicated by mixing up the bigjoiner
> > > > > > > and Y plane cases. Can't we just handle them separately. First deal with
> > > > > > > bigjoiner planes, then let each crtc handle its Y-planes independently?
> > > > > > >
> > > > > > 
> > > > > > Yea this is a complex algorithm here. But if functionally it looks right
> > > > > > I dont feel comfortable detangling it since originally written by Maarten.
> > > > > > 
> > > > > > Manasi
> > > > > >  
> > > > > > > > +	 *
> > > > > > > > +	 * 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);
> > > > > > > >  
> > > > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > > > -			    linked_plane_state->planar_linked_plane != plane);
> > > > > > > > -		drm_WARN_ON(state->base.dev,
> > > > > > > > -			    linked_plane_state->planar_slave == plane_state->planar_slave);
> > > > > > > > +			if (IS_ERR(linked_crtc_state))
> > > > > > > > +				return PTR_ERR(linked_crtc_state);
> > > > > > > > +		}
> > > > > > > >  	}
> > > > > > > >  
> > > > > > > >  	return 0;
> > > > > > > > @@ -12641,6 +12795,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)))
> > > > > > > > @@ -12684,7 +12839,14 @@ static int icl_check_nv12_planes(struct intel_crtc_state *crtc_state)
> > > > > > > >  		memcpy(linked_state->color_plane, plane_state->color_plane,
> > > > > > > >  		       sizeof(linked_state->color_plane));
> > > > > > > >  
> > > > > > > > -		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;
> > > > > > > >  
> > > > > > > > @@ -15028,6 +15190,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) {
> > > > > > > > @@ -15038,6 +15201,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;
> > > > > > > >  
> > > > > > > > @@ -15062,7 +15231,11 @@ 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 "
> > > > > > > > @@ -16531,7 +16704,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
> > > > > > > >  	new_plane_state->uapi.crtc_w = crtc_w;
> > > > > > > >  	new_plane_state->uapi.crtc_h = crtc_h;
> > > > > > > >  
> > > > > > > > -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> > > > > > > > +	intel_plane_copy_uapi_to_hw_state(new_crtc_state, new_plane_state, new_plane_state);
> > > > > > > >  
> > > > > > > >  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
> > > > > > > >  						  old_plane_state, new_plane_state);
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > > index e890c8fb779b..78010ee364f3 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > > > > @@ -467,12 +467,20 @@ enum phy_fia {
> > > > > > > >  		for_each_if(crtc)
> > > > > > > >  
> > > > > > > >  #define intel_atomic_crtc_state_for_each_plane_state( \
> > > > > > > > -		  plane, 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))))
> > > > > > > > +	plane, iter, plane_state, \
> > > > > > > > +	crtc_state) \
> > > > > > > > +	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 943709f192f7..6957eac140cd 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > > @@ -575,6 +575,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 d1263ebd3811..a3e3ac429fd4 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > > > > @@ -3150,7 +3150,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 *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;
> > > > > > > > @@ -3160,7 +3160,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)
> > > > > > > > @@ -3879,7 +3879,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > > > >  {
> > > > > > > >  	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > > > > > >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > > > > > > > -	struct intel_plane *plane;
> > > > > > > > +	struct intel_plane *plane, *iter;
> > > > > > > >  	const struct intel_plane_state *plane_state;
> > > > > > > >  	int level, latency;
> > > > > > > >  
> > > > > > > > @@ -3892,7 +3892,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
> > > > > > > >  	if (crtc_state->hw.pipe_mode.flags & DRM_MODE_FLAG_INTERLACE)
> > > > > > > >  		return false;
> > > > > > > >  
> > > > > > > > -	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) {
> > > > > > > >  		const struct skl_plane_wm *wm =
> > > > > > > >  			&crtc_state->wm.skl.optimal.planes[plane->id];
> > > > > > > >  
> > > > > > > > @@ -4714,12 +4714,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *crtc_state,
> > > > > > > >  				 u64 *plane_data_rate,
> > > > > > > >  				 u64 *uv_plane_data_rate)
> > > > > > > >  {
> > > > > > > > -	struct intel_plane *plane;
> > > > > > > > +	struct intel_plane *plane, *iter;
> > > > > > > >  	const struct intel_plane_state *plane_state;
> > > > > > > >  	u64 total_data_rate = 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;
> > > > > > > >  
> > > > > > > > @@ -4741,12 +4741,12 @@ 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;
> > > > > > > >  
> > > > > > > >  	/* 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;
> > > > > > > >  
> > > > > > > > @@ -5593,7 +5593,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;
> > > > > > > >  
> > > > > > > > @@ -5603,7 +5603,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.19.1
> > > > > > > > 
> > > > > > > > _______________________________________________
> > > > > > > > Intel-gfx mailing list
> > > > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > > > 
> > > > > > > -- 
> > > > > > > Ville Syrjälä
> > > > > > > Intel
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-14 19:47           ` Ville Syrjälä
@ 2020-09-15 23:03             ` Navare, Manasi
  2020-09-17 12:20               ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-15 23:03 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 10:47:56PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 12:38:57PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> > > On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > > > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > 
> > > > > > 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.
> > > > > > 
> > > > > > v5:
> > > > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > > > v4:
> > > > > > * Rebase (Manasi)
> > > > > > 
> > > > > > 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)
> > > > > > v3:
> > > > > > * Rebase (Manasi)
> > > > > > 
> > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > > >  	 * too big for that.
> > > > > >  	 */
> > > > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > > > -		plane_width_max = 5120;
> > > > > > +		plane_width_max = 7680;
> > > > > 
> > > > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > > > not. They should not care in fact. The caller should have that knowledge
> > > > > and can deal with it properly.
> > > > 
> > > > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > > > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > > > 
> > > > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > > > before we prune the 8K mode in intel_mode_valid
> > > > 
> > > > Where should this be added according to you?
> > > 
> > > Hmm. I guess we do need to put it into this function given the way this
> > > is structured. However we still can't assume bigjoiner can be used since
> > > it can't be used on DDI A on icl. So we should probably just pass in a
> > > bool here to indicate whether bigjoiner can be used or not.
> > >
> > 
> > So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
> > I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
> > where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
> > to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)
> 
> can_bigjoiner() {
> 	return gen >= 12 || (gen==11 && port!=A);
> }

Hmm, gen check can be done but can the port check be done in intel_dp_mode_valid() since we dont have
an encoder yet?
Else we set the bigjoiner to true here based on gen check but add the port check later in compute_config at
what point if not supported then encoder config will fail.

or can this be sufficient check:

can_bigjoiner() {
	return gen >= 12 || (gen == 11 && !intel_dp_is_edp())
}

Manasi

> 
> or something.
> 
> > 
> > Sounds good?
> > 
> > > Personally I'd just write the thing as something like:
> > > intel_mode_valid_max_plane_size(..., bool bigjoiner)
> > > {
> > > 	...
> > > 	plane_width_max = 5120 << bigjoiner;
> > > 	...
> > > }
> > > 
> > > > 
> > > > Manasi
> > > > > 
> > > > > >  		plane_height_max = 4320;
> > > > > >  	} else {
> > > > > >  		plane_width_max = 5120;
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > index d6295eb20b63..fbfea99fd804 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > > > > -	struct intel_encoder *encoder = &dig_port->base;
> > > > > > +	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;
> > > > > >  
> > > > > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > > > +
> > > > > > +	return dev_priv->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;
> > > > > >  }
> > > > > > @@ -527,7 +539,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;
> > > > > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > > > > >  		    max_bpp_small_joiner_ram);
> > > > > >  
> > > > > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > > > > @@ -576,7 +602,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)
> > > > > >  {
> > > > > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > > > > >  	u8 min_slice_count, i;
> > > > > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > > > > @@ -648,11 +683,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)
> > > > > > @@ -664,6 +703,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);
> > > > > >  
> > > > > > @@ -691,23 +745,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);
> > > > > >  }
> > > > > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > > > > >  				    "Compressed BPP/Slice Count not supported\n");
> > > > > > -- 
> > > > > > 2.19.1
> > > > > > 
> > > > > > _______________________________________________
> > > > > > Intel-gfx mailing list
> > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-15 23:03             ` Navare, Manasi
@ 2020-09-17 12:20               ` Ville Syrjälä
  2020-09-23  5:46                 ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-17 12:20 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Tue, Sep 15, 2020 at 04:03:45PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 10:47:56PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 14, 2020 at 12:38:57PM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> > > > On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > > > > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > > > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > 
> > > > > > > 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.
> > > > > > > 
> > > > > > > v5:
> > > > > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > > > > v4:
> > > > > > > * Rebase (Manasi)
> > > > > > > 
> > > > > > > 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)
> > > > > > > v3:
> > > > > > > * Rebase (Manasi)
> > > > > > > 
> > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > > > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > > > >  	 * too big for that.
> > > > > > >  	 */
> > > > > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > > > > -		plane_width_max = 5120;
> > > > > > > +		plane_width_max = 7680;
> > > > > > 
> > > > > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > > > > not. They should not care in fact. The caller should have that knowledge
> > > > > > and can deal with it properly.
> > > > > 
> > > > > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > > > > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > > > > 
> > > > > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > > > > before we prune the 8K mode in intel_mode_valid
> > > > > 
> > > > > Where should this be added according to you?
> > > > 
> > > > Hmm. I guess we do need to put it into this function given the way this
> > > > is structured. However we still can't assume bigjoiner can be used since
> > > > it can't be used on DDI A on icl. So we should probably just pass in a
> > > > bool here to indicate whether bigjoiner can be used or not.
> > > >
> > > 
> > > So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
> > > I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
> > > where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
> > > to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)
> > 
> > can_bigjoiner() {
> > 	return gen >= 12 || (gen==11 && port!=A);
> > }
> 
> Hmm, gen check can be done but can the port check be done in intel_dp_mode_valid() since we dont have
> an encoder yet?

The encoder is there already.

> Else we set the bigjoiner to true here based on gen check but add the port check later in compute_config at
> what point if not supported then encoder config will fail.
> 
> or can this be sufficient check:
> 
> can_bigjoiner() {
> 	return gen >= 12 || (gen == 11 && !intel_dp_is_edp())
> }
> 
> Manasi
> 
> > 
> > or something.
> > 
> > > 
> > > Sounds good?
> > > 
> > > > Personally I'd just write the thing as something like:
> > > > intel_mode_valid_max_plane_size(..., bool bigjoiner)
> > > > {
> > > > 	...
> > > > 	plane_width_max = 5120 << bigjoiner;
> > > > 	...
> > > > }
> > > > 
> > > > > 
> > > > > Manasi
> > > > > > 
> > > > > > >  		plane_height_max = 4320;
> > > > > > >  	} else {
> > > > > > >  		plane_width_max = 5120;
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > index d6295eb20b63..fbfea99fd804 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > > > > > -	struct intel_encoder *encoder = &dig_port->base;
> > > > > > > +	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;
> > > > > > >  
> > > > > > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > > > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > > > > +
> > > > > > > +	return dev_priv->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;
> > > > > > >  }
> > > > > > > @@ -527,7 +539,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;
> > > > > > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > > > > > >  		    max_bpp_small_joiner_ram);
> > > > > > >  
> > > > > > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > > > > > @@ -576,7 +602,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)
> > > > > > >  {
> > > > > > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > > > > > >  	u8 min_slice_count, i;
> > > > > > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > > > > > @@ -648,11 +683,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)
> > > > > > > @@ -664,6 +703,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);
> > > > > > >  
> > > > > > > @@ -691,23 +745,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);
> > > > > > >  }
> > > > > > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > > > > > >  				    "Compressed BPP/Slice Count not supported\n");
> > > > > > > -- 
> > > > > > > 2.19.1
> > > > > > > 
> > > > > > > _______________________________________________
> > > > > > > Intel-gfx mailing list
> > > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > > 
> > > > > > -- 
> > > > > > Ville Syrjälä
> > > > > > Intel
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > 
> > -- 
> > Ville Syrjälä
> > Intel

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-14 18:52             ` Ville Syrjälä
@ 2020-09-21 21:01               ` Navare, Manasi
  2020-09-22 10:19                 ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-21 21:01 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 09:52:57PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 14, 2020 at 11:32:48AM -0700, Navare, Manasi wrote:
> > On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> > > On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > > > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > 
> > > > > > > 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.
> > > > > > > 
> > > > > > > v2:
> > > > > > > * Manual rebase (Manasi)
> > > > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > > > 
> > > > > > > v3:
> > > > > > > * Rebase on drm-tip (Manasi)
> > > > > > 
> > > > > > Previous review was apparently ignored. Or is there a better version
> > > > > > somewhere? If not, this still looks very wrong.
> > > > > 
> > > > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > > > What in particular looks wrong or what review comments were unaddressed here?
> > > > 
> > > > The dvo/sdvo changes.
> > > 
> > > I recommend just dropping this patch entirely. It doesn't seem to have
> > > anything to do with the bigjoiner anyway.
> > 
> > So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
> > How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
> > static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> > +					     struct drm_display_mode *user_mode)
> > 
> > You think we dont need mode as an argument there either?
> 
> Not in this patch if all the other stuff disappears. No idea if some
> later patch might need something like it.

Hi Ville,

So this patch basically removes the hw.mode and just keeps hw.adjusted_mode
So no need to remove that? 
But basically from this patch onwards we say that there is hw.pipe_mode
and hw.adjusted_mode, there is no hw.mode.
Are you suggesting keeping hw.mode as well? Would this be replacing hw.pipe_mode then?

Manasi

> 
> > 
> > Manasi
> > > 
> > > > 
> > > > > 
> > > > > @Maarten any feedback on Ville's unaddressed comments?
> > > > > 
> > > > > Manasi
> > > > > 
> > > > > > 
> > > > > > > 
> > > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > ---
> > > > > > >  drivers/gpu/drm/i915/display/intel_display.c  | 29 ++++++++++---------
> > > > > > >  .../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, 23 insertions(+), 26 deletions(-)
> > > > > > > 
> > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > index 729ec6e0d43a..8652a7c6bf11 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > @@ -8892,9 +8892,6 @@ static void intel_get_pipe_src_size(struct intel_crtc *crtc,
> > > > > > >  	tmp = intel_de_read(dev_priv, 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,
> > > > > > > @@ -13079,7 +13076,7 @@ static void intel_dump_pipe_config(const struct intel_crtc_state *pipe_config,
> > > > > > >  		intel_dump_dp_vsc_sdp(dev_priv, &pipe_config->infoframes.vsc);
> > > > > > >  
> > > > > > >  	drm_dbg_kms(&dev_priv->drm, "requested mode:\n");
> > > > > > > -	drm_mode_debug_printmodeline(&pipe_config->hw.mode);
> > > > > > > +	drm_mode_debug_printmodeline(&pipe_config->uapi.mode);
> > > > > > >  	drm_dbg_kms(&dev_priv->drm, "adjusted mode:\n");
> > > > > > >  	drm_mode_debug_printmodeline(&pipe_config->hw.adjusted_mode);
> > > > > > >  	intel_dump_crtc_timings(dev_priv, &pipe_config->hw.adjusted_mode);
> > > > > > > @@ -13221,17 +13218,17 @@ 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;
> > > > > > >  	drm_WARN_ON(crtc_state->uapi.crtc->dev,
> > > > > > > -		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, &crtc_state->hw.mode) < 0);
> > > > > > > +		    drm_atomic_set_mode_for_crtc(&crtc_state->uapi, user_mode) < 0);
> > > > > > >  
> > > > > > >  	crtc_state->uapi.adjusted_mode = crtc_state->hw.adjusted_mode;
> > > > > > >  
> > > > > > > @@ -13277,6 +13274,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;
> > > > > > > @@ -13324,7 +13325,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.adjusted_mode,
> > > > > > >  			       &pipe_config->pipe_src_w,
> > > > > > >  			       &pipe_config->pipe_src_h);
> > > > > > >  
> > > > > > > @@ -18461,15 +18462,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
> > > > > > > @@ -18481,11 +18478,15 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > > > > > >  			 */
> > > > > > >  			crtc_state->inherited = true;
> > > > > > >  
> > > > > > > +			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 e8f809161c75..f1e29d9a75d0 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > > > @@ -807,7 +807,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 307ed8ae9a19..0b9bf1fec0f4 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dvo.c
> > > > > > > @@ -209,7 +209,7 @@ static void intel_enable_dvo(struct intel_atomic_state *state,
> > > > > > >  	u32 temp = intel_de_read(dev_priv, 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);
> > > > > > >  
> > > > > > >  	intel_de_write(dev_priv, 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 2da4388e1540..8b78ae0c39a0 100644
> > > > > > > --- a/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c
> > > > > > > @@ -1223,7 +1223,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;
> > > > > > > @@ -1234,9 +1233,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,
> > > > > > > @@ -1308,7 +1307,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;
> > > > > > > @@ -1324,12 +1322,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)) {
> > > > > > > @@ -1339,7 +1337,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);
> > > > > > >  	}
> > > > > > >  
> > > > > > > @@ -1458,7 +1455,6 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > > > >  		to_intel_sdvo_connector_state(conn_state);
> > > > > > >  	const struct intel_sdvo_connector *intel_sdvo_connector =
> > > > > > >  		to_intel_sdvo_connector(conn_state->connector);
> > > > > > > -	const struct drm_display_mode *mode = &crtc_state->hw.mode;
> > > > > > >  	struct intel_sdvo *intel_sdvo = to_sdvo(intel_encoder);
> > > > > > >  	u32 sdvox;
> > > > > > >  	struct intel_sdvo_in_out_map in_out;
> > > > > > > @@ -1491,7 +1487,7 @@ static void intel_sdvo_pre_enable(struct intel_atomic_state *state,
> > > > > > >  		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(&dev_priv->drm,
> > > > > > >  			 "Setting output timings on %s failed\n",
> > > > > > > -- 
> > > > > > > 2.19.1
> > > > > > > 
> > > > > > > _______________________________________________
> > > > > > > Intel-gfx mailing list
> > > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > > 
> > > > > > -- 
> > > > > > Ville Syrjälä
> > > > > > Intel
> > > > 
> > > > -- 
> > > > Ville Syrjälä
> > > > Intel
> > > > _______________________________________________
> > > > Intel-gfx mailing list
> > > > Intel-gfx@lists.freedesktop.org
> > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-09-14 19:21     ` Navare, Manasi
@ 2020-09-21 21:18       ` Navare, Manasi
  2020-09-22 10:27         ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-21 21:18 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Sep 14, 2020 at 12:21:26PM -0700, Navare, Manasi wrote:
> On Thu, Sep 03, 2020 at 10:23:35PM +0300, Ville Syrjälä wrote:
> > On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > 
> > > 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.
> > > 
> > > ****This needs to be checked if it still works since lot of refactoring
> > > in skl_commit_modeset_enables
> > > 
> > > v2:
> > > * Manual Rebase (Manasi)
> > > * Refactoring on intel_update_crtc and enable_crtc and removing
> > > special trans_port_sync_update (Manasi)
> > > 
> > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
> > >  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
> > >  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
> > >  3 files changed, 129 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index a1011414da6d..00b26863ffc6 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> > >  	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
> > > @@ -15754,6 +15754,52 @@ 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);
> > > +
> > > +	if (modeset) {
> > > +		/* Enable slave first */
> > > +		intel_crtc_update_active_timings(new_slave_crtc_state);
> > > +		dev_priv->display.crtc_enable(state, slave);
> > > +
> > > +		/* Then master */
> > > +		intel_crtc_update_active_timings(new_crtc_state);
> > > +		dev_priv->display.crtc_enable(state, crtc);
> > > +
> > > +		/* vblanks work again, re-enable pipe CRC. */
> > > +		intel_crtc_enable_pipe_crc(crtc);
> > > +
> > > +	} else {
> > > +		intel_pre_plane_update(state, crtc);
> > > +		intel_pre_plane_update(state, slave);
> > > +
> > > +		if (new_crtc_state->update_pipe)
> > > +			intel_encoders_update_pipe(state, crtc);
> > > +	}
> > > +
> > > +	/*
> > > +	 * 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, crtc);
> > > +	commit_pipe_config(state, slave);
> > > +
> > > +	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);
> > > +}
> > 
> > I think this should ideally all go away and just the normal logic
> > in commit_modeset_enables() should deal with it. Just like it does
> > for port sync/mst pipe dependencies.
> >
> 
> Yes I think so too. Except for the intel_pipe_update_end where
> now we send the new_slave_crtc_state() so thats still something I need to figure
> how it will work in normal code without special bigjoiner handling.
> 
> I think the 2p2p transcoder ports sync code initially had a special trans port sync handling
> function and thats why this was written this way but with the new code we just use
> the regular modeset_enables function with no special handling
> 
> Manasi
>  
> > > +
> > >  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > >  {
> > >  	struct intel_crtc_state *new_crtc_state;
> > > @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > >  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > >  {
> > >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > > -	struct intel_crtc *crtc;
> > > +	struct intel_crtc *crtc, *slave;
> > >  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
> > >  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> > > +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
> > >  	u8 update_pipes = 0, modeset_pipes = 0;
> > > +	const struct intel_crtc_state *slave_crtc_state;
> > >  	int i;
> > >  
> > >  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> > >  		enum pipe pipe = crtc->pipe;
> > >  
> > > +		if (new_crtc_state->bigjoiner_slave) {
> > > +			/* We're updated from master */
> > > +			continue;
> > > +		}
> > > +
> > >  		if (!new_crtc_state->hw.active)
> > >  			continue;
> > >  
> > > @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > >  		} else {
> > >  			modeset_pipes |= BIT(pipe);
> > >  		}
> > > +
> > > +		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;
> > > +		}
> > > +
> > > +		/* ignore allocations for crtc's that have been turned off during modeset. */
> > > +		if (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;
> > > +		}
> > 
> > Why is this here? Can't see why the current code wouldn't work just fine
> > for bigjoiner too.
> >

Ville, could you provide inputs on how intel_pipe_update_end() should change so that we can use
the current code, now this takes an additional input new_slave_crtc_state

Manasi
 
> > >  	}
> > >  
> > >  	/*
> > > @@ -15806,28 +15887,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > >  		for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> > >  						    new_crtc_state, i) {
> > >  			enum pipe pipe = crtc->pipe;
> > > +			bool ddb_changed;
> > >  
> > >  			if ((update_pipes & BIT(pipe)) == 0)
> > >  				continue;
> > >  
> > > -			if (skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> > > +			if (skl_ddb_allocation_overlaps(&new_entries[pipe],
> > >  							entries, I915_MAX_PIPES, pipe))
> > >  				continue;
> > >  
> > > -			entries[pipe] = new_crtc_state->wm.skl.ddb;
> > > +			ddb_changed = !skl_ddb_entry_equal(&new_entries[pipe], &entries[pipe]);
> > > +			entries[pipe] = new_entries[pipe];
> > >  			update_pipes &= ~BIT(pipe);
> > >  
> > > -			intel_update_crtc(state, crtc);
> > > -
> > >  			/*
> > >  			 * If this is an already active pipe, it's DDB changed,
> > >  			 * and this isn't the last pipe that needs updating
> > >  			 * 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) &&
> > > -			    (update_pipes | modeset_pipes))
> > > +			if (new_crtc_state->bigjoiner) {
> > > +				intel_update_bigjoiner(crtc, state,
> > > +						       old_crtc_state,
> > > +						       new_crtc_state);
> > > +			} else {
> > > +				intel_update_crtc(state, crtc);
> > > +			}
> > > +
> > > +			if (ddb_changed && (update_pipes | modeset_pipes))
> > >  				intel_wait_for_vblank(dev_priv, pipe);
> > >  		}
> > >  	}
> > > @@ -15863,9 +15950,18 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > >  		if ((modeset_pipes & BIT(pipe)) == 0)
> > >  			continue;
> > >  
> > > +		WARN_ON(skl_ddb_allocation_overlaps(&new_entries[pipe],
> > > +						    entries, I915_MAX_PIPES, pipe));
> > > +
> > > +		entries[pipe] = new_entries[pipe];
> > >  		modeset_pipes &= ~BIT(pipe);
> > >  
> > > -		intel_enable_crtc(state, crtc);
> > > +		if (new_crtc_state->bigjoiner)
> > > +			intel_update_bigjoiner(crtc, state,
> > > +					       old_crtc_state,
> > > +					       new_crtc_state);
> > > +		else
> > > +			intel_enable_crtc(state, crtc);
> > >  	}
> > >  
> > >  	/*
> > > @@ -15877,10 +15973,10 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > >  		if ((update_pipes & BIT(pipe)) == 0)
> > >  			continue;
> > >  
> > > -		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_crtc_state->wm.skl.ddb,
> > > +		drm_WARN_ON(&dev_priv->drm, skl_ddb_allocation_overlaps(&new_entries[pipe],
> > >  									entries, I915_MAX_PIPES, pipe));
> > >  
> > > -		entries[pipe] = new_crtc_state->wm.skl.ddb;
> > > +		entries[pipe] = new_entries[pipe];
> > >  		update_pipes &= ~BIT(pipe);
> > >  
> > >  		intel_update_crtc(state, crtc);
> > > diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > index 60eeed06a780..eaae5df546fe 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_sprite.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_sprite.c
> > > @@ -99,6 +99,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;
> > >  
> > > @@ -191,7 +193,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;
> > > @@ -206,16 +209,26 @@ 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) {
> > > -		drm_WARN_ON(&dev_priv->drm,
> > > -			    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)
> > > +			drm_WARN_ON(&dev_priv->drm,
> > > +				    drm_crtc_vblank_get(&crtc->base) != 0);
> > > +		if (slave_crtc_state && slave_crtc_state->uapi.event)
> > > +			drm_WARN_ON(&dev_priv->drm,
> > > +				    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 cd2104ba1ca1..15e7c112ec77 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.19.1
> > > 
> > > _______________________________________________
> > > Intel-gfx mailing list
> > > Intel-gfx@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > 
> > -- 
> > Ville Syrjälä
> > Intel
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-21 21:01               ` Navare, Manasi
@ 2020-09-22 10:19                 ` Ville Syrjälä
  2020-09-22 18:52                   ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-22 10:19 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 21, 2020 at 02:01:25PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 09:52:57PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 14, 2020 at 11:32:48AM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> > > > On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > > > > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > > > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > 
> > > > > > > > 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.
> > > > > > > > 
> > > > > > > > v2:
> > > > > > > > * Manual rebase (Manasi)
> > > > > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > > > > 
> > > > > > > > v3:
> > > > > > > > * Rebase on drm-tip (Manasi)
> > > > > > > 
> > > > > > > Previous review was apparently ignored. Or is there a better version
> > > > > > > somewhere? If not, this still looks very wrong.
> > > > > > 
> > > > > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > > > > What in particular looks wrong or what review comments were unaddressed here?
> > > > > 
> > > > > The dvo/sdvo changes.
> > > > 
> > > > I recommend just dropping this patch entirely. It doesn't seem to have
> > > > anything to do with the bigjoiner anyway.
> > > 
> > > So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
> > > How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
> > > static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> > > +					     struct drm_display_mode *user_mode)
> > > 
> > > You think we dont need mode as an argument there either?
> > 
> > Not in this patch if all the other stuff disappears. No idea if some
> > later patch might need something like it.
> 
> Hi Ville,
> 
> So this patch basically removes the hw.mode and just keeps hw.adjusted_mode
> So no need to remove that? 
> But basically from this patch onwards we say that there is hw.pipe_mode
> and hw.adjusted_mode, there is no hw.mode.
> Are you suggesting keeping hw.mode as well? Would this be replacing hw.pipe_mode then?

No. hw.mode is the original timings, adjusted_mode is the output timings,
pipe_mode is the the pipe timings.

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

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-09-21 21:18       ` Navare, Manasi
@ 2020-09-22 10:27         ` Ville Syrjälä
  2020-09-22 18:54           ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-22 10:27 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Sep 21, 2020 at 02:18:33PM -0700, Navare, Manasi wrote:
> On Mon, Sep 14, 2020 at 12:21:26PM -0700, Navare, Manasi wrote:
> > On Thu, Sep 03, 2020 at 10:23:35PM +0300, Ville Syrjälä wrote:
> > > On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > 
> > > > 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.
> > > > 
> > > > ****This needs to be checked if it still works since lot of refactoring
> > > > in skl_commit_modeset_enables
> > > > 
> > > > v2:
> > > > * Manual Rebase (Manasi)
> > > > * Refactoring on intel_update_crtc and enable_crtc and removing
> > > > special trans_port_sync_update (Manasi)
> > > > 
> > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
> > > >  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
> > > >  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
> > > >  3 files changed, 129 insertions(+), 19 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index a1011414da6d..00b26863ffc6 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> > > >  	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
> > > > @@ -15754,6 +15754,52 @@ 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);
> > > > +
> > > > +	if (modeset) {
> > > > +		/* Enable slave first */
> > > > +		intel_crtc_update_active_timings(new_slave_crtc_state);
> > > > +		dev_priv->display.crtc_enable(state, slave);
> > > > +
> > > > +		/* Then master */
> > > > +		intel_crtc_update_active_timings(new_crtc_state);
> > > > +		dev_priv->display.crtc_enable(state, crtc);
> > > > +
> > > > +		/* vblanks work again, re-enable pipe CRC. */
> > > > +		intel_crtc_enable_pipe_crc(crtc);
> > > > +
> > > > +	} else {
> > > > +		intel_pre_plane_update(state, crtc);
> > > > +		intel_pre_plane_update(state, slave);
> > > > +
> > > > +		if (new_crtc_state->update_pipe)
> > > > +			intel_encoders_update_pipe(state, crtc);
> > > > +	}
> > > > +
> > > > +	/*
> > > > +	 * 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, crtc);
> > > > +	commit_pipe_config(state, slave);
> > > > +
> > > > +	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);
> > > > +}
> > > 
> > > I think this should ideally all go away and just the normal logic
> > > in commit_modeset_enables() should deal with it. Just like it does
> > > for port sync/mst pipe dependencies.
> > >
> > 
> > Yes I think so too. Except for the intel_pipe_update_end where
> > now we send the new_slave_crtc_state() so thats still something I need to figure
> > how it will work in normal code without special bigjoiner handling.
> > 
> > I think the 2p2p transcoder ports sync code initially had a special trans port sync handling
> > function and thats why this was written this way but with the new code we just use
> > the regular modeset_enables function with no special handling
> > 
> > Manasi
> >  
> > > > +
> > > >  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > > >  {
> > > >  	struct intel_crtc_state *new_crtc_state;
> > > > @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > > >  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > > >  {
> > > >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > > > -	struct intel_crtc *crtc;
> > > > +	struct intel_crtc *crtc, *slave;
> > > >  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
> > > >  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> > > > +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
> > > >  	u8 update_pipes = 0, modeset_pipes = 0;
> > > > +	const struct intel_crtc_state *slave_crtc_state;
> > > >  	int i;
> > > >  
> > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> > > >  		enum pipe pipe = crtc->pipe;
> > > >  
> > > > +		if (new_crtc_state->bigjoiner_slave) {
> > > > +			/* We're updated from master */
> > > > +			continue;
> > > > +		}
> > > > +
> > > >  		if (!new_crtc_state->hw.active)
> > > >  			continue;
> > > >  
> > > > @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > > >  		} else {
> > > >  			modeset_pipes |= BIT(pipe);
> > > >  		}
> > > > +
> > > > +		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;
> > > > +		}
> > > > +
> > > > +		/* ignore allocations for crtc's that have been turned off during modeset. */
> > > > +		if (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;
> > > > +		}
> > > 
> > > Why is this here? Can't see why the current code wouldn't work just fine
> > > for bigjoiner too.
> > >
> 
> Ville, could you provide inputs on how intel_pipe_update_end() should change so that we can use
> the current code, now this takes an additional input new_slave_crtc_state

I would not change it at all. What I would do as the first step is to
treat the pipes entirely separately, just like we do for port sync/etc.
Later we can think what would be needed to make 100% sure they update
atomically.

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-22 10:19                 ` Ville Syrjälä
@ 2020-09-22 18:52                   ` Navare, Manasi
  2020-09-23 14:54                     ` Navare, Manasi
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-22 18:52 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Tue, Sep 22, 2020 at 01:19:15PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 21, 2020 at 02:01:25PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 09:52:57PM +0300, Ville Syrjälä wrote:
> > > On Mon, Sep 14, 2020 at 11:32:48AM -0700, Navare, Manasi wrote:
> > > > On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> > > > > On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > > > > > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > > > > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > > > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > > 
> > > > > > > > > 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.
> > > > > > > > > 
> > > > > > > > > v2:
> > > > > > > > > * Manual rebase (Manasi)
> > > > > > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > > > > > 
> > > > > > > > > v3:
> > > > > > > > > * Rebase on drm-tip (Manasi)
> > > > > > > > 
> > > > > > > > Previous review was apparently ignored. Or is there a better version
> > > > > > > > somewhere? If not, this still looks very wrong.
> > > > > > > 
> > > > > > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > > > > > What in particular looks wrong or what review comments were unaddressed here?
> > > > > > 
> > > > > > The dvo/sdvo changes.
> > > > > 
> > > > > I recommend just dropping this patch entirely. It doesn't seem to have
> > > > > anything to do with the bigjoiner anyway.
> > > > 
> > > > So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
> > > > How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
> > > > static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> > > > +					     struct drm_display_mode *user_mode)
> > > > 
> > > > You think we dont need mode as an argument there either?
> > > 
> > > Not in this patch if all the other stuff disappears. No idea if some
> > > later patch might need something like it.
> > 
> > Hi Ville,
> > 
> > So this patch basically removes the hw.mode and just keeps hw.adjusted_mode
> > So no need to remove that? 
> > But basically from this patch onwards we say that there is hw.pipe_mode
> > and hw.adjusted_mode, there is no hw.mode.
> > Are you suggesting keeping hw.mode as well? Would this be replacing hw.pipe_mode then?
> 
> No. hw.mode is the original timings, adjusted_mode is the output timings,
> pipe_mode is the the pipe timings.

So is the suggestion to keep hw.mode so the original timings as well as adjusted_mode and
then have pipe_mode for per pipe timings.
So get rid of this patch meaning do not remove hw.mode?

Manasi

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

* Re: [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling.
  2020-09-22 10:27         ` Ville Syrjälä
@ 2020-09-22 18:54           ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-09-22 18:54 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Tue, Sep 22, 2020 at 01:27:35PM +0300, Ville Syrjälä wrote:
> On Mon, Sep 21, 2020 at 02:18:33PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 12:21:26PM -0700, Navare, Manasi wrote:
> > > On Thu, Sep 03, 2020 at 10:23:35PM +0300, Ville Syrjälä wrote:
> > > > On Wed, Jul 15, 2020 at 03:42:21PM -0700, Manasi Navare wrote:
> > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > 
> > > > > 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.
> > > > > 
> > > > > ****This needs to be checked if it still works since lot of refactoring
> > > > > in skl_commit_modeset_enables
> > > > > 
> > > > > v2:
> > > > > * Manual Rebase (Manasi)
> > > > > * Refactoring on intel_update_crtc and enable_crtc and removing
> > > > > special trans_port_sync_update (Manasi)
> > > > > 
> > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_display.c | 120 +++++++++++++++++--
> > > > >  drivers/gpu/drm/i915/display/intel_sprite.c  |  25 +++-
> > > > >  drivers/gpu/drm/i915/display/intel_sprite.h  |   3 +-
> > > > >  3 files changed, 129 insertions(+), 19 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index a1011414da6d..00b26863ffc6 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -15656,7 +15656,7 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> > > > >  	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
> > > > > @@ -15754,6 +15754,52 @@ 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);
> > > > > +
> > > > > +	if (modeset) {
> > > > > +		/* Enable slave first */
> > > > > +		intel_crtc_update_active_timings(new_slave_crtc_state);
> > > > > +		dev_priv->display.crtc_enable(state, slave);
> > > > > +
> > > > > +		/* Then master */
> > > > > +		intel_crtc_update_active_timings(new_crtc_state);
> > > > > +		dev_priv->display.crtc_enable(state, crtc);
> > > > > +
> > > > > +		/* vblanks work again, re-enable pipe CRC. */
> > > > > +		intel_crtc_enable_pipe_crc(crtc);
> > > > > +
> > > > > +	} else {
> > > > > +		intel_pre_plane_update(state, crtc);
> > > > > +		intel_pre_plane_update(state, slave);
> > > > > +
> > > > > +		if (new_crtc_state->update_pipe)
> > > > > +			intel_encoders_update_pipe(state, crtc);
> > > > > +	}
> > > > > +
> > > > > +	/*
> > > > > +	 * 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, crtc);
> > > > > +	commit_pipe_config(state, slave);
> > > > > +
> > > > > +	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);
> > > > > +}
> > > > 
> > > > I think this should ideally all go away and just the normal logic
> > > > in commit_modeset_enables() should deal with it. Just like it does
> > > > for port sync/mst pipe dependencies.
> > > >
> > > 
> > > Yes I think so too. Except for the intel_pipe_update_end where
> > > now we send the new_slave_crtc_state() so thats still something I need to figure
> > > how it will work in normal code without special bigjoiner handling.
> > > 
> > > I think the 2p2p transcoder ports sync code initially had a special trans port sync handling
> > > function and thats why this was written this way but with the new code we just use
> > > the regular modeset_enables function with no special handling
> > > 
> > > Manasi
> > >  
> > > > > +
> > > > >  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > > > >  {
> > > > >  	struct intel_crtc_state *new_crtc_state;
> > > > > @@ -15772,15 +15818,22 @@ static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> > > > >  static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > > > >  {
> > > > >  	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> > > > > -	struct intel_crtc *crtc;
> > > > > +	struct intel_crtc *crtc, *slave;
> > > > >  	struct intel_crtc_state *old_crtc_state, *new_crtc_state;
> > > > >  	struct skl_ddb_entry entries[I915_MAX_PIPES] = {};
> > > > > +	struct skl_ddb_entry new_entries[I915_MAX_PIPES] = {};
> > > > >  	u8 update_pipes = 0, modeset_pipes = 0;
> > > > > +	const struct intel_crtc_state *slave_crtc_state;
> > > > >  	int i;
> > > > >  
> > > > >  	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
> > > > >  		enum pipe pipe = crtc->pipe;
> > > > >  
> > > > > +		if (new_crtc_state->bigjoiner_slave) {
> > > > > +			/* We're updated from master */
> > > > > +			continue;
> > > > > +		}
> > > > > +
> > > > >  		if (!new_crtc_state->hw.active)
> > > > >  			continue;
> > > > >  
> > > > > @@ -15791,6 +15844,34 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
> > > > >  		} else {
> > > > >  			modeset_pipes |= BIT(pipe);
> > > > >  		}
> > > > > +
> > > > > +		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;
> > > > > +		}
> > > > > +
> > > > > +		/* ignore allocations for crtc's that have been turned off during modeset. */
> > > > > +		if (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;
> > > > > +		}
> > > > 
> > > > Why is this here? Can't see why the current code wouldn't work just fine
> > > > for bigjoiner too.
> > > >
> > 
> > Ville, could you provide inputs on how intel_pipe_update_end() should change so that we can use
> > the current code, now this takes an additional input new_slave_crtc_state
> 
> I would not change it at all. What I would do as the first step is to
> treat the pipes entirely separately, just like we do for port sync/etc.
> Later we can think what would be needed to make 100% sure they update
> atomically.

Okay yes so just do the updates sequentially first do all slaves then master like
we do for trans port sync and see what happens without changing
anything special in pipe_update_start and pipe_update_end functions ?

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

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-17 12:20               ` Ville Syrjälä
@ 2020-09-23  5:46                 ` Navare, Manasi
  2020-09-23  9:57                   ` Ville Syrjälä
  0 siblings, 1 reply; 80+ messages in thread
From: Navare, Manasi @ 2020-09-23  5:46 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 17, 2020 at 03:20:46PM +0300, Ville Syrjälä wrote:
> On Tue, Sep 15, 2020 at 04:03:45PM -0700, Navare, Manasi wrote:
> > On Mon, Sep 14, 2020 at 10:47:56PM +0300, Ville Syrjälä wrote:
> > > On Mon, Sep 14, 2020 at 12:38:57PM -0700, Navare, Manasi wrote:
> > > > On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> > > > > On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > > > > > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > > > > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > 
> > > > > > > > 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.
> > > > > > > > 
> > > > > > > > v5:
> > > > > > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > > > > > v4:
> > > > > > > > * Rebase (Manasi)
> > > > > > > > 
> > > > > > > > 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)
> > > > > > > > v3:
> > > > > > > > * Rebase (Manasi)
> > > > > > > > 
> > > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > > > > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > > > > >  	 * too big for that.
> > > > > > > >  	 */
> > > > > > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > > > > > -		plane_width_max = 5120;
> > > > > > > > +		plane_width_max = 7680;
> > > > > > > 
> > > > > > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > > > > > not. They should not care in fact. The caller should have that knowledge
> > > > > > > and can deal with it properly.
> > > > > > 
> > > > > > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > > > > > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > > > > > 
> > > > > > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > > > > > before we prune the 8K mode in intel_mode_valid
> > > > > > 
> > > > > > Where should this be added according to you?
> > > > > 
> > > > > Hmm. I guess we do need to put it into this function given the way this
> > > > > is structured. However we still can't assume bigjoiner can be used since
> > > > > it can't be used on DDI A on icl. So we should probably just pass in a
> > > > > bool here to indicate whether bigjoiner can be used or not.
> > > > >
> > > > 
> > > > So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
> > > > I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
> > > > where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
> > > > to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)
> > > 
> > > can_bigjoiner() {
> > > 	return gen >= 12 || (gen==11 && port!=A);

On Gen 11, Port A is eDP or MIPI DSI so I could check:

can_bigjoiner()
{
	return gen >=12 || (gen == 11 && !intel_dp_is_edp())
}

The above should be okay right?

Manasi

> > > }
> > 
> > Hmm, gen check can be done but can the port check be done in intel_dp_mode_valid() since we dont have
> > an encoder yet?
> 
> The encoder is there already.
> 
> > Else we set the bigjoiner to true here based on gen check but add the port check later in compute_config at
> > what point if not supported then encoder config will fail.
> > 
> > or can this be sufficient check:
> > 
> > can_bigjoiner() {
> > 	return gen >= 12 || (gen == 11 && !intel_dp_is_edp())
> > }
> > 
> > Manasi
> > 
> > > 
> > > or something.
> > > 
> > > > 
> > > > Sounds good?
> > > > 
> > > > > Personally I'd just write the thing as something like:
> > > > > intel_mode_valid_max_plane_size(..., bool bigjoiner)
> > > > > {
> > > > > 	...
> > > > > 	plane_width_max = 5120 << bigjoiner;
> > > > > 	...
> > > > > }
> > > > > 
> > > > > > 
> > > > > > Manasi
> > > > > > > 
> > > > > > > >  		plane_height_max = 4320;
> > > > > > > >  	} else {
> > > > > > > >  		plane_width_max = 5120;
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > > index d6295eb20b63..fbfea99fd804 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > > > > > @@ -248,25 +248,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 *dig_port = dp_to_dig_port(intel_dp);
> > > > > > > > -	struct intel_encoder *encoder = &dig_port->base;
> > > > > > > > +	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;
> > > > > > > >  
> > > > > > > > +	if (allow_bigjoiner && INTEL_GEN(dev_priv) >= 11 && !intel_dp_is_edp(intel_dp))
> > > > > > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > > > > > +
> > > > > > > > +	return dev_priv->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;
> > > > > > > >  }
> > > > > > > > @@ -527,7 +539,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;
> > > > > > > > @@ -545,6 +558,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_dbg_kms(&i915->drm, "Max small joiner bpp: %u\n",
> > > > > > > >  		    max_bpp_small_joiner_ram);
> > > > > > > >  
> > > > > > > > @@ -554,6 +571,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_dbg_kms(&i915->drm, "Unsupported BPP %u, min %u\n",
> > > > > > > > @@ -576,7 +602,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)
> > > > > > > >  {
> > > > > > > >  	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> > > > > > > >  	u8 min_slice_count, i;
> > > > > > > > @@ -603,12 +630,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_dbg_kms(&i915->drm, "Unsupported Slice Count %d\n",
> > > > > > > > @@ -648,11 +683,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)
> > > > > > > > @@ -664,6 +703,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);
> > > > > > > >  
> > > > > > > > @@ -691,23 +745,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);
> > > > > > > >  }
> > > > > > > > @@ -2204,11 +2263,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_dbg_kms(&dev_priv->drm,
> > > > > > > >  				    "Compressed BPP/Slice Count not supported\n");
> > > > > > > > -- 
> > > > > > > > 2.19.1
> > > > > > > > 
> > > > > > > > _______________________________________________
> > > > > > > > Intel-gfx mailing list
> > > > > > > > Intel-gfx@lists.freedesktop.org
> > > > > > > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> > > > > > > 
> > > > > > > -- 
> > > > > > > Ville Syrjälä
> > > > > > > Intel
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-09-23  5:46                 ` Navare, Manasi
@ 2020-09-23  9:57                   ` Ville Syrjälä
  0 siblings, 0 replies; 80+ messages in thread
From: Ville Syrjälä @ 2020-09-23  9:57 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Tue, Sep 22, 2020 at 10:46:52PM -0700, Navare, Manasi wrote:
> On Thu, Sep 17, 2020 at 03:20:46PM +0300, Ville Syrjälä wrote:
> > On Tue, Sep 15, 2020 at 04:03:45PM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 14, 2020 at 10:47:56PM +0300, Ville Syrjälä wrote:
> > > > On Mon, Sep 14, 2020 at 12:38:57PM -0700, Navare, Manasi wrote:
> > > > > On Mon, Sep 14, 2020 at 10:17:57PM +0300, Ville Syrjälä wrote:
> > > > > > On Mon, Sep 14, 2020 at 12:00:33PM -0700, Navare, Manasi wrote:
> > > > > > > On Mon, Sep 07, 2020 at 02:20:56PM +0300, Ville Syrjälä wrote:
> > > > > > > > On Wed, Jul 15, 2020 at 03:42:15PM -0700, Manasi Navare wrote:
> > > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > > 
> > > > > > > > > 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.
> > > > > > > > > 
> > > > > > > > > v5:
> > > > > > > > > * Increase max plane width to support 8K with bigjoiner (Maarten)
> > > > > > > > > v4:
> > > > > > > > > * Rebase (Manasi)
> > > > > > > > > 
> > > > > > > > > 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)
> > > > > > > > > v3:
> > > > > > > > > * Rebase (Manasi)
> > > > > > > > > 
> > > > > > > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > > > > > > Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > > ---
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c |   2 +-
> > > > > > > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 119 ++++++++++++++-----
> > > > > > > > >  2 files changed, 91 insertions(+), 30 deletions(-)
> > > > > > > > > 
> > > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > > index 78cbfefbfa62..3ecb642805a6 100644
> > > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > > > > @@ -17400,7 +17400,7 @@ intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > > > > > >  	 * too big for that.
> > > > > > > > >  	 */
> > > > > > > > >  	if (INTEL_GEN(dev_priv) >= 11) {
> > > > > > > > > -		plane_width_max = 5120;
> > > > > > > > > +		plane_width_max = 7680;
> > > > > > > > 
> > > > > > > > This looks misplaced. Planes do no know whether bigjoiner can be used or
> > > > > > > > not. They should not care in fact. The caller should have that knowledge
> > > > > > > > and can deal with it properly.
> > > > > > > 
> > > > > > > Hmm, so the caller of intel_mode_valid_max_plane_size() should check on the bigjoiner
> > > > > > > flag and perhaps if bigjoiner is true then increase the plane_width_max to 7680?
> > > > > > > 
> > > > > > > Am still not sure where this should happen? We need to have the plane max width to be 7680
> > > > > > > before we prune the 8K mode in intel_mode_valid
> > > > > > > 
> > > > > > > Where should this be added according to you?
> > > > > > 
> > > > > > Hmm. I guess we do need to put it into this function given the way this
> > > > > > is structured. However we still can't assume bigjoiner can be used since
> > > > > > it can't be used on DDI A on icl. So we should probably just pass in a
> > > > > > bool here to indicate whether bigjoiner can be used or not.
> > > > > >
> > > > > 
> > > > > So in intel_dp_mode_valid() we set bigjoiner = true if not edp and higher clock.
> > > > > I think here we need to do the platform check also, 1. because now we are enabling this for TGL+
> > > > > where big joiner on all pipes. But we should still I think add GEN >=12 check before setting bigjoiner
> > > > > to true in intel_dp_mode_valid() and then pass that to intel_mode_valid_max_plane_size(..., book bigjoiner)
> > > > 
> > > > can_bigjoiner() {
> > > > 	return gen >= 12 || (gen==11 && port!=A);
> 
> On Gen 11, Port A is eDP or MIPI DSI so I could check:
> 
> can_bigjoiner()
> {
> 	return gen >=12 || (gen == 11 && !intel_dp_is_edp())
> }
> 
> The above should be okay right?

No. Check for port A.

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

* Re: [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode
  2020-09-22 18:52                   ` Navare, Manasi
@ 2020-09-23 14:54                     ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-09-23 14:54 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

Hi Ville,

So to confirm I am skipping this patch completely.
So basically keeping hw.mode as well

Manasi

On Tue, Sep 22, 2020 at 11:52:09AM -0700, Navare, Manasi wrote:
> On Tue, Sep 22, 2020 at 01:19:15PM +0300, Ville Syrjälä wrote:
> > On Mon, Sep 21, 2020 at 02:01:25PM -0700, Navare, Manasi wrote:
> > > On Mon, Sep 14, 2020 at 09:52:57PM +0300, Ville Syrjälä wrote:
> > > > On Mon, Sep 14, 2020 at 11:32:48AM -0700, Navare, Manasi wrote:
> > > > > On Mon, Sep 07, 2020 at 03:35:23PM +0300, Ville Syrjälä wrote:
> > > > > > On Thu, Sep 03, 2020 at 09:40:44PM +0300, Ville Syrjälä wrote:
> > > > > > > On Thu, Sep 03, 2020 at 11:04:33AM -0700, Navare, Manasi wrote:
> > > > > > > > On Thu, Sep 03, 2020 at 08:49:44PM +0300, Ville Syrjälä wrote:
> > > > > > > > > On Wed, Jul 15, 2020 at 03:42:13PM -0700, Manasi Navare wrote:
> > > > > > > > > > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > > > > > > > > > 
> > > > > > > > > > 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.
> > > > > > > > > > 
> > > > > > > > > > v2:
> > > > > > > > > > * Manual rebase (Manasi)
> > > > > > > > > > * remove the use of pipe_mode defined in patch 3 (Manasi)
> > > > > > > > > > 
> > > > > > > > > > v3:
> > > > > > > > > > * Rebase on drm-tip (Manasi)
> > > > > > > > > 
> > > > > > > > > Previous review was apparently ignored. Or is there a better version
> > > > > > > > > somewhere? If not, this still looks very wrong.
> > > > > > > > 
> > > > > > > > This was the latest rev that Maarten had in his local tree which he said should address all the review comments.
> > > > > > > > What in particular looks wrong or what review comments were unaddressed here?
> > > > > > > 
> > > > > > > The dvo/sdvo changes.
> > > > > > 
> > > > > > I recommend just dropping this patch entirely. It doesn't seem to have
> > > > > > anything to do with the bigjoiner anyway.
> > > > > 
> > > > > So for the dvo/svdo changes, no need to use the adjusted_mode instead keep using hw.mode?
> > > > > How about other cleanups like: intel_crtc_copy_hw_to_uapi_state(crtc_state, &mode); and
> > > > > static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state,
> > > > > +					     struct drm_display_mode *user_mode)
> > > > > 
> > > > > You think we dont need mode as an argument there either?
> > > > 
> > > > Not in this patch if all the other stuff disappears. No idea if some
> > > > later patch might need something like it.
> > > 
> > > Hi Ville,
> > > 
> > > So this patch basically removes the hw.mode and just keeps hw.adjusted_mode
> > > So no need to remove that? 
> > > But basically from this patch onwards we say that there is hw.pipe_mode
> > > and hw.adjusted_mode, there is no hw.mode.
> > > Are you suggesting keeping hw.mode as well? Would this be replacing hw.pipe_mode then?
> > 
> > No. hw.mode is the original timings, adjusted_mode is the output timings,
> > pipe_mode is the the pipe timings.
> 
> So is the suggestion to keep hw.mode so the original timings as well as adjusted_mode and
> then have pipe_mode for per pipe timings.
> So get rid of this patch meaning do not remove hw.mode?
> 
> Manasi
> 
> > 
> > -- 
> > Ville Syrjälä
> > Intel
> _______________________________________________
> 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] 80+ messages in thread

* Re: [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check
  2020-09-03 18:38   ` Ville Syrjälä
@ 2020-09-23 22:58     ` Navare, Manasi
  0 siblings, 0 replies; 80+ messages in thread
From: Navare, Manasi @ 2020-09-23 22:58 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Thu, Sep 03, 2020 at 09:38:31PM +0300, Ville Syrjälä wrote:
> On Wed, Jul 15, 2020 at 03:42:16PM -0700, Manasi Navare wrote:
> > From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> > 
> >  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.
> > 
> > v3:
> > * Manual Rebase (Manasi)
> >  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>
> > Signed-off-by: Manasi Navare <manasi.d.navare@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  | 201 ++++++++++++++++--
> >  .../drm/i915/display/intel_display_types.h    |   9 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |  22 +-
> >  5 files changed, 211 insertions(+), 33 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
> > index 630f49b7aa01..b9dcdc74a10d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> > @@ -270,14 +270,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 11146292b06f..fc556c032c8f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic.h
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic.h
> > @@ -43,7 +43,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_free(struct drm_atomic_state *state);
> >  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 3ecb642805a6..955e19abb563 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -8016,9 +8016,24 @@ 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;
> >  
> > @@ -8079,7 +8094,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)
> 
> What's the deal here? I think I asked this same question ages ago
> already...

Yea I have no idea why we compare pipe_config->hw.adjusted_mode.crtc_hsync_start with
pipe_mode->crtc_hdisplay?
It should just be a check of  pipe_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay
so no change needed

Ville, do you agree?

> 
> >  		return -EINVAL;
> >  
> >  	intel_crtc_compute_pixel_rate(pipe_config);
> > @@ -12433,7 +12448,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)
> >  {
> > @@ -12442,7 +12457,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;
> >  
> > @@ -12682,6 +12697,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 &&
> >  	    !drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll)) {
> >  		ret = dev_priv->display.crtc_compute_clock(crtc, crtc_state);
> >  		if (ret)
> > @@ -13206,18 +13222,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,
> > @@ -13240,7 +13269,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 intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > @@ -13276,16 +13347,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 drm_i915_private *i915 = to_i915(pipe_config->uapi.crtc->dev);
> >  	struct drm_connector *connector;
> >  	struct drm_connector_state *connector_state;
> > @@ -13327,7 +13398,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) {
> >  		struct intel_encoder *encoder =
> >  			to_intel_encoder(connector_state->best_encoder);
> >  
> > @@ -13365,7 +13436,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) {
> >  		struct intel_encoder *encoder =
> >  			to_intel_encoder(connector_state->best_encoder);
> >  
> > @@ -13422,8 +13493,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> >  	 * drm_atomic_helper_update_legacy_modeset_state() happy
> >  	 */
> >  	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;
> >  }
> > @@ -14820,6 +14889,75 @@ static bool intel_cpu_transcoders_need_modeset(struct intel_atomic_state *state,
> >  	return false;
> >  }
> >  
> > +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
> > @@ -14849,19 +14987,36 @@ 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;
> >  		}
> >  
> > -		ret = intel_crtc_prepare_cleared_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;
> > +		}
> > +
> > +		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;
> > +			}
> 
> I'm confused. Where do we add the other pipe to the state if there are no
> modesets involved?
>

We get crtc state for pipe + 1 (stolen pipe) in intel_atomic_check_bigjoiner
In the testing now I see that we correctly steal the pipe and do modeset on that

Whats your concern here, could ypu elaborate?

Manasi
 
> > +			continue;
> > +		}
> > +
> > +		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
> >  		if (ret)
> >  			goto fail;
> >  
> > -		if (!new_crtc_state->hw.enable)
> > -			continue;
> > +		ret = intel_modeset_pipe_config(state, new_crtc_state);
> > +		if (ret)
> > +			goto fail;
> >  
> > -		ret = intel_modeset_pipe_config(new_crtc_state);
> > +		ret = intel_atomic_check_bigjoiner(state, crtc, old_crtc_state,
> > +						   new_crtc_state);
> >  		if (ret)
> >  			goto fail;
> >  	}
> > @@ -15193,7 +15348,9 @@ static void intel_update_crtc(struct intel_atomic_state *state,
> >  
> >  	commit_pipe_config(state, crtc);
> >  
> > -	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 c52c8f42df68..4694cfd90a0a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1053,6 +1053,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 fbfea99fd804..29f45d2206af 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -2247,6 +2247,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,
> > @@ -2264,12 +2273,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_dbg_kms(&dev_priv->drm,
> >  				    "Compressed BPP/Slice Count not supported\n");
> > @@ -2285,14 +2294,15 @@ 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_dbg_kms(&dev_priv->drm,
> >  				    "Cannot split stream to use 2 VDSC instances\n");
> >  			return -EINVAL;
> >  		}
> > +
> > +		pipe_config->dsc.dsc_split = true;
> >  	}
> >  
> >  	ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
> > -- 
> > 2.19.1
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2020-09-23 22:57 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-15 22:42 [Intel-gfx] [PATCH v6 01/11] HAX to make DSC work on the icelake test system Manasi Navare
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 02/11] drm/i915: Remove hw.mode Manasi Navare
2020-08-17  7:26   ` Manna, Animesh
2020-09-03 17:49   ` Ville Syrjälä
2020-09-03 18:04     ` Navare, Manasi
2020-09-03 18:40       ` Ville Syrjälä
2020-09-07 12:35         ` Ville Syrjälä
2020-09-14 18:32           ` Navare, Manasi
2020-09-14 18:52             ` Ville Syrjälä
2020-09-21 21:01               ` Navare, Manasi
2020-09-22 10:19                 ` Ville Syrjälä
2020-09-22 18:52                   ` Navare, Manasi
2020-09-23 14:54                     ` Navare, Manasi
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 03/11] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
2020-08-10 12:38   ` Maarten Lankhorst
2020-08-17  7:32   ` Manna, Animesh
2020-09-03 17:54   ` Ville Syrjälä
2020-09-14 18:45     ` Navare, Manasi
2020-09-14 18:48       ` Ville Syrjälä
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 04/11] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
2020-08-10 12:40   ` Maarten Lankhorst
2020-08-21  9:41   ` Manna, Animesh
2020-08-21 21:51     ` Navare, Manasi
2020-09-07 11:20   ` Ville Syrjälä
2020-09-14 19:00     ` Navare, Manasi
2020-09-14 19:17       ` Ville Syrjälä
2020-09-14 19:38         ` Navare, Manasi
2020-09-14 19:47           ` Ville Syrjälä
2020-09-15 23:03             ` Navare, Manasi
2020-09-17 12:20               ` Ville Syrjälä
2020-09-23  5:46                 ` Navare, Manasi
2020-09-23  9:57                   ` Ville Syrjälä
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 05/11] drm/i915: Try to make bigjoiner work in atomic check Manasi Navare
2020-08-21 10:16   ` Manna, Animesh
2020-08-21 18:22     ` Navare, Manasi
2020-09-03 18:38   ` Ville Syrjälä
2020-09-23 22:58     ` Navare, Manasi
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 06/11] drm/i915: Enable big joiner support in enable and disable sequences Manasi Navare
2020-07-16 19:27   ` Manasi Navare
2020-08-10 12:45     ` Maarten Lankhorst
2020-08-10 23:04       ` Navare, Manasi
2020-07-16 21:12   ` [Intel-gfx] [PATCH v7 " Manasi Navare
2020-08-10 23:28     ` [Intel-gfx] [PATCH v8 " Manasi Navare
2020-08-27 23:35       ` Navare, Manasi
2020-08-28  6:26         ` Maarten Lankhorst
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 07/11] drm/i915: Make hardware readout work on i915 Manasi Navare
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 08/11] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
2020-09-03 19:19   ` Ville Syrjälä
2020-09-14 19:14     ` Navare, Manasi
2020-09-14 19:20       ` Ville Syrjälä
2020-09-14 19:27         ` Navare, Manasi
2020-09-14 19:34           ` Ville Syrjälä
2020-09-14 19:45             ` Navare, Manasi
2020-09-14 20:05               ` Ville Syrjälä
2020-09-15 22:40                 ` Navare, Manasi
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 09/11] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 10/11] drm/i915: Add intel_update_bigjoiner handling Manasi Navare
2020-08-24 22:15   ` Navare, Manasi
2020-09-03 19:23   ` Ville Syrjälä
2020-09-14 19:21     ` Navare, Manasi
2020-09-21 21:18       ` Navare, Manasi
2020-09-22 10:27         ` Ville Syrjälä
2020-09-22 18:54           ` Navare, Manasi
2020-07-15 22:42 ` [Intel-gfx] [PATCH v6 11/11] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
2020-08-10 12:47   ` Maarten Lankhorst
2020-07-15 22:50 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system Patchwork
2020-07-15 22:51 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-07-15 23:12 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-07-16  5:48 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2020-07-16 21:53 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev2) Patchwork
2020-07-16 21:54 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-07-16 22:14 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-07-17  1:04 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2020-08-10 23:47 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev3) Patchwork
2020-08-10 23:48 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-08-11  0:09 ` [Intel-gfx] ✗ Fi.CI.BAT: failure " Patchwork
2020-08-11 18:33 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [v6,01/11] HAX to make DSC work on the icelake test system (rev4) Patchwork
2020-08-11 18:35 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-08-11 18:56 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-08-11 20:15 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

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