Hi Maxime On Thu, 10 Dec 2020 at 13:47, Maxime Ripard <maxime@xxxxxxxxxx> wrote: > > 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") > Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> I thought we'd got a duplicate patch here, but it's moving code that was changed in patch 6/15 so it can be called from vc4_hdmi_encoder_pre_crtc_configure too. Good for confusing me! Reviewed-by: Dave Stevenson <dave.stevenson@xxxxxxxxxxxxxxx> > --- > drivers/gpu/drm/vc4/vc4_hdmi.c | 39 +++++++++++++++++++++++++--------- > 1 file changed, 29 insertions(+), 10 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c > index 0c53d7427d15..b93ee3e26e2b 100644 > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c > @@ -132,6 +132,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) > { > @@ -761,6 +782,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. > @@ -1586,7 +1609,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; > > @@ -1605,17 +1627,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, > -- > 2.28.0 >