All of lore.kernel.org
 help / color / mirror / Atom feed
* [Intel-gfx] [PATCH v11 00/12] Big joiner enabling
@ 2020-10-22  5:42 Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 01/12] HAX to make DSC work on the icelake test system Manasi Navare
                   ` (16 more replies)
  0 siblings, 17 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

Thsi series has all the previous review commenst addressed
and Patches split into smaller patches for cleaner bisect.

Maarten Lankhorst (7):
  HAX to make DSC work on the icelake test system
  drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  drm/i915: Try to make bigjoiner work in atomic check
  drm/i915: Link planes in a bigjoiner configuration, v3.
  drm/i915: Add bigjoiner aware plane clipping checks
  drm/i915: Add debugfs dumping for bigjoiner, v3.

Manasi Navare (5):
  drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner
    modes
  drm/i915/dp: Prep for bigjoiner atomic check
  drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave
  drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
  drm/i915: HW state readout for Bigjoiner case

 drivers/gpu/drm/drm_dp_helper.c               |   4 +-
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
 drivers/gpu/drm/i915/display/intel_atomic.c   |   9 +-
 drivers/gpu/drm/i915/display/intel_atomic.h   |   3 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c | 113 ++-
 .../gpu/drm/i915/display/intel_atomic_plane.h |   7 +-
 drivers/gpu/drm/i915/display/intel_ddi.c      |  68 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 922 ++++++++++++++----
 drivers/gpu/drm/i915/display/intel_display.h  |  23 +-
 .../drm/i915/display/intel_display_debugfs.c  |  29 +-
 .../drm/i915/display/intel_display_types.h    |  32 +-
 drivers/gpu/drm/i915/display/intel_dp.c       | 140 ++-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   2 +-
 drivers/gpu/drm/i915/display/intel_dsi.c      |   2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c     |   2 +-
 drivers/gpu/drm/i915/display/intel_sprite.c   |  21 +-
 drivers/gpu/drm/i915/display/intel_vdsc.c     | 201 ++--
 drivers/gpu/drm/i915/display/intel_vdsc.h     |   6 +-
 drivers/gpu/drm/i915/intel_pm.c               |  96 +-
 include/drm/drm_dp_helper.h                   |   1 +
 20 files changed, 1245 insertions(+), 438 deletions(-)

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

* [Intel-gfx] [PATCH v11 01/12] HAX to make DSC work on the icelake test system
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 02/12] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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 14ddf28ecac0..945c752eac2b 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -2065,7 +2065,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 {
@@ -2089,7 +2089,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 f55a9d1320ca..ff30cc240e19 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -1549,6 +1549,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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 02/12] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 01/12] HAX to make DSC work on the icelake test system Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes Manasi Navare
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

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

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.

v6:
* renaming in separate function, only pipe_mode here (Ville)
* Add description (Maarten)
v5:
* Rebase (Manasi)
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>
Reviewed-by: Animesh Manna <animesh.manna@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 41 +++++-----
 .../drm/i915/display/intel_display_types.h    | 11 ++-
 drivers/gpu/drm/i915/intel_pm.c               | 76 +++++++++----------
 3 files changed, 70 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 130303e0298a..9b4fcc734122 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6167,18 +6167,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,
@@ -8192,7 +8190,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;
 
 	/*
@@ -8229,7 +8227,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);
@@ -8239,7 +8237,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) {
@@ -8250,16 +8248,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;
 	}
@@ -8302,7 +8300,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);
@@ -12817,15 +12815,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);
 }
@@ -13455,8 +13453,9 @@ 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;
+	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
 	crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter;
+
 	intel_crtc_copy_uapi_to_hw_state_nomodeset(crtc_state);
 }
 
@@ -13559,7 +13558,7 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 	 * computation to clearly distinguish it from the adjusted mode, which
 	 * can be changed by the connectors in the below retry loop.
 	 */
-	drm_mode_get_hv_timing(&pipe_config->hw.mode,
+	drm_mode_get_hv_timing(&pipe_config->hw.pipe_mode,
 			       &pipe_config->pipe_src_w,
 			       &pipe_config->pipe_src_h);
 
@@ -13653,6 +13652,9 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
 		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
+	/* without bigjoiner, pipe_mode == adjusted_mode */
+	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
+
 	return 0;
 }
 
@@ -18910,6 +18912,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;
+
 			intel_crtc_compute_pixel_rate(crtc_state);
 
 			intel_crtc_update_active_timings(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index f6f0626649e0..b526afee595c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -817,15 +817,22 @@ struct intel_crtc_state {
 	 * The following members are used to verify the hardware state:
 	 * - enable
 	 * - active
-	 * - mode / adjusted_mode
+	 * - 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 mode, adjusted_mode;
+		struct drm_display_mode mode, pipe_mode, adjusted_mode;
 		enum drm_scaling_filter scaling_filter;
 	} hw;
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 0ef01a01ef8d..18e52763dfec 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -899,12 +899,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,
@@ -1135,8 +1135,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;
 
@@ -1163,8 +1163,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);
 
@@ -1660,8 +1660,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)
@@ -1671,8 +1671,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) {
@@ -2261,12 +2261,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;
@@ -2345,8 +2345,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;
@@ -2356,7 +2356,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;
@@ -2372,8 +2372,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;
@@ -2383,7 +2383,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)
@@ -2421,12 +2421,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;
@@ -2474,7 +2474,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;
 
@@ -2482,8 +2482,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);
@@ -2573,7 +2573,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);
 
@@ -2601,7 +2601,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);
@@ -2626,7 +2626,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);
 }
@@ -3883,7 +3883,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) {
@@ -4174,8 +4174,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;
@@ -4205,7 +4205,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;
 
@@ -5093,7 +5093,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;
@@ -5282,14 +5282,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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 01/12] HAX to make DSC work on the icelake test system Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 02/12] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-23 17:17   ` Ville Syrjälä
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
                   ` (13 subsequent siblings)
  16 siblings, 1 reply; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

No functional changes. This patch just moves some mode checks
around to prepare for adding bigjoiner related mode validation

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dp.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 818daab252f3..2c29e7f5281b 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -721,6 +721,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
 
+	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
+		return MODE_H_ILLEGAL;
+
 	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
 		if (mode->hdisplay > fixed_mode->hdisplay)
 			return MODE_PANEL;
@@ -731,6 +734,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
 		target_clock = fixed_mode->clock;
 	}
 
+	if (mode->clock < 10000)
+		return MODE_CLOCK_LOW;
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -771,12 +777,6 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	    target_clock > max_dotclk)
 		return MODE_CLOCK_HIGH;
 
-	if (mode->clock < 10000)
-		return MODE_CLOCK_LOW;
-
-	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
-		return MODE_H_ILLEGAL;
-
 	status = intel_dp_mode_valid_downstream(intel_connector,
 						mode, target_clock);
 	if (status != MODE_OK)
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (2 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-23 17:32   ` Ville Syrjälä
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 05/12] drm/i915/dp: Prep for bigjoiner atomic check Manasi Navare
                   ` (12 subsequent siblings)
  16 siblings, 2 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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.

v9:
* Restric Bigjoiner on PORT A (Ville)
v8:
* use source dotclock for max dotclock (Manasi)
v7:
* Add can_bigjoiner() helper (Ville)
* Pass bigjoiner to plane_size validation (Ville)
v6:
* Rebase after dp_downstream mode valid changes (Manasi)
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 |   5 +-
 drivers/gpu/drm/i915/display/intel_display.h |   3 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 106 +++++++++++++++----
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
 drivers/gpu/drm/i915/display/intel_dsi.c     |   2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c    |   2 +-
 6 files changed, 96 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 9b4fcc734122..1c2d67ae361d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -17751,7 +17751,8 @@ intel_mode_valid(struct drm_device *dev,
 
 enum drm_mode_status
 intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
-				const struct drm_display_mode *mode)
+				const struct drm_display_mode *mode,
+				bool bigjoiner)
 {
 	int plane_width_max, plane_height_max;
 
@@ -17768,7 +17769,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 = 5120 << bigjoiner;
 		plane_height_max = 4320;
 	} else {
 		plane_width_max = 5120;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 1b946209e06b..4f8dee9dfb4d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
 bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
 enum drm_mode_status
 intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
-				const struct drm_display_mode *mode);
+				const struct drm_display_mode *mode,
+				bool bigjoiner);
 enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
 bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 2c29e7f5281b..d123e5a508c1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -254,6 +254,29 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
+static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
+{
+	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);
+
+	return INTEL_GEN(dev_priv) >= 12 ||
+		(INTEL_GEN(dev_priv) == 11 &&
+		 encoder->port != PORT_A);
+}
+
+static int intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
+{
+	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &intel_dig_port->base;
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+
+	if (allow_bigjoiner && intel_dp_can_bigjoiner(intel_dp))
+		return 2 * dev_priv->max_dotclk_freq;
+
+	return dev_priv->max_dotclk_freq;
+}
+
 static int cnl_max_source_rate(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -519,7 +542,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;
@@ -537,6 +561,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);
 
@@ -546,6 +574,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",
@@ -568,7 +605,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;
@@ -595,12 +633,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",
@@ -684,10 +730,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
 	const struct drm_display_info *info = &connector->base.display_info;
 	int tmds_clock;
 
-	if (intel_dp->dfp.max_dotclock &&
-	    target_clock > intel_dp->dfp.max_dotclock)
-		return MODE_CLOCK_HIGH;
-
 	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
 	tmds_clock = target_clock;
 	if (drm_mode_is_420_only(info, mode))
@@ -717,6 +759,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	u16 dsc_max_output_bpp = 0;
 	u8 dsc_slice_count = 0;
 	enum drm_mode_status status;
+	bool dsc = false, bigjoiner = false;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
@@ -724,6 +767,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	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)
 			return MODE_PANEL;
@@ -737,6 +782,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	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 = intel_dp_can_bigjoiner(intel_dp);
+	}
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -765,24 +822,35 @@ 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_rate > max_rate && !dsc) {
+		DRM_DEBUG_KMS("Cannot drive without DSC\n");
+		return MODE_CLOCK_HIGH;
+	}
 
 	status = intel_dp_mode_valid_downstream(intel_connector,
 						mode, target_clock);
 	if (status != MODE_OK)
 		return status;
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
 }
 
 u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
@@ -2297,11 +2365,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");
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index c8fcec4d0788..fd5faa5d7c22 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -714,7 +714,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 		return 0;
 	}
 
-	*status = intel_mode_valid_max_plane_size(dev_priv, mode);
+	*status = intel_mode_valid_max_plane_size(dev_priv, mode, true);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
index afa4e6817e8c..f453ceb8d149 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi.c
@@ -75,7 +75,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
 			return MODE_CLOCK_HIGH;
 	}
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
 }
 
 struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index f90838bc74fb..82674a8853c6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,7 +2274,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 	if (status != MODE_OK)
 		return status;
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
 }
 
 bool intel_hdmi_deep_color_possible(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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 05/12] drm/i915/dp: Prep for bigjoiner atomic check
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (3 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in " Manasi Navare
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

No functional changes here. Just pass intel_atomic_state
along with crtc_state to certain atomic_check functions.
This will lay the foundation for adding bigjoiner master/slave
states in atomic check.

Cc: Ville Syrjälä <ville.syrjala@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 | 21 ++++++++++++--------
 3 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 86be032bcf96..e243ce97b534 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 285de07011dc..62a3365ed5e6 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 1c2d67ae361d..92cd38964142 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -13442,13 +13442,17 @@ 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;
+
+	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;
@@ -13456,7 +13460,7 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
 	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
 	crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter;
 
-	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)
@@ -13479,7 +13483,8 @@ 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)
+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);
@@ -13511,7 +13516,7 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
 	kfree(saved_state);
 
-	intel_crtc_copy_uapi_to_hw_state(crtc_state);
+	intel_crtc_copy_uapi_to_hw_state(state, crtc_state);
 
 	return 0;
 }
@@ -15212,12 +15217,12 @@ 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);
+		ret = intel_crtc_prepare_cleared_state(state, new_crtc_state);
 		if (ret)
 			goto fail;
 
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in atomic check
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (4 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 05/12] drm/i915/dp: Prep for bigjoiner atomic check Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-23 17:42   ` Ville Syrjälä
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave Manasi Navare
                   ` (10 subsequent siblings)
  16 siblings, 2 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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.

v4:
* Fixes in intel_crtc_compute_config (Ville)
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_display.c  | 181 ++++++++++++++++--
 .../drm/i915/display/intel_display_types.h    |   9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  22 ++-
 3 files changed, 191 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 92cd38964142..ffee6afe4ddb 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8237,9 +8237,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;
 
@@ -8300,7 +8315,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_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -12657,7 +12672,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)
 {
@@ -12666,7 +12681,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;
 
@@ -12906,6 +12921,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)
@@ -13447,6 +13463,15 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *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);
 }
 
@@ -13482,6 +13507,47 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
 				  crtc_state->hw.ctm);
 }
 
+static int
+copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
+			  const struct intel_crtc_state *from_crtc_state)
+{
+	struct intel_crtc_state *saved_state;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+	if (!saved_state)
+		return -ENOMEM;
+
+	saved_state->uapi = crtc_state->uapi;
+	saved_state->scaler_state = crtc_state->scaler_state;
+	saved_state->shared_dpll = crtc_state->shared_dpll;
+	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
+	saved_state->crc_enabled = crtc_state->crc_enabled;
+
+	intel_crtc_free_hw_state(crtc_state);
+	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
+	kfree(saved_state);
+
+	/* Re-init hw state */
+	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
+	crtc_state->hw.enable = from_crtc_state->hw.enable;
+	crtc_state->hw.active = from_crtc_state->hw.active;
+	crtc_state->hw.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)
@@ -13522,10 +13588,10 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
 }
 
 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;
@@ -13567,7 +13633,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);
 
@@ -13605,7 +13671,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);
 
@@ -13657,9 +13723,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
 		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
 		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
-	/* without bigjoiner, pipe_mode == adjusted_mode */
-	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
-
 	return 0;
 }
 
@@ -15055,6 +15118,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;
+}
+
 /**
  * DOC: asynchronous flip implementation
  *
@@ -15222,14 +15354,31 @@ static int intel_atomic_check(struct drm_device *dev,
 			continue;
 		}
 
+		/* 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;
 	}
@@ -15567,7 +15716,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 b526afee595c..59ed94d68b55 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1070,6 +1070,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 d123e5a508c1..cb604899a881 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2349,6 +2349,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,
@@ -2366,12 +2375,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");
@@ -2387,14 +2396,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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (5 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in " Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-26 21:56   ` Navare, Manasi
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
                   ` (9 subsequent siblings)
  16 siblings, 1 reply; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

Make vdsc work when no output is enabled. The big joiner needs VDSC
on the slave, so enable it and set the appropriate bits.
So remove encoder usage from dsc functions.

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     |   9 +-
 drivers/gpu/drm/i915/display/intel_display.c |   3 +
 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    |   6 +-
 6 files changed, 110 insertions(+), 117 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 096652921453..0fecf372be11 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1492,7 +1492,7 @@ 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);
+	intel_dsc_get_config(pipe_config);
 
 	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
 	pipe_config->port_clock = intel_dpll_get_freq(i915,
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 09811be08cfe..59db465ea7df 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2216,13 +2216,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
 	    intel_phy_is_tc(dev_priv, phy))
 		intel_display_power_get(dev_priv,
 					intel_ddi_main_link_aux_domain(dig_port));
-
-	/*
-	 * VDSC power is needed when DSC is enabled
-	 */
-	if (crtc_state->dsc.compression_enable)
-		intel_display_power_get(dev_priv,
-					intel_dsc_power_domain(crtc_state));
 }
 
 void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
@@ -4408,7 +4401,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
 		return;
 
-	intel_dsc_get_config(encoder, pipe_config);
+	intel_dsc_get_config(pipe_config);
 
 	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index ffee6afe4ddb..338fa48a144d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7602,6 +7602,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;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index cb604899a881..3ce419e71a83 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2066,12 +2066,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..65d301c23580 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.h
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
@@ -11,15 +11,13 @@
 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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (6 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-23  7:57     ` Dan Carpenter
                     ` (2 more replies)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case Manasi Navare
                   ` (8 subsequent siblings)
  16 siblings, 3 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

Enabling is done in a special sequence and so should plane updates
be. Ideally the end user never notices the second pipe is used.

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

This uses generic modeset_enables() calls like trans port sync
but still has special handling for disable since for slave we
should not disable things like encoder, plls that are not enabled
for  slave.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  25 +++-
 drivers/gpu/drm/i915/display/intel_display.c | 118 +++++++++++++++----
 2 files changed, 118 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 59db465ea7df..050891a130c1 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"
@@ -3500,7 +3501,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,
@@ -3572,7 +3574,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,
@@ -3821,6 +3824,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
@@ -4037,7 +4055,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);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 338fa48a144d..1be77ba2f9cf 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7232,6 +7232,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 	intel_de_write(dev_priv, reg, val);
 }
 
+static void icl_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)
 {
@@ -7245,34 +7284,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->bigjoiner) {
+		intel_encoders_pre_pll_enable(state, crtc);
 
-	if (new_crtc_state->shared_dpll)
-		intel_enable_shared_dpll(new_crtc_state);
-
-	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 {
+		icl_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;
 
@@ -7308,6 +7352,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) {
@@ -15683,6 +15732,9 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
 
 	dev_priv->display.crtc_enable(state, crtc);
 
+	if (new_crtc_state->bigjoiner_slave)
+		return;
+
 	/* vblanks work again, re-enable pipe CRC. */
 	intel_crtc_enable_pipe_crc(crtc);
 }
@@ -15747,8 +15799,21 @@ 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);
 
+	/*
+	 * We still need special handling for disabling bigjoiner master
+	 * and slaves since for slave we do not have encoder or plls
+	 * so we dont need to disable those.
+	 */
+	if (old_crtc_state->bigjoiner) {
+		intel_crtc_disable_planes(state,
+					  old_crtc_state->bigjoiner_linked_crtc);
+		old_crtc_state->bigjoiner_linked_crtc->active = false;
+	}
+
 	/*
 	 * We need to disable pipe CRC before disabling the pipe,
 	 * or we race against vblank off.
@@ -15777,7 +15842,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)
 			continue;
 
 		if (!old_crtc_state->hw.active)
@@ -15802,10 +15867,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);
@@ -15903,7 +15976,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			continue;
 
 		if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
-		    is_trans_port_sync_master(new_crtc_state))
+		    is_trans_port_sync_master(new_crtc_state) ||
+		    (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave))
 			continue;
 
 		modeset_pipes &= ~BIT(pipe);
@@ -15913,7 +15987,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 
 	/*
 	 * Then we enable all remaining pipes that depend on other
-	 * pipes: MST slaves and port sync masters.
+	 * pipes: MST slaves and port sync masters, big joiner master
 	 */
 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
 		enum pipe pipe = crtc->pipe;
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (7 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-23 18:00   ` Ville Syrjälä
  2020-10-26 22:29   ` Navare, Manasi
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
                   ` (7 subsequent siblings)
  16 siblings, 2 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5:42 UTC (permalink / raw)
  To: intel-gfx

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

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

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

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

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
 drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
 .../drm/i915/display/intel_display_types.h    |   1 +
 4 files changed, 260 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
index 0fecf372be11..104a423e0cd5 100644
--- a/drivers/gpu/drm/i915/display/icl_dsi.c
+++ b/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4408,20 +4408,14 @@ 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);
 	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
 	u32 temp, flags = 0;
 
-	/* XXX: DSI transcoder paranoia */
-	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
-		return;
-
-	intel_dsc_get_config(pipe_config);
-
 	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
 	if (temp & TRANS_DDI_PHSYNC)
 		flags |= DRM_MODE_FLAG_PHSYNC;
@@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
 	default:
 		break;
 	}
+}
+
+void intel_ddi_get_config(struct intel_encoder *encoder,
+			  struct intel_crtc_state *pipe_config)
+{
+	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
+
+	/* XXX: DSI transcoder paranoia */
+	if (drm_WARN_ON(&dev_priv->drm, 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);
@@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3631,6 +3631,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;
 
@@ -3653,7 +3655,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);
@@ -3675,6 +3677,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;
 
@@ -8272,6 +8279,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);
@@ -9186,20 +9217,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);
 }
@@ -10768,6 +10801,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);
@@ -10876,6 +10910,13 @@ 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) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "Does not support Bigjoiner Fb stretching yet\n");
+		goto error;
+	}
+
 	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;
@@ -11366,6 +11407,8 @@ 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
@@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		active = true;
 	}
 
-	if (!active)
-		goto out;
+	intel_dsc_get_config(pipe_config);
 
-	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
+	if (!active) {
+		/* bigjoiner slave doesn't enable transcoder */
+		if (!pipe_config->bigjoiner_slave)
+			goto out;
+
+		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);
@@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
 		}
 	}
 
-	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
+	if (pipe_config->bigjoiner_slave) {
+		/* Cannot be read out as a slave, set to 0. */
+		pipe_config->pixel_multiplier = 0;
+	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
 	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
 		pipe_config->pixel_multiplier =
 			intel_de_read(dev_priv,
@@ -12536,7 +12591,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);
 
@@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
+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);
-
+	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;
 	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
 
@@ -14183,21 +14240,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)) ||
@@ -14207,24 +14285,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)
@@ -14250,7 +14315,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))
@@ -14271,48 +14337,50 @@ 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(port_clock);
+
+		PIPE_CONF_CHECK_I(min_voltage_level);
+	}
 
 	PIPE_CONF_CHECK_X(infoframes.enable);
 	PIPE_CONF_CHECK_X(infoframes.gcp);
@@ -14324,6 +14392,9 @@ 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);
@@ -14595,6 +14666,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;
 
 	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
 	intel_crtc_free_hw_state(old_crtc_state);
@@ -14623,7 +14695,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;
 		bool active;
 
@@ -14633,12 +14708,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);
@@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;
 
 		/*
@@ -18856,7 +18931,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)) {
@@ -19067,9 +19143,19 @@ 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);
 			if (encoder->sync_state)
 				encoder->sync_state(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;
 		}
@@ -19125,16 +19211,15 @@ 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 = &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
@@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
 			/* 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;
+
+			if (crtc_state->bigjoiner)
+				mode.hdisplay *= 2;
+
 			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) {
@@ -19199,6 +19291,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);
+		}
 	}
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 59ed94d68b55..d82ba1b9d8ef 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -845,6 +845,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 */
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (8 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-26 20:18   ` Ville Syrjälä
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 11/12] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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.

v6:
* Fix from_plane_state assignments (Manasi)
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 |  53 ++++-
 .../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(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 3334ff253600..5df928f8f322 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -246,12 +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);
 
-	plane_state->hw.crtc = from_plane_state->uapi.crtc;
+	if (from_plane_state->uapi.crtc)
+		plane_state->hw.crtc = crtc_state->uapi.crtc;
+	else
+		plane_state->hw.crtc = NULL;
+
 	plane_state->hw.fb = from_plane_state->uapi.fb;
 	if (plane_state->hw.fb)
 		drm_framebuffer_get(plane_state->hw.fb);
@@ -320,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;
 }
 
@@ -339,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 c0715a3ea47b..579cccc1fd91 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3718,7 +3718,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);
 
@@ -12801,26 +12801,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;
 
-		linked_plane_state = intel_atomic_get_plane_state(state, linked);
-		if (IS_ERR(linked_plane_state))
-			return PTR_ERR(linked_plane_state);
+			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_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;
@@ -12860,6 +13014,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)))
@@ -12903,7 +13058,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;
 
@@ -15253,6 +15415,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) {
@@ -15263,6 +15426,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;
 
@@ -15287,7 +15456,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 "
@@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3144,7 +3144,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;
@@ -3154,7 +3154,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)
@@ -3873,7 +3873,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;
 
@@ -3886,7 +3886,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];
 
@@ -4708,12 +4708,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;
 
@@ -4735,12 +4735,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;
 
@@ -5587,7 +5587,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;
 
@@ -5597,7 +5597,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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 11/12] drm/i915: Add bigjoiner aware plane clipping checks
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (9 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 12/12] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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)

v3:
* hw.rotation instead of uapi.rotation (Ville)

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 5df928f8f322..32a013798836 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.color_encoding = from_plane_state->uapi.color_encoding;
 	plane_state->hw.color_range = from_plane_state->uapi.color_range;
 	plane_state->hw.scaling_filter = from_plane_state->uapi.scaling_filter;
+
+	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,
@@ -520,6 +523,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->hw.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 579cccc1fd91..e706f202e195 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4414,12 +4414,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;
 
@@ -11701,11 +11699,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 b6deeb338477..172453821b64 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -2059,10 +2059,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;
 
@@ -2117,11 +2115,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;
 
@@ -2328,10 +2325,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] 49+ messages in thread

* [Intel-gfx] [PATCH v11 12/12] drm/i915: Add debugfs dumping for bigjoiner, v3.
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (10 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 11/12] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
@ 2020-10-22  5:42 ` Manasi Navare
  2020-10-22  6:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Big joiner enabling Patchwork
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-22  5: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 cfb4c1474982..963069b266ab 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -755,6 +755,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 =
@@ -773,12 +784,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)
@@ -874,6 +895,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] 49+ messages in thread

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Big joiner enabling
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (11 preceding siblings ...)
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 12/12] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
@ 2020-10-22  6:01 ` Patchwork
  2020-10-22  6:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Patchwork @ 2020-10-22  6:01 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

Series: Big joiner enabling
URL   : https://patchwork.freedesktop.org/series/82944/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
28921f36dd2c HAX to make DSC work on the icelake test system
4e9e1fe595d7 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
-:7: WARNING:TYPO_SPELLING: 'halfs' may be misspelled - perhaps 'halves'?
#7: 
With bigjoiner, there will be 2 pipes driving 2 halfs of 1 transcoder,

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

total: 0 errors, 1 warnings, 1 checks, 366 lines checked
c4a7f00c7188 drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes
f2fbe5b3f867 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
4e7811e6d8ed drm/i915/dp: Prep for bigjoiner atomic check
f5dd757111ef drm/i915: Try to make bigjoiner work in atomic check
-:100: WARNING:LONG_LINE: line length of 101 exceeds 100 columns
#100: FILE: drivers/gpu/drm/i915/display/intel_display.c:13472:
+								  crtc_state->bigjoiner_linked_crtc);

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

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

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

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

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

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

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

total: 0 errors, 3 warnings, 5 checks, 337 lines checked
c5aeb07221de drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave
eeb383630551 drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
-:120: ERROR:CODE_INDENT: code indent should use tabs where possible
#120: FILE: drivers/gpu/drm/i915/display/intel_display.c:7263:
+                 * Enable sequence steps 1-7 on bigjoiner master$

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

-:164: ERROR:SPACING: space required before the open brace '{'
#164: FILE: drivers/gpu/drm/i915/display/intel_display.c:7302:
+	if (!new_crtc_state->bigjoiner_slave || !transcoder_is_dsi(cpu_transcoder)){

-:165: WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (16, 16)
#165: FILE: drivers/gpu/drm/i915/display/intel_display.c:7303:
+		if (!transcoder_is_dsi(cpu_transcoder))
+		intel_set_transcoder_timings(new_crtc_state);

total: 3 errors, 1 warnings, 0 checks, 242 lines checked
c95ea184d537 drm/i915: HW state readout for Bigjoiner case
-:79: WARNING:LONG_LINE_COMMENT: line length of 106 exceeds 100 columns
#79: FILE: drivers/gpu/drm/i915/display/intel_ddi.c:4529:
+		/* Our own transcoder needs to be disabled when reading it in intel_ddi_read_func_ctl() */

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

-:106: WARNING:TABSTOP: Statements should start on a tabstop
#106: FILE: drivers/gpu/drm/i915/display/intel_display.c:3634:
+	 struct intel_crtc_state *crtc_state =

-:246: WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#246: FILE: drivers/gpu/drm/i915/display/intel_display.c:11501:
+^I} else ^Iif (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||$

-:258: WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#258: FILE: drivers/gpu/drm/i915/display/intel_display.c:11579:
+^I} else ^Iif (pipe_config->cpu_transcoder != TRANSCODER_EDP &&$

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

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

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

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

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

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

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

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

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

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

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

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

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

total: 6 errors, 6 warnings, 0 checks, 482 lines checked
bf37cfa8496f drm/i915: Add bigjoiner aware plane clipping checks
040cc02e306c 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:787:
+	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:797:
+			   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:801:
+			   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] 49+ messages in thread

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for Big joiner enabling
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (12 preceding siblings ...)
  2020-10-22  6:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Big joiner enabling Patchwork
@ 2020-10-22  6:03 ` Patchwork
  2020-10-22  6:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 49+ messages in thread
From: Patchwork @ 2020-10-22  6:03 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

Series: Big joiner enabling
URL   : https://patchwork.freedesktop.org/series/82944/
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/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+./drivers/gpu/drm/amd/amdgpu/../amdgpu/amdgv_sriovmsg.h:261:49: error: static assertion failed: "amd_sriov_msg_pf2vf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1367:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1367:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1367:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1368:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1368:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1368:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1427:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1427:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c:1427:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:262:16: error: incompatible types in comparison expression (different type sizes):
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:262:16:    unsigned long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_device.c:262:16:    unsigned long long *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:274:25: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:274:25:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:274:25:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:275:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:275:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:275:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:330:17: error: incompatible types in comparison expression (different address spaces):
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:330:17:    struct dma_fence *
+drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c:330:17:    struct dma_fence [noderef] __rcu *
+drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h:92:56: error: marked inline, but without a definition
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49: error: static assertion failed: "amd_sriov_msg_vf2pf_info must be 1 KB"
+drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h:257:49:


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

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for Big joiner enabling
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (13 preceding siblings ...)
  2020-10-22  6:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
@ 2020-10-22  6:26 ` Patchwork
  2020-10-22  8:09 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
  2020-10-28  0:28 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for Big joiner enabling (rev5) Patchwork
  16 siblings, 0 replies; 49+ messages in thread
From: Patchwork @ 2020-10-22  6:26 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


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

== Series Details ==

Series: Big joiner enabling
URL   : https://patchwork.freedesktop.org/series/82944/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_9180 -> Patchwork_18761
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

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

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

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

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-kbl-7500u:       [PASS][1] -> [DMESG-FAIL][2] ([i915#165])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/fi-kbl-7500u/igt@kms_chamelium@hdmi-edid-read.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/fi-kbl-7500u/igt@kms_chamelium@hdmi-edid-read.html

  * igt@kms_cursor_legacy@basic-flip-after-cursor-atomic:
    - fi-icl-u2:          [PASS][3] -> [DMESG-WARN][4] ([i915#1982])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/fi-icl-u2/igt@kms_cursor_legacy@basic-flip-after-cursor-atomic.html

  
#### Possible fixes ####

  * igt@kms_chamelium@hdmi-crc-fast:
    - fi-kbl-7500u:       [DMESG-WARN][5] ([i915#2203]) -> [PASS][6]
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/fi-kbl-7500u/igt@kms_chamelium@hdmi-crc-fast.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/fi-kbl-7500u/igt@kms_chamelium@hdmi-crc-fast.html
    - fi-icl-u2:          [FAIL][7] ([i915#1161]) -> [PASS][8]
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/fi-icl-u2/igt@kms_chamelium@hdmi-crc-fast.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/fi-icl-u2/igt@kms_chamelium@hdmi-crc-fast.html

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

  
#### Warnings ####

  * igt@i915_pm_rpm@module-reload:
    - fi-kbl-guc:         [DMESG-WARN][11] ([i915#2203]) -> [DMESG-FAIL][12] ([i915#2203])
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/fi-kbl-guc/igt@i915_pm_rpm@module-reload.html

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

  [i915#1161]: https://gitlab.freedesktop.org/drm/intel/issues/1161
  [i915#165]: https://gitlab.freedesktop.org/drm/intel/issues/165
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2203]: https://gitlab.freedesktop.org/drm/intel/issues/2203


Participating hosts (45 -> 36)
------------------------------

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


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

  * Linux: CI_DRM_9180 -> Patchwork_18761

  CI-20190529: 20190529
  CI_DRM_9180: b174cec7fd714a954d4a65088ca53e32ae9cd45e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5822: b4bcf05cb9839037128905deda7146434155cc41 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18761: 040cc02e306c96264ba552adc8c96a7fcd09d386 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

040cc02e306c drm/i915: Add debugfs dumping for bigjoiner, v3.
bf37cfa8496f drm/i915: Add bigjoiner aware plane clipping checks
ed5b71b1f929 drm/i915: Link planes in a bigjoiner configuration, v3.
c95ea184d537 drm/i915: HW state readout for Bigjoiner case
eeb383630551 drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
c5aeb07221de drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave
f5dd757111ef drm/i915: Try to make bigjoiner work in atomic check
4e7811e6d8ed drm/i915/dp: Prep for bigjoiner atomic check
f2fbe5b3f867 drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
c4a7f00c7188 drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes
4e9e1fe595d7 drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
28921f36dd2c 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_18761/index.html

[-- Attachment #1.2: Type: text/html, Size: 5717 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] 49+ messages in thread

* [Intel-gfx] ✓ Fi.CI.IGT: success for Big joiner enabling
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (14 preceding siblings ...)
  2020-10-22  6:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-10-22  8:09 ` Patchwork
  2020-10-28  0:28 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for Big joiner enabling (rev5) Patchwork
  16 siblings, 0 replies; 49+ messages in thread
From: Patchwork @ 2020-10-22  8:09 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx


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

== Series Details ==

Series: Big joiner enabling
URL   : https://patchwork.freedesktop.org/series/82944/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_9180_full -> Patchwork_18761_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

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

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

### IGT changes ###

#### Suppressed ####

  The following results come from untrusted machines, tests, or statuses.
  They do not affect the overall result.

  * {igt@core_hotunplug@hotrebind}:
    - shard-hsw:          NOTRUN -> [WARN][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-hsw6/igt@core_hotunplug@hotrebind.html

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

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

### IGT changes ###

#### Issues hit ####

  * igt@gem_busy@extended@bcs0:
    - shard-snb:          [PASS][2] -> [INCOMPLETE][3] ([i915#82])
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-snb5/igt@gem_busy@extended@bcs0.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-snb2/igt@gem_busy@extended@bcs0.html

  * igt@gem_exec_suspend@basic:
    - shard-glk:          [PASS][4] -> [FAIL][5] ([i915#1888])
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk7/igt@gem_exec_suspend@basic.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk7/igt@gem_exec_suspend@basic.html

  * igt@gen9_exec_parse@allowed-all:
    - shard-apl:          [PASS][6] -> [DMESG-WARN][7] ([i915#1436] / [i915#1635] / [i915#716])
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-apl8/igt@gen9_exec_parse@allowed-all.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-apl1/igt@gen9_exec_parse@allowed-all.html

  * igt@i915_pm_rc6_residency@rc6-fence:
    - shard-hsw:          [PASS][8] -> [WARN][9] ([i915#1519])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-hsw7/igt@i915_pm_rc6_residency@rc6-fence.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-hsw8/igt@i915_pm_rc6_residency@rc6-fence.html

  * igt@i915_suspend@debugfs-reader:
    - shard-kbl:          [PASS][10] -> [INCOMPLETE][11] ([i915#155])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-kbl1/igt@i915_suspend@debugfs-reader.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-kbl6/igt@i915_suspend@debugfs-reader.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-skl:          [PASS][12] -> [INCOMPLETE][13] ([i915#198])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl2/igt@i915_suspend@fence-restore-tiled2untiled.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl7/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_big_fb@y-tiled-8bpp-rotate-180:
    - shard-kbl:          [PASS][14] -> [DMESG-WARN][15] ([i915#1982]) +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-kbl1/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-kbl6/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html

  * igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge:
    - shard-skl:          [PASS][16] -> [DMESG-WARN][17] ([i915#1982]) +3 similar issues
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl6/igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl10/igt@kms_cursor_edge_walk@pipe-b-256x256-right-edge.html

  * igt@kms_cursor_legacy@flip-vs-cursor-legacy:
    - shard-skl:          [PASS][18] -> [FAIL][19] ([i915#2346])
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl3/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl3/igt@kms_cursor_legacy@flip-vs-cursor-legacy.html

  * igt@kms_draw_crc@draw-method-rgb565-mmap-cpu-untiled:
    - shard-hsw:          [PASS][20] -> [DMESG-WARN][21] ([i915#1982])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-hsw1/igt@kms_draw_crc@draw-method-rgb565-mmap-cpu-untiled.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-hsw6/igt@kms_draw_crc@draw-method-rgb565-mmap-cpu-untiled.html

  * igt@kms_draw_crc@draw-method-xrgb8888-render-xtiled:
    - shard-snb:          [PASS][22] -> [FAIL][23] ([i915#54]) +1 similar issue
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-snb5/igt@kms_draw_crc@draw-method-xrgb8888-render-xtiled.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-snb2/igt@kms_draw_crc@draw-method-xrgb8888-render-xtiled.html

  * igt@kms_frontbuffer_tracking@fbc-shrfb-scaledprimary:
    - shard-tglb:         [PASS][24] -> [DMESG-WARN][25] ([i915#1982]) +2 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-tglb5/igt@kms_frontbuffer_tracking@fbc-shrfb-scaledprimary.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-tglb7/igt@kms_frontbuffer_tracking@fbc-shrfb-scaledprimary.html

  * igt@kms_hdr@bpc-switch-suspend:
    - shard-skl:          [PASS][26] -> [FAIL][27] ([i915#1188])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl6/igt@kms_hdr@bpc-switch-suspend.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl10/igt@kms_hdr@bpc-switch-suspend.html

  * igt@kms_plane_alpha_blend@pipe-b-coverage-7efc:
    - shard-skl:          [PASS][28] -> [FAIL][29] ([fdo#108145] / [i915#265])
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl7/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl1/igt@kms_plane_alpha_blend@pipe-b-coverage-7efc.html

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         [PASS][30] -> [SKIP][31] ([fdo#109441]) +1 similar issue
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-iclb2/igt@kms_psr@psr2_cursor_render.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-iclb8/igt@kms_psr@psr2_cursor_render.html

  * igt@kms_universal_plane@universal-plane-gen9-features-pipe-a:
    - shard-apl:          [PASS][32] -> [DMESG-WARN][33] ([i915#1635] / [i915#1982])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-apl3/igt@kms_universal_plane@universal-plane-gen9-features-pipe-a.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-apl4/igt@kms_universal_plane@universal-plane-gen9-features-pipe-a.html

  * igt@kms_vblank@pipe-a-accuracy-idle:
    - shard-glk:          [PASS][34] -> [FAIL][35] ([i915#43])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk2/igt@kms_vblank@pipe-a-accuracy-idle.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk5/igt@kms_vblank@pipe-a-accuracy-idle.html

  * igt@perf@blocking:
    - shard-skl:          [PASS][36] -> [FAIL][37] ([i915#1542]) +1 similar issue
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl9/igt@perf@blocking.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl2/igt@perf@blocking.html

  
#### Possible fixes ####

  * igt@core_hotunplug@unbind-rebind:
    - shard-skl:          [DMESG-WARN][38] ([i915#1982]) -> [PASS][39] +5 similar issues
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl10/igt@core_hotunplug@unbind-rebind.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl8/igt@core_hotunplug@unbind-rebind.html
    - shard-iclb:         [DMESG-WARN][40] ([i915#1982]) -> [PASS][41]
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-iclb4/igt@core_hotunplug@unbind-rebind.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-iclb4/igt@core_hotunplug@unbind-rebind.html

  * igt@gem_exec_reloc@basic-many-active@rcs0:
    - shard-hsw:          [FAIL][42] ([i915#2389]) -> [PASS][43]
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-hsw5/igt@gem_exec_reloc@basic-many-active@rcs0.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-hsw8/igt@gem_exec_reloc@basic-many-active@rcs0.html
    - shard-snb:          [FAIL][44] ([i915#2389]) -> [PASS][45]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-snb5/igt@gem_exec_reloc@basic-many-active@rcs0.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-snb4/igt@gem_exec_reloc@basic-many-active@rcs0.html

  * igt@gem_exec_schedule@pi-common@bcs0:
    - shard-apl:          [INCOMPLETE][46] ([i915#1635]) -> [PASS][47]
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-apl7/igt@gem_exec_schedule@pi-common@bcs0.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-apl3/igt@gem_exec_schedule@pi-common@bcs0.html

  * igt@gem_exec_whisper@basic-contexts-priority-all:
    - shard-iclb:         [INCOMPLETE][48] -> [PASS][49]
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-iclb2/igt@gem_exec_whisper@basic-contexts-priority-all.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-iclb6/igt@gem_exec_whisper@basic-contexts-priority-all.html

  * igt@gem_exec_whisper@basic-fds-all:
    - shard-glk:          [DMESG-WARN][50] ([i915#118] / [i915#95]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk4/igt@gem_exec_whisper@basic-fds-all.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk9/igt@gem_exec_whisper@basic-fds-all.html

  * igt@gem_exec_whisper@basic-queues-priority-all:
    - shard-skl:          [FAIL][52] -> [PASS][53]
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl6/igt@gem_exec_whisper@basic-queues-priority-all.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl10/igt@gem_exec_whisper@basic-queues-priority-all.html

  * igt@gem_userptr_blits@unsync-unmap-cycles:
    - shard-skl:          [TIMEOUT][54] ([i915#2424]) -> [PASS][55]
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl3/igt@gem_userptr_blits@unsync-unmap-cycles.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl3/igt@gem_userptr_blits@unsync-unmap-cycles.html

  * igt@gen9_exec_parse@allowed-single:
    - shard-skl:          [DMESG-WARN][56] ([i915#1436] / [i915#716]) -> [PASS][57]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl3/igt@gen9_exec_parse@allowed-single.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl7/igt@gen9_exec_parse@allowed-single.html

  * igt@i915_pm_dc@dc6-psr:
    - shard-skl:          [INCOMPLETE][58] ([i915#198]) -> [PASS][59]
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl1/igt@i915_pm_dc@dc6-psr.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl1/igt@i915_pm_dc@dc6-psr.html

  * {igt@kms_async_flips@async-flip-with-page-flip-events}:
    - shard-kbl:          [FAIL][60] ([i915#2521]) -> [PASS][61]
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-kbl4/igt@kms_async_flips@async-flip-with-page-flip-events.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-kbl7/igt@kms_async_flips@async-flip-with-page-flip-events.html

  * igt@kms_big_fb@linear-32bpp-rotate-180:
    - shard-glk:          [DMESG-FAIL][62] ([i915#118] / [i915#95]) -> [PASS][63]
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk5/igt@kms_big_fb@linear-32bpp-rotate-180.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk1/igt@kms_big_fb@linear-32bpp-rotate-180.html

  * igt@kms_big_fb@y-tiled-8bpp-rotate-180:
    - shard-apl:          [DMESG-WARN][64] ([i915#1635] / [i915#1982]) -> [PASS][65]
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-apl7/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-apl6/igt@kms_big_fb@y-tiled-8bpp-rotate-180.html

  * igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled:
    - shard-snb:          [SKIP][66] ([fdo#109271]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-snb5/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-snb2/igt@kms_draw_crc@draw-method-rgb565-pwrite-untiled.html

  * igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1:
    - shard-glk:          [FAIL][68] ([i915#79]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk2/igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk2/igt@kms_flip@flip-vs-expired-vblank@b-hdmi-a1.html

  * igt@kms_frontbuffer_tracking@fbc-modesetfrombusy:
    - shard-glk:          [FAIL][70] ([i915#49]) -> [PASS][71]
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-glk7/igt@kms_frontbuffer_tracking@fbc-modesetfrombusy.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-glk7/igt@kms_frontbuffer_tracking@fbc-modesetfrombusy.html
    - shard-snb:          [FAIL][72] ([i915#2546]) -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-snb5/igt@kms_frontbuffer_tracking@fbc-modesetfrombusy.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-snb2/igt@kms_frontbuffer_tracking@fbc-modesetfrombusy.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render:
    - shard-tglb:         [DMESG-WARN][74] ([i915#1982]) -> [PASS][75]
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-tglb2/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-tglb1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-render.html

  * igt@kms_hdr@bpc-switch-dpms:
    - shard-skl:          [FAIL][76] ([i915#1188]) -> [PASS][77]
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl10/igt@kms_hdr@bpc-switch-dpms.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl8/igt@kms_hdr@bpc-switch-dpms.html

  * igt@kms_psr@psr2_sprite_plane_move:
    - shard-iclb:         [SKIP][78] ([fdo#109441]) -> [PASS][79] +1 similar issue
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-iclb6/igt@kms_psr@psr2_sprite_plane_move.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-iclb2/igt@kms_psr@psr2_sprite_plane_move.html

  * igt@perf@polling-parameterized:
    - shard-iclb:         [FAIL][80] ([i915#1542]) -> [PASS][81]
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-iclb5/igt@perf@polling-parameterized.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-iclb5/igt@perf@polling-parameterized.html

  
#### Warnings ####

  * igt@kms_flip@flip-vs-suspend-interruptible@a-edp1:
    - shard-skl:          [DMESG-WARN][82] ([i915#1982]) -> [INCOMPLETE][83] ([i915#198] / [i915#1982])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-skl4/igt@kms_flip@flip-vs-suspend-interruptible@a-edp1.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/shard-skl8/igt@kms_flip@flip-vs-suspend-interruptible@a-edp1.html

  * igt@runner@aborted:
    - shard-apl:          [FAIL][84] ([i915#1610] / [i915#1635] / [i915#2439]) -> [FAIL][85] ([fdo#109271] / [i915#1635] / [i915#716])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_9180/shard-apl7/igt@runner@aborted.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_18761/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#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#1519]: https://gitlab.freedesktop.org/drm/intel/issues/1519
  [i915#1542]: https://gitlab.freedesktop.org/drm/intel/issues/1542
  [i915#155]: https://gitlab.freedesktop.org/drm/intel/issues/155
  [i915#1610]: https://gitlab.freedesktop.org/drm/intel/issues/1610
  [i915#1635]: https://gitlab.freedesktop.org/drm/intel/issues/1635
  [i915#1888]: https://gitlab.freedesktop.org/drm/intel/issues/1888
  [i915#198]: https://gitlab.freedesktop.org/drm/intel/issues/198
  [i915#1982]: https://gitlab.freedesktop.org/drm/intel/issues/1982
  [i915#2346]: https://gitlab.freedesktop.org/drm/intel/issues/2346
  [i915#2389]: https://gitlab.freedesktop.org/drm/intel/issues/2389
  [i915#2424]: https://gitlab.freedesktop.org/drm/intel/issues/2424
  [i915#2439]: https://gitlab.freedesktop.org/drm/intel/issues/2439
  [i915#2521]: https://gitlab.freedesktop.org/drm/intel/issues/2521
  [i915#2546]: https://gitlab.freedesktop.org/drm/intel/issues/2546
  [i915#265]: https://gitlab.freedesktop.org/drm/intel/issues/265
  [i915#43]: https://gitlab.freedesktop.org/drm/intel/issues/43
  [i915#49]: https://gitlab.freedesktop.org/drm/intel/issues/49
  [i915#54]: https://gitlab.freedesktop.org/drm/intel/issues/54
  [i915#716]: https://gitlab.freedesktop.org/drm/intel/issues/716
  [i915#79]: https://gitlab.freedesktop.org/drm/intel/issues/79
  [i915#82]: https://gitlab.freedesktop.org/drm/intel/issues/82
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95


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

  No changes in participating hosts


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

  * Linux: CI_DRM_9180 -> Patchwork_18761

  CI-20190529: 20190529
  CI_DRM_9180: b174cec7fd714a954d4a65088ca53e32ae9cd45e @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_5822: b4bcf05cb9839037128905deda7146434155cc41 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_18761: 040cc02e306c96264ba552adc8c96a7fcd09d386 @ 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_18761/index.html

[-- Attachment #1.2: Type: text/html, Size: 22277 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
  2020-10-23  7:57     ` Dan Carpenter
@ 2020-10-23  7:57     ` Dan Carpenter
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  2 siblings, 0 replies; 49+ messages in thread
From: Dan Carpenter @ 2020-10-23  7:57 UTC (permalink / raw)
  To: kbuild, Manasi Navare, intel-gfx; +Cc: kbuild-all

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

Hi Manasi,

url:    https://github.com/0day-ci/linux/commits/Manasi-Navare/Big-joiner-enabling/20201022-134216
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-m001-20201022 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:7303 hsw_crtc_enable() warn: if statement not indented

Old smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:6237 skl_update_scaler_plane() error: we previously assumed 'fb' could be null (see line 6221)
drivers/gpu/drm/i915/display/intel_display.c:15236 kill_bigjoiner_slave() warn: inconsistent indenting

vim +7303 drivers/gpu/drm/i915/display/intel_display.c

1e98f88cea0ff5 drivers/gpu/drm/i915/display/intel_display.c Lucas De Marchi   2019-12-24  7274  static void hsw_crtc_enable(struct intel_atomic_state *state,
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7275  			    struct intel_crtc *crtc)
6be4a6078e41a8 drivers/gpu/drm/i915/intel_display.c         Jesse Barnes      2010-09-10  7276  {
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7277  	const struct intel_crtc_state *new_crtc_state =
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7278  		intel_atomic_get_new_crtc_state(state, crtc);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7279  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7280  	enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7281  	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
ed69cd40685c94 drivers/gpu/drm/i915/intel_display.c         Imre Deak         2017-10-02  7282  	bool psl_clkgate_wa;
2c07245fb8f7f0 drivers/gpu/drm/i915/intel_display.c         Zhenyu Wang       2009-06-05  7283  
e57291c2d39522 drivers/gpu/drm/i915/display/intel_display.c Pankaj Bharadiya  2020-02-20  7284  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7285  		return;
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7286  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7287  	if (!new_crtc_state->bigjoiner) {
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7288  		intel_encoders_pre_pll_enable(state, crtc);
95a7a2ae46652f drivers/gpu/drm/i915/intel_display.c         Imre Deak         2016-06-13  7289  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7290  		if (new_crtc_state->shared_dpll)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7291  			intel_enable_shared_dpll(new_crtc_state);
df8ad70ca34f9b drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-06-25  7292  
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7293  		intel_encoders_pre_enable(state, crtc);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7294  	} else {
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7295  		icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7296  	}
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7297  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7298  	intel_set_pipe_src_size(new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7299  	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7300  		bdw_set_pipemisc(new_crtc_state);
c8af5274c3cbac drivers/gpu/drm/i915/intel_display.c         Paulo Zanoni      2018-05-02  7301  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7302  	if (!new_crtc_state->bigjoiner_slave || !transcoder_is_dsi(cpu_transcoder)){
d7edc4e57bfefc drivers/gpu/drm/i915/intel_display.c         Ville Syrjälä     2016-06-22 @7303  		if (!transcoder_is_dsi(cpu_transcoder))
e7fc3f902d76f1 drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-08  7304  		intel_set_transcoder_timings(new_crtc_state);
                                                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This looks correct, only the indenting is wrong.

4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7305  
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7306  		if (cpu_transcoder != TRANSCODER_EDP &&
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7307  		    !transcoder_is_dsi(cpu_transcoder))
dc008bf0aa091c drivers/gpu/drm/i915/display/intel_display.c Jani Nikula       2020-01-27  7308  			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7309  				       new_crtc_state->pixel_multiplier - 1);
ebb69c95175609 drivers/gpu/drm/i915/intel_display.c         Clint Taylor      2014-09-30  7310  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7311  		if (new_crtc_state->has_pch_encoder)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7312  			intel_cpu_transcoder_set_m_n(new_crtc_state,
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7313  						     &new_crtc_state->fdi_m_n, NULL);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7314  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7315  		hsw_set_frame_start_delay(new_crtc_state);
cc7a4cffea2195 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-10-24  7316  	}
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7317  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7318  	if (!transcoder_is_dsi(cpu_transcoder))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7319  		hsw_set_pipeconf(new_crtc_state);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7320  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

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

[-- Attachment #3: 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
@ 2020-10-23  7:57     ` Dan Carpenter
  0 siblings, 0 replies; 49+ messages in thread
From: Dan Carpenter @ 2020-10-23  7:57 UTC (permalink / raw)
  To: kbuild

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

Hi Manasi,

url:    https://github.com/0day-ci/linux/commits/Manasi-Navare/Big-joiner-enabling/20201022-134216
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-m001-20201022 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:7303 hsw_crtc_enable() warn: if statement not indented

Old smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:6237 skl_update_scaler_plane() error: we previously assumed 'fb' could be null (see line 6221)
drivers/gpu/drm/i915/display/intel_display.c:15236 kill_bigjoiner_slave() warn: inconsistent indenting

vim +7303 drivers/gpu/drm/i915/display/intel_display.c

1e98f88cea0ff5 drivers/gpu/drm/i915/display/intel_display.c Lucas De Marchi   2019-12-24  7274  static void hsw_crtc_enable(struct intel_atomic_state *state,
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7275  			    struct intel_crtc *crtc)
6be4a6078e41a8 drivers/gpu/drm/i915/intel_display.c         Jesse Barnes      2010-09-10  7276  {
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7277  	const struct intel_crtc_state *new_crtc_state =
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7278  		intel_atomic_get_new_crtc_state(state, crtc);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7279  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7280  	enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7281  	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
ed69cd40685c94 drivers/gpu/drm/i915/intel_display.c         Imre Deak         2017-10-02  7282  	bool psl_clkgate_wa;
2c07245fb8f7f0 drivers/gpu/drm/i915/intel_display.c         Zhenyu Wang       2009-06-05  7283  
e57291c2d39522 drivers/gpu/drm/i915/display/intel_display.c Pankaj Bharadiya  2020-02-20  7284  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7285  		return;
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7286  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7287  	if (!new_crtc_state->bigjoiner) {
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7288  		intel_encoders_pre_pll_enable(state, crtc);
95a7a2ae46652f drivers/gpu/drm/i915/intel_display.c         Imre Deak         2016-06-13  7289  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7290  		if (new_crtc_state->shared_dpll)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7291  			intel_enable_shared_dpll(new_crtc_state);
df8ad70ca34f9b drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-06-25  7292  
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7293  		intel_encoders_pre_enable(state, crtc);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7294  	} else {
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7295  		icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7296  	}
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7297  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7298  	intel_set_pipe_src_size(new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7299  	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7300  		bdw_set_pipemisc(new_crtc_state);
c8af5274c3cbac drivers/gpu/drm/i915/intel_display.c         Paulo Zanoni      2018-05-02  7301  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7302  	if (!new_crtc_state->bigjoiner_slave || !transcoder_is_dsi(cpu_transcoder)){
d7edc4e57bfefc drivers/gpu/drm/i915/intel_display.c         Ville Syrjälä     2016-06-22 @7303  		if (!transcoder_is_dsi(cpu_transcoder))
e7fc3f902d76f1 drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-08  7304  		intel_set_transcoder_timings(new_crtc_state);
                                                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This looks correct, only the indenting is wrong.

4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7305  
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7306  		if (cpu_transcoder != TRANSCODER_EDP &&
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7307  		    !transcoder_is_dsi(cpu_transcoder))
dc008bf0aa091c drivers/gpu/drm/i915/display/intel_display.c Jani Nikula       2020-01-27  7308  			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7309  				       new_crtc_state->pixel_multiplier - 1);
ebb69c95175609 drivers/gpu/drm/i915/intel_display.c         Clint Taylor      2014-09-30  7310  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7311  		if (new_crtc_state->has_pch_encoder)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7312  			intel_cpu_transcoder_set_m_n(new_crtc_state,
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7313  						     &new_crtc_state->fdi_m_n, NULL);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7314  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7315  		hsw_set_frame_start_delay(new_crtc_state);
cc7a4cffea2195 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-10-24  7316  	}
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7317  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7318  	if (!transcoder_is_dsi(cpu_transcoder))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7319  		hsw_set_pipeconf(new_crtc_state);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7320  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

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

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

* Re: [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
@ 2020-10-23  7:57     ` Dan Carpenter
  0 siblings, 0 replies; 49+ messages in thread
From: Dan Carpenter @ 2020-10-23  7:57 UTC (permalink / raw)
  To: kbuild-all

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

Hi Manasi,

url:    https://github.com/0day-ci/linux/commits/Manasi-Navare/Big-joiner-enabling/20201022-134216
base:   git://anongit.freedesktop.org/drm/drm-tip drm-tip
config: x86_64-randconfig-m001-20201022 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:7303 hsw_crtc_enable() warn: if statement not indented

Old smatch warnings:
drivers/gpu/drm/i915/display/intel_display.c:6237 skl_update_scaler_plane() error: we previously assumed 'fb' could be null (see line 6221)
drivers/gpu/drm/i915/display/intel_display.c:15236 kill_bigjoiner_slave() warn: inconsistent indenting

vim +7303 drivers/gpu/drm/i915/display/intel_display.c

1e98f88cea0ff5 drivers/gpu/drm/i915/display/intel_display.c Lucas De Marchi   2019-12-24  7274  static void hsw_crtc_enable(struct intel_atomic_state *state,
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7275  			    struct intel_crtc *crtc)
6be4a6078e41a8 drivers/gpu/drm/i915/intel_display.c         Jesse Barnes      2010-09-10  7276  {
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7277  	const struct intel_crtc_state *new_crtc_state =
7451a074bf2f26 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7278  		intel_atomic_get_new_crtc_state(state, crtc);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7279  	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7280  	enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7281  	enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
ed69cd40685c94 drivers/gpu/drm/i915/intel_display.c         Imre Deak         2017-10-02  7282  	bool psl_clkgate_wa;
2c07245fb8f7f0 drivers/gpu/drm/i915/intel_display.c         Zhenyu Wang       2009-06-05  7283  
e57291c2d39522 drivers/gpu/drm/i915/display/intel_display.c Pankaj Bharadiya  2020-02-20  7284  	if (drm_WARN_ON(&dev_priv->drm, crtc->active))
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7285  		return;
f7abfe8b281991 drivers/gpu/drm/i915/intel_display.c         Chris Wilson      2010-09-13  7286  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7287  	if (!new_crtc_state->bigjoiner) {
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7288  		intel_encoders_pre_pll_enable(state, crtc);
95a7a2ae46652f drivers/gpu/drm/i915/intel_display.c         Imre Deak         2016-06-13  7289  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7290  		if (new_crtc_state->shared_dpll)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7291  			intel_enable_shared_dpll(new_crtc_state);
df8ad70ca34f9b drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-06-25  7292  
e44c84a14469d3 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7293  		intel_encoders_pre_enable(state, crtc);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7294  	} else {
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7295  		icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7296  	}
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7297  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7298  	intel_set_pipe_src_size(new_crtc_state);
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7299  	if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7300  		bdw_set_pipemisc(new_crtc_state);
c8af5274c3cbac drivers/gpu/drm/i915/intel_display.c         Paulo Zanoni      2018-05-02  7301  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7302  	if (!new_crtc_state->bigjoiner_slave || !transcoder_is_dsi(cpu_transcoder)){
d7edc4e57bfefc drivers/gpu/drm/i915/intel_display.c         Ville Syrjälä     2016-06-22 @7303  		if (!transcoder_is_dsi(cpu_transcoder))
e7fc3f902d76f1 drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-08  7304  		intel_set_transcoder_timings(new_crtc_state);
                                                                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This looks correct, only the indenting is wrong.

4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7305  
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7306  		if (cpu_transcoder != TRANSCODER_EDP &&
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7307  		    !transcoder_is_dsi(cpu_transcoder))
dc008bf0aa091c drivers/gpu/drm/i915/display/intel_display.c Jani Nikula       2020-01-27  7308  			intel_de_write(dev_priv, PIPE_MULT(cpu_transcoder),
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7309  				       new_crtc_state->pixel_multiplier - 1);
ebb69c95175609 drivers/gpu/drm/i915/intel_display.c         Clint Taylor      2014-09-30  7310  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7311  		if (new_crtc_state->has_pch_encoder)
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7312  			intel_cpu_transcoder_set_m_n(new_crtc_state,
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7313  						     &new_crtc_state->fdi_m_n, NULL);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7314  
502d871459d25e drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-11-18  7315  		hsw_set_frame_start_delay(new_crtc_state);
cc7a4cffea2195 drivers/gpu/drm/i915/display/intel_display.c Ville Syrjälä     2019-10-24  7316  	}
4d1de975683218 drivers/gpu/drm/i915/intel_display.c         Jani Nikula       2016-03-18  7317  
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7318  	if (!transcoder_is_dsi(cpu_transcoder))
9587d0b839b5fd drivers/gpu/drm/i915/display/intel_display.c Manasi Navare     2020-10-21  7319  		hsw_set_pipeconf(new_crtc_state);
229fca97437310 drivers/gpu/drm/i915/intel_display.c         Daniel Vetter     2014-04-24  7320  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

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

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

* Re: [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes Manasi Navare
@ 2020-10-23 17:17   ` Ville Syrjälä
  0 siblings, 0 replies; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 17:17 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Oct 21, 2020 at 10:42:14PM -0700, Manasi Navare wrote:
> No functional changes. This patch just moves some mode checks
> around to prepare for adding bigjoiner related mode validation
> 
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 818daab252f3..2c29e7f5281b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -721,6 +721,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return MODE_NO_DBLESCAN;
>  
> +	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> +		return MODE_H_ILLEGAL;
> +
>  	if (intel_dp_is_edp(intel_dp) && fixed_mode) {
>  		if (mode->hdisplay > fixed_mode->hdisplay)
>  			return MODE_PANEL;
> @@ -731,6 +734,9 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  		target_clock = fixed_mode->clock;
>  	}
>  
> +	if (mode->clock < 10000)
> +		return MODE_CLOCK_LOW;
> +

No idea what this check is actually trying to achieve, but
since it was already there no harm in moving it around.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>  
> @@ -771,12 +777,6 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	    target_clock > max_dotclk)
>  		return MODE_CLOCK_HIGH;
>  
> -	if (mode->clock < 10000)
> -		return MODE_CLOCK_LOW;
> -
> -	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
> -		return MODE_H_ILLEGAL;
> -
>  	status = intel_dp_mode_valid_downstream(intel_connector,
>  						mode, target_clock);
>  	if (status != MODE_OK)
> -- 
> 2.19.1

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

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

* Re: [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
@ 2020-10-23 17:32   ` Ville Syrjälä
  2020-10-23 18:30     ` Navare, Manasi
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  1 sibling, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 17:32 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Oct 21, 2020 at 10: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.
> 
> v9:
> * Restric Bigjoiner on PORT A (Ville)
> v8:
> * use source dotclock for max dotclock (Manasi)
> v7:
> * Add can_bigjoiner() helper (Ville)
> * Pass bigjoiner to plane_size validation (Ville)
> v6:
> * Rebase after dp_downstream mode valid changes (Manasi)
> 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 |   5 +-
>  drivers/gpu/drm/i915/display/intel_display.h |   3 +-
>  drivers/gpu/drm/i915/display/intel_dp.c      | 106 +++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
>  drivers/gpu/drm/i915/display/intel_dsi.c     |   2 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c    |   2 +-
>  6 files changed, 96 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 9b4fcc734122..1c2d67ae361d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -17751,7 +17751,8 @@ intel_mode_valid(struct drm_device *dev,
>  
>  enum drm_mode_status
>  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> -				const struct drm_display_mode *mode)
> +				const struct drm_display_mode *mode,
> +				bool bigjoiner)
>  {
>  	int plane_width_max, plane_height_max;
>  
> @@ -17768,7 +17769,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 = 5120 << bigjoiner;
>  		plane_height_max = 4320;
>  	} else {
>  		plane_width_max = 5120;
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index 1b946209e06b..4f8dee9dfb4d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
>  bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
>  enum drm_mode_status
>  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> -				const struct drm_display_mode *mode);
> +				const struct drm_display_mode *mode,
> +				bool bigjoiner);
>  enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
>  bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index 2c29e7f5281b..d123e5a508c1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -254,6 +254,29 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
>  	return max_link_clock * max_lanes;
>  }
>  
> +static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
> +{
> +	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);
> +
> +	return INTEL_GEN(dev_priv) >= 12 ||
> +		(INTEL_GEN(dev_priv) == 11 &&
> +		 encoder->port != PORT_A);
> +}
> +
> +static int intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> +{
> +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> +	struct intel_encoder *encoder = &intel_dig_port->base;
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +
> +	if (allow_bigjoiner && intel_dp_can_bigjoiner(intel_dp))
> +		return 2 * dev_priv->max_dotclk_freq;
> +
> +	return dev_priv->max_dotclk_freq;
> +}
> +
>  static int cnl_max_source_rate(struct intel_dp *intel_dp)
>  {
>  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> @@ -519,7 +542,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;
> @@ -537,6 +561,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);
>  
> @@ -546,6 +574,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",
> @@ -568,7 +605,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;
> @@ -595,12 +633,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",
> @@ -684,10 +730,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
>  	const struct drm_display_info *info = &connector->base.display_info;
>  	int tmds_clock;
>  
> -	if (intel_dp->dfp.max_dotclock &&
> -	    target_clock > intel_dp->dfp.max_dotclock)
> -		return MODE_CLOCK_HIGH;
> -
>  	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
>  	tmds_clock = target_clock;
>  	if (drm_mode_is_420_only(info, mode))
> @@ -717,6 +759,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	u16 dsc_max_output_bpp = 0;
>  	u8 dsc_slice_count = 0;
>  	enum drm_mode_status status;
> +	bool dsc = false, bigjoiner = false;
>  
>  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
>  		return MODE_NO_DBLESCAN;
> @@ -724,6 +767,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	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)
>  			return MODE_PANEL;
> @@ -737,6 +782,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
>  	if (mode->clock < 10000)
>  		return MODE_CLOCK_LOW;
>  
> +	if (target_clock > max_dotclk) {
> +		if (intel_dp_is_edp(intel_dp))
> +			return MODE_CLOCK_HIGH;

Not sure why we check for edp?

> +
> +		max_dotclk = intel_dp_max_dotclock(intel_dp, true);
> +
> +		if (target_clock > max_dotclk)
> +			return MODE_CLOCK_HIGH;
> +
> +		bigjoiner = intel_dp_can_bigjoiner(intel_dp);

Isn't that just going to be =true always?

I guess the logic here is a bit confusing on account of the extra
roundtrips throught the other functions.

Might be less confusing to just avoid that stuff and
simplify this down to something like this:

max_dotclock = dev_priv->max_dotclk;
if (target_clock > max_dotclock && can_bigjoiner) {
	bigjoiner = true;
	max_dotclock *= 2;
}
if (target_clock > max_dotclock)
	return CLOCK_HIGH;


> +	}
> +
>  	max_link_clock = intel_dp_max_link_rate(intel_dp);
>  	max_lanes = intel_dp_max_lane_count(intel_dp);
>  
> @@ -765,24 +822,35 @@ 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");

No debugs anywhere else in this function, so probably shouldn't have
them here either.

>  		return MODE_CLOCK_HIGH;
> +	}
> +
> +	if (mode_rate > max_rate && !dsc) {
> +		DRM_DEBUG_KMS("Cannot drive without DSC\n");

ditto.

I guess if we wanted to differentiate between fail due to no dsc
vs. just clock is too high we could add something like
MODE_NO_COMPRESSION. Probably should take a good look at these
MODE_FOO values and nuke all unused ones...


> +		return MODE_CLOCK_HIGH;
> +	}
>  
>  	status = intel_dp_mode_valid_downstream(intel_connector,
>  						mode, target_clock);
>  	if (status != MODE_OK)
>  		return status;
>  
> -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> +	return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
>  }
>  
>  u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
> @@ -2297,11 +2365,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");
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index c8fcec4d0788..fd5faa5d7c22 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -714,7 +714,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
>  		return 0;
>  	}
>  
> -	*status = intel_mode_valid_max_plane_size(dev_priv, mode);
> +	*status = intel_mode_valid_max_plane_size(dev_priv, mode, true);

true?

>  	return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
> index afa4e6817e8c..f453ceb8d149 100644
> --- a/drivers/gpu/drm/i915/display/intel_dsi.c
> +++ b/drivers/gpu/drm/i915/display/intel_dsi.c
> @@ -75,7 +75,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
>  			return MODE_CLOCK_HIGH;
>  	}
>  
> -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> +	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
>  }
>  
>  struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index f90838bc74fb..82674a8853c6 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -2274,7 +2274,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
>  	if (status != MODE_OK)
>  		return status;
>  
> -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> +	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
>  }
>  
>  bool intel_hdmi_deep_color_possible(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

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

* Re: [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in atomic check
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in " Manasi Navare
@ 2020-10-23 17:42   ` Ville Syrjälä
  2020-10-23 18:13     ` Navare, Manasi
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  1 sibling, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 17:42 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Oct 21, 2020 at 10:42:17PM -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.
> 
> v4:
> * Fixes in intel_crtc_compute_config (Ville)
> 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_display.c  | 181 ++++++++++++++++--
>  .../drm/i915/display/intel_display_types.h    |   9 +
>  drivers/gpu/drm/i915/display/intel_dp.c       |  22 ++-
>  3 files changed, 191 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 92cd38964142..ffee6afe4ddb 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -8237,9 +8237,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;
>  
> @@ -8300,7 +8315,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_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
>  		return -EINVAL;
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -12657,7 +12672,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)
>  {
> @@ -12666,7 +12681,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) {

There's still this extra noise in the patch. I thought you were going
to split out the calling convention changes to reduce it?

>  		if (connector_state->crtc != &crtc->base)
>  			continue;
>  
> @@ -12906,6 +12921,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)
> @@ -13447,6 +13463,15 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *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);
>  }
>  
> @@ -13482,6 +13507,47 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
>  				  crtc_state->hw.ctm);
>  }
>  
> +static int
> +copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
> +			  const struct intel_crtc_state *from_crtc_state)
> +{
> +	struct intel_crtc_state *saved_state;
> +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> +	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
> +	if (!saved_state)
> +		return -ENOMEM;
> +
> +	saved_state->uapi = crtc_state->uapi;
> +	saved_state->scaler_state = crtc_state->scaler_state;
> +	saved_state->shared_dpll = crtc_state->shared_dpll;
> +	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> +	saved_state->crc_enabled = crtc_state->crc_enabled;
> +
> +	intel_crtc_free_hw_state(crtc_state);
> +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> +	kfree(saved_state);
> +
> +	/* Re-init hw state */
> +	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
> +	crtc_state->hw.enable = from_crtc_state->hw.enable;
> +	crtc_state->hw.active = from_crtc_state->hw.active;
> +	crtc_state->hw.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)
> @@ -13522,10 +13588,10 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
>  }
>  
>  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;
> @@ -13567,7 +13633,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);
>  
> @@ -13605,7 +13671,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);
>  
> @@ -13657,9 +13723,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
>  		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
>  		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
>  
> -	/* without bigjoiner, pipe_mode == adjusted_mode */
> -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
> -
>  	return 0;
>  }
>  
> @@ -15055,6 +15118,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;
> +}
> +
>  /**
>   * DOC: asynchronous flip implementation
>   *
> @@ -15222,14 +15354,31 @@ static int intel_atomic_check(struct drm_device *dev,
>  			continue;
>  		}
>  
> +		/* 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;
>  	}
> @@ -15567,7 +15716,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 b526afee595c..59ed94d68b55 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -1070,6 +1070,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 d123e5a508c1..cb604899a881 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2349,6 +2349,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;
> +		}

That second check is redundant I think. intel_crtc_compute_config()
already takes care of it.

So seems like we should be good with just something super simple like:

if (crtc_clock > dev_priv->max_dotclock && can_bigjoiner())
	bigjoiner = true;


> +		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,
> @@ -2366,12 +2375,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");
> @@ -2387,14 +2396,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case Manasi Navare
@ 2020-10-23 18:00   ` Ville Syrjälä
  2020-10-26 22:33     ` Navare, Manasi
  2020-10-26 22:29   ` Navare, Manasi
  1 sibling, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 18:00 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Oct 21, 2020 at 10:42:20PM -0700, Manasi Navare wrote:
> Skip iterating over bigjoiner slaves, only the master has the state we
> care about.
> 
> Add the width of the bigjoiner slave to the reconstructed fb.
> 
> Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> master.
> 
> And last, disable bigjoiner slave from primary if reconstruction fails.
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |   1 +
>  4 files changed, 260 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 0fecf372be11..104a423e0cd5 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4408,20 +4408,14 @@ 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);
>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	u32 temp, flags = 0;
>  
> -	/* XXX: DSI transcoder paranoia */
> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> -		return;
> -
> -	intel_dsc_get_config(pipe_config);
> -
>  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
>  		flags |= DRM_MODE_FLAG_PHSYNC;
> @@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	default:
>  		break;
>  	}
> +}
> +
> +void intel_ddi_get_config(struct intel_encoder *encoder,
> +			  struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +
> +	/* XXX: DSI transcoder paranoia */
> +	if (drm_WARN_ON(&dev_priv->drm, 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);
> @@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3631,6 +3631,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;
>  
> @@ -3653,7 +3655,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);
> @@ -3675,6 +3677,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;
>  
> @@ -8272,6 +8279,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);
> @@ -9186,20 +9217,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;

This part doesn't seem to have anything to do with the rest of the
patch. What is it its purpose?

>  
>  	drm_mode_set_name(mode);
>  }
> @@ -10768,6 +10801,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);
> @@ -10876,6 +10910,13 @@ 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) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Does not support Bigjoiner Fb stretching yet\n");

"stretch" makes me think this has something to do with
scaling, which it does not. Also I have to wonder what
is the thing that "does not support". Ie. I guess I would
word it differently. Maybe something like:
"Unsupported bigjoiner configuration for initial FB"

Also I think we can check this before we even allocate the
fb struct, which means the goto error can be replaced
with a simple return.

> +		goto error;
> +	}
> +
>  	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;
> @@ -11366,6 +11407,8 @@ 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
> @@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		active = true;
>  	}
>  
> -	if (!active)
> -		goto out;
> +	intel_dsc_get_config(pipe_config);
>  
> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> +	if (!active) {
> +		/* bigjoiner slave doesn't enable transcoder */
> +		if (!pipe_config->bigjoiner_slave)
> +			goto out;
> +
> +		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);
> @@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> +	if (pipe_config->bigjoiner_slave) {
> +		/* Cannot be read out as a slave, set to 0. */
> +		pipe_config->pixel_multiplier = 0;

I think all the dozens of places with these readout hacks will need a
FIXME just so we don't forget to fix them. They also make the code semi
illegible so a FIXME would at least remind me when I wtf at the code
later.

> +	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
>  		pipe_config->pixel_multiplier =
>  			intel_de_read(dev_priv,
> @@ -12536,7 +12591,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);
>  
> @@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
> +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);
> -
> +	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;
>  	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
>  
> @@ -14183,21 +14240,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)) ||
> @@ -14207,24 +14285,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)
> @@ -14250,7 +14315,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))
> @@ -14271,48 +14337,50 @@ 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(port_clock);
> +
> +		PIPE_CONF_CHECK_I(min_voltage_level);
> +	}
>  
>  	PIPE_CONF_CHECK_X(infoframes.enable);
>  	PIPE_CONF_CHECK_X(infoframes.gcp);
> @@ -14324,6 +14392,9 @@ 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);
> @@ -14595,6 +14666,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;
>  
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>  	intel_crtc_free_hw_state(old_crtc_state);
> @@ -14623,7 +14695,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;
>  		bool active;
>  
> @@ -14633,12 +14708,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);

Introducing that wrapper could easily be a separate patch.

>  	}
>  
>  	intel_crtc_compute_pixel_rate(pipe_config);
> @@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;

This part looks like a separate patch.

>  
>  		/*
> @@ -18856,7 +18931,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)) {
> @@ -19067,9 +19143,19 @@ 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);
>  			if (encoder->sync_state)
>  				encoder->sync_state(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;
>  		}
> @@ -19125,16 +19211,15 @@ 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 = &crtc_state->hw.mode;
> +			struct drm_display_mode mode;

Didn't we decide to keep hw.mode for now? If so, this looks very
suspicious.

>  
>  			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
> @@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			/* 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;
> +
> +			if (crtc_state->bigjoiner)
> +				mode.hdisplay *= 2;
> +
>  			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) {
> @@ -19199,6 +19291,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);
> +		}
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 59ed94d68b55..d82ba1b9d8ef 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -845,6 +845,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 */
> -- 
> 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in atomic check
  2020-10-23 17:42   ` Ville Syrjälä
@ 2020-10-23 18:13     ` Navare, Manasi
  2020-10-23 18:30       ` Ville Syrjälä
  0 siblings, 1 reply; 49+ messages in thread
From: Navare, Manasi @ 2020-10-23 18:13 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 08:42:00PM +0300, Ville Syrjälä wrote:
> On Wed, Oct 21, 2020 at 10:42:17PM -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.
> > 
> > v4:
> > * Fixes in intel_crtc_compute_config (Ville)
> > 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_display.c  | 181 ++++++++++++++++--
> >  .../drm/i915/display/intel_display_types.h    |   9 +
> >  drivers/gpu/drm/i915/display/intel_dp.c       |  22 ++-
> >  3 files changed, 191 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 92cd38964142..ffee6afe4ddb 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -8237,9 +8237,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;
> >  
> > @@ -8300,7 +8315,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_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
> >  		return -EINVAL;
> >  
> >  	intel_crtc_compute_pixel_rate(pipe_config);
> > @@ -12657,7 +12672,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)
> >  {
> > @@ -12666,7 +12681,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) {
> 
> There's still this extra noise in the patch. I thought you were going
> to split out the calling convention changes to reduce it?

Hmm I split the calling convention changes that were adding from_crtc_state into a separate patch
May be I will split this one out too in a diff patch?


> 
> >  		if (connector_state->crtc != &crtc->base)
> >  			continue;
> >  
> > @@ -12906,6 +12921,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)
> > @@ -13447,6 +13463,15 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *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);
> >  }
> >  
> > @@ -13482,6 +13507,47 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
> >  				  crtc_state->hw.ctm);
> >  }
> >  
> > +static int
> > +copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
> > +			  const struct intel_crtc_state *from_crtc_state)
> > +{
> > +	struct intel_crtc_state *saved_state;
> > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > +
> > +	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
> > +	if (!saved_state)
> > +		return -ENOMEM;
> > +
> > +	saved_state->uapi = crtc_state->uapi;
> > +	saved_state->scaler_state = crtc_state->scaler_state;
> > +	saved_state->shared_dpll = crtc_state->shared_dpll;
> > +	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> > +	saved_state->crc_enabled = crtc_state->crc_enabled;
> > +
> > +	intel_crtc_free_hw_state(crtc_state);
> > +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> > +	kfree(saved_state);
> > +
> > +	/* Re-init hw state */
> > +	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
> > +	crtc_state->hw.enable = from_crtc_state->hw.enable;
> > +	crtc_state->hw.active = from_crtc_state->hw.active;
> > +	crtc_state->hw.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)
> > @@ -13522,10 +13588,10 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
> >  }
> >  
> >  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;
> > @@ -13567,7 +13633,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);
> >  
> > @@ -13605,7 +13671,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);
> >  
> > @@ -13657,9 +13723,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> >  		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
> >  		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> >  
> > -	/* without bigjoiner, pipe_mode == adjusted_mode */
> > -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
> > -
> >  	return 0;
> >  }
> >  
> > @@ -15055,6 +15118,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;
> > +}
> > +
> >  /**
> >   * DOC: asynchronous flip implementation
> >   *
> > @@ -15222,14 +15354,31 @@ static int intel_atomic_check(struct drm_device *dev,
> >  			continue;
> >  		}
> >  
> > +		/* 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;
> >  	}
> > @@ -15567,7 +15716,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 b526afee595c..59ed94d68b55 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -1070,6 +1070,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 d123e5a508c1..cb604899a881 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -2349,6 +2349,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;
> > +		}
> 
> That second check is redundant I think. intel_crtc_compute_config()
> already takes care of it.

Why is it redundant? I mean with bigjoiner = true we still need to make sure
that crtc_clock is not > max dotclock with bigjoiner right?

> 
> So seems like we should be good with just something super simple like:
> 
> if (crtc_clock > dev_priv->max_dotclock && can_bigjoiner())
> 	bigjoiner = true;

Manasi

> 
> 
> > +		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,
> > @@ -2366,12 +2375,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");
> > @@ -2387,14 +2396,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-23 17:32   ` Ville Syrjälä
@ 2020-10-23 18:30     ` Navare, Manasi
  2020-10-23 18:44       ` Ville Syrjälä
  0 siblings, 1 reply; 49+ messages in thread
From: Navare, Manasi @ 2020-10-23 18:30 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 08:32:00PM +0300, Ville Syrjälä wrote:
> On Wed, Oct 21, 2020 at 10: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.
> > 
> > v9:
> > * Restric Bigjoiner on PORT A (Ville)
> > v8:
> > * use source dotclock for max dotclock (Manasi)
> > v7:
> > * Add can_bigjoiner() helper (Ville)
> > * Pass bigjoiner to plane_size validation (Ville)
> > v6:
> > * Rebase after dp_downstream mode valid changes (Manasi)
> > 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 |   5 +-
> >  drivers/gpu/drm/i915/display/intel_display.h |   3 +-
> >  drivers/gpu/drm/i915/display/intel_dp.c      | 106 +++++++++++++++----
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
> >  drivers/gpu/drm/i915/display/intel_dsi.c     |   2 +-
> >  drivers/gpu/drm/i915/display/intel_hdmi.c    |   2 +-
> >  6 files changed, 96 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > index 9b4fcc734122..1c2d67ae361d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -17751,7 +17751,8 @@ intel_mode_valid(struct drm_device *dev,
> >  
> >  enum drm_mode_status
> >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > -				const struct drm_display_mode *mode)
> > +				const struct drm_display_mode *mode,
> > +				bool bigjoiner)
> >  {
> >  	int plane_width_max, plane_height_max;
> >  
> > @@ -17768,7 +17769,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 = 5120 << bigjoiner;
> >  		plane_height_max = 4320;
> >  	} else {
> >  		plane_width_max = 5120;
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > index 1b946209e06b..4f8dee9dfb4d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> >  bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
> >  enum drm_mode_status
> >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > -				const struct drm_display_mode *mode);
> > +				const struct drm_display_mode *mode,
> > +				bool bigjoiner);
> >  enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
> >  bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 2c29e7f5281b..d123e5a508c1 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -254,6 +254,29 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> >  	return max_link_clock * max_lanes;
> >  }
> >  
> > +static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
> > +{
> > +	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);
> > +
> > +	return INTEL_GEN(dev_priv) >= 12 ||
> > +		(INTEL_GEN(dev_priv) == 11 &&
> > +		 encoder->port != PORT_A);
> > +}
> > +
> > +static int intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> > +{
> > +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > +	struct intel_encoder *encoder = &intel_dig_port->base;
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +
> > +	if (allow_bigjoiner && intel_dp_can_bigjoiner(intel_dp))
> > +		return 2 * dev_priv->max_dotclk_freq;
> > +
> > +	return dev_priv->max_dotclk_freq;
> > +}
> > +
> >  static int cnl_max_source_rate(struct intel_dp *intel_dp)
> >  {
> >  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > @@ -519,7 +542,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;
> > @@ -537,6 +561,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);
> >  
> > @@ -546,6 +574,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",
> > @@ -568,7 +605,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;
> > @@ -595,12 +633,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",
> > @@ -684,10 +730,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
> >  	const struct drm_display_info *info = &connector->base.display_info;
> >  	int tmds_clock;
> >  
> > -	if (intel_dp->dfp.max_dotclock &&
> > -	    target_clock > intel_dp->dfp.max_dotclock)
> > -		return MODE_CLOCK_HIGH;
> > -
> >  	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
> >  	tmds_clock = target_clock;
> >  	if (drm_mode_is_420_only(info, mode))
> > @@ -717,6 +759,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  	u16 dsc_max_output_bpp = 0;
> >  	u8 dsc_slice_count = 0;
> >  	enum drm_mode_status status;
> > +	bool dsc = false, bigjoiner = false;
> >  
> >  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> >  		return MODE_NO_DBLESCAN;
> > @@ -724,6 +767,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  	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)
> >  			return MODE_PANEL;
> > @@ -737,6 +782,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
> >  	if (mode->clock < 10000)
> >  		return MODE_CLOCK_LOW;
> >  
> > +	if (target_clock > max_dotclk) {
> > +		if (intel_dp_is_edp(intel_dp))
> > +			return MODE_CLOCK_HIGH;
> 
> Not sure why we check for edp?

We dont support bigjoiner on edp so on edp thsi would be a mode_clock_high

> 
> > +
> > +		max_dotclk = intel_dp_max_dotclock(intel_dp, true);
> > +
> > +		if (target_clock > max_dotclk)
> > +			return MODE_CLOCK_HIGH;
> > +
> > +		bigjoiner = intel_dp_can_bigjoiner(intel_dp);
> 
> Isn't that just going to be =true always?
> 
> I guess the logic here is a bit confusing on account of the extra
> roundtrips throught the other functions.
> 
> Might be less confusing to just avoid that stuff and
> simplify this down to something like this:
> 
> max_dotclock = dev_priv->max_dotclk;
> if (target_clock > max_dotclock && can_bigjoiner) {
> 	bigjoiner = true;
> 	max_dotclock *= 2;
> }
> if (target_clock > max_dotclock)
> 	return CLOCK_HIGH;

Yes this looks better, I will change this

> 
> 
> > +	}
> > +
> >  	max_link_clock = intel_dp_max_link_rate(intel_dp);
> >  	max_lanes = intel_dp_max_lane_count(intel_dp);
> >  
> > @@ -765,24 +822,35 @@ 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");
> 
> No debugs anywhere else in this function, so probably shouldn't have
> them here either.
> 
> >  		return MODE_CLOCK_HIGH;
> > +	}
> > +
> > +	if (mode_rate > max_rate && !dsc) {
> > +		DRM_DEBUG_KMS("Cannot drive without DSC\n");
> 
> ditto.
> 
> I guess if we wanted to differentiate between fail due to no dsc
> vs. just clock is too high we could add something like
> MODE_NO_COMPRESSION. Probably should take a good look at these
> MODE_FOO values and nuke all unused ones...

Hmm yea agreed for now will remove the debugfs and we can add the MODE_NO_COMPRESSION later as followup

> 
> 
> > +		return MODE_CLOCK_HIGH;
> > +	}
> >  
> >  	status = intel_dp_mode_valid_downstream(intel_connector,
> >  						mode, target_clock);
> >  	if (status != MODE_OK)
> >  		return status;
> >  
> > -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> > +	return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
> >  }
> >  
> >  u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
> > @@ -2297,11 +2365,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");
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index c8fcec4d0788..fd5faa5d7c22 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -714,7 +714,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
> >  		return 0;
> >  	}
> >  
> > -	*status = intel_mode_valid_max_plane_size(dev_priv, mode);
> > +	*status = intel_mode_valid_max_plane_size(dev_priv, mode, true);
> 
> true?

Hmm will leave this to false for mst

Manasi

> 
> >  	return 0;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
> > index afa4e6817e8c..f453ceb8d149 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dsi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dsi.c
> > @@ -75,7 +75,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
> >  			return MODE_CLOCK_HIGH;
> >  	}
> >  
> > -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> > +	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
> >  }
> >  
> >  struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
> > diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > index f90838bc74fb..82674a8853c6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> > @@ -2274,7 +2274,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
> >  	if (status != MODE_OK)
> >  		return status;
> >  
> > -	return intel_mode_valid_max_plane_size(dev_priv, mode);
> > +	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
> >  }
> >  
> >  bool intel_hdmi_deep_color_possible(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
> 
> -- 
> 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in atomic check
  2020-10-23 18:13     ` Navare, Manasi
@ 2020-10-23 18:30       ` Ville Syrjälä
  0 siblings, 0 replies; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 18:30 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 11:13:47AM -0700, Navare, Manasi wrote:
> On Fri, Oct 23, 2020 at 08:42:00PM +0300, Ville Syrjälä wrote:
> > On Wed, Oct 21, 2020 at 10:42:17PM -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.
> > > 
> > > v4:
> > > * Fixes in intel_crtc_compute_config (Ville)
> > > 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_display.c  | 181 ++++++++++++++++--
> > >  .../drm/i915/display/intel_display_types.h    |   9 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c       |  22 ++-
> > >  3 files changed, 191 insertions(+), 21 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 92cd38964142..ffee6afe4ddb 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -8237,9 +8237,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;
> > >  
> > > @@ -8300,7 +8315,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_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
> > >  		return -EINVAL;
> > >  
> > >  	intel_crtc_compute_pixel_rate(pipe_config);
> > > @@ -12657,7 +12672,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)
> > >  {
> > > @@ -12666,7 +12681,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) {
> > 
> > There's still this extra noise in the patch. I thought you were going
> > to split out the calling convention changes to reduce it?
> 
> Hmm I split the calling convention changes that were adding from_crtc_state into a separate patch
> May be I will split this one out too in a diff patch?

Go through all the patches, read them all while keeping the
single thought "which parts can be split out?" foremost in
our mind. When you no longer find any parts that can be split
out then the patch is ready, not before.

> 
> 
> > 
> > >  		if (connector_state->crtc != &crtc->base)
> > >  			continue;
> > >  
> > > @@ -12906,6 +12921,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)
> > > @@ -13447,6 +13463,15 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *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);
> > >  }
> > >  
> > > @@ -13482,6 +13507,47 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
> > >  				  crtc_state->hw.ctm);
> > >  }
> > >  
> > > +static int
> > > +copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
> > > +			  const struct intel_crtc_state *from_crtc_state)
> > > +{
> > > +	struct intel_crtc_state *saved_state;
> > > +	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> > > +
> > > +	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
> > > +	if (!saved_state)
> > > +		return -ENOMEM;
> > > +
> > > +	saved_state->uapi = crtc_state->uapi;
> > > +	saved_state->scaler_state = crtc_state->scaler_state;
> > > +	saved_state->shared_dpll = crtc_state->shared_dpll;
> > > +	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
> > > +	saved_state->crc_enabled = crtc_state->crc_enabled;
> > > +
> > > +	intel_crtc_free_hw_state(crtc_state);
> > > +	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
> > > +	kfree(saved_state);
> > > +
> > > +	/* Re-init hw state */
> > > +	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
> > > +	crtc_state->hw.enable = from_crtc_state->hw.enable;
> > > +	crtc_state->hw.active = from_crtc_state->hw.active;
> > > +	crtc_state->hw.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)
> > > @@ -13522,10 +13588,10 @@ intel_crtc_prepare_cleared_state(struct intel_atomic_state *state,
> > >  }
> > >  
> > >  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;
> > > @@ -13567,7 +13633,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);
> > >  
> > > @@ -13605,7 +13671,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);
> > >  
> > > @@ -13657,9 +13723,6 @@ intel_modeset_pipe_config(struct intel_crtc_state *pipe_config)
> > >  		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
> > >  		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
> > >  
> > > -	/* without bigjoiner, pipe_mode == adjusted_mode */
> > > -	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
> > > -
> > >  	return 0;
> > >  }
> > >  
> > > @@ -15055,6 +15118,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;
> > > +}
> > > +
> > >  /**
> > >   * DOC: asynchronous flip implementation
> > >   *
> > > @@ -15222,14 +15354,31 @@ static int intel_atomic_check(struct drm_device *dev,
> > >  			continue;
> > >  		}
> > >  
> > > +		/* 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;
> > >  	}
> > > @@ -15567,7 +15716,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 b526afee595c..59ed94d68b55 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -1070,6 +1070,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 d123e5a508c1..cb604899a881 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -2349,6 +2349,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;
> > > +		}
> > 
> > That second check is redundant I think. intel_crtc_compute_config()
> > already takes care of it.
> 
> Why is it redundant? I mean with bigjoiner = true we still need to make sure
> that crtc_clock is not > max dotclock with bigjoiner right?

intel_crtc_compute_config() already takes care of it, like I said.

> 
> > 
> > So seems like we should be good with just something super simple like:
> > 
> > if (crtc_clock > dev_priv->max_dotclock && can_bigjoiner())
> > 	bigjoiner = true;
> 
> Manasi
> 
> > 
> > 
> > > +		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,
> > > @@ -2366,12 +2375,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");
> > > @@ -2387,14 +2396,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

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

* Re: [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-23 18:30     ` Navare, Manasi
@ 2020-10-23 18:44       ` Ville Syrjälä
  2020-10-26 23:47         ` Navare, Manasi
  0 siblings, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-23 18:44 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 11:30:08AM -0700, Navare, Manasi wrote:
> On Fri, Oct 23, 2020 at 08:32:00PM +0300, Ville Syrjälä wrote:
> > On Wed, Oct 21, 2020 at 10: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.
> > > 
> > > v9:
> > > * Restric Bigjoiner on PORT A (Ville)
> > > v8:
> > > * use source dotclock for max dotclock (Manasi)
> > > v7:
> > > * Add can_bigjoiner() helper (Ville)
> > > * Pass bigjoiner to plane_size validation (Ville)
> > > v6:
> > > * Rebase after dp_downstream mode valid changes (Manasi)
> > > 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 |   5 +-
> > >  drivers/gpu/drm/i915/display/intel_display.h |   3 +-
> > >  drivers/gpu/drm/i915/display/intel_dp.c      | 106 +++++++++++++++----
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
> > >  drivers/gpu/drm/i915/display/intel_dsi.c     |   2 +-
> > >  drivers/gpu/drm/i915/display/intel_hdmi.c    |   2 +-
> > >  6 files changed, 96 insertions(+), 24 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 9b4fcc734122..1c2d67ae361d 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -17751,7 +17751,8 @@ intel_mode_valid(struct drm_device *dev,
> > >  
> > >  enum drm_mode_status
> > >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > -				const struct drm_display_mode *mode)
> > > +				const struct drm_display_mode *mode,
> > > +				bool bigjoiner)
> > >  {
> > >  	int plane_width_max, plane_height_max;
> > >  
> > > @@ -17768,7 +17769,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 = 5120 << bigjoiner;
> > >  		plane_height_max = 4320;
> > >  	} else {
> > >  		plane_width_max = 5120;
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > index 1b946209e06b..4f8dee9dfb4d 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > @@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> > >  bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
> > >  enum drm_mode_status
> > >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > -				const struct drm_display_mode *mode);
> > > +				const struct drm_display_mode *mode,
> > > +				bool bigjoiner);
> > >  enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
> > >  bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
> > >  
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index 2c29e7f5281b..d123e5a508c1 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -254,6 +254,29 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> > >  	return max_link_clock * max_lanes;
> > >  }
> > >  
> > > +static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
> > > +{
> > > +	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);
> > > +
> > > +	return INTEL_GEN(dev_priv) >= 12 ||
> > > +		(INTEL_GEN(dev_priv) == 11 &&
> > > +		 encoder->port != PORT_A);
> > > +}
> > > +
> > > +static int intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> > > +{
> > > +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > > +	struct intel_encoder *encoder = &intel_dig_port->base;
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > +
> > > +	if (allow_bigjoiner && intel_dp_can_bigjoiner(intel_dp))
> > > +		return 2 * dev_priv->max_dotclk_freq;
> > > +
> > > +	return dev_priv->max_dotclk_freq;
> > > +}
> > > +
> > >  static int cnl_max_source_rate(struct intel_dp *intel_dp)
> > >  {
> > >  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > > @@ -519,7 +542,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;
> > > @@ -537,6 +561,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);
> > >  
> > > @@ -546,6 +574,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",
> > > @@ -568,7 +605,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;
> > > @@ -595,12 +633,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",
> > > @@ -684,10 +730,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
> > >  	const struct drm_display_info *info = &connector->base.display_info;
> > >  	int tmds_clock;
> > >  
> > > -	if (intel_dp->dfp.max_dotclock &&
> > > -	    target_clock > intel_dp->dfp.max_dotclock)
> > > -		return MODE_CLOCK_HIGH;
> > > -
> > >  	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
> > >  	tmds_clock = target_clock;
> > >  	if (drm_mode_is_420_only(info, mode))
> > > @@ -717,6 +759,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > >  	u16 dsc_max_output_bpp = 0;
> > >  	u8 dsc_slice_count = 0;
> > >  	enum drm_mode_status status;
> > > +	bool dsc = false, bigjoiner = false;
> > >  
> > >  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> > >  		return MODE_NO_DBLESCAN;
> > > @@ -724,6 +767,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > >  	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)
> > >  			return MODE_PANEL;
> > > @@ -737,6 +782,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > >  	if (mode->clock < 10000)
> > >  		return MODE_CLOCK_LOW;
> > >  
> > > +	if (target_clock > max_dotclk) {
> > > +		if (intel_dp_is_edp(intel_dp))
> > > +			return MODE_CLOCK_HIGH;
> > 
> > Not sure why we check for edp?
> 
> We dont support bigjoiner on edp so on edp thsi would be a mode_clock_high

Something to do with dsc calculations, or why exactly?

If there's an actual reason then just put the check into 
intel_can_bigjoiner(). I would accompany it with a comment
explaining why it is needed.

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

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
@ 2020-10-26 20:18   ` Ville Syrjälä
  2020-10-26 22:34     ` Navare, Manasi
  2020-10-26 22:41     ` Navare, Manasi
  0 siblings, 2 replies; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-26 20:18 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

On Wed, Oct 21, 2020 at 10:42:21PM -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.
> 
> v6:
> * Fix from_plane_state assignments (Manasi)
> 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 |  53 ++++-
>  .../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(+), 40 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 3334ff253600..5df928f8f322 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -246,12 +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);
>  
> -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> +	if (from_plane_state->uapi.crtc)
> +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> +	else
> +		plane_state->hw.crtc = NULL;
> +
>  	plane_state->hw.fb = from_plane_state->uapi.fb;
>  	if (plane_state->hw.fb)
>  		drm_framebuffer_get(plane_state->hw.fb);
> @@ -320,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;
>  }
>  
> @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3718,7 +3718,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);
>  
> @@ -12801,26 +12801,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;

Why would we even need this bigjoiner stuff in the planes? AFAICS about
the only thing we should need is someting like

for_each_plane_on_master()
	add_same_plane_on_slave()

somewhere before we do the plane->check() stuff. I guess start
of intel_atomic_check_planes() could be the right spot.

> +	}
> +	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;
>  
> -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> -		if (IS_ERR(linked_plane_state))
> -			return PTR_ERR(linked_plane_state);
> +			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_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;
> @@ -12860,6 +13014,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)))
> @@ -12903,7 +13058,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;
>  
> @@ -15253,6 +15415,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) {
> @@ -15263,6 +15426,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;
>  
> @@ -15287,7 +15456,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 "
> @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3144,7 +3144,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;
> @@ -3154,7 +3154,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)
> @@ -3873,7 +3873,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;
>  
> @@ -3886,7 +3886,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];
>  
> @@ -4708,12 +4708,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;
>  
> @@ -4735,12 +4735,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;
>  
> @@ -5587,7 +5587,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;
>  
> @@ -5597,7 +5597,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave Manasi Navare
@ 2020-10-26 21:56   ` Navare, Manasi
  0 siblings, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 21:56 UTC (permalink / raw)
  To: intel-gfx

@Ville, as per our IRC discussions, I am taking your Ack on this patch

Manasi

On Wed, Oct 21, 2020 at 10:42:18PM -0700, Manasi Navare wrote:
> Make vdsc work when no output is enabled. The big joiner needs VDSC
> on the slave, so enable it and set the appropriate bits.
> So remove encoder usage from dsc functions.
> 
> 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     |   9 +-
>  drivers/gpu/drm/i915/display/intel_display.c |   3 +
>  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    |   6 +-
>  6 files changed, 110 insertions(+), 117 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 096652921453..0fecf372be11 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1492,7 +1492,7 @@ 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);
> +	intel_dsc_get_config(pipe_config);
>  
>  	/* FIXME: adapt icl_ddi_clock_get() for DSI and use that? */
>  	pipe_config->port_clock = intel_dpll_get_freq(i915,
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 09811be08cfe..59db465ea7df 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2216,13 +2216,6 @@ static void intel_ddi_get_power_domains(struct intel_encoder *encoder,
>  	    intel_phy_is_tc(dev_priv, phy))
>  		intel_display_power_get(dev_priv,
>  					intel_ddi_main_link_aux_domain(dig_port));
> -
> -	/*
> -	 * VDSC power is needed when DSC is enabled
> -	 */
> -	if (crtc_state->dsc.compression_enable)
> -		intel_display_power_get(dev_priv,
> -					intel_dsc_power_domain(crtc_state));
>  }
>  
>  void intel_ddi_enable_pipe_clock(struct intel_encoder *encoder,
> @@ -4408,7 +4401,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
>  		return;
>  
> -	intel_dsc_get_config(encoder, pipe_config);
> +	intel_dsc_get_config(pipe_config);
>  
>  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index ffee6afe4ddb..338fa48a144d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7602,6 +7602,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;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index cb604899a881..3ce419e71a83 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2066,12 +2066,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..65d301c23580 100644
> --- a/drivers/gpu/drm/i915/display/intel_vdsc.h
> +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h
> @@ -11,15 +11,13 @@
>  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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
  2020-10-23  7:57     ` Dan Carpenter
@ 2020-10-26 21:57   ` Navare, Manasi
  2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
  2 siblings, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 21:57 UTC (permalink / raw)
  To: intel-gfx

@Ville, Addressed your review comments from prev review
and assuming your Ack on this

Manasi

On Wed, Oct 21, 2020 at 10:42:19PM -0700, Manasi Navare wrote:
> Enabling is done in a special sequence and so should plane updates
> be. Ideally the end user never notices the second pipe is used.
> 
> This way ideally everything will be tear free, and updates are
> really atomic as userspace expects it.
> 
> This uses generic modeset_enables() calls like trans port sync
> but still has special handling for disable since for slave we
> should not disable things like encoder, plls that are not enabled
> for  slave.
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c     |  25 +++-
>  drivers/gpu/drm/i915/display/intel_display.c | 118 +++++++++++++++----
>  2 files changed, 118 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 59db465ea7df..050891a130c1 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"
> @@ -3500,7 +3501,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,
> @@ -3572,7 +3574,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,
> @@ -3821,6 +3824,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
> @@ -4037,7 +4055,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);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 338fa48a144d..1be77ba2f9cf 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7232,6 +7232,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
>  	intel_de_write(dev_priv, reg, val);
>  }
>  
> +static void icl_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)
>  {
> @@ -7245,34 +7284,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->bigjoiner) {
> +		intel_encoders_pre_pll_enable(state, crtc);
>  
> -	if (new_crtc_state->shared_dpll)
> -		intel_enable_shared_dpll(new_crtc_state);
> -
> -	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 {
> +		icl_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;
>  
> @@ -7308,6 +7352,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) {
> @@ -15683,6 +15732,9 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
>  
>  	dev_priv->display.crtc_enable(state, crtc);
>  
> +	if (new_crtc_state->bigjoiner_slave)
> +		return;
> +
>  	/* vblanks work again, re-enable pipe CRC. */
>  	intel_crtc_enable_pipe_crc(crtc);
>  }
> @@ -15747,8 +15799,21 @@ 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);
>  
> +	/*
> +	 * We still need special handling for disabling bigjoiner master
> +	 * and slaves since for slave we do not have encoder or plls
> +	 * so we dont need to disable those.
> +	 */
> +	if (old_crtc_state->bigjoiner) {
> +		intel_crtc_disable_planes(state,
> +					  old_crtc_state->bigjoiner_linked_crtc);
> +		old_crtc_state->bigjoiner_linked_crtc->active = false;
> +	}
> +
>  	/*
>  	 * We need to disable pipe CRC before disabling the pipe,
>  	 * or we race against vblank off.
> @@ -15777,7 +15842,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)
>  			continue;
>  
>  		if (!old_crtc_state->hw.active)
> @@ -15802,10 +15867,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);
> @@ -15903,7 +15976,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  			continue;
>  
>  		if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
> -		    is_trans_port_sync_master(new_crtc_state))
> +		    is_trans_port_sync_master(new_crtc_state) ||
> +		    (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave))
>  			continue;
>  
>  		modeset_pipes &= ~BIT(pipe);
> @@ -15913,7 +15987,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
>  
>  	/*
>  	 * Then we enable all remaining pipes that depend on other
> -	 * pipes: MST slaves and port sync masters.
> +	 * pipes: MST slaves and port sync masters, big joiner master
>  	 */
>  	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
>  		enum pipe pipe = crtc->pipe;
> -- 
> 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case Manasi Navare
  2020-10-23 18:00   ` Ville Syrjälä
@ 2020-10-26 22:29   ` Navare, Manasi
  1 sibling, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 22:29 UTC (permalink / raw)
  To: intel-gfx

@Ville all your review comments addressed and as per IRC, considering your ACK on this

Manasi

On Wed, Oct 21, 2020 at 10:42:20PM -0700, Manasi Navare wrote:
> Skip iterating over bigjoiner slaves, only the master has the state we
> care about.
> 
> Add the width of the bigjoiner slave to the reconstructed fb.
> 
> Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> master.
> 
> And last, disable bigjoiner slave from primary if reconstruction fails.
> 
> Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> ---
>  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
>  drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
>  drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
>  .../drm/i915/display/intel_display_types.h    |   1 +
>  4 files changed, 260 insertions(+), 118 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> index 0fecf372be11..104a423e0cd5 100644
> --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> @@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4408,20 +4408,14 @@ 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);
>  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
>  	u32 temp, flags = 0;
>  
> -	/* XXX: DSI transcoder paranoia */
> -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> -		return;
> -
> -	intel_dsc_get_config(pipe_config);
> -
>  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
>  	if (temp & TRANS_DDI_PHSYNC)
>  		flags |= DRM_MODE_FLAG_PHSYNC;
> @@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
>  	default:
>  		break;
>  	}
> +}
> +
> +void intel_ddi_get_config(struct intel_encoder *encoder,
> +			  struct intel_crtc_state *pipe_config)
> +{
> +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> +
> +	/* XXX: DSI transcoder paranoia */
> +	if (drm_WARN_ON(&dev_priv->drm, 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);
> @@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3631,6 +3631,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;
>  
> @@ -3653,7 +3655,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);
> @@ -3675,6 +3677,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;
>  
> @@ -8272,6 +8279,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);
> @@ -9186,20 +9217,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);
>  }
> @@ -10768,6 +10801,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);
> @@ -10876,6 +10910,13 @@ 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) {
> +		drm_dbg_kms(&dev_priv->drm,
> +			    "Does not support Bigjoiner Fb stretching yet\n");
> +		goto error;
> +	}
> +
>  	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;
> @@ -11366,6 +11407,8 @@ 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
> @@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		active = true;
>  	}
>  
> -	if (!active)
> -		goto out;
> +	intel_dsc_get_config(pipe_config);
>  
> -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> +	if (!active) {
> +		/* bigjoiner slave doesn't enable transcoder */
> +		if (!pipe_config->bigjoiner_slave)
> +			goto out;
> +
> +		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);
> @@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
>  		}
>  	}
>  
> -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> +	if (pipe_config->bigjoiner_slave) {
> +		/* Cannot be read out as a slave, set to 0. */
> +		pipe_config->pixel_multiplier = 0;
> +	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
>  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
>  		pipe_config->pixel_multiplier =
>  			intel_de_read(dev_priv,
> @@ -12536,7 +12591,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);
>  
> @@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
> +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);
> -
> +	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;
>  	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
>  
> @@ -14183,21 +14240,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)) ||
> @@ -14207,24 +14285,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)
> @@ -14250,7 +14315,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))
> @@ -14271,48 +14337,50 @@ 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(port_clock);
> +
> +		PIPE_CONF_CHECK_I(min_voltage_level);
> +	}
>  
>  	PIPE_CONF_CHECK_X(infoframes.enable);
>  	PIPE_CONF_CHECK_X(infoframes.gcp);
> @@ -14324,6 +14392,9 @@ 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);
> @@ -14595,6 +14666,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;
>  
>  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
>  	intel_crtc_free_hw_state(old_crtc_state);
> @@ -14623,7 +14695,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;
>  		bool active;
>  
> @@ -14633,12 +14708,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);
> @@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;
>  
>  		/*
> @@ -18856,7 +18931,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)) {
> @@ -19067,9 +19143,19 @@ 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);
>  			if (encoder->sync_state)
>  				encoder->sync_state(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;
>  		}
> @@ -19125,16 +19211,15 @@ 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 = &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
> @@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
>  			/* 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;
> +
> +			if (crtc_state->bigjoiner)
> +				mode.hdisplay *= 2;
> +
>  			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) {
> @@ -19199,6 +19291,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);
> +		}
>  	}
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 59ed94d68b55..d82ba1b9d8ef 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -845,6 +845,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 */
> -- 
> 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-23 18:00   ` Ville Syrjälä
@ 2020-10-26 22:33     ` Navare, Manasi
  2020-10-27 13:39       ` Ville Syrjälä
  0 siblings, 1 reply; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 22:33 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 09:00:25PM +0300, Ville Syrjälä wrote:
> On Wed, Oct 21, 2020 at 10:42:20PM -0700, Manasi Navare wrote:
> > Skip iterating over bigjoiner slaves, only the master has the state we
> > care about.
> > 
> > Add the width of the bigjoiner slave to the reconstructed fb.
> > 
> > Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> > master.
> > 
> > And last, disable bigjoiner slave from primary if reconstruction fails.
> > 
> > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > ---
> >  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
> >  drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
> >  drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
> >  .../drm/i915/display/intel_display_types.h    |   1 +
> >  4 files changed, 260 insertions(+), 118 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> > index 0fecf372be11..104a423e0cd5 100644
> > --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> > +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> > @@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -4408,20 +4408,14 @@ 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);
> >  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> >  	u32 temp, flags = 0;
> >  
> > -	/* XXX: DSI transcoder paranoia */
> > -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> > -		return;
> > -
> > -	intel_dsc_get_config(pipe_config);
> > -
> >  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> >  	if (temp & TRANS_DDI_PHSYNC)
> >  		flags |= DRM_MODE_FLAG_PHSYNC;
> > @@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> >  	default:
> >  		break;
> >  	}
> > +}
> > +
> > +void intel_ddi_get_config(struct intel_encoder *encoder,
> > +			  struct intel_crtc_state *pipe_config)
> > +{
> > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > +
> > +	/* XXX: DSI transcoder paranoia */
> > +	if (drm_WARN_ON(&dev_priv->drm, 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);
> > @@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3631,6 +3631,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;
> >  
> > @@ -3653,7 +3655,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);
> > @@ -3675,6 +3677,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;
> >  
> > @@ -8272,6 +8279,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);
> > @@ -9186,20 +9217,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;
> 
> This part doesn't seem to have anything to do with the rest of the
> patch. What is it its purpose?

May be just add this to Patch 2: drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split

Would that be okay?

> 
> >  
> >  	drm_mode_set_name(mode);
> >  }
> > @@ -10768,6 +10801,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);
> > @@ -10876,6 +10910,13 @@ 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) {
> > +		drm_dbg_kms(&dev_priv->drm,
> > +			    "Does not support Bigjoiner Fb stretching yet\n");
> 
> "stretch" makes me think this has something to do with
> scaling, which it does not. Also I have to wonder what
> is the thing that "does not support". Ie. I guess I would
> word it differently. Maybe something like:
> "Unsupported bigjoiner configuration for initial FB"
> 
> Also I think we can check this before we even allocate the
> fb struct, which means the goto error can be replaced
> with a simple return.

Okay will change the debug message and move this to the top if the
function so we can just return

Assuming your r-b after these changes?

Manasi

> 
> > +		goto error;
> > +	}
> > +
> >  	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;
> > @@ -11366,6 +11407,8 @@ 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
> > @@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> >  		active = true;
> >  	}
> >  
> > -	if (!active)
> > -		goto out;
> > +	intel_dsc_get_config(pipe_config);
> >  
> > -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > +	if (!active) {
> > +		/* bigjoiner slave doesn't enable transcoder */
> > +		if (!pipe_config->bigjoiner_slave)
> > +			goto out;
> > +
> > +		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);
> > @@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> >  		}
> >  	}
> >  
> > -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > +	if (pipe_config->bigjoiner_slave) {
> > +		/* Cannot be read out as a slave, set to 0. */
> > +		pipe_config->pixel_multiplier = 0;
> 
> I think all the dozens of places with these readout hacks will need a
> FIXME just so we don't forget to fix them. They also make the code semi
> illegible so a FIXME would at least remind me when I wtf at the code
> later.
> 
> > +	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> >  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> >  		pipe_config->pixel_multiplier =
> >  			intel_de_read(dev_priv,
> > @@ -12536,7 +12591,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);
> >  
> > @@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
> > +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);
> > -
> > +	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;
> >  	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
> >  
> > @@ -14183,21 +14240,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)) ||
> > @@ -14207,24 +14285,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)
> > @@ -14250,7 +14315,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))
> > @@ -14271,48 +14337,50 @@ 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(port_clock);
> > +
> > +		PIPE_CONF_CHECK_I(min_voltage_level);
> > +	}
> >  
> >  	PIPE_CONF_CHECK_X(infoframes.enable);
> >  	PIPE_CONF_CHECK_X(infoframes.gcp);
> > @@ -14324,6 +14392,9 @@ 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);
> > @@ -14595,6 +14666,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;
> >  
> >  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> >  	intel_crtc_free_hw_state(old_crtc_state);
> > @@ -14623,7 +14695,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;
> >  		bool active;
> >  
> > @@ -14633,12 +14708,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);
> 
> Introducing that wrapper could easily be a separate patch.
> 
> >  	}
> >  
> >  	intel_crtc_compute_pixel_rate(pipe_config);
> > @@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;
> 
> This part looks like a separate patch.
> 
> >  
> >  		/*
> > @@ -18856,7 +18931,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)) {
> > @@ -19067,9 +19143,19 @@ 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);
> >  			if (encoder->sync_state)
> >  				encoder->sync_state(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;
> >  		}
> > @@ -19125,16 +19211,15 @@ 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 = &crtc_state->hw.mode;
> > +			struct drm_display_mode mode;
> 
> Didn't we decide to keep hw.mode for now? If so, this looks very
> suspicious.
> 
> >  
> >  			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
> > @@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> >  			/* 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;
> > +
> > +			if (crtc_state->bigjoiner)
> > +				mode.hdisplay *= 2;
> > +
> >  			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) {
> > @@ -19199,6 +19291,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);
> > +		}
> >  	}
> >  }
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > index 59ed94d68b55..d82ba1b9d8ef 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -845,6 +845,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 */
> > -- 
> > 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-26 20:18   ` Ville Syrjälä
@ 2020-10-26 22:34     ` Navare, Manasi
  2020-10-26 22:41     ` Navare, Manasi
  1 sibling, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 22:34 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

@Ville, assuming no comments or concerns as a Ack By you on this

Manasi

On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > 
> > v6:
> > * Fix from_plane_state assignments (Manasi)
> > 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 |  53 ++++-
> >  .../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(+), 40 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index 3334ff253600..5df928f8f322 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -246,12 +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);
> >  
> > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > +	if (from_plane_state->uapi.crtc)
> > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > +	else
> > +		plane_state->hw.crtc = NULL;
> > +
> >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> >  	if (plane_state->hw.fb)
> >  		drm_framebuffer_get(plane_state->hw.fb);
> > @@ -320,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;
> >  }
> >  
> > @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3718,7 +3718,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);
> >  
> > @@ -12801,26 +12801,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;
> 
> Why would we even need this bigjoiner stuff in the planes? AFAICS about
> the only thing we should need is someting like
> 
> for_each_plane_on_master()
> 	add_same_plane_on_slave()
> 
> somewhere before we do the plane->check() stuff. I guess start
> of intel_atomic_check_planes() could be the right spot.
> 
> > +	}
> > +	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;
> >  
> > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > -		if (IS_ERR(linked_plane_state))
> > -			return PTR_ERR(linked_plane_state);
> > +			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_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;
> > @@ -12860,6 +13014,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)))
> > @@ -12903,7 +13058,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;
> >  
> > @@ -15253,6 +15415,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) {
> > @@ -15263,6 +15426,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;
> >  
> > @@ -15287,7 +15456,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 "
> > @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3144,7 +3144,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;
> > @@ -3154,7 +3154,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)
> > @@ -3873,7 +3873,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;
> >  
> > @@ -3886,7 +3886,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];
> >  
> > @@ -4708,12 +4708,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;
> >  
> > @@ -4735,12 +4735,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;
> >  
> > @@ -5587,7 +5587,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;
> >  
> > @@ -5597,7 +5597,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-26 20:18   ` Ville Syrjälä
  2020-10-26 22:34     ` Navare, Manasi
@ 2020-10-26 22:41     ` Navare, Manasi
  2020-10-27 13:42       ` Ville Syrjälä
  1 sibling, 1 reply; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 22:41 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > 
> > v6:
> > * Fix from_plane_state assignments (Manasi)
> > 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 |  53 ++++-
> >  .../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(+), 40 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index 3334ff253600..5df928f8f322 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -246,12 +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);
> >  
> > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > +	if (from_plane_state->uapi.crtc)
> > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > +	else
> > +		plane_state->hw.crtc = NULL;
> > +
> >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> >  	if (plane_state->hw.fb)
> >  		drm_framebuffer_get(plane_state->hw.fb);
> > @@ -320,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;
> >  }
> >  
> > @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3718,7 +3718,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);
> >  
> > @@ -12801,26 +12801,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;
> 
> Why would we even need this bigjoiner stuff in the planes? AFAICS about
> the only thing we should need is someting like
> 
> for_each_plane_on_master()
> 	add_same_plane_on_slave()
> 
> somewhere before we do the plane->check() stuff. I guess start
> of intel_atomic_check_planes() could be the right spot.
>

Yes may be but honestly I leave this optimization/change to the original
author Maarten or you as a follow up

Manasi
 
> > +	}
> > +	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;
> >  
> > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > -		if (IS_ERR(linked_plane_state))
> > -			return PTR_ERR(linked_plane_state);
> > +			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_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;
> > @@ -12860,6 +13014,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)))
> > @@ -12903,7 +13058,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;
> >  
> > @@ -15253,6 +15415,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) {
> > @@ -15263,6 +15426,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;
> >  
> > @@ -15287,7 +15456,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 "
> > @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3144,7 +3144,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;
> > @@ -3154,7 +3154,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)
> > @@ -3873,7 +3873,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;
> >  
> > @@ -3886,7 +3886,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];
> >  
> > @@ -4708,12 +4708,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;
> >  
> > @@ -4735,12 +4735,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;
> >  
> > @@ -5587,7 +5587,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;
> >  
> > @@ -5597,7 +5597,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-23 18:44       ` Ville Syrjälä
@ 2020-10-26 23:47         ` Navare, Manasi
  0 siblings, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-26 23:47 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Fri, Oct 23, 2020 at 09:44:00PM +0300, Ville Syrjälä wrote:
> On Fri, Oct 23, 2020 at 11:30:08AM -0700, Navare, Manasi wrote:
> > On Fri, Oct 23, 2020 at 08:32:00PM +0300, Ville Syrjälä wrote:
> > > On Wed, Oct 21, 2020 at 10: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.
> > > > 
> > > > v9:
> > > > * Restric Bigjoiner on PORT A (Ville)
> > > > v8:
> > > > * use source dotclock for max dotclock (Manasi)
> > > > v7:
> > > > * Add can_bigjoiner() helper (Ville)
> > > > * Pass bigjoiner to plane_size validation (Ville)
> > > > v6:
> > > > * Rebase after dp_downstream mode valid changes (Manasi)
> > > > 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 |   5 +-
> > > >  drivers/gpu/drm/i915/display/intel_display.h |   3 +-
> > > >  drivers/gpu/drm/i915/display/intel_dp.c      | 106 +++++++++++++++----
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c  |   2 +-
> > > >  drivers/gpu/drm/i915/display/intel_dsi.c     |   2 +-
> > > >  drivers/gpu/drm/i915/display/intel_hdmi.c    |   2 +-
> > > >  6 files changed, 96 insertions(+), 24 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 9b4fcc734122..1c2d67ae361d 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -17751,7 +17751,8 @@ intel_mode_valid(struct drm_device *dev,
> > > >  
> > > >  enum drm_mode_status
> > > >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > -				const struct drm_display_mode *mode)
> > > > +				const struct drm_display_mode *mode,
> > > > +				bool bigjoiner)
> > > >  {
> > > >  	int plane_width_max, plane_height_max;
> > > >  
> > > > @@ -17768,7 +17769,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 = 5120 << bigjoiner;
> > > >  		plane_height_max = 4320;
> > > >  	} else {
> > > >  		plane_width_max = 5120;
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> > > > index 1b946209e06b..4f8dee9dfb4d 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > @@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> > > >  bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
> > > >  enum drm_mode_status
> > > >  intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
> > > > -				const struct drm_display_mode *mode);
> > > > +				const struct drm_display_mode *mode,
> > > > +				bool bigjoiner);
> > > >  enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
> > > >  bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
> > > >  
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > index 2c29e7f5281b..d123e5a508c1 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > @@ -254,6 +254,29 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
> > > >  	return max_link_clock * max_lanes;
> > > >  }
> > > >  
> > > > +static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
> > > > +{
> > > > +	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);
> > > > +
> > > > +	return INTEL_GEN(dev_priv) >= 12 ||
> > > > +		(INTEL_GEN(dev_priv) == 11 &&
> > > > +		 encoder->port != PORT_A);
> > > > +}
> > > > +
> > > > +static int intel_dp_max_dotclock(struct intel_dp *intel_dp, bool allow_bigjoiner)
> > > > +{
> > > > +	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > > > +	struct intel_encoder *encoder = &intel_dig_port->base;
> > > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > > +
> > > > +	if (allow_bigjoiner && intel_dp_can_bigjoiner(intel_dp))
> > > > +		return 2 * dev_priv->max_dotclk_freq;
> > > > +
> > > > +	return dev_priv->max_dotclk_freq;
> > > > +}
> > > > +
> > > >  static int cnl_max_source_rate(struct intel_dp *intel_dp)
> > > >  {
> > > >  	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
> > > > @@ -519,7 +542,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;
> > > > @@ -537,6 +561,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);
> > > >  
> > > > @@ -546,6 +574,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",
> > > > @@ -568,7 +605,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;
> > > > @@ -595,12 +633,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",
> > > > @@ -684,10 +730,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
> > > >  	const struct drm_display_info *info = &connector->base.display_info;
> > > >  	int tmds_clock;
> > > >  
> > > > -	if (intel_dp->dfp.max_dotclock &&
> > > > -	    target_clock > intel_dp->dfp.max_dotclock)
> > > > -		return MODE_CLOCK_HIGH;
> > > > -
> > > >  	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
> > > >  	tmds_clock = target_clock;
> > > >  	if (drm_mode_is_420_only(info, mode))
> > > > @@ -717,6 +759,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > > >  	u16 dsc_max_output_bpp = 0;
> > > >  	u8 dsc_slice_count = 0;
> > > >  	enum drm_mode_status status;
> > > > +	bool dsc = false, bigjoiner = false;
> > > >  
> > > >  	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
> > > >  		return MODE_NO_DBLESCAN;
> > > > @@ -724,6 +767,8 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > > >  	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)
> > > >  			return MODE_PANEL;
> > > > @@ -737,6 +782,18 @@ intel_dp_mode_valid(struct drm_connector *connector,
> > > >  	if (mode->clock < 10000)
> > > >  		return MODE_CLOCK_LOW;
> > > >  
> > > > +	if (target_clock > max_dotclk) {
> > > > +		if (intel_dp_is_edp(intel_dp))
> > > > +			return MODE_CLOCK_HIGH;
> > > 
> > > Not sure why we check for edp?
> > 
> > We dont support bigjoiner on edp so on edp thsi would be a mode_clock_high
> 
> Something to do with dsc calculations, or why exactly?
> 
> If there's an actual reason then just put the check into 
> intel_can_bigjoiner(). I would accompany it with a comment
> explaining why it is needed.

I am double checking with HW Architects on bigjoiner restrictions
on eDP.
Mostly it should work but features like PSR and DC states wont work.
So I think thats why we dont enable this for eDP yet.

But either ways I will add this restriction to the can_bigjoiner function then?

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

* [Intel-gfx] [PATCH v12 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3.
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
  2020-10-23 17:32   ` Ville Syrjälä
@ 2020-10-27  5:50   ` Manasi Navare
  1 sibling, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-27  5:50 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.

v10:
* Simplify logic (Ville)
* Allow bigjoiner on edp (Ville)
v9:
* Restric Bigjoiner on PORT A (Ville)
v8:
* use source dotclock for max dotclock (Manasi)
v7:
* Add can_bigjoiner() helper (Ville)
* Pass bigjoiner to plane_size validation (Ville)
v6:
* Rebase after dp_downstream mode valid changes (Manasi)
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 |  5 +-
 drivers/gpu/drm/i915/display/intel_display.h |  3 +-
 drivers/gpu/drm/i915/display/intel_dp.c      | 83 +++++++++++++++-----
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  2 +-
 drivers/gpu/drm/i915/display/intel_dsi.c     |  2 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c    |  2 +-
 6 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index ab00c99975f5..486ce71070bf 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -17755,7 +17755,8 @@ intel_mode_valid(struct drm_device *dev,
 
 enum drm_mode_status
 intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
-				const struct drm_display_mode *mode)
+				const struct drm_display_mode *mode,
+				bool bigjoiner)
 {
 	int plane_width_max, plane_height_max;
 
@@ -17772,7 +17773,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 = 5120 << bigjoiner;
 		plane_height_max = 4320;
 	} else {
 		plane_width_max = 5120;
diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
index 1b946209e06b..4f8dee9dfb4d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -497,7 +497,8 @@ u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
 bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
 enum drm_mode_status
 intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv,
-				const struct drm_display_mode *mode);
+				const struct drm_display_mode *mode,
+				bool bigjoiner);
 enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
 bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 2c29e7f5281b..aebcff7068f0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -254,6 +254,17 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
 	return max_link_clock * max_lanes;
 }
 
+static bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
+{
+	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);
+
+	return INTEL_GEN(dev_priv) >= 12 ||
+		(INTEL_GEN(dev_priv) == 11 &&
+		 encoder->port != PORT_A);
+}
+
 static int cnl_max_source_rate(struct intel_dp *intel_dp)
 {
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@ -519,7 +530,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;
@@ -537,6 +549,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);
 
@@ -546,6 +562,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",
@@ -568,7 +593,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;
@@ -595,12 +621,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",
@@ -684,10 +718,6 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector,
 	const struct drm_display_info *info = &connector->base.display_info;
 	int tmds_clock;
 
-	if (intel_dp->dfp.max_dotclock &&
-	    target_clock > intel_dp->dfp.max_dotclock)
-		return MODE_CLOCK_HIGH;
-
 	/* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */
 	tmds_clock = target_clock;
 	if (drm_mode_is_420_only(info, mode))
@@ -717,6 +747,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	u16 dsc_max_output_bpp = 0;
 	u8 dsc_slice_count = 0;
 	enum drm_mode_status status;
+	bool dsc = false, bigjoiner = false;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
@@ -737,6 +768,13 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (mode->clock < 10000)
 		return MODE_CLOCK_LOW;
 
+	if (target_clock > max_dotclk && intel_dp_can_bigjoiner(intel_dp)) {
+		bigjoiner = true;
+		max_dotclk *= 2;
+	}
+	if (target_clock > max_dotclk)
+		return MODE_CLOCK_HIGH;
+
 	max_link_clock = intel_dp_max_link_rate(intel_dp);
 	max_lanes = intel_dp_max_lane_count(intel_dp);
 
@@ -765,16 +803,23 @@ 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)
+		return MODE_CLOCK_HIGH;
+
+	if (mode_rate > max_rate && !dsc)
 		return MODE_CLOCK_HIGH;
 
 	status = intel_dp_mode_valid_downstream(intel_connector,
@@ -782,7 +827,7 @@ intel_dp_mode_valid(struct drm_connector *connector,
 	if (status != MODE_OK)
 		return status;
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
 }
 
 u32 intel_dp_pack_aux(const u8 *src, int src_bytes)
@@ -2297,11 +2342,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");
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index c8fcec4d0788..0c8684634fca 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -714,7 +714,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
 		return 0;
 	}
 
-	*status = intel_mode_valid_max_plane_size(dev_priv, mode);
+	*status = intel_mode_valid_max_plane_size(dev_priv, mode, false);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c
index afa4e6817e8c..f453ceb8d149 100644
--- a/drivers/gpu/drm/i915/display/intel_dsi.c
+++ b/drivers/gpu/drm/i915/display/intel_dsi.c
@@ -75,7 +75,7 @@ enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
 			return MODE_CLOCK_HIGH;
 	}
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
 }
 
 struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index f90838bc74fb..82674a8853c6 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -2274,7 +2274,7 @@ intel_hdmi_mode_valid(struct drm_connector *connector,
 	if (status != MODE_OK)
 		return status;
 
-	return intel_mode_valid_max_plane_size(dev_priv, mode);
+	return intel_mode_valid_max_plane_size(dev_priv, mode, false);
 }
 
 bool intel_hdmi_deep_color_possible(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] 49+ messages in thread

* [Intel-gfx] [PATCH v12 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
  2020-10-23  7:57     ` Dan Carpenter
  2020-10-26 21:57   ` Navare, Manasi
@ 2020-10-27  5:50   ` Manasi Navare
  2 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-27  5:50 UTC (permalink / raw)
  To: intel-gfx

Enabling is done in a special sequence and so should plane updates
be. Ideally the end user never notices the second pipe is used.

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

This uses generic modeset_enables() calls like trans port sync
but still has special handling for disable since for slave we
should not disable things like encoder, plls that are not enabled
for  slave.

Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     |  25 +++-
 drivers/gpu/drm/i915/display/intel_display.c | 118 +++++++++++++++----
 2 files changed, 118 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 753ac6f4d4e3..a710b5958d45 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"
@@ -3500,7 +3501,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,
@@ -3572,7 +3574,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,
@@ -3821,6 +3824,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
@@ -4037,7 +4055,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);
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index c4716fda3c06..5cf128668a79 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7232,6 +7232,45 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
 	intel_de_write(dev_priv, reg, val);
 }
 
+static void icl_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)
 {
@@ -7245,34 +7284,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 {
+		icl_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;
 
@@ -7308,6 +7352,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) {
@@ -15687,6 +15736,9 @@ static void intel_enable_crtc(struct intel_atomic_state *state,
 
 	dev_priv->display.crtc_enable(state, crtc);
 
+	if (new_crtc_state->bigjoiner_slave)
+		return;
+
 	/* vblanks work again, re-enable pipe CRC. */
 	intel_crtc_enable_pipe_crc(crtc);
 }
@@ -15751,8 +15803,21 @@ 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);
 
+	/*
+	 * We still need special handling for disabling bigjoiner master
+	 * and slaves since for slave we do not have encoder or plls
+	 * so we dont need to disable those.
+	 */
+	if (old_crtc_state->bigjoiner) {
+		intel_crtc_disable_planes(state,
+					  old_crtc_state->bigjoiner_linked_crtc);
+		old_crtc_state->bigjoiner_linked_crtc->active = false;
+	}
+
 	/*
 	 * We need to disable pipe CRC before disabling the pipe,
 	 * or we race against vblank off.
@@ -15781,7 +15846,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)
 			continue;
 
 		if (!old_crtc_state->hw.active)
@@ -15806,10 +15871,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);
@@ -15907,7 +15980,8 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			continue;
 
 		if (intel_dp_mst_is_slave_trans(new_crtc_state) ||
-		    is_trans_port_sync_master(new_crtc_state))
+		    is_trans_port_sync_master(new_crtc_state) ||
+		    (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave))
 			continue;
 
 		modeset_pipes &= ~BIT(pipe);
@@ -15917,7 +15991,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 
 	/*
 	 * Then we enable all remaining pipes that depend on other
-	 * pipes: MST slaves and port sync masters.
+	 * pipes: MST slaves and port sync masters, big joiner master
 	 */
 	for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
 		enum pipe pipe = crtc->pipe;
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v12 05/12] drm/i915/dp: Prep for bigjoiner atomic check
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 05/12] drm/i915/dp: Prep for bigjoiner atomic check Manasi Navare
@ 2020-10-27  5:50   ` Manasi Navare
  0 siblings, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-27  5:50 UTC (permalink / raw)
  To: intel-gfx

No functional changes here. Just pass intel_atomic_state
along with crtc_state to certain atomic_check functions.
This will lay the foundation for adding bigjoiner master/slave
states in atomic check.

v2:
* More prep with intel_atomic_state (Ville)

Cc: Ville Syrjälä <ville.syrjala@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 | 35 +++++++++++---------
 3 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 86be032bcf96..e243ce97b534 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 285de07011dc..62a3365ed5e6 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 486ce71070bf..2bbbe0a6d4c7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -12661,7 +12661,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)
 {
@@ -12670,7 +12670,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;
 
@@ -13446,13 +13446,17 @@ 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;
+
+	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;
@@ -13460,7 +13464,7 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_crtc_state *crtc_state)
 	crtc_state->hw.pipe_mode = crtc_state->hw.adjusted_mode = crtc_state->uapi.adjusted_mode;
 	crtc_state->hw.scaling_filter = crtc_state->uapi.scaling_filter;
 
-	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)
@@ -13483,7 +13487,8 @@ 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)
+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);
@@ -13515,16 +13520,16 @@ intel_crtc_prepare_cleared_state(struct intel_crtc_state *crtc_state)
 	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
 	kfree(saved_state);
 
-	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;
@@ -13566,7 +13571,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);
 
@@ -13604,7 +13609,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);
 
@@ -15216,19 +15221,19 @@ 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);
+		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(new_crtc_state);
+		ret = intel_modeset_pipe_config(state, new_crtc_state);
 		if (ret)
 			goto fail;
 	}
-- 
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] 49+ messages in thread

* [Intel-gfx] [PATCH v12 06/12] drm/i915: Try to make bigjoiner work in atomic check
  2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in " Manasi Navare
  2020-10-23 17:42   ` Ville Syrjälä
@ 2020-10-27  5:50   ` Manasi Navare
  1 sibling, 0 replies; 49+ messages in thread
From: Manasi Navare @ 2020-10-27  5:50 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.

v4:
* Fixes in intel_crtc_compute_config (Ville)
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_display.c  | 169 +++++++++++++++++-
 .../drm/i915/display/intel_display_types.h    |   9 +
 drivers/gpu/drm/i915/display/intel_dp.c       |  22 ++-
 3 files changed, 185 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 2bbbe0a6d4c7..91c6991217c2 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -8237,9 +8237,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;
 
@@ -8300,7 +8315,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_mode->crtc_hsync_start == pipe_mode->crtc_hdisplay)
 		return -EINVAL;
 
 	intel_crtc_compute_pixel_rate(pipe_config);
@@ -12910,6 +12925,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)
@@ -13451,6 +13467,15 @@ intel_crtc_copy_uapi_to_hw_state_nomodeset(struct intel_atomic_state *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);
 }
 
@@ -13486,6 +13511,47 @@ static void intel_crtc_copy_hw_to_uapi_state(struct intel_crtc_state *crtc_state
 				  crtc_state->hw.ctm);
 }
 
+static int
+copy_bigjoiner_crtc_state(struct intel_crtc_state *crtc_state,
+			  const struct intel_crtc_state *from_crtc_state)
+{
+	struct intel_crtc_state *saved_state;
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+	saved_state = kmemdup(from_crtc_state, sizeof(*saved_state), GFP_KERNEL);
+	if (!saved_state)
+		return -ENOMEM;
+
+	saved_state->uapi = crtc_state->uapi;
+	saved_state->scaler_state = crtc_state->scaler_state;
+	saved_state->shared_dpll = crtc_state->shared_dpll;
+	saved_state->dpll_hw_state = crtc_state->dpll_hw_state;
+	saved_state->crc_enabled = crtc_state->crc_enabled;
+
+	intel_crtc_free_hw_state(crtc_state);
+	memcpy(crtc_state, saved_state, sizeof(*crtc_state));
+	kfree(saved_state);
+
+	/* Re-init hw state */
+	memset(&crtc_state->hw, 0, sizeof(saved_state->hw));
+	crtc_state->hw.enable = from_crtc_state->hw.enable;
+	crtc_state->hw.active = from_crtc_state->hw.active;
+	crtc_state->hw.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)
@@ -13661,9 +13727,6 @@ intel_modeset_pipe_config(struct intel_atomic_state *state,
 		    "hw max bpp: %i, pipe bpp: %i, dithering: %i\n",
 		    base_bpp, pipe_config->pipe_bpp, pipe_config->dither);
 
-	/* without bigjoiner, pipe_mode == adjusted_mode */
-	pipe_config->hw.pipe_mode = pipe_config->hw.adjusted_mode;
-
 	return 0;
 }
 
@@ -15059,6 +15122,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;
+}
+
 /**
  * DOC: asynchronous flip implementation
  *
@@ -15226,16 +15358,33 @@ static int intel_atomic_check(struct drm_device *dev,
 			continue;
 		}
 
+		/* 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_atomic_check_bigjoiner(state, crtc, old_crtc_state,
+						   new_crtc_state);
+		if (ret)
+			goto fail;
 	}
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
@@ -15571,7 +15720,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 b526afee595c..59ed94d68b55 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1070,6 +1070,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 aebcff7068f0..c3780c5ec7fc 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2326,6 +2326,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,
@@ -2343,12 +2352,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");
@@ -2364,14 +2373,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-26 22:33     ` Navare, Manasi
@ 2020-10-27 13:39       ` Ville Syrjälä
  2020-10-27 18:11         ` Navare, Manasi
  0 siblings, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-27 13:39 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Oct 26, 2020 at 03:33:36PM -0700, Navare, Manasi wrote:
> On Fri, Oct 23, 2020 at 09:00:25PM +0300, Ville Syrjälä wrote:
> > On Wed, Oct 21, 2020 at 10:42:20PM -0700, Manasi Navare wrote:
> > > Skip iterating over bigjoiner slaves, only the master has the state we
> > > care about.
> > > 
> > > Add the width of the bigjoiner slave to the reconstructed fb.
> > > 
> > > Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> > > master.
> > > 
> > > And last, disable bigjoiner slave from primary if reconstruction fails.
> > > 
> > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
> > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
> > >  drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
> > >  .../drm/i915/display/intel_display_types.h    |   1 +
> > >  4 files changed, 260 insertions(+), 118 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> > > index 0fecf372be11..104a423e0cd5 100644
> > > --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> > > +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> > > @@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > @@ -4408,20 +4408,14 @@ 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);
> > >  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > >  	u32 temp, flags = 0;
> > >  
> > > -	/* XXX: DSI transcoder paranoia */
> > > -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> > > -		return;
> > > -
> > > -	intel_dsc_get_config(pipe_config);
> > > -
> > >  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> > >  	if (temp & TRANS_DDI_PHSYNC)
> > >  		flags |= DRM_MODE_FLAG_PHSYNC;
> > > @@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> > >  	default:
> > >  		break;
> > >  	}
> > > +}
> > > +
> > > +void intel_ddi_get_config(struct intel_encoder *encoder,
> > > +			  struct intel_crtc_state *pipe_config)
> > > +{
> > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > > +
> > > +	/* XXX: DSI transcoder paranoia */
> > > +	if (drm_WARN_ON(&dev_priv->drm, 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);
> > > @@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -3631,6 +3631,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;
> > >  
> > > @@ -3653,7 +3655,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);
> > > @@ -3675,6 +3677,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;
> > >  
> > > @@ -8272,6 +8279,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);
> > > @@ -9186,20 +9217,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;
> > 
> > This part doesn't seem to have anything to do with the rest of the
> > patch. What is it its purpose?
> 
> May be just add this to Patch 2: drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split

What does it have to do with that?

> 
> Would that be okay?
> 
> > 
> > >  
> > >  	drm_mode_set_name(mode);
> > >  }
> > > @@ -10768,6 +10801,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);
> > > @@ -10876,6 +10910,13 @@ 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) {
> > > +		drm_dbg_kms(&dev_priv->drm,
> > > +			    "Does not support Bigjoiner Fb stretching yet\n");
> > 
> > "stretch" makes me think this has something to do with
> > scaling, which it does not. Also I have to wonder what
> > is the thing that "does not support". Ie. I guess I would
> > word it differently. Maybe something like:
> > "Unsupported bigjoiner configuration for initial FB"
> > 
> > Also I think we can check this before we even allocate the
> > fb struct, which means the goto error can be replaced
> > with a simple return.
> 
> Okay will change the debug message and move this to the top if the
> function so we can just return
> 
> Assuming your r-b after these changes?

Stop assuming. I'll give the rb when it's ready.

> 
> Manasi
> 
> > 
> > > +		goto error;
> > > +	}
> > > +
> > >  	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;
> > > @@ -11366,6 +11407,8 @@ 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
> > > @@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> > >  		active = true;
> > >  	}
> > >  
> > > -	if (!active)
> > > -		goto out;
> > > +	intel_dsc_get_config(pipe_config);
> > >  
> > > -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > > +	if (!active) {
> > > +		/* bigjoiner slave doesn't enable transcoder */
> > > +		if (!pipe_config->bigjoiner_slave)
> > > +			goto out;
> > > +
> > > +		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);
> > > @@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> > >  		}
> > >  	}
> > >  
> > > -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > > +	if (pipe_config->bigjoiner_slave) {
> > > +		/* Cannot be read out as a slave, set to 0. */
> > > +		pipe_config->pixel_multiplier = 0;
> > 
> > I think all the dozens of places with these readout hacks will need a
> > FIXME just so we don't forget to fix them. They also make the code semi
> > illegible so a FIXME would at least remind me when I wtf at the code
> > later.
> > 
> > > +	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > >  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> > >  		pipe_config->pixel_multiplier =
> > >  			intel_de_read(dev_priv,
> > > @@ -12536,7 +12591,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);
> > >  
> > > @@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
> > > +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);
> > > -
> > > +	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;
> > >  	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
> > >  
> > > @@ -14183,21 +14240,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)) ||
> > > @@ -14207,24 +14285,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)
> > > @@ -14250,7 +14315,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))
> > > @@ -14271,48 +14337,50 @@ 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(port_clock);
> > > +
> > > +		PIPE_CONF_CHECK_I(min_voltage_level);
> > > +	}
> > >  
> > >  	PIPE_CONF_CHECK_X(infoframes.enable);
> > >  	PIPE_CONF_CHECK_X(infoframes.gcp);
> > > @@ -14324,6 +14392,9 @@ 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);
> > > @@ -14595,6 +14666,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;
> > >  
> > >  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> > >  	intel_crtc_free_hw_state(old_crtc_state);
> > > @@ -14623,7 +14695,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;
> > >  		bool active;
> > >  
> > > @@ -14633,12 +14708,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);
> > 
> > Introducing that wrapper could easily be a separate patch.
> > 
> > >  	}
> > >  
> > >  	intel_crtc_compute_pixel_rate(pipe_config);
> > > @@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;
> > 
> > This part looks like a separate patch.
> > 
> > >  
> > >  		/*
> > > @@ -18856,7 +18931,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)) {
> > > @@ -19067,9 +19143,19 @@ 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);
> > >  			if (encoder->sync_state)
> > >  				encoder->sync_state(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;
> > >  		}
> > > @@ -19125,16 +19211,15 @@ 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 = &crtc_state->hw.mode;
> > > +			struct drm_display_mode mode;
> > 
> > Didn't we decide to keep hw.mode for now? If so, this looks very
> > suspicious.
> > 
> > >  
> > >  			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
> > > @@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > >  			/* 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;
> > > +
> > > +			if (crtc_state->bigjoiner)
> > > +				mode.hdisplay *= 2;
> > > +
> > >  			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) {
> > > @@ -19199,6 +19291,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);
> > > +		}
> > >  	}
> > >  }
> > >  
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 59ed94d68b55..d82ba1b9d8ef 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -845,6 +845,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 */
> > > -- 
> > > 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-26 22:41     ` Navare, Manasi
@ 2020-10-27 13:42       ` Ville Syrjälä
  2020-10-27 18:19         ` Navare, Manasi
  0 siblings, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-27 13:42 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
> On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> > On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > > 
> > > v6:
> > > * Fix from_plane_state assignments (Manasi)
> > > 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 |  53 ++++-
> > >  .../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(+), 40 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > index 3334ff253600..5df928f8f322 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > @@ -246,12 +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);
> > >  
> > > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > +	if (from_plane_state->uapi.crtc)
> > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > +	else
> > > +		plane_state->hw.crtc = NULL;
> > > +
> > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > >  	if (plane_state->hw.fb)
> > >  		drm_framebuffer_get(plane_state->hw.fb);
> > > @@ -320,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;
> > >  }
> > >  
> > > @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -3718,7 +3718,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);
> > >  
> > > @@ -12801,26 +12801,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;
> > 
> > Why would we even need this bigjoiner stuff in the planes? AFAICS about
> > the only thing we should need is someting like
> > 
> > for_each_plane_on_master()
> > 	add_same_plane_on_slave()
> > 
> > somewhere before we do the plane->check() stuff. I guess start
> > of intel_atomic_check_planes() could be the right spot.
> >
> 
> Yes may be but honestly I leave this optimization/change to the original
> author Maarten or you as a follow up

I don't want to see several hundred lines of totally uneccessary code
added. If it's buggy (which it may very well be because it's too big to
review properly) we are going to have to revert it anyway. If anything
else has changed in the same code the revertr is going to be a huge
pain.

> 
> Manasi
>  
> > > +	}
> > > +	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;
> > >  
> > > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > > -		if (IS_ERR(linked_plane_state))
> > > -			return PTR_ERR(linked_plane_state);
> > > +			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_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;
> > > @@ -12860,6 +13014,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)))
> > > @@ -12903,7 +13058,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;
> > >  
> > > @@ -15253,6 +15415,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) {
> > > @@ -15263,6 +15426,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;
> > >  
> > > @@ -15287,7 +15456,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 "
> > > @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3144,7 +3144,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;
> > > @@ -3154,7 +3154,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)
> > > @@ -3873,7 +3873,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;
> > >  
> > > @@ -3886,7 +3886,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];
> > >  
> > > @@ -4708,12 +4708,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;
> > >  
> > > @@ -4735,12 +4735,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;
> > >  
> > > @@ -5587,7 +5587,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;
> > >  
> > > @@ -5597,7 +5597,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case
  2020-10-27 13:39       ` Ville Syrjälä
@ 2020-10-27 18:11         ` Navare, Manasi
  0 siblings, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-27 18:11 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Tue, Oct 27, 2020 at 03:39:08PM +0200, Ville Syrjälä wrote:
> On Mon, Oct 26, 2020 at 03:33:36PM -0700, Navare, Manasi wrote:
> > On Fri, Oct 23, 2020 at 09:00:25PM +0300, Ville Syrjälä wrote:
> > > On Wed, Oct 21, 2020 at 10:42:20PM -0700, Manasi Navare wrote:
> > > > Skip iterating over bigjoiner slaves, only the master has the state we
> > > > care about.
> > > > 
> > > > Add the width of the bigjoiner slave to the reconstructed fb.
> > > > 
> > > > Hide the bigjoiner slave to userspace, and double the mode on bigjoiner
> > > > master.
> > > > 
> > > > And last, disable bigjoiner slave from primary if reconstruction fails.
> > > > 
> > > > Signed-off-by: Manasi Navare <manasi.d.navare@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/i915/display/icl_dsi.c        |   2 -
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c      |  36 +-
> > > >  drivers/gpu/drm/i915/display/intel_display.c  | 339 ++++++++++++------
> > > >  .../drm/i915/display/intel_display_types.h    |   1 +
> > > >  4 files changed, 260 insertions(+), 118 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c
> > > > index 0fecf372be11..104a423e0cd5 100644
> > > > --- a/drivers/gpu/drm/i915/display/icl_dsi.c
> > > > +++ b/drivers/gpu/drm/i915/display/icl_dsi.c
> > > > @@ -1492,8 +1492,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(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 050891a130c1..d5a0d0664c2d 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -4408,20 +4408,14 @@ 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);
> > > >  	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > > >  	u32 temp, flags = 0;
> > > >  
> > > > -	/* XXX: DSI transcoder paranoia */
> > > > -	if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
> > > > -		return;
> > > > -
> > > > -	intel_dsc_get_config(pipe_config);
> > > > -
> > > >  	temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
> > > >  	if (temp & TRANS_DDI_PHSYNC)
> > > >  		flags |= DRM_MODE_FLAG_PHSYNC;
> > > > @@ -4515,6 +4509,29 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
> > > >  	default:
> > > >  		break;
> > > >  	}
> > > > +}
> > > > +
> > > > +void intel_ddi_get_config(struct intel_encoder *encoder,
> > > > +			  struct intel_crtc_state *pipe_config)
> > > > +{
> > > > +	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > > +	enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
> > > > +
> > > > +	/* XXX: DSI transcoder paranoia */
> > > > +	if (drm_WARN_ON(&dev_priv->drm, 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);
> > > > @@ -4540,7 +4557,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 1be77ba2f9cf..c0715a3ea47b 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -3631,6 +3631,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;
> > > >  
> > > > @@ -3653,7 +3655,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);
> > > > @@ -3675,6 +3677,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;
> > > >  
> > > > @@ -8272,6 +8279,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);
> > > > @@ -9186,20 +9217,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;
> > > 
> > > This part doesn't seem to have anything to do with the rest of the
> > > patch. What is it its purpose?
> > 
> > May be just add this to Patch 2: drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split
> 
> What does it have to do with that?

Well thats the patch where the hw_mode is introduced, so I could add there.
But I can also just create a separate patch for this.

Manasi 
> 
> > 
> > Would that be okay?
> > 
> > > 
> > > >  
> > > >  	drm_mode_set_name(mode);
> > > >  }
> > > > @@ -10768,6 +10801,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);
> > > > @@ -10876,6 +10910,13 @@ 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) {
> > > > +		drm_dbg_kms(&dev_priv->drm,
> > > > +			    "Does not support Bigjoiner Fb stretching yet\n");
> > > 
> > > "stretch" makes me think this has something to do with
> > > scaling, which it does not. Also I have to wonder what
> > > is the thing that "does not support". Ie. I guess I would
> > > word it differently. Maybe something like:
> > > "Unsupported bigjoiner configuration for initial FB"
> > > 
> > > Also I think we can check this before we even allocate the
> > > fb struct, which means the goto error can be replaced
> > > with a simple return.
> > 
> > Okay will change the debug message and move this to the top if the
> > function so we can just return
> > 
> > Assuming your r-b after these changes?
> 
> Stop assuming. I'll give the rb when it's ready.
> 
> > 
> > Manasi
> > 
> > > 
> > > > +		goto error;
> > > > +	}
> > > > +
> > > >  	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;
> > > > @@ -11366,6 +11407,8 @@ 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
> > > > @@ -11439,10 +11482,19 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> > > >  		active = true;
> > > >  	}
> > > >  
> > > > -	if (!active)
> > > > -		goto out;
> > > > +	intel_dsc_get_config(pipe_config);
> > > >  
> > > > -	if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > > > +	if (!active) {
> > > > +		/* bigjoiner slave doesn't enable transcoder */
> > > > +		if (!pipe_config->bigjoiner_slave)
> > > > +			goto out;
> > > > +
> > > > +		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);
> > > > @@ -11517,7 +11569,10 @@ static bool hsw_get_pipe_config(struct intel_crtc *crtc,
> > > >  		}
> > > >  	}
> > > >  
> > > > -	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > > > +	if (pipe_config->bigjoiner_slave) {
> > > > +		/* Cannot be read out as a slave, set to 0. */
> > > > +		pipe_config->pixel_multiplier = 0;
> > > 
> > > I think all the dozens of places with these readout hacks will need a
> > > FIXME just so we don't forget to fix them. They also make the code semi
> > > illegible so a FIXME would at least remind me when I wtf at the code
> > > later.
> > > 
> > > > +	} else 	if (pipe_config->cpu_transcoder != TRANSCODER_EDP &&
> > > >  	    !transcoder_is_dsi(pipe_config->cpu_transcoder)) {
> > > >  		pipe_config->pixel_multiplier =
> > > >  			intel_de_read(dev_priv,
> > > > @@ -12536,7 +12591,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);
> > > >  
> > > > @@ -13540,13 +13595,15 @@ intel_crtc_copy_uapi_to_hw_state(struct intel_atomic_state *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)
> > > > +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);
> > > > -
> > > > +	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;
> > > >  	crtc_state->uapi.scaling_filter = crtc_state->hw.scaling_filter;
> > > >  
> > > > @@ -14183,21 +14240,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)) ||
> > > > @@ -14207,24 +14285,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)
> > > > @@ -14250,7 +14315,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))
> > > > @@ -14271,48 +14337,50 @@ 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(port_clock);
> > > > +
> > > > +		PIPE_CONF_CHECK_I(min_voltage_level);
> > > > +	}
> > > >  
> > > >  	PIPE_CONF_CHECK_X(infoframes.enable);
> > > >  	PIPE_CONF_CHECK_X(infoframes.gcp);
> > > > @@ -14324,6 +14392,9 @@ 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);
> > > > @@ -14595,6 +14666,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;
> > > >  
> > > >  	__drm_atomic_helper_crtc_destroy_state(&old_crtc_state->uapi);
> > > >  	intel_crtc_free_hw_state(old_crtc_state);
> > > > @@ -14623,7 +14695,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;
> > > >  		bool active;
> > > >  
> > > > @@ -14633,12 +14708,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);
> > > 
> > > Introducing that wrapper could easily be a separate patch.
> > > 
> > > >  	}
> > > >  
> > > >  	intel_crtc_compute_pixel_rate(pipe_config);
> > > > @@ -18543,7 +18618,7 @@ int intel_modeset_init_nogem(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;
> > > 
> > > This part looks like a separate patch.
> > > 
> > > >  
> > > >  		/*
> > > > @@ -18856,7 +18931,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)) {
> > > > @@ -19067,9 +19143,19 @@ 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);
> > > >  			if (encoder->sync_state)
> > > >  				encoder->sync_state(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;
> > > >  		}
> > > > @@ -19125,16 +19211,15 @@ 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 = &crtc_state->hw.mode;
> > > > +			struct drm_display_mode mode;
> > > 
> > > Didn't we decide to keep hw.mode for now? If so, this looks very
> > > suspicious.
> > > 
> > > >  
> > > >  			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
> > > > @@ -19149,11 +19234,18 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
> > > >  			/* 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;
> > > > +
> > > > +			if (crtc_state->bigjoiner)
> > > > +				mode.hdisplay *= 2;
> > > > +
> > > >  			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) {
> > > > @@ -19199,6 +19291,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);
> > > > +		}
> > > >  	}
> > > >  }
> > > >  
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > index 59ed94d68b55..d82ba1b9d8ef 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -845,6 +845,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 */
> > > > -- 
> > > > 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-27 13:42       ` Ville Syrjälä
@ 2020-10-27 18:19         ` Navare, Manasi
  2020-10-27 19:11           ` Ville Syrjälä
  0 siblings, 1 reply; 49+ messages in thread
From: Navare, Manasi @ 2020-10-27 18:19 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Tue, Oct 27, 2020 at 03:42:30PM +0200, Ville Syrjälä wrote:
> On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
> > On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> > > On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > > > 
> > > > v6:
> > > > * Fix from_plane_state assignments (Manasi)
> > > > 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 |  53 ++++-
> > > >  .../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(+), 40 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > index 3334ff253600..5df928f8f322 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > @@ -246,12 +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);
> > > >  
> > > > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > +	if (from_plane_state->uapi.crtc)
> > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > +	else
> > > > +		plane_state->hw.crtc = NULL;
> > > > +
> > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > >  	if (plane_state->hw.fb)
> > > >  		drm_framebuffer_get(plane_state->hw.fb);
> > > > @@ -320,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;
> > > >  }
> > > >  
> > > > @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -3718,7 +3718,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);
> > > >  
> > > > @@ -12801,26 +12801,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;
> > > 
> > > Why would we even need this bigjoiner stuff in the planes? AFAICS about
> > > the only thing we should need is someting like
> > > 
> > > for_each_plane_on_master()
> > > 	add_same_plane_on_slave()
> > > 
> > > somewhere before we do the plane->check() stuff. I guess start
> > > of intel_atomic_check_planes() could be the right spot.
> > >
> > 
> > Yes may be but honestly I leave this optimization/change to the original
> > author Maarten or you as a follow up
> 
> I don't want to see several hundred lines of totally uneccessary code
> added. If it's buggy (which it may very well be because it's too big to
> review properly) we are going to have to revert it anyway. If anything
> else has changed in the same code the revertr is going to be a huge
> pain.
>

This entire patch just does the linking of planes and there is no
unnecessary code. Also since I am just a carrier of this code and not
the original author I dont know how this can be simplified
without breaking the functionality. 
So I am not able to address your concern here. If Maarten has the
bandwidth he can jump in to rewrite this or you can.

Manasi
 
> > 
> > Manasi
> >  
> > > > +	}
> > > > +	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;
> > > >  
> > > > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > > > -		if (IS_ERR(linked_plane_state))
> > > > -			return PTR_ERR(linked_plane_state);
> > > > +			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_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;
> > > > @@ -12860,6 +13014,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)))
> > > > @@ -12903,7 +13058,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;
> > > >  
> > > > @@ -15253,6 +15415,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) {
> > > > @@ -15263,6 +15426,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;
> > > >  
> > > > @@ -15287,7 +15456,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 "
> > > > @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > @@ -3144,7 +3144,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;
> > > > @@ -3154,7 +3154,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)
> > > > @@ -3873,7 +3873,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;
> > > >  
> > > > @@ -3886,7 +3886,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];
> > > >  
> > > > @@ -4708,12 +4708,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;
> > > >  
> > > > @@ -4735,12 +4735,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;
> > > >  
> > > > @@ -5587,7 +5587,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;
> > > >  
> > > > @@ -5597,7 +5597,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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-27 18:19         ` Navare, Manasi
@ 2020-10-27 19:11           ` Ville Syrjälä
  2020-10-28 12:26             ` Maarten Lankhorst
  0 siblings, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-27 19:11 UTC (permalink / raw)
  To: Navare, Manasi; +Cc: intel-gfx

On Tue, Oct 27, 2020 at 11:19:16AM -0700, Navare, Manasi wrote:
> On Tue, Oct 27, 2020 at 03:42:30PM +0200, Ville Syrjälä wrote:
> > On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
> > > On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> > > > On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > > > > 
> > > > > v6:
> > > > > * Fix from_plane_state assignments (Manasi)
> > > > > 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 |  53 ++++-
> > > > >  .../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(+), 40 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > index 3334ff253600..5df928f8f322 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > > > @@ -246,12 +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);
> > > > >  
> > > > > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > > > +	if (from_plane_state->uapi.crtc)
> > > > > +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > > > > +	else
> > > > > +		plane_state->hw.crtc = NULL;
> > > > > +
> > > > >  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > > > >  	if (plane_state->hw.fb)
> > > > >  		drm_framebuffer_get(plane_state->hw.fb);
> > > > > @@ -320,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;
> > > > >  }
> > > > >  
> > > > > @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -3718,7 +3718,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);
> > > > >  
> > > > > @@ -12801,26 +12801,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;
> > > > 
> > > > Why would we even need this bigjoiner stuff in the planes? AFAICS about
> > > > the only thing we should need is someting like
> > > > 
> > > > for_each_plane_on_master()
> > > > 	add_same_plane_on_slave()
> > > > 
> > > > somewhere before we do the plane->check() stuff. I guess start
> > > > of intel_atomic_check_planes() could be the right spot.
> > > >
> > > 
> > > Yes may be but honestly I leave this optimization/change to the original
> > > author Maarten or you as a follow up
> > 
> > I don't want to see several hundred lines of totally uneccessary code
> > added. If it's buggy (which it may very well be because it's too big to
> > review properly) we are going to have to revert it anyway. If anything
> > else has changed in the same code the revertr is going to be a huge
> > pain.
> >
> 
> This entire patch just does the linking of planes and there is no
> unnecessary code.

Yes there is. Each plane should have a proper hw state so there 
should be absolutely no need for this linking stuff.

> Also since I am just a carrier of this code and not
> the original author I dont know how this can be simplified
> without breaking the functionality. 

You don't understand the code, I don't understand the code. How do
you suggest we can merge this? If there is any problem with the code
we have no choice but a full revert.

> So I am not able to address your concern here. If Maarten has the
> bandwidth he can jump in to rewrite this or you can.
> 
> Manasi
>  
> > > 
> > > Manasi
> > >  
> > > > > +	}
> > > > > +	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;
> > > > >  
> > > > > -		linked_plane_state = intel_atomic_get_plane_state(state, linked);
> > > > > -		if (IS_ERR(linked_plane_state))
> > > > > -			return PTR_ERR(linked_plane_state);
> > > > > +			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_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;
> > > > > @@ -12860,6 +13014,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)))
> > > > > @@ -12903,7 +13058,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;
> > > > >  
> > > > > @@ -15253,6 +15415,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) {
> > > > > @@ -15263,6 +15426,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;
> > > > >  
> > > > > @@ -15287,7 +15456,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 "
> > > > > @@ -16902,7 +17075,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 4f8dee9dfb4d..73f495bba141 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.h
> > > > > @@ -468,12 +468,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 d82ba1b9d8ef..69e6b0dc03a2 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > > > @@ -593,6 +593,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 18e52763dfec..8400e53f3f94 100644
> > > > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > > > @@ -3144,7 +3144,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;
> > > > > @@ -3154,7 +3154,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)
> > > > > @@ -3873,7 +3873,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;
> > > > >  
> > > > > @@ -3886,7 +3886,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];
> > > > >  
> > > > > @@ -4708,12 +4708,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;
> > > > >  
> > > > > @@ -4735,12 +4735,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;
> > > > >  
> > > > > @@ -5587,7 +5587,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;
> > > > >  
> > > > > @@ -5597,7 +5597,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] 49+ messages in thread

* [Intel-gfx] ✗ Fi.CI.BUILD: failure for Big joiner enabling (rev5)
  2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
                   ` (15 preceding siblings ...)
  2020-10-22  8:09 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
@ 2020-10-28  0:28 ` Patchwork
  16 siblings, 0 replies; 49+ messages in thread
From: Patchwork @ 2020-10-28  0:28 UTC (permalink / raw)
  To: Manasi Navare; +Cc: intel-gfx

== Series Details ==

Series: Big joiner enabling (rev5)
URL   : https://patchwork.freedesktop.org/series/82944/
State : failure

== Summary ==

CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  DESCEND  objtool
  CHK     include/generated/compile.h
  CC [M]  drivers/gpu/drm/i915/display/intel_dp.o
drivers/gpu/drm/i915/display/intel_dp.c: In function ‘intel_dp_dsc_compute_config’:
drivers/gpu/drm/i915/display/intel_dp.c:2327:34: error: implicit declaration of function ‘intel_dp_max_dotclock’; did you mean ‘intel_dp_set_clock’? [-Werror=implicit-function-declaration]
  if (adjusted_mode->crtc_clock > intel_dp_max_dotclock(intel_dp, false)) {
                                  ^~~~~~~~~~~~~~~~~~~~~
                                  intel_dp_set_clock
cc1: all warnings being treated as errors
scripts/Makefile.build:283: recipe for target 'drivers/gpu/drm/i915/display/intel_dp.o' failed
make[4]: *** [drivers/gpu/drm/i915/display/intel_dp.o] Error 1
scripts/Makefile.build:500: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:500: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:500: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1799: recipe for target 'drivers' failed
make: *** [drivers] Error 2


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

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

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-27 19:11           ` Ville Syrjälä
@ 2020-10-28 12:26             ` Maarten Lankhorst
  2020-10-28 13:04               ` Ville Syrjälä
  0 siblings, 1 reply; 49+ messages in thread
From: Maarten Lankhorst @ 2020-10-28 12:26 UTC (permalink / raw)
  To: Ville Syrjälä, Navare, Manasi; +Cc: intel-gfx


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

Op 27-10-2020 om 20:11 schreef Ville Syrjälä:
> On Tue, Oct 27, 2020 at 11:19:16AM -0700, Navare, Manasi wrote:
>> On Tue, Oct 27, 2020 at 03:42:30PM +0200, Ville Syrjälä wrote:
>>> On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
>>>> On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
>>>>> On Wed, Oct 21, 2020 at 10:42:21PM -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.
>>>>>>
>>>>>> v6:
>>>>>> * Fix from_plane_state assignments (Manasi)
>>>>>> 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 |  53 ++++-
>>>>>>  .../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(+), 40 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>>> index 3334ff253600..5df928f8f322 100644
>>>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
>>>>>> @@ -246,12 +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);
>>>>>>  
>>>>>> -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
>>>>>> +	if (from_plane_state->uapi.crtc)
>>>>>> +		plane_state->hw.crtc = crtc_state->uapi.crtc;
>>>>>> +	else
>>>>>> +		plane_state->hw.crtc = NULL;
>>>>>> +
>>>>>>  	plane_state->hw.fb = from_plane_state->uapi.fb;
>>>>>>  	if (plane_state->hw.fb)
>>>>>>  		drm_framebuffer_get(plane_state->hw.fb);
>>>>>> @@ -320,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;
>>>>>>  }
>>>>>>  
>>>>>> @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
>>>>>> --- a/drivers/gpu/drm/i915/display/intel_display.c
>>>>>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
>>>>>> @@ -3718,7 +3718,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);
>>>>>>  
>>>>>> @@ -12801,26 +12801,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;
>>>>> Why would we even need this bigjoiner stuff in the planes? AFAICS about
>>>>> the only thing we should need is someting like
>>>>>
>>>>> for_each_plane_on_master()
>>>>> 	add_same_plane_on_slave()
>>>>>
>>>>> somewhere before we do the plane->check() stuff. I guess start
>>>>> of intel_atomic_check_planes() could be the right spot.
>>>>>
>>>> Yes may be but honestly I leave this optimization/change to the original
>>>> author Maarten or you as a follow up
>>> I don't want to see several hundred lines of totally uneccessary code
>>> added. If it's buggy (which it may very well be because it's too big to
>>> review properly) we are going to have to revert it anyway. If anything
>>> else has changed in the same code the revertr is going to be a huge
>>> pain.
>>>
>> This entire patch just does the linking of planes and there is no
>> unnecessary code.
> Yes there is. Each plane should have a proper hw state so there 
> should be absolutely no need for this linking stuff.
>
>> Also since I am just a carrier of this code and not
>> the original author I dont know how this can be simplified
>> without breaking the functionality. 
> You don't understand the code, I don't understand the code. How do
> you suggest we can merge this? If there is any problem with the code
> we have no choice but a full revert.

Hey,

There's good reason to link the planes. The reason is similar to linking Y and CbCr planes.
You're completely correct that hardware programming doesn't need the linking, and planes are
in theory standalone.

But there's also atomic. The lifetime of plane_state on the bigjoiner slave plane must be
linked to the lifetime of the master plane. Otherwise if you do a commit on the master plane,
you may get a use after free on slave. To prevent this I just linked them together. :)

~Maarten

~Maarten


[-- Attachment #1.2: Type: text/html, Size: 11729 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] 49+ messages in thread

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-28 12:26             ` Maarten Lankhorst
@ 2020-10-28 13:04               ` Ville Syrjälä
  2020-10-28 22:15                 ` Navare, Manasi
  0 siblings, 1 reply; 49+ messages in thread
From: Ville Syrjälä @ 2020-10-28 13:04 UTC (permalink / raw)
  To: Maarten Lankhorst; +Cc: intel-gfx

On Wed, Oct 28, 2020 at 01:26:27PM +0100, Maarten Lankhorst wrote:
> Op 27-10-2020 om 20:11 schreef Ville Syrjälä:
> > On Tue, Oct 27, 2020 at 11:19:16AM -0700, Navare, Manasi wrote:
> >> On Tue, Oct 27, 2020 at 03:42:30PM +0200, Ville Syrjälä wrote:
> >>> On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
> >>>> On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> >>>>> On Wed, Oct 21, 2020 at 10:42:21PM -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.
> >>>>>>
> >>>>>> v6:
> >>>>>> * Fix from_plane_state assignments (Manasi)
> >>>>>> 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 |  53 ++++-
> >>>>>>  .../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(+), 40 deletions(-)
> >>>>>>
> >>>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>>> index 3334ff253600..5df928f8f322 100644
> >>>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> >>>>>> @@ -246,12 +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);
> >>>>>>  
> >>>>>> -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> >>>>>> +	if (from_plane_state->uapi.crtc)
> >>>>>> +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> >>>>>> +	else
> >>>>>> +		plane_state->hw.crtc = NULL;
> >>>>>> +
> >>>>>>  	plane_state->hw.fb = from_plane_state->uapi.fb;
> >>>>>>  	if (plane_state->hw.fb)
> >>>>>>  		drm_framebuffer_get(plane_state->hw.fb);
> >>>>>> @@ -320,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;
> >>>>>>  }
> >>>>>>  
> >>>>>> @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> >>>>>> --- a/drivers/gpu/drm/i915/display/intel_display.c
> >>>>>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> >>>>>> @@ -3718,7 +3718,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);
> >>>>>>  
> >>>>>> @@ -12801,26 +12801,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;
> >>>>> Why would we even need this bigjoiner stuff in the planes? AFAICS about
> >>>>> the only thing we should need is someting like
> >>>>>
> >>>>> for_each_plane_on_master()
> >>>>> 	add_same_plane_on_slave()
> >>>>>
> >>>>> somewhere before we do the plane->check() stuff. I guess start
> >>>>> of intel_atomic_check_planes() could be the right spot.
> >>>>>
> >>>> Yes may be but honestly I leave this optimization/change to the original
> >>>> author Maarten or you as a follow up
> >>> I don't want to see several hundred lines of totally uneccessary code
> >>> added. If it's buggy (which it may very well be because it's too big to
> >>> review properly) we are going to have to revert it anyway. If anything
> >>> else has changed in the same code the revertr is going to be a huge
> >>> pain.
> >>>> >> This entire patch just does the linking of planes and there is no
> >> unnecessary code.
> > Yes there is. Each plane should have a proper hw state so there 
> > should be absolutely no need for this linking stuff.
> >
> >> Also since I am just a carrier of this code and not
> >> the original author I dont know how this can be simplified
> >> without breaking the functionality. 
> > You don't understand the code, I don't understand the code. How do
> > you suggest we can merge this? If there is any problem with the code
> > we have no choice but a full revert.
> 
> Hey,
> 
> There's good reason to link the planes. The reason is similar to linking Y and CbCr planes.

There we actually have to link them in some fashion because that's what
the hw requires. But with the uapi vs. hw state split we should be able
to make a proper state copy there too, and thus we could get rid of the
magic "let's use the other plane's state during commit" stuff.

> You're completely correct that hardware programming doesn't need the linking, and planes are
> in theory standalone.
> 
> But there's also atomic. The lifetime of plane_state on the bigjoiner slave plane must be
> linked to the lifetime of the master plane. Otherwise if you do a commit on the master plane,
> you may get a use after free on slave. To prevent this I just linked them together. :)

There should be nothing in the slave's plane state that references the
master's state. Whatever pointers we have there (fb/gamma/etc.) should
be refcounted. So can't immediately think where any uaf would come from. 

That said. Looks like watermarks are a bit of a mess again. Time to
finally get rid of that intel_atomic_crtc_state_for_each_plane_state()
I think...

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

* Re: [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3.
  2020-10-28 13:04               ` Ville Syrjälä
@ 2020-10-28 22:15                 ` Navare, Manasi
  0 siblings, 0 replies; 49+ messages in thread
From: Navare, Manasi @ 2020-10-28 22:15 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Wed, Oct 28, 2020 at 03:04:37PM +0200, Ville Syrjälä wrote:
> On Wed, Oct 28, 2020 at 01:26:27PM +0100, Maarten Lankhorst wrote:
> > Op 27-10-2020 om 20:11 schreef Ville Syrjälä:
> > > On Tue, Oct 27, 2020 at 11:19:16AM -0700, Navare, Manasi wrote:
> > >> On Tue, Oct 27, 2020 at 03:42:30PM +0200, Ville Syrjälä wrote:
> > >>> On Mon, Oct 26, 2020 at 03:41:48PM -0700, Navare, Manasi wrote:
> > >>>> On Mon, Oct 26, 2020 at 10:18:54PM +0200, Ville Syrjälä wrote:
> > >>>>> On Wed, Oct 21, 2020 at 10:42:21PM -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.
> > >>>>>>
> > >>>>>> v6:
> > >>>>>> * Fix from_plane_state assignments (Manasi)
> > >>>>>> 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 |  53 ++++-
> > >>>>>>  .../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(+), 40 deletions(-)
> > >>>>>>
> > >>>>>> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>>> index 3334ff253600..5df928f8f322 100644
> > >>>>>> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>>> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > >>>>>> @@ -246,12 +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);
> > >>>>>>  
> > >>>>>> -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > >>>>>> +	if (from_plane_state->uapi.crtc)
> > >>>>>> +		plane_state->hw.crtc = crtc_state->uapi.crtc;
> > >>>>>> +	else
> > >>>>>> +		plane_state->hw.crtc = NULL;
> > >>>>>> +
> > >>>>>>  	plane_state->hw.fb = from_plane_state->uapi.fb;
> > >>>>>>  	if (plane_state->hw.fb)
> > >>>>>>  		drm_framebuffer_get(plane_state->hw.fb);
> > >>>>>> @@ -320,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;
> > >>>>>>  }
> > >>>>>>  
> > >>>>>> @@ -339,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 c0715a3ea47b..579cccc1fd91 100644
> > >>>>>> --- a/drivers/gpu/drm/i915/display/intel_display.c
> > >>>>>> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > >>>>>> @@ -3718,7 +3718,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);
> > >>>>>>  
> > >>>>>> @@ -12801,26 +12801,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;
> > >>>>> Why would we even need this bigjoiner stuff in the planes? AFAICS about
> > >>>>> the only thing we should need is someting like
> > >>>>>
> > >>>>> for_each_plane_on_master()
> > >>>>> 	add_same_plane_on_slave()
> > >>>>>
> > >>>>> somewhere before we do the plane->check() stuff. I guess start
> > >>>>> of intel_atomic_check_planes() could be the right spot.
> > >>>>>
> > >>>> Yes may be but honestly I leave this optimization/change to the original
> > >>>> author Maarten or you as a follow up
> > >>> I don't want to see several hundred lines of totally uneccessary code
> > >>> added. If it's buggy (which it may very well be because it's too big to
> > >>> review properly) we are going to have to revert it anyway. If anything
> > >>> else has changed in the same code the revertr is going to be a huge
> > >>> pain.
> > >>>> >> This entire patch just does the linking of planes and there is no
> > >> unnecessary code.
> > > Yes there is. Each plane should have a proper hw state so there 
> > > should be absolutely no need for this linking stuff.
> > >
> > >> Also since I am just a carrier of this code and not
> > >> the original author I dont know how this can be simplified
> > >> without breaking the functionality. 
> > > You don't understand the code, I don't understand the code. How do
> > > you suggest we can merge this? If there is any problem with the code
> > > we have no choice but a full revert.
> > 
> > Hey,
> > 
> > There's good reason to link the planes. The reason is similar to linking Y and CbCr planes.
> 
> There we actually have to link them in some fashion because that's what
> the hw requires. But with the uapi vs. hw state split we should be able
> to make a proper state copy there too, and thus we could get rid of the
> magic "let's use the other plane's state during commit" stuff.
> 
> > You're completely correct that hardware programming doesn't need the linking, and planes are
> > in theory standalone.
> > 
> > But there's also atomic. The lifetime of plane_state on the bigjoiner slave plane must be
> > linked to the lifetime of the master plane. Otherwise if you do a commit on the master plane,
> > you may get a use after free on slave. To prevent this I just linked them together. :)
> 
> There should be nothing in the slave's plane state that references the
> master's state. Whatever pointers we have there (fb/gamma/etc.) should
> be refcounted. So can't immediately think where any uaf would come from. 
> 
> That said. Looks like watermarks are a bit of a mess again. Time to
> finally get rid of that intel_atomic_crtc_state_for_each_plane_state()
> I think...
> 

So can we move forward with the plane linking as of now or would @Maarten have
some BW to change this?

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

end of thread, other threads:[~2020-10-28 22:13 UTC | newest]

Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-22  5:42 [Intel-gfx] [PATCH v11 00/12] Big joiner enabling Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 01/12] HAX to make DSC work on the icelake test system Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 02/12] drm/i915: Add hw.pipe_mode to allow bigjoiner pipe/transcoder split Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 03/12] drm/i915/dp: Some reshuffling in mode_valid as prep for bigjoiner modes Manasi Navare
2020-10-23 17:17   ` Ville Syrjälä
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 04/12] drm/i915/dp: Allow big joiner modes in intel_dp_mode_valid(), v3 Manasi Navare
2020-10-23 17:32   ` Ville Syrjälä
2020-10-23 18:30     ` Navare, Manasi
2020-10-23 18:44       ` Ville Syrjälä
2020-10-26 23:47         ` Navare, Manasi
2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 05/12] drm/i915/dp: Prep for bigjoiner atomic check Manasi Navare
2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 06/12] drm/i915: Try to make bigjoiner work in " Manasi Navare
2020-10-23 17:42   ` Ville Syrjälä
2020-10-23 18:13     ` Navare, Manasi
2020-10-23 18:30       ` Ville Syrjälä
2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 07/12] drm/i915/dp: Modify VDSC helpers to configure DSC for Bigjoiner slave Manasi Navare
2020-10-26 21:56   ` Navare, Manasi
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 08/12] drm/i915/dp: Master/Slave enable/disable sequence for bigjoiner Manasi Navare
2020-10-23  7:57   ` Dan Carpenter
2020-10-23  7:57     ` Dan Carpenter
2020-10-23  7:57     ` Dan Carpenter
2020-10-26 21:57   ` Navare, Manasi
2020-10-27  5:50   ` [Intel-gfx] [PATCH v12 " Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 09/12] drm/i915: HW state readout for Bigjoiner case Manasi Navare
2020-10-23 18:00   ` Ville Syrjälä
2020-10-26 22:33     ` Navare, Manasi
2020-10-27 13:39       ` Ville Syrjälä
2020-10-27 18:11         ` Navare, Manasi
2020-10-26 22:29   ` Navare, Manasi
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 10/12] drm/i915: Link planes in a bigjoiner configuration, v3 Manasi Navare
2020-10-26 20:18   ` Ville Syrjälä
2020-10-26 22:34     ` Navare, Manasi
2020-10-26 22:41     ` Navare, Manasi
2020-10-27 13:42       ` Ville Syrjälä
2020-10-27 18:19         ` Navare, Manasi
2020-10-27 19:11           ` Ville Syrjälä
2020-10-28 12:26             ` Maarten Lankhorst
2020-10-28 13:04               ` Ville Syrjälä
2020-10-28 22:15                 ` Navare, Manasi
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 11/12] drm/i915: Add bigjoiner aware plane clipping checks Manasi Navare
2020-10-22  5:42 ` [Intel-gfx] [PATCH v11 12/12] drm/i915: Add debugfs dumping for bigjoiner, v3 Manasi Navare
2020-10-22  6:01 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Big joiner enabling Patchwork
2020-10-22  6:03 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2020-10-22  6:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-10-22  8:09 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2020-10-28  0:28 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for Big joiner enabling (rev5) 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.