This is a note to let you know that I've just added the patch titled drm/vc4: hdmi: Update the CEC clock divider on HSM rate change to the 5.11-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-vc4-hdmi-update-the-cec-clock-divider-on-hsm-rat.patch and it can be found in the queue-5.11 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. commit 7823bfa6823f9524fbb4a05435c999c633c0e9a9 Author: Maxime Ripard <maxime@xxxxxxxxxx> Date: Mon Jan 11 15:23:01 2021 +0100 drm/vc4: hdmi: Update the CEC clock divider on HSM rate change [ Upstream commit 47fa9a80270e20a0c4ddaffca1f144d22cc59620 ] As part of the enable sequence we might change the HSM clock rate if the pixel rate is different than the one we were already dealing with. On the BCM2835 however, the CEC clock derives from the HSM clock so any rate change will need to be reflected in the CEC clock divider to output 40kHz. Fixes: cd4cb49dc5bb ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate") Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> Acked-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx> Tested-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx> Link: https://patchwork.freedesktop.org/patch/msgid/20210111142309.193441-8-maxime@xxxxxxxxxx (cherry picked from commit a9dd0b9a5c3e11c79e6ff9c7fdf07c471732dcb6) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index eff9014750e2d..a9f494590c578 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -119,6 +119,27 @@ static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi) HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL); } +#ifdef CONFIG_DRM_VC4_HDMI_CEC +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) +{ + u16 clk_cnt; + u32 value; + + value = HDMI_READ(HDMI_CEC_CNTRL_1); + value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; + + /* + * Set the clock divider: the hsm_clock rate and this divider + * setting will give a 40 kHz CEC clock. + */ + clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ; + value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT; + HDMI_WRITE(HDMI_CEC_CNTRL_1, value); +} +#else +static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} +#endif + static enum drm_connector_status vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) { @@ -651,6 +672,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder) return; } + vc4_hdmi_cec_update_clk_div(vc4_hdmi); + /* * FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup * at 300MHz. @@ -1467,7 +1490,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) { struct cec_connector_info conn_info; struct platform_device *pdev = vc4_hdmi->pdev; - u16 clk_cnt; u32 value; int ret; @@ -1486,17 +1508,14 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info); HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff); + value = HDMI_READ(HDMI_CEC_CNTRL_1); - value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK; - /* - * Set the logical address to Unregistered and set the clock - * divider: the hsm_clock rate and this divider setting will - * give a 40 kHz CEC clock. - */ - clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ; - value |= VC4_HDMI_CEC_ADDR_MASK | - (clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT); + /* Set the logical address to Unregistered */ + value |= VC4_HDMI_CEC_ADDR_MASK; HDMI_WRITE(HDMI_CEC_CNTRL_1, value); + + vc4_hdmi_cec_update_clk_div(vc4_hdmi); + ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0), vc4_cec_irq_handler, vc4_cec_irq_handler_thread, 0,