Commit d6fe5887 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2022-10-06-1' of...

Merge tag 'drm-intel-next-fixes-2022-10-06-1' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-next

- Round to closest in g4x+ HDMI clock readout (Ville Syrjälä)
- Update MOCS table for EHL (Tejas Upadhyay)
- Fix PSR_IMR/IIR field handling (Jouni Högander)
- Fix watermark calculations for gen12+ RC CCS modifier (Ville Syrjälä)
- Fix watermark calculations for gen12+ MC CCS modifier (Ville Syrjälä)
- Fix watermark calculations for gen12+ CCS+CC modifier (Ville Syrjälä)
- Fix watermark calculations for DG2 CCS modifiers (Ville Syrjälä)
- Fix watermark calculations for DG2 CCS+CC modifier (Ville Syrjälä)
- Reject excessive dotclocks early (Ville Syrjälä)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Yz6rkXI9HKFUvtWK@tursulin-desk
parents bafaf67c cdf6428d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ static void intel_hdmi_get_config(struct intel_encoder *encoder,
	pipe_config->hw.adjusted_mode.flags |= flags;

	if ((tmp & SDVO_COLOR_FORMAT_MASK) == HDMI_COLOR_FORMAT_12bpc)
		dotclock = pipe_config->port_clock * 2 / 3;
		dotclock = DIV_ROUND_CLOSEST(pipe_config->port_clock * 2, 3);
	else
		dotclock = pipe_config->port_clock;

+18 −0
Original line number Diff line number Diff line
@@ -8130,6 +8130,17 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv)
	drm_helper_move_panel_connectors_to_head(&dev_priv->drm);
}

static int max_dotclock(struct drm_i915_private *i915)
{
	int max_dotclock = i915->max_dotclk_freq;

	/* icl+ might use bigjoiner */
	if (DISPLAY_VER(i915) >= 11)
		max_dotclock *= 2;

	return max_dotclock;
}

static enum drm_mode_status
intel_mode_valid(struct drm_device *dev,
		 const struct drm_display_mode *mode)
@@ -8167,6 +8178,13 @@ intel_mode_valid(struct drm_device *dev,
			   DRM_MODE_FLAG_CLKDIV2))
		return MODE_BAD;

	/*
	 * Reject clearly excessive dotclocks early to
	 * avoid having to worry about huge integers later.
	 */
	if (mode->clock > max_dotclock(dev_priv))
		return MODE_CLOCK_HIGH;

	/* Transcoder timing limits */
	if (DISPLAY_VER(dev_priv) >= 11) {
		hdisplay_max = 16384;
+47 −31
Original line number Diff line number Diff line
@@ -116,34 +116,56 @@ static bool psr2_global_enabled(struct intel_dp *intel_dp)
	}
}

static u32 psr_irq_psr_error_bit_get(struct intel_dp *intel_dp)
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

	return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_ERROR :
		EDP_PSR_ERROR(intel_dp->psr.transcoder);
}

static u32 psr_irq_post_exit_bit_get(struct intel_dp *intel_dp)
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

	return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_POST_EXIT :
		EDP_PSR_POST_EXIT(intel_dp->psr.transcoder);
}

static u32 psr_irq_pre_entry_bit_get(struct intel_dp *intel_dp)
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

	return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_PRE_ENTRY :
		EDP_PSR_PRE_ENTRY(intel_dp->psr.transcoder);
}

static u32 psr_irq_mask_get(struct intel_dp *intel_dp)
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);

	return DISPLAY_VER(dev_priv) >= 12 ? TGL_PSR_MASK :
		EDP_PSR_MASK(intel_dp->psr.transcoder);
}

static void psr_irq_control(struct intel_dp *intel_dp)
{
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
	enum transcoder trans_shift;
	i915_reg_t imr_reg;
	u32 mask, val;

	/*
	 * gen12+ has registers relative to transcoder and one per transcoder
	 * using the same bit definition: handle it as TRANSCODER_EDP to force
	 * 0 shift in bit definition
	 */
	if (DISPLAY_VER(dev_priv) >= 12) {
		trans_shift = 0;
	if (DISPLAY_VER(dev_priv) >= 12)
		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
	} else {
		trans_shift = intel_dp->psr.transcoder;
	else
		imr_reg = EDP_PSR_IMR;
	}

	mask = EDP_PSR_ERROR(trans_shift);
	mask = psr_irq_psr_error_bit_get(intel_dp);
	if (intel_dp->psr.debug & I915_PSR_DEBUG_IRQ)
		mask |= EDP_PSR_POST_EXIT(trans_shift) |
			EDP_PSR_PRE_ENTRY(trans_shift);
		mask |= psr_irq_post_exit_bit_get(intel_dp) |
			psr_irq_pre_entry_bit_get(intel_dp);

	/* Warning: it is masking/setting reserved bits too */
	val = intel_de_read(dev_priv, imr_reg);
	val &= ~EDP_PSR_TRANS_MASK(trans_shift);
	val &= ~psr_irq_mask_get(intel_dp);
	val |= ~mask;
	intel_de_write(dev_priv, imr_reg, val);
}
@@ -191,25 +213,21 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
	ktime_t time_ns =  ktime_get();
	enum transcoder trans_shift;
	i915_reg_t imr_reg;

	if (DISPLAY_VER(dev_priv) >= 12) {
		trans_shift = 0;
	if (DISPLAY_VER(dev_priv) >= 12)
		imr_reg = TRANS_PSR_IMR(intel_dp->psr.transcoder);
	} else {
		trans_shift = intel_dp->psr.transcoder;
	else
		imr_reg = EDP_PSR_IMR;
	}

	if (psr_iir & EDP_PSR_PRE_ENTRY(trans_shift)) {
	if (psr_iir & psr_irq_pre_entry_bit_get(intel_dp)) {
		intel_dp->psr.last_entry_attempt = time_ns;
		drm_dbg_kms(&dev_priv->drm,
			    "[transcoder %s] PSR entry attempt in 2 vblanks\n",
			    transcoder_name(cpu_transcoder));
	}

	if (psr_iir & EDP_PSR_POST_EXIT(trans_shift)) {
	if (psr_iir & psr_irq_post_exit_bit_get(intel_dp)) {
		intel_dp->psr.last_exit = time_ns;
		drm_dbg_kms(&dev_priv->drm,
			    "[transcoder %s] PSR exit completed\n",
@@ -226,7 +244,7 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
		}
	}

	if (psr_iir & EDP_PSR_ERROR(trans_shift)) {
	if (psr_iir & psr_irq_psr_error_bit_get(intel_dp)) {
		u32 val;

		drm_warn(&dev_priv->drm, "[transcoder %s] PSR aux error\n",
@@ -243,7 +261,7 @@ void intel_psr_irq_handler(struct intel_dp *intel_dp, u32 psr_iir)
		 * or unset irq_aux_error.
		 */
		val = intel_de_read(dev_priv, imr_reg);
		val |= EDP_PSR_ERROR(trans_shift);
		val |= psr_irq_psr_error_bit_get(intel_dp);
		intel_de_write(dev_priv, imr_reg, val);

		schedule_work(&intel_dp->psr.work);
@@ -1194,14 +1212,12 @@ static bool psr_interrupt_error_check(struct intel_dp *intel_dp)
	 * first time that PSR HW tries to activate so lets keep PSR disabled
	 * to avoid any rendering problems.
	 */
	if (DISPLAY_VER(dev_priv) >= 12) {
	if (DISPLAY_VER(dev_priv) >= 12)
		val = intel_de_read(dev_priv,
				    TRANS_PSR_IIR(intel_dp->psr.transcoder));
		val &= EDP_PSR_ERROR(0);
	} else {
	else
		val = intel_de_read(dev_priv, EDP_PSR_IIR);
		val &= EDP_PSR_ERROR(intel_dp->psr.transcoder);
	}
	val &= psr_irq_psr_error_bit_get(intel_dp);
	if (val) {
		intel_dp->psr.sink_not_reliable = true;
		drm_dbg_kms(&dev_priv->drm,
+14 −2
Original line number Diff line number Diff line
@@ -1710,10 +1710,22 @@ skl_compute_wm_params(const struct intel_crtc_state *crtc_state,
		      modifier == I915_FORMAT_MOD_4_TILED ||
		      modifier == I915_FORMAT_MOD_Yf_TILED ||
		      modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
		      modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
		      modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
		      modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
		      modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
		      modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
		      modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
	wp->x_tiled = modifier == I915_FORMAT_MOD_X_TILED;
	wp->rc_surface = modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
			 modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
			 modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
			 modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC ||
			 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS ||
			 modifier == I915_FORMAT_MOD_4_TILED_DG2_MC_CCS ||
			 modifier == I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC;
	wp->is_planar = intel_format_info_is_yuv_semiplanar(format, modifier);

	wp->width = width;
+8 −0
Original line number Diff line number Diff line
@@ -207,6 +207,14 @@ static const struct drm_i915_mocs_entry broxton_mocs_table[] = {
	MOCS_ENTRY(15, \
		   LE_3_WB | LE_TC_1_LLC | LE_LRUM(2) | LE_AOM(1), \
		   L3_3_WB), \
	/* Bypass LLC - Uncached (EHL+) */ \
	MOCS_ENTRY(16, \
		   LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \
		   L3_1_UC), \
	/* Bypass LLC - L3 (Read-Only) (EHL+) */ \
	MOCS_ENTRY(17, \
		   LE_1_UC | LE_TC_1_LLC | LE_SCF(1), \
		   L3_3_WB), \
	/* Self-Snoop - L3 + LLC */ \
	MOCS_ENTRY(18, \
		   LE_3_WB | LE_TC_1_LLC | LE_LRUM(3) | LE_SSE(3), \
Loading