2019-09-11 08:31:03

by Cheng-Yi Chiang

[permalink] [raw]
Subject: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

From: Yakir Yang <[email protected]>

When transmitting IEC60985 linear PCM audio, we configure the
Aduio Sample Channel Status information in the IEC60958 frame.
The status bit is already available in iec.status of hdmi_codec_params.

This fix the issue that audio does not come out on some monitors
(e.g. LG 22CV241)

Note that these registers are only for interfaces:
I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
(AHBAUDDMA).
For S/PDIF interface this information comes from the stream.

Currently this function dw_hdmi_set_channel_status is only called
from dw-hdmi-i2s-audio in I2S setup.

Signed-off-by: Yakir Yang <[email protected]>
Signed-off-by: Cheng-Yi Chiang <[email protected]>
---

Change from v2 to v3:
1. Reuse what is already set in iec.status in hw_param.
2. Remove all useless definition of registers and values.
3. Note that the original sampling frequency is not written to
the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
Without that it can still play audio fine.

.../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
include/drm/bridge/dw_hdmi.h | 1 +
4 files changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 34d8e837555f..20f4f92dd866 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
}

dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
+ dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
dw_hdmi_set_channel_count(hdmi, hparms->channels);
dw_hdmi_set_channel_allocation(hdmi, hparms->cea.channel_allocation);

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bd65d0479683..aa7efd4da1c8 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
return n;
}

+/*
+ * When transmitting IEC60958 linear PCM audio, these registers allow to
+ * configure the channel status information of all the channel status
+ * bits in the IEC60958 frame. For the moment this configuration is only
+ * used when the I2S audio interface, General Purpose Audio (GPA),
+ * or AHB audio DMA (AHBAUDDMA) interface is active
+ * (for S/PDIF interface this information comes from the stream).
+ */
+void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
+ u8 *channel_status)
+{
+ /*
+ * Set channel status register for frequency and word length.
+ * Use default values for other registers.
+ */
+ hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
+ hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
+
static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
unsigned long pixel_clk, unsigned int sample_rate)
{
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index 6988f12d89d9..fcff5059db24 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -158,6 +158,8 @@
#define HDMI_FC_SPDDEVICEINF 0x1062
#define HDMI_FC_AUDSCONF 0x1063
#define HDMI_FC_AUDSSTAT 0x1064
+#define HDMI_FC_AUDSCHNLS7 0x106e
+#define HDMI_FC_AUDSCHNLS8 0x106f
#define HDMI_FC_DATACH0FILL 0x1070
#define HDMI_FC_DATACH1FILL 0x1071
#define HDMI_FC_DATACH2FILL 0x1072
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index cf528c289857..4b3e863c4f8a 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);

void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
+void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
--
2.23.0.162.g0b9fbb3734-goog


2019-09-11 16:57:46

by Jernej Skrabec

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

Dne sreda, 11. september 2019 ob 18:23:59 CEST je Neil Armstrong napisal(a):
> On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
> > From: Yakir Yang <[email protected]>
> >
> > When transmitting IEC60985 linear PCM audio, we configure the
> > Aduio Sample Channel Status information in the IEC60958 frame.
> > The status bit is already available in iec.status of hdmi_codec_params.
> >
> > This fix the issue that audio does not come out on some monitors
> > (e.g. LG 22CV241)
> >
> > Note that these registers are only for interfaces:
> > I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
> > (AHBAUDDMA).
> > For S/PDIF interface this information comes from the stream.
> >
> > Currently this function dw_hdmi_set_channel_status is only called
> > from dw-hdmi-i2s-audio in I2S setup.
> >
> > Signed-off-by: Yakir Yang <[email protected]>
> > Signed-off-by: Cheng-Yi Chiang <[email protected]>
> > ---
> >
> > Change from v2 to v3:
> > 1. Reuse what is already set in iec.status in hw_param.
> > 2. Remove all useless definition of registers and values.
> > 3. Note that the original sampling frequency is not written to
> >
> > the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
> > Without that it can still play audio fine.
> >
> > .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
> > include/drm/bridge/dw_hdmi.h | 1 +
> > 4 files changed, 24 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index
> > 34d8e837555f..20f4f92dd866 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev,
> > void *data,>
> > }
> >
> > dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
> >
> > + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
> >
> > dw_hdmi_set_channel_count(hdmi, hparms->channels);
> > dw_hdmi_set_channel_allocation(hdmi, hparms-
>cea.channel_allocation);
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
> > bd65d0479683..aa7efd4da1c8 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq,
> > unsigned long pixel_clk)>
> > return n;
> >
> > }
> >
> > +/*
> > + * When transmitting IEC60958 linear PCM audio, these registers allow to
> > + * configure the channel status information of all the channel status
> > + * bits in the IEC60958 frame. For the moment this configuration is only
> > + * used when the I2S audio interface, General Purpose Audio (GPA),
> > + * or AHB audio DMA (AHBAUDDMA) interface is active
> > + * (for S/PDIF interface this information comes from the stream).
> > + */
> > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
> > + u8 *channel_status)
> > +{
> > + /*
> > + * Set channel status register for frequency and word length.
> > + * Use default values for other registers.
> > + */
> > + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
> > + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
> > +}
> > +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
> > +
> >
> > static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
> >
> > unsigned long pixel_clk, unsigned int sample_rate)
> >
> > {
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h index
> > 6988f12d89d9..fcff5059db24 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > @@ -158,6 +158,8 @@
> >
> > #define HDMI_FC_SPDDEVICEINF 0x1062
> > #define HDMI_FC_AUDSCONF 0x1063
> > #define HDMI_FC_AUDSSTAT 0x1064
> >
> > +#define HDMI_FC_AUDSCHNLS7 0x106e
> > +#define HDMI_FC_AUDSCHNLS8 0x106f
> >
> > #define HDMI_FC_DATACH0FILL 0x1070
> > #define HDMI_FC_DATACH1FILL 0x1071
> > #define HDMI_FC_DATACH2FILL 0x1072
> >
> > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > index cf528c289857..4b3e863c4f8a 100644
> > --- a/include/drm/bridge/dw_hdmi.h
> > +++ b/include/drm/bridge/dw_hdmi.h
> > @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool
> > hpd, bool rx_sense);>
> > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
> > void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
> >
> > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
> > *channel_status);
> >
> > void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int
> > ca);
> > void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
> > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
>
> Looks fine for me:
> Reviewed-by: Neil Armstrong <[email protected]>
>
> Jonas ? Jernej ? Russell ?

Patch itself is fine, I'm just wondering if more information should be copied
from status array to registers. But I think they are not 1:1 mapping so some
more work would be needed. Anyway, patch is:

Reviewed-by: Jernej Skrabec <[email protected]>

Best regards,
Jernej

>
> If it's ok for you I'll apply it.
>
> Neil




2019-09-11 20:31:55

by Cheng-Yi Chiang

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

On Thu, Sep 12, 2019 at 12:54 AM Jernej Škrabec <[email protected]> wrote:
>
> Dne sreda, 11. september 2019 ob 18:23:59 CEST je Neil Armstrong napisal(a):
> > On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
> > > From: Yakir Yang <[email protected]>
> > >
> > > When transmitting IEC60985 linear PCM audio, we configure the
> > > Aduio Sample Channel Status information in the IEC60958 frame.
> > > The status bit is already available in iec.status of hdmi_codec_params.
> > >
> > > This fix the issue that audio does not come out on some monitors
> > > (e.g. LG 22CV241)
> > >
> > > Note that these registers are only for interfaces:
> > > I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
> > > (AHBAUDDMA).
> > > For S/PDIF interface this information comes from the stream.
> > >
> > > Currently this function dw_hdmi_set_channel_status is only called
> > > from dw-hdmi-i2s-audio in I2S setup.
> > >
> > > Signed-off-by: Yakir Yang <[email protected]>
> > > Signed-off-by: Cheng-Yi Chiang <[email protected]>
> > > ---
> > >
> > > Change from v2 to v3:
> > > 1. Reuse what is already set in iec.status in hw_param.
> > > 2. Remove all useless definition of registers and values.
> > > 3. Note that the original sampling frequency is not written to
> > >
> > > the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
> > > Without that it can still play audio fine.
> > >
> > > .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
> > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
> > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
> > > include/drm/bridge/dw_hdmi.h | 1 +
> > > 4 files changed, 24 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index
> > > 34d8e837555f..20f4f92dd866 100644
> > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev,
> > > void *data,>
> > > }
> > >
> > > dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
> > >
> > > + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
> > >
> > > dw_hdmi_set_channel_count(hdmi, hparms->channels);
> > > dw_hdmi_set_channel_allocation(hdmi, hparms-
> >cea.channel_allocation);
> > >
> > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
> > > bd65d0479683..aa7efd4da1c8 100644
> > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq,
> > > unsigned long pixel_clk)>
> > > return n;
> > >
> > > }
> > >
> > > +/*
> > > + * When transmitting IEC60958 linear PCM audio, these registers allow to
> > > + * configure the channel status information of all the channel status
> > > + * bits in the IEC60958 frame. For the moment this configuration is only
> > > + * used when the I2S audio interface, General Purpose Audio (GPA),
> > > + * or AHB audio DMA (AHBAUDDMA) interface is active
> > > + * (for S/PDIF interface this information comes from the stream).
> > > + */
> > > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
> > > + u8 *channel_status)
> > > +{
> > > + /*
> > > + * Set channel status register for frequency and word length.
> > > + * Use default values for other registers.
> > > + */
> > > + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
> > > + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
> > > +}
> > > +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
> > > +
> > >
> > > static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
> > >
> > > unsigned long pixel_clk, unsigned int sample_rate)
> > >
> > > {
> > >
> > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h index
> > > 6988f12d89d9..fcff5059db24 100644
> > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > @@ -158,6 +158,8 @@
> > >
> > > #define HDMI_FC_SPDDEVICEINF 0x1062
> > > #define HDMI_FC_AUDSCONF 0x1063
> > > #define HDMI_FC_AUDSSTAT 0x1064
> > >
> > > +#define HDMI_FC_AUDSCHNLS7 0x106e
> > > +#define HDMI_FC_AUDSCHNLS8 0x106f
> > >
> > > #define HDMI_FC_DATACH0FILL 0x1070
> > > #define HDMI_FC_DATACH1FILL 0x1071
> > > #define HDMI_FC_DATACH2FILL 0x1072
> > >
> > > diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> > > index cf528c289857..4b3e863c4f8a 100644
> > > --- a/include/drm/bridge/dw_hdmi.h
> > > +++ b/include/drm/bridge/dw_hdmi.h
> > > @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool
> > > hpd, bool rx_sense);>
> > > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
> > > void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
> > >
> > > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
> > > *channel_status);
> > >
> > > void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int
> > > ca);
> > > void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
> > > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
> >
> > Looks fine for me:
> > Reviewed-by: Neil Armstrong <[email protected]>
> >
> > Jonas ? Jernej ? Russell ?
>
> Patch itself is fine, I'm just wondering if more information should be copied
> from status array to registers. But I think they are not 1:1 mapping so some
> more work would be needed. Anyway, patch is:

Hi Jernej,
Yes you are right. I was thinking about the same thing.
But there are also some fields in the IEC60958 spec not mapped to the
registers on dw-hdmi.
So I ended up just writing the two registers in the original ykk's
patch, and ignoring "original sampling frequency" like pcm_iec958.
It turns out that audio plays fine on my LG monitor. So I suggest we
can keep this patch as simple as it is, and add more register setting
if we find issue.
Thanks!

>
>
> Reviewed-by: Jernej Skrabec <[email protected]>
>
> Best regards,
> Jernej
>
> >
> > If it's ok for you I'll apply it.
> >
> > Neil
>
>
>
>

2019-09-11 20:38:42

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
> From: Yakir Yang <[email protected]>
>
> When transmitting IEC60985 linear PCM audio, we configure the
> Aduio Sample Channel Status information in the IEC60958 frame.
> The status bit is already available in iec.status of hdmi_codec_params.
>
> This fix the issue that audio does not come out on some monitors
> (e.g. LG 22CV241)
>
> Note that these registers are only for interfaces:
> I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
> (AHBAUDDMA).
> For S/PDIF interface this information comes from the stream.
>
> Currently this function dw_hdmi_set_channel_status is only called
> from dw-hdmi-i2s-audio in I2S setup.
>
> Signed-off-by: Yakir Yang <[email protected]>
> Signed-off-by: Cheng-Yi Chiang <[email protected]>
> ---
>
> Change from v2 to v3:
> 1. Reuse what is already set in iec.status in hw_param.
> 2. Remove all useless definition of registers and values.
> 3. Note that the original sampling frequency is not written to
> the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
> Without that it can still play audio fine.
>
> .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
> include/drm/bridge/dw_hdmi.h | 1 +
> 4 files changed, 24 insertions(+)
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> index 34d8e837555f..20f4f92dd866 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
> }
>
> dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
> + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
> dw_hdmi_set_channel_count(hdmi, hparms->channels);
> dw_hdmi_set_channel_allocation(hdmi, hparms->cea.channel_allocation);
>
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index bd65d0479683..aa7efd4da1c8 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk)
> return n;
> }
>
> +/*
> + * When transmitting IEC60958 linear PCM audio, these registers allow to
> + * configure the channel status information of all the channel status
> + * bits in the IEC60958 frame. For the moment this configuration is only
> + * used when the I2S audio interface, General Purpose Audio (GPA),
> + * or AHB audio DMA (AHBAUDDMA) interface is active
> + * (for S/PDIF interface this information comes from the stream).
> + */
> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
> + u8 *channel_status)
> +{
> + /*
> + * Set channel status register for frequency and word length.
> + * Use default values for other registers.
> + */
> + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
> + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
> +}
> +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
> +
> static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
> unsigned long pixel_clk, unsigned int sample_rate)
> {
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> index 6988f12d89d9..fcff5059db24 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> @@ -158,6 +158,8 @@
> #define HDMI_FC_SPDDEVICEINF 0x1062
> #define HDMI_FC_AUDSCONF 0x1063
> #define HDMI_FC_AUDSSTAT 0x1064
> +#define HDMI_FC_AUDSCHNLS7 0x106e
> +#define HDMI_FC_AUDSCHNLS8 0x106f
> #define HDMI_FC_DATACH0FILL 0x1070
> #define HDMI_FC_DATACH1FILL 0x1071
> #define HDMI_FC_DATACH2FILL 0x1072
> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
> index cf528c289857..4b3e863c4f8a 100644
> --- a/include/drm/bridge/dw_hdmi.h
> +++ b/include/drm/bridge/dw_hdmi.h
> @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
>
> void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
> void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8 *channel_status);
> void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
> void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
> void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
>

Looks fine for me:
Reviewed-by: Neil Armstrong <[email protected]>

Jonas ? Jernej ? Russell ?

If it's ok for you I'll apply it.

Neil

2019-09-12 15:30:50

by Jernej Skrabec

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

Dne sreda, 11. september 2019 ob 19:02:38 CEST je Cheng-yi Chiang napisal(a):
> On Thu, Sep 12, 2019 at 12:54 AM Jernej Škrabec <[email protected]>
wrote:
> > Dne sreda, 11. september 2019 ob 18:23:59 CEST je Neil Armstrong
napisal(a):
> > > On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
> > > > From: Yakir Yang <[email protected]>
> > > >
> > > > When transmitting IEC60985 linear PCM audio, we configure the
> > > > Aduio Sample Channel Status information in the IEC60958 frame.
> > > > The status bit is already available in iec.status of
> > > > hdmi_codec_params.
> > > >
> > > > This fix the issue that audio does not come out on some monitors
> > > > (e.g. LG 22CV241)
> > > >
> > > > Note that these registers are only for interfaces:
> > > > I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
> > > > (AHBAUDDMA).
> > > > For S/PDIF interface this information comes from the stream.
> > > >
> > > > Currently this function dw_hdmi_set_channel_status is only called
> > > > from dw-hdmi-i2s-audio in I2S setup.
> > > >
> > > > Signed-off-by: Yakir Yang <[email protected]>
> > > > Signed-off-by: Cheng-Yi Chiang <[email protected]>
> > > > ---
> > > >
> > > > Change from v2 to v3:
> > > > 1. Reuse what is already set in iec.status in hw_param.
> > > > 2. Remove all useless definition of registers and values.
> > > > 3. Note that the original sampling frequency is not written to
> > > >
> > > > the channel status as we reuse create_iec958_consumer in
> > > > pcm_iec958.c.
> > > > Without that it can still play audio fine.
> > > >
> > > > .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
> > > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20
> > > > +++++++++++++++++++
> > > > drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
> > > > include/drm/bridge/dw_hdmi.h | 1 +
> > > > 4 files changed, 24 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index
> > > > 34d8e837555f..20f4f92dd866 100644
> > > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> > > > @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device
> > > > *dev,
> > > > void *data,>
> > > >
> > > > }
> > > >
> > > > dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
> > > >
> > > > + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
> > > >
> > > > dw_hdmi_set_channel_count(hdmi, hparms->channels);
> > > > dw_hdmi_set_channel_allocation(hdmi, hparms-
> > >
> > >cea.channel_allocation);
> > >
> > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
> > > > bd65d0479683..aa7efd4da1c8 100644
> > > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> > > > @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int
> > > > freq,
> > > > unsigned long pixel_clk)>
> > > >
> > > > return n;
> > > >
> > > > }
> > > >
> > > > +/*
> > > > + * When transmitting IEC60958 linear PCM audio, these registers allow
> > > > to
> > > > + * configure the channel status information of all the channel status
> > > > + * bits in the IEC60958 frame. For the moment this configuration is
> > > > only
> > > > + * used when the I2S audio interface, General Purpose Audio (GPA),
> > > > + * or AHB audio DMA (AHBAUDDMA) interface is active
> > > > + * (for S/PDIF interface this information comes from the stream).
> > > > + */
> > > > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
> > > > + u8 *channel_status)
> > > > +{
> > > > + /*
> > > > + * Set channel status register for frequency and word length.
> > > > + * Use default values for other registers.
> > > > + */
> > > > + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
> > > > + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
> > > > +
> > > >
> > > > static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
> > > >
> > > > unsigned long pixel_clk, unsigned int sample_rate)
> > > >
> > > > {
> > > >
> > > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h index
> > > > 6988f12d89d9..fcff5059db24 100644
> > > > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
> > > > @@ -158,6 +158,8 @@
> > > >
> > > > #define HDMI_FC_SPDDEVICEINF 0x1062
> > > > #define HDMI_FC_AUDSCONF 0x1063
> > > > #define HDMI_FC_AUDSSTAT 0x1064
> > > >
> > > > +#define HDMI_FC_AUDSCHNLS7 0x106e
> > > > +#define HDMI_FC_AUDSCHNLS8 0x106f
> > > >
> > > > #define HDMI_FC_DATACH0FILL 0x1070
> > > > #define HDMI_FC_DATACH1FILL 0x1071
> > > > #define HDMI_FC_DATACH2FILL 0x1072
> > > >
> > > > diff --git a/include/drm/bridge/dw_hdmi.h
> > > > b/include/drm/bridge/dw_hdmi.h
> > > > index cf528c289857..4b3e863c4f8a 100644
> > > > --- a/include/drm/bridge/dw_hdmi.h
> > > > +++ b/include/drm/bridge/dw_hdmi.h
> > > > @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi,
> > > > bool
> > > > hpd, bool rx_sense);>
> > > >
> > > > void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int
> > > > rate);
> > > > void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int
> > > > cnt);
> > > >
> > > > +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
> > > > *channel_status);
> > > >
> > > > void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned
> > > > int
> > > > ca);
> > > > void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
> > > > void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
> > >
> > > Looks fine for me:
> > > Reviewed-by: Neil Armstrong <[email protected]>
> > >
> > > Jonas ? Jernej ? Russell ?
> >
> > Patch itself is fine, I'm just wondering if more information should be
> > copied from status array to registers. But I think they are not 1:1
> > mapping so some
> > more work would be needed. Anyway, patch is:
> Hi Jernej,
> Yes you are right. I was thinking about the same thing.
> But there are also some fields in the IEC60958 spec not mapped to the
> registers on dw-hdmi.
> So I ended up just writing the two registers in the original ykk's
> patch, and ignoring "original sampling frequency" like pcm_iec958.
> It turns out that audio plays fine on my LG monitor. So I suggest we
> can keep this patch as simple as it is, and add more register setting
> if we find issue.
> Thanks!

I think that for reliable audio passthrough support these registers will have
to be updated, but as I said, I'm fine with this patch as-is.

Best regards,
Jernej

>
> > Reviewed-by: Jernej Skrabec <[email protected]>
> >
> > Best regards,
> > Jernej
> >
> > > If it's ok for you I'll apply it.
> > >
> > > Neil




2019-09-13 06:42:09

by Jonas Karlman

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

On 2019-09-11 19:02, Cheng-yi Chiang wrote:
> On Thu, Sep 12, 2019 at 12:54 AM Jernej Škrabec <[email protected]> wrote:
>> Dne sreda, 11. september 2019 ob 18:23:59 CEST je Neil Armstrong napisal(a):
>>> On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
>>>> From: Yakir Yang <[email protected]>
>>>>
>>>> When transmitting IEC60985 linear PCM audio, we configure the
>>>> Aduio Sample Channel Status information in the IEC60958 frame.
>>>> The status bit is already available in iec.status of hdmi_codec_params.
>>>>
>>>> This fix the issue that audio does not come out on some monitors
>>>> (e.g. LG 22CV241)
>>>>
>>>> Note that these registers are only for interfaces:
>>>> I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
>>>> (AHBAUDDMA).
>>>> For S/PDIF interface this information comes from the stream.
>>>>
>>>> Currently this function dw_hdmi_set_channel_status is only called
>>>> from dw-hdmi-i2s-audio in I2S setup.
>>>>
>>>> Signed-off-by: Yakir Yang <[email protected]>
>>>> Signed-off-by: Cheng-Yi Chiang <[email protected]>
>>>> ---
>>>>
>>>> Change from v2 to v3:
>>>> 1. Reuse what is already set in iec.status in hw_param.
>>>> 2. Remove all useless definition of registers and values.
>>>> 3. Note that the original sampling frequency is not written to
>>>>
>>>> the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
>>>> Without that it can still play audio fine.
>>>>
>>>> .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
>>>> include/drm/bridge/dw_hdmi.h | 1 +
>>>> 4 files changed, 24 insertions(+)
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index
>>>> 34d8e837555f..20f4f92dd866 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>> @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev,
>>>> void *data,>
>>>> }
>>>>
>>>> dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
>>>>
>>>> + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
>>>>
>>>> dw_hdmi_set_channel_count(hdmi, hparms->channels);
>>>> dw_hdmi_set_channel_allocation(hdmi, hparms-
>>> cea.channel_allocation);
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
>>>> bd65d0479683..aa7efd4da1c8 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq,
>>>> unsigned long pixel_clk)>
>>>> return n;
>>>>
>>>> }
>>>>
>>>> +/*
>>>> + * When transmitting IEC60958 linear PCM audio, these registers allow to
>>>> + * configure the channel status information of all the channel status
>>>> + * bits in the IEC60958 frame. For the moment this configuration is only
>>>> + * used when the I2S audio interface, General Purpose Audio (GPA),
>>>> + * or AHB audio DMA (AHBAUDDMA) interface is active
>>>> + * (for S/PDIF interface this information comes from the stream).
>>>> + */
>>>> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
>>>> + u8 *channel_status)
>>>> +{
>>>> + /*
>>>> + * Set channel status register for frequency and word length.
>>>> + * Use default values for other registers.
>>>> + */
>>>> + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
>>>> + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
>>>> +
>>>>
>>>> static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
>>>>
>>>> unsigned long pixel_clk, unsigned int sample_rate)
>>>>
>>>> {
>>>>
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h index
>>>> 6988f12d89d9..fcff5059db24 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>> @@ -158,6 +158,8 @@
>>>>
>>>> #define HDMI_FC_SPDDEVICEINF 0x1062
>>>> #define HDMI_FC_AUDSCONF 0x1063
>>>> #define HDMI_FC_AUDSSTAT 0x1064
>>>>
>>>> +#define HDMI_FC_AUDSCHNLS7 0x106e
>>>> +#define HDMI_FC_AUDSCHNLS8 0x106f
>>>>
>>>> #define HDMI_FC_DATACH0FILL 0x1070
>>>> #define HDMI_FC_DATACH1FILL 0x1071
>>>> #define HDMI_FC_DATACH2FILL 0x1072
>>>>
>>>> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
>>>> index cf528c289857..4b3e863c4f8a 100644
>>>> --- a/include/drm/bridge/dw_hdmi.h
>>>> +++ b/include/drm/bridge/dw_hdmi.h
>>>> @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool
>>>> hpd, bool rx_sense);>
>>>> void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
>>>> void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
>>>>
>>>> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
>>>> *channel_status);
>>>>
>>>> void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int
>>>> ca);
>>>> void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
>>>> void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
>>> Looks fine for me:
>>> Reviewed-by: Neil Armstrong <[email protected]>
>>>
>>> Jonas ? Jernej ? Russell ?
>> Patch itself is fine, I'm just wondering if more information should be copied
>> from status array to registers. But I think they are not 1:1 mapping so some
>> more work would be needed. Anyway, patch is:
> Hi Jernej,
> Yes you are right. I was thinking about the same thing.
> But there are also some fields in the IEC60958 spec not mapped to the
> registers on dw-hdmi.
> So I ended up just writing the two registers in the original ykk's
> patch, and ignoring "original sampling frequency" like pcm_iec958.
> It turns out that audio plays fine on my LG monitor. So I suggest we
> can keep this patch as simple as it is, and add more register setting
> if we find issue.
> Thanks!

In my old multi-channel lpcm patch [1] I only wrote sample rate to FC_AUDSCHNLS7.
This is much cleaner and simpler, and setting FC_AUDSCHNLS8 does not cause any
problems when I tested on ASUS Tinker Board S (RK3288).

Reviewed-by: Jonas Karlman <[email protected]>


[1] https://github.com/Kwiboo/linux-rockchip/commit/4af9ebc567ccf0a0851fa260097021c27aebbb6b

Regards,
Jonas

>
>>
>> Reviewed-by: Jernej Skrabec <[email protected]>
>>
>> Best regards,
>> Jernej
>>
>>> If it's ok for you I'll apply it.
>>>
>>> Neil
>>>

2019-09-13 10:39:07

by Neil Armstrong

[permalink] [raw]
Subject: Re: [PATCH v3] drm: bridge/dw_hdmi: add audio sample channel status setting

On 13/09/2019 08:37, Jonas Karlman wrote:
> On 2019-09-11 19:02, Cheng-yi Chiang wrote:
>> On Thu, Sep 12, 2019 at 12:54 AM Jernej Škrabec <[email protected]> wrote:
>>> Dne sreda, 11. september 2019 ob 18:23:59 CEST je Neil Armstrong napisal(a):
>>>> On 11/09/2019 10:26, Cheng-Yi Chiang wrote:
>>>>> From: Yakir Yang <[email protected]>
>>>>>
>>>>> When transmitting IEC60985 linear PCM audio, we configure the
>>>>> Aduio Sample Channel Status information in the IEC60958 frame.
>>>>> The status bit is already available in iec.status of hdmi_codec_params.
>>>>>
>>>>> This fix the issue that audio does not come out on some monitors
>>>>> (e.g. LG 22CV241)
>>>>>
>>>>> Note that these registers are only for interfaces:
>>>>> I2S audio interface, General Purpose Audio (GPA), or AHB audio DMA
>>>>> (AHBAUDDMA).
>>>>> For S/PDIF interface this information comes from the stream.
>>>>>
>>>>> Currently this function dw_hdmi_set_channel_status is only called
>>>>> from dw-hdmi-i2s-audio in I2S setup.
>>>>>
>>>>> Signed-off-by: Yakir Yang <[email protected]>
>>>>> Signed-off-by: Cheng-Yi Chiang <[email protected]>
>>>>> ---
>>>>>
>>>>> Change from v2 to v3:
>>>>> 1. Reuse what is already set in iec.status in hw_param.
>>>>> 2. Remove all useless definition of registers and values.
>>>>> 3. Note that the original sampling frequency is not written to
>>>>>
>>>>> the channel status as we reuse create_iec958_consumer in pcm_iec958.c.
>>>>> Without that it can still play audio fine.
>>>>>
>>>>> .../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
>>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 20 +++++++++++++++++++
>>>>> drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 2 ++
>>>>> include/drm/bridge/dw_hdmi.h | 1 +
>>>>> 4 files changed, 24 insertions(+)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index
>>>>> 34d8e837555f..20f4f92dd866 100644
>>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
>>>>> @@ -102,6 +102,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev,
>>>>> void *data,>
>>>>> }
>>>>>
>>>>> dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
>>>>>
>>>>> + dw_hdmi_set_channel_status(hdmi, hparms->iec.status);
>>>>>
>>>>> dw_hdmi_set_channel_count(hdmi, hparms->channels);
>>>>> dw_hdmi_set_channel_allocation(hdmi, hparms-
>>>> cea.channel_allocation);
>>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index
>>>>> bd65d0479683..aa7efd4da1c8 100644
>>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>>> @@ -582,6 +582,26 @@ static unsigned int hdmi_compute_n(unsigned int freq,
>>>>> unsigned long pixel_clk)>
>>>>> return n;
>>>>>
>>>>> }
>>>>>
>>>>> +/*
>>>>> + * When transmitting IEC60958 linear PCM audio, these registers allow to
>>>>> + * configure the channel status information of all the channel status
>>>>> + * bits in the IEC60958 frame. For the moment this configuration is only
>>>>> + * used when the I2S audio interface, General Purpose Audio (GPA),
>>>>> + * or AHB audio DMA (AHBAUDDMA) interface is active
>>>>> + * (for S/PDIF interface this information comes from the stream).
>>>>> + */
>>>>> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi,
>>>>> + u8 *channel_status)
>>>>> +{
>>>>> + /*
>>>>> + * Set channel status register for frequency and word length.
>>>>> + * Use default values for other registers.
>>>>> + */
>>>>> + hdmi_writeb(hdmi, channel_status[3], HDMI_FC_AUDSCHNLS7);
>>>>> + hdmi_writeb(hdmi, channel_status[4], HDMI_FC_AUDSCHNLS8);
>>>>> +}
>>>>> +EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_status);
>>>>> +
>>>>>
>>>>> static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
>>>>>
>>>>> unsigned long pixel_clk, unsigned int sample_rate)
>>>>>
>>>>> {
>>>>>
>>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h index
>>>>> 6988f12d89d9..fcff5059db24 100644
>>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
>>>>> @@ -158,6 +158,8 @@
>>>>>
>>>>> #define HDMI_FC_SPDDEVICEINF 0x1062
>>>>> #define HDMI_FC_AUDSCONF 0x1063
>>>>> #define HDMI_FC_AUDSSTAT 0x1064
>>>>>
>>>>> +#define HDMI_FC_AUDSCHNLS7 0x106e
>>>>> +#define HDMI_FC_AUDSCHNLS8 0x106f
>>>>>
>>>>> #define HDMI_FC_DATACH0FILL 0x1070
>>>>> #define HDMI_FC_DATACH1FILL 0x1071
>>>>> #define HDMI_FC_DATACH2FILL 0x1072
>>>>>
>>>>> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
>>>>> index cf528c289857..4b3e863c4f8a 100644
>>>>> --- a/include/drm/bridge/dw_hdmi.h
>>>>> +++ b/include/drm/bridge/dw_hdmi.h
>>>>> @@ -156,6 +156,7 @@ void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool
>>>>> hpd, bool rx_sense);>
>>>>> void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
>>>>> void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
>>>>>
>>>>> +void dw_hdmi_set_channel_status(struct dw_hdmi *hdmi, u8
>>>>> *channel_status);
>>>>>
>>>>> void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int
>>>>> ca);
>>>>> void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
>>>>> void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
>>>> Looks fine for me:
>>>> Reviewed-by: Neil Armstrong <[email protected]>
>>>>
>>>> Jonas ? Jernej ? Russell ?
>>> Patch itself is fine, I'm just wondering if more information should be copied
>>> from status array to registers. But I think they are not 1:1 mapping so some
>>> more work would be needed. Anyway, patch is:
>> Hi Jernej,
>> Yes you are right. I was thinking about the same thing.
>> But there are also some fields in the IEC60958 spec not mapped to the
>> registers on dw-hdmi.
>> So I ended up just writing the two registers in the original ykk's
>> patch, and ignoring "original sampling frequency" like pcm_iec958.
>> It turns out that audio plays fine on my LG monitor. So I suggest we
>> can keep this patch as simple as it is, and add more register setting
>> if we find issue.
>> Thanks!
>
> In my old multi-channel lpcm patch [1] I only wrote sample rate to FC_AUDSCHNLS7.
> This is much cleaner and simpler, and setting FC_AUDSCHNLS8 does not cause any
> problems when I tested on ASUS Tinker Board S (RK3288).
>
> Reviewed-by: Jonas Karlman <[email protected]>
>
>
> [1] https://github.com/Kwiboo/linux-rockchip/commit/4af9ebc567ccf0a0851fa260097021c27aebbb6b

Thanks Jonas, Jernej,

Applying now.

Neil

>
> Regards,
> Jonas
>
>>
>>>
>>> Reviewed-by: Jernej Skrabec <[email protected]>
>>>
>>> Best regards,
>>> Jernej
>>>
>>>> If it's ok for you I'll apply it.
>>>>
>>>> Neil
>>>>