[PATCH 06/16] drm/i915: Enable big joiner support in hsw_crtc_enable.

Maarten Lankhorst maarten.lankhorst at linux.intel.com
Tue Aug 6 08:51:49 UTC 2019


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

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

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_ddi.c     | 10 ++++++---
 drivers/gpu/drm/i915/display/intel_display.c | 19 ++++++++++++++---
 drivers/gpu/drm/i915/display/intel_vdsc.c    | 22 +++++++++++++-------
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index f912f61a4795..bb9b9ce9fd9b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1206,12 +1206,16 @@ static void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
 }
 
 static struct intel_encoder *
-intel_ddi_get_crtc_encoder(struct intel_crtc *crtc)
+intel_ddi_get_crtc_encoder(const struct intel_crtc_state *crtc_state)
 {
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct intel_encoder *encoder, *ret = NULL;
 	int num_encoders = 0;
 
+	if (crtc_state->bigjoiner_master_crtc)
+		crtc = crtc_state->bigjoiner_master_crtc;
+
 	for_each_encoder_on_crtc(dev, &crtc->base, encoder) {
 		ret = encoder;
 		num_encoders++;
@@ -1764,7 +1768,7 @@ void intel_ddi_set_vc_payload_alloc(const struct intel_crtc_state *crtc_state,
 void intel_ddi_enable_transcoder_func(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
+	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc_state);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
@@ -2139,7 +2143,7 @@ void intel_ddi_enable_pipe_clock(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_encoder *encoder = intel_ddi_get_crtc_encoder(crtc);
+	struct intel_encoder *encoder = intel_ddi_get_crtc_encoder(crtc_state);
 	enum port port = encoder->port;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index ac4349cdb406..119c886f79a4 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6457,6 +6457,12 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 
 	intel_encoders_pre_enable(intel_crtc, pipe_config, state);
 
+	if (pipe_config->bigjoiner_master_crtc != NULL) {
+		/* nothing to enable in bigjoiner slave case, but we need the port clock */
+		intel_ddi_enable_pipe_clock(pipe_config);
+		intel_dsc_enable(NULL, pipe_config);
+	}
+
 	if (intel_crtc_has_dp_encoder(pipe_config))
 		intel_dp_set_m_n(pipe_config, M1_N1);
 
@@ -6508,9 +6514,12 @@ static void haswell_crtc_enable(struct intel_crtc_state *pipe_config,
 	if (INTEL_GEN(dev_priv) >= 11)
 		icl_set_pipe_chicken(intel_crtc);
 
-	intel_ddi_set_pipe_settings(pipe_config);
-	if (!transcoder_is_dsi(cpu_transcoder))
-		intel_ddi_enable_transcoder_func(pipe_config);
+	if (pipe_config->bigjoiner_master_crtc == NULL) {
+		intel_ddi_set_pipe_settings(pipe_config);
+
+		if (!transcoder_is_dsi(cpu_transcoder))
+			intel_ddi_enable_transcoder_func(pipe_config);
+	}
 
 	if (dev_priv->display.initial_watermarks != NULL)
 		dev_priv->display.initial_watermarks(state, pipe_config);
@@ -6651,6 +6660,9 @@ static void haswell_crtc_disable(struct intel_crtc_state *old_crtc_state,
 	else
 		ironlake_pfit_disable(old_crtc_state);
 
+	if (old_crtc_state->bigjoiner_master_crtc != NULL)
+		intel_ddi_disable_pipe_clock(old_crtc_state);
+
 	intel_encoders_post_disable(intel_crtc, old_crtc_state, state);
 
 	intel_encoders_post_pll_disable(intel_crtc, old_crtc_state, state);
@@ -13970,6 +13982,7 @@ static void intel_update_crtc(struct intel_crtc *crtc,
 
 	if (modeset) {
 		update_scanline_offset(new_crtc_state);
+		drm_calc_timestamping_constants(&crtc->base, &new_crtc_state->hw.adjusted_mode);
 		dev_priv->display.crtc_enable(new_crtc_state, state);
 
 		/* vblanks work again, re-enable pipe CRC. */
diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c
index cf27311a75f6..b51f77a103b7 100644
--- a/drivers/gpu/drm/i915/display/intel_vdsc.c
+++ b/drivers/gpu/drm/i915/display/intel_vdsc.c
@@ -480,11 +480,10 @@ intel_dsc_power_domain(const struct intel_crtc_state *crtc_state)
 		return POWER_DOMAIN_TRANSCODER(cpu_transcoder);
 }
 
-static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
-						const struct intel_crtc_state *crtc_state)
+static void intel_configure_pps_for_dsc_encoder(const struct intel_crtc_state *crtc_state)
 {
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dp_dsc_cfg;
 	enum pipe pipe = crtc->pipe;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
@@ -494,6 +493,9 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
 	u8 num_vdsc_instances = (crtc_state->dsc_params.dsc_split) ? 2 : 1;
 	int i = 0;
 
+	if (crtc_state->bigjoiner)
+		num_vdsc_instances *= 2;
+
 	/* Populate PICTURE_PARAMETER_SET_0 registers */
 	pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
 		DSC_VER_MIN_SHIFT |
@@ -547,7 +549,7 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
 	pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) |
 		DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
 	DRM_INFO("PPS2 = 0x%08x\n", pps_val);
-	if (encoder->type == INTEL_OUTPUT_EDP) {
+	if (cpu_transcoder == TRANSCODER_EDP) {
 		I915_WRITE(DSCA_PICTURE_PARAMETER_SET_2, pps_val);
 		/*
 		 * If 2 VDSC instances are needed, configure PPS for second
@@ -903,7 +905,7 @@ 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);
+	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;
@@ -916,9 +918,10 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 	intel_display_power_get(dev_priv,
 				intel_dsc_power_domain(crtc_state));
 
-	intel_configure_pps_for_dsc_encoder(encoder, crtc_state);
+	intel_configure_pps_for_dsc_encoder(crtc_state);
 
-	intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
+	if (!crtc_state->bigjoiner_master_crtc)
+		intel_dp_write_dsc_pps_sdp(encoder, crtc_state);
 
 	if (crtc_state->cpu_transcoder == TRANSCODER_EDP) {
 		dss_ctl1_reg = DSS_CTL1;
@@ -932,6 +935,11 @@ void intel_dsc_enable(struct intel_encoder *encoder,
 		dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
 		dss_ctl1_val |= JOINER_ENABLE;
 	}
+	if (crtc_state->bigjoiner) {
+		dss_ctl1_val |= BIG_JOINER_ENABLE;
+		if (crtc_state->bigjoiner_master_crtc == NULL)
+			dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
+	}
 	I915_WRITE(dss_ctl1_reg, dss_ctl1_val);
 	I915_WRITE(dss_ctl2_reg, dss_ctl2_val);
 }
-- 
2.20.1



More information about the Intel-gfx-trybot mailing list