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

Merge tag 'drm-intel-next-fixes-2025-06-05' of...

Merge tag 'drm-intel-next-fixes-2025-06-05' of https://gitlab.freedesktop.org/drm/i915/kernel

 into drm-next

- Fix PSR register definitions for ALPM
- Fix u32 overflow in SNPS PHY HDMI PLL setup
- Fix GuC pending message underflow when submit fails
- Fix GuC wakeref underflow race during reset

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://lore.kernel.org/r/aEFW1wGnt1kTVNGF@jlahtine-mobl
parents 61a4b7d7 791d7600
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -325,8 +325,8 @@
#define  PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK	REG_GENMASK(20, 16)
#define  PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION(val)	REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
#define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION_MASK	REG_GENMASK(12, 8)
#define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(val)	REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
#define  PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION(val)	REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_FIRST_LFPS_HALF_CYCLE_DURATION_MASK, val)
#define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK	REG_GENMASK(4, 0)
#define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(val)	REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LFPS_HALF_CYCLE_DURATION_MASK, val)
#define  PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION(val)	REG_FIELD_PREP(PORT_ALPM_LFPS_CTL_LAST_LFPS_HALF_CYCLE_DURATION_MASK, val)

#endif /* __INTEL_PSR_REGS_H__ */
+8 −8
Original line number Diff line number Diff line
@@ -41,12 +41,12 @@ static s64 interp(s64 x, s64 x1, s64 x2, s64 y1, s64 y2)
{
	s64 dydx;

	dydx = DIV_ROUND_UP_ULL((y2 - y1) * 100000, (x2 - x1));
	dydx = DIV64_U64_ROUND_UP((y2 - y1) * 100000, (x2 - x1));

	return (y1 + DIV_ROUND_UP_ULL(dydx * (x - x1), 100000));
	return (y1 + DIV64_U64_ROUND_UP(dydx * (x - x1), 100000));
}

static void get_ana_cp_int_prop(u32 vco_clk,
static void get_ana_cp_int_prop(u64 vco_clk,
				u32 refclk_postscalar,
				int mpll_ana_v2i,
				int c, int a,
@@ -115,16 +115,16 @@ static void get_ana_cp_int_prop(u32 vco_clk,
								      CURVE0_MULTIPLIER));

	scaled_interpolated_sqrt =
			int_sqrt(DIV_ROUND_UP_ULL(interpolated_product, vco_div_refclk_float) *
			int_sqrt(DIV64_U64_ROUND_UP(interpolated_product, vco_div_refclk_float) *
			DIV_ROUND_DOWN_ULL(1000000000000ULL, 55));

	/* Scale vco_div_refclk for ana_cp_int */
	scaled_vco_div_refclk2 = DIV_ROUND_UP_ULL(vco_div_refclk_float, 1000000);
	adjusted_vco_clk2 = 1460281 * DIV_ROUND_UP_ULL(scaled_interpolated_sqrt *
	adjusted_vco_clk2 = 1460281 * DIV64_U64_ROUND_UP(scaled_interpolated_sqrt *
						       scaled_vco_div_refclk2,
						       curve_1_interpolated);

	*ana_cp_prop = DIV_ROUND_UP_ULL(adjusted_vco_clk2, curve_2_scaled2);
	*ana_cp_prop = DIV64_U64_ROUND_UP(adjusted_vco_clk2, curve_2_scaled2);
	*ana_cp_prop = max(1, min(*ana_cp_prop, 127));
}

@@ -165,10 +165,10 @@ static void compute_hdmi_tmds_pll(u64 pixel_clock, u32 refclk,
	/* Select appropriate v2i point */
	if (datarate <= INTEL_SNPS_PHY_HDMI_9999MHZ) {
		mpll_ana_v2i = 2;
		tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_9999MHZ, datarate));
		tx_clk_div = ilog2(div64_u64(INTEL_SNPS_PHY_HDMI_9999MHZ, datarate));
	} else {
		mpll_ana_v2i = 3;
		tx_clk_div = ilog2(DIV_ROUND_DOWN_ULL(INTEL_SNPS_PHY_HDMI_16GHZ, datarate));
		tx_clk_div = ilog2(div64_u64(INTEL_SNPS_PHY_HDMI_16GHZ, datarate));
	}
	vco_clk = (datarate << tx_clk_div) >> 1;

+15 −4
Original line number Diff line number Diff line
@@ -633,7 +633,7 @@ static int guc_submission_send_busy_loop(struct intel_guc *guc,
		atomic_inc(&guc->outstanding_submission_g2h);

	ret = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
	if (ret)
	if (ret && g2h_len_dw)
		atomic_dec(&guc->outstanding_submission_g2h);

	return ret;
@@ -3443,17 +3443,28 @@ static inline int guc_lrc_desc_unpin(struct intel_context *ce)
	 * GuC is active, lets destroy this context, but at this point we can still be racing
	 * with suspend, so we undo everything if the H2G fails in deregister_context so
	 * that GuC reset will find this context during clean up.
	 *
	 * There is a race condition where the reset code could have altered
	 * this context's state and done a wakeref put before we try to
	 * deregister it here. So check if the context is still set to be
	 * destroyed before undoing earlier changes, to avoid two wakeref puts
	 * on the same context.
	 */
	ret = deregister_context(ce, ce->guc_id.id);
	if (ret) {
		bool pending_destroyed;
		spin_lock_irqsave(&ce->guc_state.lock, flags);
		pending_destroyed = context_destroyed(ce);
		if (pending_destroyed) {
			set_context_registered(ce);
			clr_context_destroyed(ce);
		}
		spin_unlock_irqrestore(&ce->guc_state.lock, flags);
		/*
		 * As gt-pm is awake at function entry, intel_wakeref_put_async merely decrements
		 * the wakeref immediately but per function spec usage call this after unlock.
		 */
		if (pending_destroyed)
			intel_wakeref_put_async(&gt->wakeref);
	}