Skip to content

Commit c377925

Browse files
mripardgregkh
authored andcommitted
drm/vc4: hdmi: Update the CEC clock divider on HSM rate change
[ Upstream commit 47fa9a8 ] 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: cd4cb49 ("drm/vc4: hdmi: Adjust HSM clock rate depending on pixel rate") Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Link: https://patchwork.freedesktop.org/patch/msgid/20210111142309.193441-8-maxime@cerno.tech (cherry picked from commit a9dd0b9) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ecd8c74 commit c377925

1 file changed

Lines changed: 29 additions & 10 deletions

File tree

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,27 @@ static void vc5_hdmi_reset(struct vc4_hdmi *vc4_hdmi)
119119
HDMI_READ(HDMI_CLOCK_STOP) | VC4_DVP_HT_CLOCK_STOP_PIXEL);
120120
}
121121

122+
#ifdef CONFIG_DRM_VC4_HDMI_CEC
123+
static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi)
124+
{
125+
u16 clk_cnt;
126+
u32 value;
127+
128+
value = HDMI_READ(HDMI_CEC_CNTRL_1);
129+
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
130+
131+
/*
132+
* Set the clock divider: the hsm_clock rate and this divider
133+
* setting will give a 40 kHz CEC clock.
134+
*/
135+
clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
136+
value |= clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT;
137+
HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
138+
}
139+
#else
140+
static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {}
141+
#endif
142+
122143
static enum drm_connector_status
123144
vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
124145
{
@@ -652,6 +673,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder)
652673
return;
653674
}
654675

676+
vc4_hdmi_cec_update_clk_div(vc4_hdmi);
677+
655678
/*
656679
* FIXME: When the pixel freq is 594MHz (4k60), this needs to be setup
657680
* at 300MHz.
@@ -1468,7 +1491,6 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
14681491
{
14691492
struct cec_connector_info conn_info;
14701493
struct platform_device *pdev = vc4_hdmi->pdev;
1471-
u16 clk_cnt;
14721494
u32 value;
14731495
int ret;
14741496

@@ -1487,17 +1509,14 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi)
14871509
cec_s_conn_info(vc4_hdmi->cec_adap, &conn_info);
14881510

14891511
HDMI_WRITE(HDMI_CEC_CPU_MASK_SET, 0xffffffff);
1512+
14901513
value = HDMI_READ(HDMI_CEC_CNTRL_1);
1491-
value &= ~VC4_HDMI_CEC_DIV_CLK_CNT_MASK;
1492-
/*
1493-
* Set the logical address to Unregistered and set the clock
1494-
* divider: the hsm_clock rate and this divider setting will
1495-
* give a 40 kHz CEC clock.
1496-
*/
1497-
clk_cnt = clk_get_rate(vc4_hdmi->hsm_clock) / CEC_CLOCK_FREQ;
1498-
value |= VC4_HDMI_CEC_ADDR_MASK |
1499-
(clk_cnt << VC4_HDMI_CEC_DIV_CLK_CNT_SHIFT);
1514+
/* Set the logical address to Unregistered */
1515+
value |= VC4_HDMI_CEC_ADDR_MASK;
15001516
HDMI_WRITE(HDMI_CEC_CNTRL_1, value);
1517+
1518+
vc4_hdmi_cec_update_clk_div(vc4_hdmi);
1519+
15011520
ret = devm_request_threaded_irq(&pdev->dev, platform_get_irq(pdev, 0),
15021521
vc4_cec_irq_handler,
15031522
vc4_cec_irq_handler_thread, 0,

0 commit comments

Comments
 (0)