Hi Andrzej, Gentle ping, do you think this could go in drm-misc-next for 5.3 ? Thanks, Neil On 12/06/2019 10:51, Neil Armstrong wrote: > When using an I2S source using a different clock source (usually the I2S > audio HW uses dedicated PLLs, different from the HDMI PHY PLL), fixed > CTS values will cause some frequent audio drop-out and glitches as > reported on Amlogic, Allwinner and Rockchip SoCs setups. > > Setting the CTS in automatic mode will let the HDMI controller generate > automatically the CTS value to match the input audio clock. > > The DesignWare DW-HDMI User Guide explains: > For Automatic CTS generation > Write "0" on the bit field "CTS_manual", Register 0x3205: AUD_CTS3 > > The DesignWare DW-HDMI Databook explains : > If "CTS_manual" bit equals 0b this registers contains "audCTS[19:0]" > generated by the Cycle time counter according to specified timing. > > Cc: Jernej Skrabec <jernej.skrabec@xxxxxxxx> > Cc: Maxime Ripard <maxime.ripard@xxxxxxxxxxx> > Cc: Jonas Karlman <jonas@xxxxxxxxx> > Cc: Heiko Stuebner <heiko@xxxxxxxxx> > Cc: Jerome Brunet <jbrunet@xxxxxxxxxxxx> > Signed-off-by: Neil Armstrong <narmstrong@xxxxxxxxxxxx> > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +++++++++++++++-------- > 1 file changed, 29 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > index c68b6ed1bb35..6458c3a31d23 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -437,8 +437,14 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts, > /* nshift factor = 0 */ > hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); > > - hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) | > - HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); > + /* Use automatic CTS generation mode when CTS is not set */ > + if (cts) > + hdmi_writeb(hdmi, ((cts >> 16) & > + HDMI_AUD_CTS3_AUDCTS19_16_MASK) | > + HDMI_AUD_CTS3_CTS_MANUAL, > + HDMI_AUD_CTS3); > + else > + hdmi_writeb(hdmi, 0, HDMI_AUD_CTS3); > hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); > hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); > > @@ -508,24 +514,32 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, > { > unsigned long ftdms = pixel_clk; > unsigned int n, cts; > + u8 config3; > u64 tmp; > > n = hdmi_compute_n(sample_rate, pixel_clk); > > - /* > - * Compute the CTS value from the N value. Note that CTS and N > - * can be up to 20 bits in total, so we need 64-bit math. Also > - * note that our TDMS clock is not fully accurate; it is accurate > - * to kHz. This can introduce an unnecessary remainder in the > - * calculation below, so we don't try to warn about that. > - */ > - tmp = (u64)ftdms * n; > - do_div(tmp, 128 * sample_rate); > - cts = tmp; > + config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID); > > - dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", > - __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, > - n, cts); > + /* Only compute CTS when using internal AHB audio */ > + if (config3 & HDMI_CONFIG3_AHBAUDDMA) { > + /* > + * Compute the CTS value from the N value. Note that CTS and N > + * can be up to 20 bits in total, so we need 64-bit math. Also > + * note that our TDMS clock is not fully accurate; it is > + * accurate to kHz. This can introduce an unnecessary remainder > + * in the calculation below, so we don't try to warn about that. > + */ > + tmp = (u64)ftdms * n; > + do_div(tmp, 128 * sample_rate); > + cts = tmp; > + > + dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", > + __func__, sample_rate, > + ftdms / 1000000, (ftdms / 1000) % 1000, > + n, cts); > + } else > + cts = 0; > > spin_lock_irq(&hdmi->audio_lock); > hdmi->audio_n = n; > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel