From: sashiko-bot@kernel.org
To: "Krzysztof Kozlowski" <krzysztof.kozlowski@oss.qualcomm.com>
Cc: dri-devel@lists.freedesktop.org, neil.armstrong@linaro.org,
robh@kernel.org, devicetree@vger.kernel.org,
linux-phy@lists.infradead.org, olteanv@gmail.com,
vkoul@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH RFC/DO NOT MERGE 10/12] drm/msm/hdmi_phy_eliza: Add support for Synopsys-based HDMI phy on Eliza
Date: Fri, 28 Aug 2026 14:19:23 +0000 [thread overview]
Message-ID: <20260828141923.8E5F81F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260828-drm-msm-hdmi-eliza-v1-10-67843277de17@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 10 potential issue(s) to consider:
- [High] Silent truncation of 64-bit integers passed to `gcd()` on 32-bit architectures leads to incorrect clock calculations.
- [High] 32-bit integer overflow during PHY bit rate calculation causes incorrect hardware configuration for high-bandwidth displays.
- [High] Deterministic division by zero during CCF clock registration due to uninitialized configuration.
- [High] Severe CPU soft lockup risk due to excessive 3-second busy-wait loop using `readl_poll_timeout_atomic`.
- [High] Premature integer division causes precision loss yielding incorrect hardware PLL parameters.
- [Medium] Data race on PLL configuration state by bypassing Common Clock Framework (CCF) synchronization.
- [Low] 64-bit division using '/' and standard division macros causes build failure on 32-bit platforms.
- [Low] Unsupported floating-point literals used in integer calculations.
- [Low] Use of `mdelay(8)` wastes CPU resources in a sleepable context.
- [Low] Fragile design conflates the presence of PHY regulators with the name format of device tree memory resources.
--
commit 9c53defce3c459b1740fbff4f2434baad5c70aee
Author: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Subject: drm/msm/hdmi_phy_eliza: Add support for Synopsys-based HDMI phy on Eliza
Add driver for HDMI phy block from Synopsys used on Eliza SoC. Adjust core
parts for handling HDMI phy initialization sequence.
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
> @@ -168,13 +171,17 @@ static int msm_hdmi_phy_probe(struct platform_device *pdev)
> if (!phy->cfg)
> return -ENODEV;
>
> - phy->mmio = msm_ioremap(pdev, "hdmi_phy");
> + if (phy->cfg->num_regs)
> + phy->mmio = msm_ioremap(pdev, "hdmi_phy");
> + else
> + phy->mmio = msm_ioremap(pdev, NULL);
[Severity: Low]
Does this use a fragile heuristic? This logic overloads the presence of
power regulators (num_regs) to guess the format of device tree memory
resources. These two hardware properties are orthogonal, which could break
if future device tree bindings diverge.
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_eliza.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_eliza.c
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy_eliza.c
[ ... ]
> +static int hdmi_eliza_pll_calculator(struct hdmi_pll_eliza *pll,
> + unsigned long rate,
> + unsigned long parent_rate,
> + struct hdmi_eliza_phy_pll_reg_cfg *cfg)
> +{
[ ... ]
> + s64 precision3 = 1e3;
> + s64 precision6 = 1e6;
[Severity: Low]
Are these floating-point literals supported? Scientific notation defaults
to double literals, which relies on compiler implicit conversion to integers.
The kernel strictly prohibits floating-point types.
[ ... ]
> + /* expon = floor(log2(4.999999e9/base_rate)) */
> + utemp = 4.999999e9;
[Severity: Low]
Are these floating-point literals supported? This is another instance where
scientific notation will evaluate as a double literal.
> +
> + expon = fls64(utemp / base_rate) - 1;
[Severity: Low]
Can this cause a build failure on 32-bit platforms? The direct 64-bit
division operator triggers a dependency on __udivdi3, which is unresolved
on 32-bit architectures. do_div or div64_u64 should be used instead.
[ ... ]
> + /* multiplier = 2*(floor(bit_rate) * 2**expon / ref_clk_int) -16) */
> + multiplier = DIV_ROUND_UP(vco_freq, ref_clk_int);
[Severity: Low]
Could this also trigger a 32-bit build failure? DIV_ROUND_UP performs a
native division, and since vco_freq is a 64-bit value, this requires a 64-bit
division routine that is unavailable on 32-bit builds.
[ ... ]
> + if (aux2 == 0) {
> + cfg->remainder = 0;
> + cfg->denominator = 1;
> + } else {
> + cfg->remainder = DIV_ROUND_UP(aux2, gcd(aux1, aux2));
> + cfg->denominator = DIV_ROUND_UP(aux1, gcd(aux1, aux2));
[Severity: High]
Does this truncate 64-bit values on 32-bit architectures? The gcd function
takes unsigned long parameters, which are 32-bit on 32-bit kernels. Since
aux1 and aux2 can hold values requiring up to 36 bits, they will be silently
truncated when passed into gcd, feeding incorrect fractions into the PLL
configuration.
[ ... ]
> + /* stemp = (REF_CLK_MHZ/2**ref_ana_mpll_div) */
> + stemp = (REF_CLK_HZ / 1000000) * precision3;
[Severity: High]
Does this premature division cause a loss of precision? REF_CLK_HZ is
divided by 1,000,000 first, which drops the remainder before scaling. With
REF_CLK_HZ at 38,400,000, the result truncates to 38 instead of preserving
the 0.4 MHz. The error is then squared later, propagating significant drift
into the PLL analog parameters.
[ ... ]
> + cfg->cp_int_holder = DIV_ROUND_CLOSEST(stemp3, precision6);
[Severity: Low]
Can this result in a build failure on 32-bit architectures?
DIV_ROUND_CLOSEST triggers native division on s64 variables, which will fail
to link without __divdi3.
[ ... ]
> +static int hdmi_eliza_pll_prepare(struct clk_hw *hw)
> +{
[ ... ]
> + /*
> + * This Synopsys PLL does not have a PLL lock-like register, thus there
> + * is no way to tell when the PLL actually locked.
> + * Returning now, would lead to stuck pclk or iface RCG clocks at off
> + * (disp_cc_mdss_hdmi_pclk_clk status stuck at 'off'),
> + * thus obviously the professional solution is to delay.
> + * 8 ms was figured out during tests, not based on any datasheet.
> + */
> + mdelay(8);
> +
> + return 0;
> +}
[Severity: Low]
Is mdelay strictly necessary here? Busy-waiting the CPU for 8 milliseconds
wastes resources in a context where sleeping is fully permitted. The prepare
callback can safely yield the CPU using msleep or usleep_range.
[ ... ]
> +static u64 hdmi_eliza_pll_vco_freq(u64 ref_clk_hz, u32 multiplier, u32 frac_quot,
> + u32 frac_rem, u32 frac_den)
> +{
> + u64 num;
> + u64 den;
> +
> + num = 32ULL * 65536ULL * frac_den +
> + (u64)multiplier * 65536ULL * frac_den +
> + 2ULL * ((u64)frac_quot * frac_den + frac_rem);
> +
> + den = 2ULL * 65536ULL * frac_den;
> +
> + return mul_u64_u64_div_u64(ref_clk_hz, num, den);
> +}
> +
> +static unsigned long hdmi_eliza_pll_recalc_rate(struct clk_hw *hw,
> + unsigned long parent_rate)
> +{
> + struct hdmi_pll_eliza *pll = hw_clk_to_pll(hw);
> + u64 rate;
> +
> + rate = hdmi_eliza_pll_vco_freq(REF_CLK_HZ, pll->cfg.multiplier,
> + pll->cfg.quotient, pll->cfg.remainder,
> + pll->cfg.denominator);
[ ... ]
> +int msm_hdmi_pll_eliza_init(struct platform_device *pdev)
> +{
[ ... ]
> + pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
[ ... ]
> + ret = devm_clk_hw_register(dev, &pll->clk_hw);
[Severity: High]
Can this lead to a division by zero during probe?
When devm_clk_hw_register is called, the Common Clock Framework immediately
invokes recalc_rate. Because the pll structure is zero-allocated,
pll->cfg.denominator is zero. This zero is passed into
hdmi_eliza_pll_vco_freq, which results in den evaluating to 0 and
triggering a kernel panic in mul_u64_u64_div_u64.
[ ... ]
> +static void hdmi_eliza_phy_tx_lane_config(struct hdmi_phy *phy,
> + unsigned long pixclock)
> +{
> + const unsigned int bpp = 24;
[ ... ]
> + if (pixclock * bpp >= HDMI_PHY_MAX_BIT_RATE)
> + hdmi_phy_update_bits(phy, REG_HDMI_ELIZA_PHY_TX_COMMON_CONTROL_0, BIT(2), 0);
> + else
[Severity: High]
Will this calculation overflow 32-bit bounds before the comparison?
The pixclock parameter is typed as unsigned long, which is 32-bit on 32-bit
kernels. For high bandwidth displays, multiplying a high pixclock by 24 will
exceed the 32-bit integer maximum of 4.29 billion. This overflow will result
in a smaller wrapped value, breaking the conditional check and incorrectly
programming the PHY for high-resolution displays.
[ ... ]
> +static int hdmi_eliza_phy_ready_poll(struct hdmi_phy *phy, u32 reg, u32 mask, u32 val)
> +{
> + u32 state;
> + const u32 sleep_us = 2000;
> + const u32 timeout_us = 3000000;
> +
> + if (readl_poll_timeout_atomic((phy->mmio + reg), state,
> + ((state & mask) == val),
> + sleep_us, timeout_us)) {
[Severity: High]
Does this present a severe CPU soft lockup risk?
The readl_poll_timeout_atomic macro disables preemption and spins using a
udelay. Looping a 2000 microsecond delay for up to 3,000,000 microseconds
(3 seconds) violates scheduling rules and is very likely to trigger watchdog
lockups if the hardware fails to respond.
[ ... ]
> +static void hdmi_eliza_phy_init(struct hdmi_phy *phy,
> + unsigned long pixclock)
> +{
[ ... ]
> + hdmi_eliza_pll_configure_pll(phy->pll, 396000000, 19200000);
[Severity: Medium]
Does this bypass the Common Clock Framework synchronization?
Directly invoking hdmi_eliza_pll_configure_pll here forcefully mutates the
shared pll->cfg state locklessly. CCF invariants generally mandate that
clock state modifications are protected by prepare_lock. Concurrently
reading the clock state from sysfs or debugfs could hit a data race.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260828-drm-msm-hdmi-eliza-v1-0-67843277de17@oss.qualcomm.com?part=10
next prev parent reply other threads:[~2026-08-28 14:19 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 14:04 [PATCH RFC/DO NOT MERGE 00/12] drm/msm/hdmi: Add Eliza HDMI and HDMI PHY Krzysztof Kozlowski
2026-08-28 14:04 ` [PATCH RFC/DO NOT MERGE 01/12] drm/msm/hdmi_bridge: Drop redundant initialization in msm_hdmi_bridge_init() Krzysztof Kozlowski
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 02/12] drm/msm: Properly handle msm_ioremap() without name Krzysztof Kozlowski
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 03/12] drm/msm/dsi: Fix indentation of if block in dsi_mgr_bridge_mode_valid() Krzysztof Kozlowski
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 04/12] dt-bindings: display/msm: hdmi: Correct name of disallowed supplies Krzysztof Kozlowski
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 05/12] dt-bindings: display/msm: hdmi: Add Eliza HDMI TX Krzysztof Kozlowski
2026-08-28 14:12 ` sashiko-bot
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 06/12] dt-bindings: display/msm: eliza-hdmi-phy: Add Eliza HDMI PHY Krzysztof Kozlowski
2026-08-28 14:10 ` sashiko-bot
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 07/12] drm/msm/hdmi: Split PHY init from power up Krzysztof Kozlowski
2026-08-28 14:22 ` sashiko-bot
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 08/12] drm/msm/hdmi: Add support for PM OPP table Krzysztof Kozlowski
2026-08-28 14:16 ` sashiko-bot
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 09/12] drm/msm/hdmi: Add HDMI for Eliza SoC Krzysztof Kozlowski
2026-08-28 14:22 ` sashiko-bot
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 10/12] drm/msm/hdmi_phy_eliza: Add support for Synopsys-based HDMI phy on Eliza Krzysztof Kozlowski
2026-08-28 14:19 ` sashiko-bot [this message]
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 11/12] arm64: dts: qcom: eliza: Add HDMI display with HDMI PHY Krzysztof Kozlowski
2026-08-28 14:05 ` [PATCH RFC/DO NOT MERGE 12/12] arm64: dts: qcom: eliza-evk: Add native HDMI Krzysztof Kozlowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260828141923.8E5F81F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=krzysztof.kozlowski@oss.qualcomm.com \
--cc=linux-phy@lists.infradead.org \
--cc=neil.armstrong@linaro.org \
--cc=olteanv@gmail.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox