Re: [PATCH v3 7/9] drm/vc4: hdmi: Clamp CEC clock divider to its register field width

From: Dave Stevenson

Date: Tue Oct 27 2026 - 13:51:02 EST


On Wed, 14 Oct 2026 at 02:03, Cristian Ciocaltea
<cristian.ciocaltea@xxxxxxxxxxxxx> wrote:
>
> The CEC clock divider computed in vc4_hdmi_cec_update_clk_div() is
> written unmasked into the 12-bit DIV_CLK_CNT field of the CEC_CNTRL_1
> register. On BCM2835, the CEC clock is obtained by dividing the HSM
> clock, which in turn is scaled to 101% of the pixel clock. For HSM
> clock rates above 163.8 MHz, the divider exceeds the field limit (4095),
> corrupting the adjacent CEC_ADDR field and truncating the effective
> divider, which breaks CEC entirely.
>
> The BCM2835 maximum pixel clock of 162 MHz yields an HSM clock of 163.62
> MHz, so the overflow cannot currently be triggered.
>
> Clamp the divider to the field maximum. This is a prerequisite for
> raising the BCM2835 maximum pixel clock to 165 MHz, which pushes the HSM
> clock up to 166.65 MHz. The CEC bit clock will then run up to ~1.75%
> faster than the nominal 40 kHz, i.e. ~40.7 kHz, which is still within
> the CEC bit-timing tolerances.
>
> Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
> Closes: https://lore.kernel.org/all/sashiko-outbox-168686@xxxxxxxxxx/
> Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@xxxxxxxxxxxxx>

Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx>

> ---
> drivers/gpu/drm/vc4/vc4_hdmi.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
> index 2451ff85e759..0a95e14792e8 100644
> --- a/drivers/gpu/drm/vc4/vc4_hdmi.c
> +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
> @@ -231,9 +231,14 @@ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi)
>
> /*
> * Set the clock divider: the hsm_clock rate and this divider
> - * setting will give a 40 kHz CEC clock.
> + * setting will give a 40 kHz CEC clock. Clamp the divider to
> + * its 12-bit field to avoid corrupting CEC_ADDR; for HSM rates
> + * above 163.8 MHz, the CEC clock runs marginally faster, but
> + * still within CEC timing tolerances.
> */
> - clk_cnt = cec_rate / CEC_CLOCK_FREQ;
> + clk_cnt = min_t(unsigned long, cec_rate / CEC_CLOCK_FREQ,
> + VC4_HDMI_CEC_DIV_CLK_CNT_MASK >>
> + VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
> value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
> HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
>
>
> --
> 2.55.0
>