[PATCH 25/25] HAX: drm/i915: fake joiner support

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Fri Aug 30 15:08:36 UTC 2019


This adds a module parameter i915.fake_joiner to allow merging 2 screens
on pipe B and C if they have same resolution + timings, to test the
bigjoiner plane code. I've used it to test that the bigjoiner plane code
works as intended, without being limited by a display that supports DSC.

Can be useful for testing 2p2p as a 2p1p case, if you modify igt to assign
PIPE_B and PIPE_C, and create a fb that's 2x as wide as mode->hdisplay.

Used for validating plane programming, both packed and NV12.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c      |  2 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 47 +++++++++++++++----
 .../drm/i915/display/intel_display_types.h    |  2 +
 drivers/gpu/drm/i915/display/intel_vdsc.c     |  2 +-
 drivers/gpu/drm/i915/i915_params.c            |  3 ++
 drivers/gpu/drm/i915/i915_params.h            |  3 +-
 6 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 8ed44e59a039..f7ae91c2e851 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1213,7 +1213,7 @@ intel_ddi_get_crtc_encoder(const struct intel_crtc_state *crtc_state)
 	struct intel_encoder *encoder, *ret = NULL;
 	int num_encoders = 0;
 
-	if (crtc_state->bigjoiner_slave)
+	if (crtc_state->bigjoiner_slave && !crtc_state->fake_joiner)
 		crtc = crtc_state->bigjoiner_linked_crtc;
 
 	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 6497d06f4497..075145c94797 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6490,7 +6490,7 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (WARN_ON(intel_crtc->active))
 		return;
 
-	if (!pipe_config->bigjoiner) {
+	if (!pipe_config->bigjoiner || pipe_config->fake_joiner) {
 		intel_encoders_pre_pll_enable(intel_crtc, pipe_config, state);
 
 		if (pipe_config->shared_dpll)
@@ -6696,7 +6696,7 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 	else
 		ironlake_pfit_disable(old_crtc_state);
 
-	if (old_crtc_state->bigjoiner) {
+	if (old_crtc_state->bigjoiner && !old_crtc_state->fake_joiner) {
 		struct intel_crtc *master;
 		struct intel_crtc_state *master_crtc_state;
 
@@ -11933,7 +11933,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
 	if (mode_changed && pipe_config->hw.enable &&
 	    dev_priv->display.crtc_compute_clock &&
 	    !WARN_ON(pipe_config->shared_dpll) &&
-	    !pipe_config->bigjoiner_slave) {
+	    (!pipe_config->bigjoiner_slave || pipe_config->fake_joiner)) {
 		ret = dev_priv->display.crtc_compute_clock(intel_crtc,
 							   pipe_config);
 		if (ret)
@@ -13359,7 +13359,7 @@ verify_crtc_state(struct intel_crtc *crtc,
 			"(expected %i, found %i)\n",
 			new_crtc_state->hw.active, crtc->active);
 
-	if (new_crtc_state->bigjoiner_slave)
+	if (new_crtc_state->bigjoiner_slave && !new_crtc_state->fake_joiner)
 		master = new_crtc_state->bigjoiner_linked_crtc;
 
 	for_each_encoder_on_crtc(dev, &master->base, encoder) {
@@ -13899,6 +13899,31 @@ static int intel_atomic_check_bigjoiner(struct intel_atomic_state *state)
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
 					    new_crtc_state, i) {
+
+		/* Potentially set up a fake joiner config */
+		if (crtc->pipe == PIPE_B && !new_crtc_state->bigjoiner &&
+		    new_crtc_state->hw.active) {
+			slave = intel_get_crtc_for_pipe(dev_priv, crtc->pipe + 1);
+			slave_crtc_state = intel_atomic_get_crtc_state(&state->base, slave);
+			if (IS_ERR(slave_crtc_state))
+				return PTR_ERR(slave_crtc_state);
+
+			if (slave_crtc_state->hw.active &&
+			    slave_crtc_state->hw.adjusted_mode.crtc_clock ==
+			    new_crtc_state->hw.adjusted_mode.crtc_clock &&
+			    slave_crtc_state->pipe_src_h == new_crtc_state->pipe_src_h &&
+			    slave_crtc_state->pipe_src_w == new_crtc_state->pipe_src_w &&
+			    i915_modparams.fake_joiner) {
+				DRM_ERROR("Using fake bigjoiner config\n");
+				new_crtc_state->fake_joiner = slave_crtc_state->fake_joiner = true;
+				new_crtc_state->bigjoiner = slave_crtc_state->bigjoiner = true;
+				slave_crtc_state->bigjoiner_slave = true;
+				new_crtc_state->bigjoiner_linked_crtc = slave;
+				slave_crtc_state->bigjoiner_linked_crtc = crtc;
+				continue;
+			}
+		}
+
 		if (!new_crtc_state->uapi.enable || !new_crtc_state->bigjoiner) {
 			if (!old_crtc_state->bigjoiner)
 				continue;
@@ -14261,7 +14286,9 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 	 */
 	for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, old_crtc_state,
 						    new_crtc_state, i) {
-		if (!needs_modeset(new_crtc_state) || old_crtc_state->bigjoiner_slave)
+		if (!needs_modeset(new_crtc_state) ||
+		    (old_crtc_state->bigjoiner_slave && !old_crtc_state->fake_joiner))
+
 			continue;
 
 		intel_pre_plane_update(old_crtc_state, new_crtc_state);
@@ -14272,7 +14299,7 @@ static void intel_commit_modeset_disables(struct intel_atomic_state *state)
 						      new_crtc_state,
 						      crtc);
 
-		if (old_crtc_state->bigjoiner) {
+		if (old_crtc_state->bigjoiner && !old_crtc_state->fake_joiner) {
 			struct intel_crtc *slave = old_crtc_state->bigjoiner_linked_crtc;
 			struct intel_crtc_state *old_slave_crtc_state =
 				intel_atomic_get_crtc_state(&state->base, slave);
@@ -14368,14 +14395,14 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 	const struct intel_crtc_state *slave_crtc_state;
 
 	for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
-		if (new_crtc_state->bigjoiner_slave) {
+		if (new_crtc_state->bigjoiner_slave && !new_crtc_state->fake_joiner) {
 			/* clear dirty bit, we're updated in master */
 			state->wm_results.dirty_pipes &= drm_crtc_mask(&crtc->base);
 			continue;
 		}
 
 		if (new_crtc_state->hw.active) {
-			if (new_crtc_state->bigjoiner) {
+			if (new_crtc_state->bigjoiner && !new_crtc_state->bigjoiner_slave && !new_crtc_state->fake_joiner) {
 				slave = new_crtc_state->bigjoiner_linked_crtc;
 				slave_crtc_state =
 					intel_atomic_get_new_crtc_state(state,
@@ -14425,7 +14452,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			pipe = crtc->pipe;
 
 			if (updated & cmask || !new_crtc_state->hw.active ||
-			    new_crtc_state->bigjoiner_slave)
+			    (new_crtc_state->bigjoiner_slave && !new_crtc_state->fake_joiner))
 				continue;
 
 			if (skl_ddb_allocation_overlaps(&new_entries[i], entries,
@@ -14445,7 +14472,7 @@ static void skl_commit_modeset_enables(struct intel_atomic_state *state)
 			    state->wm_results.dirty_pipes != updated)
 				vbl_wait = true;
 
-			if (new_crtc_state->bigjoiner)
+			if (new_crtc_state->bigjoiner && !new_crtc_state->fake_joiner)
 				intel_update_bigjoiner(crtc, state,
 						       old_crtc_state,
 						       new_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 14707c25dbe4..beebf8c361ce 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1026,6 +1026,8 @@ struct intel_crtc_state {
 	/* big joiner slave crtc? */
 	bool bigjoiner_slave;
 
+	bool fake_joiner;
+
 	/* linked crtc for bigjoiner, either slave or master */
 	struct intel_crtc *bigjoiner_linked_crtc;
 
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index 3cfbd3250df5..f1c058b7d604 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -946,7 +946,7 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
 		dss_ctl1_val |= JOINER_ENABLE;
 	}
-	if (crtc_state->bigjoiner) {
+	if (crtc_state->bigjoiner && !crtc_state->fake_joiner) {
 		dss_ctl1_val |= BIG_JOINER_ENABLE;
 		if (!crtc_state->bigjoiner_slave)
 			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
index 296452f9efe4..d97662cb86de 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -173,6 +173,9 @@ i915_param_named(enable_dpcd_backlight, int, 0600,
 	"Enable support for DPCD backlight control"
 	"(-1=use per-VBT LFP backlight type setting, 0=disabled [default], 1=enabled)");
 
+i915_param_named(fake_joiner, bool, 0600,
+	"Enable fake joiner and make a big screen out of pipe B and C if the timings are identical.");
+
 #if IS_ENABLED(CONFIG_DRM_I915_GVT)
 i915_param_named(enable_gvt, bool, 0400,
 	"Enable support for Intel GVT-g graphics virtualization host support(default:false)");
diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
index d29ade3b7de6..1f752eef081f 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -77,7 +77,8 @@ struct drm_printer;
 	param(bool, verbose_state_checks, true) \
 	param(bool, nuclear_pageflip, false) \
 	param(bool, enable_dp_mst, true) \
-	param(bool, enable_gvt, false)
+	param(bool, enable_gvt, false) \
+	param(bool, fake_joiner, false)
 
 #define MEMBER(T, member, ...) T member;
 struct i915_params {
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list