linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio
@ 2019-06-12  8:51 ` Neil Armstrong
  2019-06-15  9:17   ` Jernej Škrabec
                     ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Neil Armstrong @ 2019-06-12  8:51 UTC (permalink / raw)
  To: a.hajda, Laurent.pinchart
  Cc: Neil Armstrong, dri-devel, linux-kernel, Jernej Skrabec,
	Maxime Ripard, Jonas Karlman, Heiko Stuebner, Jerome Brunet

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@siol.net>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
 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;
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio
  2019-06-12  8:51 ` [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio Neil Armstrong
@ 2019-06-15  9:17   ` Jernej Škrabec
  2019-06-19 21:22   ` Doug Anderson
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jernej Škrabec @ 2019-06-15  9:17 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: a.hajda, Laurent.pinchart, dri-devel, linux-kernel,
	Maxime Ripard, Jonas Karlman, Heiko Stuebner, Jerome Brunet

Dne sreda, 12. junij 2019 ob 10:51:47 CEST je Neil Armstrong napisal(a):
> 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@siol.net>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>

Tested-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>

Best regards,
Jernej




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio
  2019-06-12  8:51 ` [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio Neil Armstrong
  2019-06-15  9:17   ` Jernej Škrabec
@ 2019-06-19 21:22   ` Doug Anderson
  2019-06-20 14:38   ` Neil Armstrong
  2019-07-01 10:36   ` Andrzej Hajda
  3 siblings, 0 replies; 5+ messages in thread
From: Doug Anderson @ 2019-06-19 21:22 UTC (permalink / raw)
  To: Neil Armstrong
  Cc: Andrzej Hajda, Laurent Pinchart, dri-devel, LKML, Jernej Skrabec,
	Maxime Ripard, Jonas Karlman, Heiko Stuebner, Jerome Brunet

Hi,

On Wed, Jun 12, 2019 at 1:51 AM Neil Armstrong <narmstrong@baylibre.com> 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@siol.net>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 44 +++++++++++++++--------
>  1 file changed, 29 insertions(+), 15 deletions(-)

Tested-by: Douglas Anderson <dianders@chromium.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio
  2019-06-12  8:51 ` [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio Neil Armstrong
  2019-06-15  9:17   ` Jernej Škrabec
  2019-06-19 21:22   ` Doug Anderson
@ 2019-06-20 14:38   ` Neil Armstrong
  2019-07-01 10:36   ` Andrzej Hajda
  3 siblings, 0 replies; 5+ messages in thread
From: Neil Armstrong @ 2019-06-20 14:38 UTC (permalink / raw)
  To: a.hajda, Laurent.pinchart
  Cc: dri-devel, linux-kernel, Jernej Skrabec, Maxime Ripard,
	Jonas Karlman, Heiko Stuebner, Jerome Brunet

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@siol.net>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  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;
> 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio
  2019-06-12  8:51 ` [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio Neil Armstrong
                     ` (2 preceding siblings ...)
  2019-06-20 14:38   ` Neil Armstrong
@ 2019-07-01 10:36   ` Andrzej Hajda
  3 siblings, 0 replies; 5+ messages in thread
From: Andrzej Hajda @ 2019-07-01 10:36 UTC (permalink / raw)
  To: Neil Armstrong, Laurent.pinchart
  Cc: dri-devel, linux-kernel, Jernej Skrabec, Maxime Ripard,
	Jonas Karlman, Heiko Stuebner, Jerome Brunet

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@siol.net>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Jerome Brunet <jbrunet@baylibre.com>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>


Queued to drm-misc-next.


Regards

Andrzej


> ---
>  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;



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2019-07-01 10:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20190612085155epcas1p14ea44ab7c6cf6309a1e25a6e8b5f36ed@epcas1p1.samsung.com>
2019-06-12  8:51 ` [PATCH] drm/bridge: dw-hdmi: Use automatic CTS generation mode when using non-AHB audio Neil Armstrong
2019-06-15  9:17   ` Jernej Škrabec
2019-06-19 21:22   ` Doug Anderson
2019-06-20 14:38   ` Neil Armstrong
2019-07-01 10:36   ` Andrzej Hajda

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).