Skip to content

Commit 791d760

Browse files
dibinmsjlahtine-intel
authored andcommitted
drm/i915/display: Fix u32 overflow in SNPS PHY HDMI PLL setup
When configuring the HDMI PLL, calculations use DIV_ROUND_UP_ULL and DIV_ROUND_DOWN_ULL macros, which internally rely on do_div. However, do_div expects a 32-bit (u32) divisor, and at higher data rates, the divisor can exceed this limit. This leads to incorrect division results and ultimately misconfigured PLL values. This fix replaces do_div calls with div64_base64 calls where diviser can exceed u32 limit. Fixes: 5947642 ("drm/i915/display: Add support for SNPS PHY HDMI PLL algorithm for DG2") Cc: Ankit Nautiyal <[email protected]> Cc: Suraj Kandpal <[email protected]> Cc: Jani Nikula <[email protected]> Signed-off-by: Dibin Moolakadan Subrahmanian <[email protected]> Reviewed-by: Ankit Nautiyal <[email protected]> Signed-off-by: Ankit Nautiyal <[email protected]> Link: https://lore.kernel.org/r/[email protected] (cherry picked from commit ce92411) Signed-off-by: Joonas Lahtinen <[email protected]>
1 parent 0323a51 commit 791d760

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ static s64 interp(s64 x, s64 x1, s64 x2, s64 y1, s64 y2)
4141
{
4242
s64 dydx;
4343

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

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

49-
static void get_ana_cp_int_prop(u32 vco_clk,
49+
static void get_ana_cp_int_prop(u64 vco_clk,
5050
u32 refclk_postscalar,
5151
int mpll_ana_v2i,
5252
int c, int a,
@@ -115,16 +115,16 @@ static void get_ana_cp_int_prop(u32 vco_clk,
115115
CURVE0_MULTIPLIER));
116116

117117
scaled_interpolated_sqrt =
118-
int_sqrt(DIV_ROUND_UP_ULL(interpolated_product, vco_div_refclk_float) *
118+
int_sqrt(DIV64_U64_ROUND_UP(interpolated_product, vco_div_refclk_float) *
119119
DIV_ROUND_DOWN_ULL(1000000000000ULL, 55));
120120

121121
/* Scale vco_div_refclk for ana_cp_int */
122122
scaled_vco_div_refclk2 = DIV_ROUND_UP_ULL(vco_div_refclk_float, 1000000);
123-
adjusted_vco_clk2 = 1460281 * DIV_ROUND_UP_ULL(scaled_interpolated_sqrt *
123+
adjusted_vco_clk2 = 1460281 * DIV64_U64_ROUND_UP(scaled_interpolated_sqrt *
124124
scaled_vco_div_refclk2,
125125
curve_1_interpolated);
126126

127-
*ana_cp_prop = DIV_ROUND_UP_ULL(adjusted_vco_clk2, curve_2_scaled2);
127+
*ana_cp_prop = DIV64_U64_ROUND_UP(adjusted_vco_clk2, curve_2_scaled2);
128128
*ana_cp_prop = max(1, min(*ana_cp_prop, 127));
129129
}
130130

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

0 commit comments

Comments
 (0)