[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-09 Thread Russell King - ARM Linux
On Fri, Oct 09, 2015 at 01:02:11PM -0300, Fabio Estevam wrote:
> On Fri, Oct 9, 2015 at 1:00 PM, Russell King - ARM Linux
>  wrote:
> 
> >> Thanks, Russell!
> >>
> >> Got audio to play on my HDMI TV :-)
> >>
> >> For the entire series:
> >>
> >> Tested-by: Fabio Estevam 
> >
> > Just to confirm - that's for _all_ of these 8 patches, including the
> > changes to the ACR code in the last four patches, and you're happy that
> > I send all of these:
> >
> > drm: bridge/dw_hdmi-ahb-audio: add audio driver
> > drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
> > drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
> > drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
> > drm: bridge/dw_hdmi: avoid being recursive in N calculation
> > drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
> > drm: bridge/dw_hdmi: remove ratio support from ACR code
> > drm: bridge/dw_hdmi: replace CTS calculation for the ACR
> 
> That's correct. Thanks, Russell

Thanks.  I'll drop that set into linux-next tonight, along with the TDA998x
and Armada DRM patches that haven't seen an airing there yet - before asking
David to pull them next week (the timescale has slipped...)

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-09 Thread Russell King - ARM Linux
On Tue, Oct 06, 2015 at 05:25:16PM -0300, Fabio Estevam wrote:
> On Tue, Oct 6, 2015 at 3:54 PM, Russell King - ARM Linux
>  wrote:
> 
> > Make sure you have the ALSA config file, as alsalib won't get on
> > with dw-hdmi only accepting 24-bit audio without this.  A copy is
> > attached.  It also tells ALSA how to deal with multi-channel audio
> > as well.
> 
> Thanks, Russell!
> 
> Got audio to play on my HDMI TV :-)
> 
> For the entire series:
> 
> Tested-by: Fabio Estevam 

Just to confirm - that's for _all_ of these 8 patches, including the
changes to the ACR code in the last four patches, and you're happy that
I send all of these:

drm: bridge/dw_hdmi-ahb-audio: add audio driver
drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
drm: bridge/dw_hdmi: avoid being recursive in N calculation
drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
drm: bridge/dw_hdmi: remove ratio support from ACR code
drm: bridge/dw_hdmi: replace CTS calculation for the ACR

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-09 Thread Fabio Estevam
On Fri, Oct 9, 2015 at 1:00 PM, Russell King - ARM Linux
 wrote:

>> Thanks, Russell!
>>
>> Got audio to play on my HDMI TV :-)
>>
>> For the entire series:
>>
>> Tested-by: Fabio Estevam 
>
> Just to confirm - that's for _all_ of these 8 patches, including the
> changes to the ACR code in the last four patches, and you're happy that
> I send all of these:
>
> drm: bridge/dw_hdmi-ahb-audio: add audio driver
> drm: bridge/dw_hdmi-ahb-audio: parse ELD from HDMI driver
> drm: bridge/dw_hdmi-ahb-audio: basic support for multi-channel PCM audio
> drm: bridge/dw_hdmi-ahb-audio: allow larger buffer sizes
> drm: bridge/dw_hdmi: avoid being recursive in N calculation
> drm: bridge/dw_hdmi: adjust pixel clock values in N calculation
> drm: bridge/dw_hdmi: remove ratio support from ACR code
> drm: bridge/dw_hdmi: replace CTS calculation for the ACR

That's correct. Thanks, Russell


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-06 Thread Russell King - ARM Linux
On Tue, Oct 06, 2015 at 03:45:32PM -0300, Fabio Estevam wrote:
> On Tue, Oct 6, 2015 at 3:18 PM, Russell King - ARM Linux
>  wrote:
> 
> > Sorry, I've been out for most of the day.  There's no DT patches required.
> >
> > The dw_hdmi bridge driver creates its own platform device for the audio,
> > which should then bind to the dw_hdmi-ahb-audio driver using normal Linux
> > methods.
> >
> > I don't know what's wrong with your setup, for me, it just works:
> >
> > [1.358829] dwhdmi-imx 12.hdmi: Detected HDMI controller 
> > 0x13:0xa:0xa0:0xc1
> > [1.377173] imx-drm display-subsystem: bound 12.hdmi (ops 
> > dw_hdmi_imx_ops)
> > ...
> > [2.851343] ALSA device list:
> > [2.857364]   #0: DW-HDMI rev 0x0a, irq 21
> >
> > as it always has done for me.  There's nothing special about it.
> 
> Great, got it to probe now:
> 
> [7.454760] ALSA device list:
> [7.457764]   #0: DW-HDMI rev 0x0a, irq 19
> [7.461990]   #1: wm8962-audio
> 
> There was a conflict and I resolved incorrectly here. Will try to play
> a wav file via aplay now.

Make sure you have the ALSA config file, as alsalib won't get on
with dw-hdmi only accepting 24-bit audio without this.  A copy is
attached.  It also tells ALSA how to deal with multi-channel audio
as well.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
-- next part --
#
# All PCM must be 24-bit for easy kernel conversion.
# IEC958 formatted output can be sent directly.
#
# Direct-to-hardware converting to 24-bit output.
#
dw-hdmi-ahb-aud.pcm.hw-s24le {
@args [ CARD ]
@args.CARD { type string }
type linear
slave.pcm { 
type hw
card $CARD
}
slave.format S24_LE
}

#
# Dmix hardware 24-bit output.
#
dw-hdmi-ahb-aud.pcm.dmix-s24le {
@args [ CARD ]
@args.CARD { type string }
type plug
slave.pcm { @func concat strings [ "dmix:" $CARD ",FORMAT=S24_LE" ] }
}

#
# Softvol with dmix output
#
dw-hdmi-ahb-aud.pcm.default {
@args [ CARD ]
@args.CARD { type string }
type asym
playback.pcm {
type softvol
slave.pcm {
@func refer name { 
@func concat strings [
"cards."
{ @func card_driver card $CARD }
".pcm.dmix-s24le:CARD=" $CARD
]
}
}
control {
name "PCM Playback Volume"
card $CARD
}
}
}

#
# Common output path for front and surround outputs
#
dw-hdmi-ahb-aud.pcm.common.0 {
@args [ CARD ]
@args.CARD { type string }
type asym
playback.pcm {
type softvol
slave.pcm {
@func refer name { 
@func concat strings [
"cards."
{ @func card_driver card $CARD }
".pcm.hw-s24le:CARD=" $CARD
]
}
}
control {
name "PCM Playback Volume"
card $CARD
}
}
}



dw-hdmi-ahb-aud.pcm.front.0 cards.dw-hdmi-ahb-aud.pcm.common.0

# The mapping of ALSA channels to surround channels is very imprecise.
# ALSA uses a different terminology and speaker placement to the CEA
# surround positioning.  CEA has the positioning of:
#
#   LFE
#   FL  FLC FC  FRC FR
#
#
#   RL  RLC RC  RRC RR
#
# ALSA's idea is:
#
#   LFE
#   FL  C   FR
#
#   SL  SR
#
#   RL  RR
#
# We do our best to map between these representations.



dw-hdmi-ahb-aud.pcm.surround40.0 {
@args [ CARD ]
@args.CARD { type string }
type empty
slave.pcm {
@func refer
name { 
@func concat strings [
"cards.dw-hdmi-ahb-aud.pcm.common.0:CARD="
$CARD
]
}
}
}

# surround 41 and surround50 are (annoyingly) mapped to surround51
# We could do without stacking two 'route' plugins on top of each other





dw-hdmi-ahb-aud.pcm.surround51.0 {
@args [ CARD ]
@args.CARD { type string }
type route
slave.pcm {
@func refer
name { 
@func concat strings [
"cards.dw-hdmi-ahb-aud.pcm.common.0:CARD="
$CARD
 

[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-06 Thread Russell King - ARM Linux
On Tue, Oct 06, 2015 at 03:07:40PM -0300, Fabio Estevam wrote:
> On Sat, Aug 8, 2015 at 1:10 PM, Russell King
>  wrote:
> > Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
> > format supported by the hardware is its own special IEC958 based format,
> > which is not compatible with any ALSA format.  To avoid doing too much
> > data manipulation within the driver, we support only ALSAs IEC958 LE and
> > 24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
> > format.
> >
> > A more desirable solution would be to have this conversion in userspace,
> > but ALSA does not appear to allow such transformations outside of
> > libasound itself.
> >
> > Signed-off-by: Russell King 
> 
> I applied this series, but the HDMI audio card is not registered. I
> guess I missed the dts pieces. Are the dts patches available?

Sorry, I've been out for most of the day.  There's no DT patches required.

The dw_hdmi bridge driver creates its own platform device for the audio,
which should then bind to the dw_hdmi-ahb-audio driver using normal Linux
methods.

I don't know what's wrong with your setup, for me, it just works:

[1.358829] dwhdmi-imx 12.hdmi: Detected HDMI controller 
0x13:0xa:0xa0:0xc1
[1.377173] imx-drm display-subsystem: bound 12.hdmi (ops 
dw_hdmi_imx_ops)
...
[2.851343] ALSA device list:
[2.857364]   #0: DW-HDMI rev 0x0a, irq 21

as it always has done for me.  There's nothing special about it.

There's nothing special about it - it's a standard ALSA PCM audio driver,
it doesn't have any requirements over and above having ALSA and ALSA's PCM
support enabled.  If you didn't have those enabled, but somehow had the
dw_hdmi-ahb-audio set as built-in, you'd get a link time error, so it's
not a configuration issue.

It works for me on all iMX6 platforms (solo, dual-lite, dual and quad).

As it's a straight ALSA device, it doesn't need any codec or any of the
ASoC infrastructure either.

I guess the thing to start looking at is whether the device and driver
appear in /sys/bus/platform/{devices,drivers}/.  You should have:

/sys/bus/platform/devices/dw-hdmi-ahb-audio.0.auto 
/sys/bus/platform/drivers/dw-hdmi-ahb-audio

and obviously the latter should contain the symlink to the device.  If
that is present, then the driver has bound, and it should appear in
/proc/asound/cards.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-06 Thread Fabio Estevam
On Tue, Oct 6, 2015 at 3:54 PM, Russell King - ARM Linux
 wrote:

> Make sure you have the ALSA config file, as alsalib won't get on
> with dw-hdmi only accepting 24-bit audio without this.  A copy is
> attached.  It also tells ALSA how to deal with multi-channel audio
> as well.

Thanks, Russell!

Got audio to play on my HDMI TV :-)

For the entire series:

Tested-by: Fabio Estevam 


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-06 Thread Fabio Estevam
On Tue, Oct 6, 2015 at 3:18 PM, Russell King - ARM Linux
 wrote:

> Sorry, I've been out for most of the day.  There's no DT patches required.
>
> The dw_hdmi bridge driver creates its own platform device for the audio,
> which should then bind to the dw_hdmi-ahb-audio driver using normal Linux
> methods.
>
> I don't know what's wrong with your setup, for me, it just works:
>
> [1.358829] dwhdmi-imx 12.hdmi: Detected HDMI controller 
> 0x13:0xa:0xa0:0xc1
> [1.377173] imx-drm display-subsystem: bound 12.hdmi (ops 
> dw_hdmi_imx_ops)
> ...
> [2.851343] ALSA device list:
> [2.857364]   #0: DW-HDMI rev 0x0a, irq 21
>
> as it always has done for me.  There's nothing special about it.

Great, got it to probe now:

[7.454760] ALSA device list:
[7.457764]   #0: DW-HDMI rev 0x0a, irq 19
[7.461990]   #1: wm8962-audio

There was a conflict and I resolved incorrectly here. Will try to play
a wav file via aplay now.

Thanks


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-10-06 Thread Fabio Estevam
On Sat, Aug 8, 2015 at 1:10 PM, Russell King
 wrote:
> Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
> format supported by the hardware is its own special IEC958 based format,
> which is not compatible with any ALSA format.  To avoid doing too much
> data manipulation within the driver, we support only ALSAs IEC958 LE and
> 24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
> format.
>
> A more desirable solution would be to have this conversion in userspace,
> but ALSA does not appear to allow such transformations outside of
> libasound itself.
>
> Signed-off-by: Russell King 

I applied this series, but the HDMI audio card is not registered. I
guess I missed the dts pieces. Are the dts patches available?

Thanks


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-10 Thread Mark Brown
On Mon, Aug 10, 2015 at 05:49:41PM +0100, Russell King - ARM Linux wrote:

> I'm not sure what the right solution is here: modifying every audio
> player out there to make HDMI work sanely is crazy.  Having alsalib
> automatically generate the correct AES channel status bytes for
> linear audio formats seems to be sensible, but difficult given its
> present structure with the defaults - the iec958 plugin has no idea
> if the defaults are being used or not.

> The advantage of having the horrid conversion in the kernel is that
> we can choose to generate proper AES channel status data without
> regard to userspace for standard linear PCM, and when the iec958 plugin
> is being used with proper channel status (eg, in compressed audio
> pass-through mode by VLC) then that works too.

The other advantage of doing it in kernel is that it also fixes tinyalsa
applications (which mainly means Android systems) by default for PCM
data.
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: 



[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-10 Thread Russell King - ARM Linux
On Mon, Aug 10, 2015 at 02:23:07PM +0200, Takashi Iwai wrote:
> I admit that alsa-lib code is very horrible to follow -- but I guess
> the change you'd need for iec958 plugin would be fairly small.  We can
> add a config option and let iec958 behaving slightly differently
> depending on it.

Yes, but there's other problems there as well.

The IEC958 plugin does the job of adding the 4 AES bytes and formatting
fairly well, but the problem when the 'default' bytes specified in the
ALSA configuration files are used.

Let's take the old chestnut of PulseAudio, or even aplay, or the miriad
of other audio-only players out there.

Most of them do not supply the AES bytes to be used, so we end up with
the default.

The default is... 0x04 0x82 0x00 0x02, which specifies a sample rate
of 48kHz.  However, the actual sample rate may not be 48kHz.  At least
the HDMI specifications say that the channel status data must be correct,
and there are AV receivers out there which do make use of this, and if
the channel status does not agree with the actual sample rate, they
either refuse to recognise the audio stream (saying there's nothing
there) or they intermittently mute the audio.  Yamaha RX-V677 is one
example which has this behaviour.

The only compliant program that I've found so far is VLC in SPDIF
pass-through mode, which is the only case where VLC passes the
channel status information.  Everything else seems broken in this
regard, by falling back to the default.

Obviously, aplay can be made to work by setting the AES bytes
manually when specifying the device for it to use, but this is not
really user-friendly or programmer friendly - especially as the
current use model expects things to "just work" (the common case
being PCM output on a PC which doesn't care about channel status.)

I'm not sure what the right solution is here: modifying every audio
player out there to make HDMI work sanely is crazy.  Having alsalib
automatically generate the correct AES channel status bytes for
linear audio formats seems to be sensible, but difficult given its
present structure with the defaults - the iec958 plugin has no idea
if the defaults are being used or not.

The advantage of having the horrid conversion in the kernel is that
we can choose to generate proper AES channel status data without
regard to userspace for standard linear PCM, and when the iec958 plugin
is being used with proper channel status (eg, in compressed audio
pass-through mode by VLC) then that works too.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-10 Thread Takashi Iwai
On Mon, 10 Aug 2015 12:39:21 +0200,
Russell King - ARM Linux wrote:
> 
> On Mon, Aug 10, 2015 at 12:05:07PM +0200, Takashi Iwai wrote:
> > On Sat, 08 Aug 2015 18:10:06 +0200,
> > Russell King wrote:
> > > +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> > > +{
> > > + struct snd_dw_hdmi *dw = data;
> > > + struct snd_pcm_substream *substream;
> > > + unsigned stat;
> > > +
> > > + stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > > + if (!stat)
> > > + return IRQ_NONE;
> > > +
> > > + writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > > +
> > > + substream = dw->substream;
> > > + if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> > > + snd_pcm_period_elapsed(substream);
> > > + if (dw->substream)
> > > + dw_hdmi_start_dma(dw);
> > > + }
> > 
> > Don't we need locking?
> 
> Possibly.
> 
> > In theory, the trigger can be issued while the irq is being handled.
> 
> Well, we can't have a lock around the whole of the above, because that
> results in deadlock (as snd_pcm_period_elapsed() can end up calling into
> the trigger method.)

Yes, and a usual workaround is to unlock temporarily at calling
snd_pcm_period_elapsed(), then relock or call it at the end of 
handler.

> I'm not happy to throw a spinlock around this
> because of the in-built format conversion (something else I'm really not
> happy about - which has to exist here because alsalib is soo painful
> to add custom sample reformatting to - such modules have to be built
> as part of alsalib itself rather than an add-on module.)

I admit that alsa-lib code is very horrible to follow -- but I guess
the change you'd need for iec958 plugin would be fairly small.  We can
add a config option and let iec958 behaving slightly differently
depending on it.

Meanwhile, having an in-kernel workaround makes it much easier to
deploy, so I think it's OK to have this in driver for now.

> > > +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> > > +{
> > > + struct snd_dw_hdmi *dw = substream->private_data;
> > > + int ret = 0;
> > > +
> > > + switch (cmd) {
> > > + case SNDRV_PCM_TRIGGER_START:
> > > + dw->buf_offset = 0;
> > > + dw->substream = substream;
> > > + dw_hdmi_start_dma(dw);
> > > + dw_hdmi_audio_enable(dw->data.hdmi);
> > > + substream->runtime->delay = substream->runtime->period_size;
> > > + break;
> > > +
> > > + case SNDRV_PCM_TRIGGER_STOP:
> > > + dw_hdmi_stop_dma(dw);
> > > + dw_hdmi_audio_disable(dw->data.hdmi);
> > > + break;
> > > +
> > > + default:
> > > + ret = -EINVAL;
> > > + break;
> > 
> > SNDRV_PCM_TRIGGER_SUSPEND may be passed at suspend, too.
> 
> I think rather than adding code which would be difficult for me to test,
> I'd instead remove the suspend/resume callbacks, or at least disable them
> until someone can test that feature, or is willing to implement it.

That's fine.

> > > +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream 
> > > *substream)
> > > +{
> > > + struct snd_pcm_runtime *runtime = substream->runtime;
> > > + struct snd_dw_hdmi *dw = substream->private_data;
> > > +
> > > + return bytes_to_frames(runtime, dw->buf_offset);
> > 
> > So, this returns the offset that has been reformatted.  Does the
> > hardware support any better position reporting?  We may give the delay
> > from the driver if possible.
> 
> Basically, no.  Reading a 32-bit DMA position as separate bytes while
> DMA is active is racy.
> 
> This is the best we can do, and the way we report the position has been
> arrived at after what's getting on for two years of testing with
> pulseaudio, vlc direct access & spdif pass-through, aplay, etc:
> 
> Author: Russell King 
> Date:   Thu Nov 7 16:01:45 2013 +
> 
> drm: bridge/dw_hdmi-ahb-audio: add audio driver

OK, then this is a driver with the low update granularity.  Hopefully
we'll get some good API to indicate that in near future, as we've been
discussing about it for a while.


thanks,

Takashi


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-10 Thread Takashi Iwai
On Sat, 08 Aug 2015 18:10:06 +0200,
Russell King wrote:
> 
> Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
> format supported by the hardware is its own special IEC958 based format,
> which is not compatible with any ALSA format.  To avoid doing too much
> data manipulation within the driver, we support only ALSAs IEC958 LE and
> 24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
> format.
> 
> A more desirable solution would be to have this conversion in userspace,
> but ALSA does not appear to allow such transformations outside of
> libasound itself.
> 
> Signed-off-by: Russell King 
> ---
>  drivers/gpu/drm/bridge/Kconfig |  10 +
>  drivers/gpu/drm/bridge/Makefile|   1 +
>  drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 561 
> +
>  drivers/gpu/drm/bridge/dw_hdmi-audio.h |  13 +
>  drivers/gpu/drm/bridge/dw_hdmi.c   |  24 ++
>  drivers/gpu/drm/bridge/dw_hdmi.h   |   3 +
>  6 files changed, 612 insertions(+)
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
>  create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index acef3223772c..56ed35fe0734 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -3,6 +3,16 @@ config DRM_DW_HDMI
>   depends on DRM
>   select DRM_KMS_HELPER
>  
> +config DRM_DW_HDMI_AHB_AUDIO
> + tristate "Synopsis Designware AHB Audio interface"
> + depends on DRM_DW_HDMI && SND
> + select SND_PCM
> + select SND_PCM_IEC958
> + help
> +   Support the AHB Audio interface which is part of the Synopsis
> +   Designware HDMI block.  This is used in conjunction with
> +   the i.MX6 HDMI driver.
> +
>  config DRM_PTN3460
>   tristate "PTN3460 DP/LVDS bridge"
>   depends on DRM
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 8dfebd984370..eb80dbbb8365 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
>  obj-$(CONFIG_DRM_PS8622) += ps8622.o
>  obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
>  obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
> +obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
> diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c 
> b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> new file mode 100644
> index ..22bbbc5c2393
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
> @@ -0,0 +1,561 @@
> +/*
> + * DesignWare HDMI audio driver
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Written and tested against the Designware HDMI Tx found in iMX6.
> + */
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "dw_hdmi-audio.h"
> +
> +#define DRIVER_NAME "dw-hdmi-ahb-audio"
> +
> +/* Provide some bits rather than bit offsets */
> +enum {
> + HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
> + HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
> + HDMI_AHB_DMA_START_START = BIT(0),
> + HDMI_AHB_DMA_STOP_STOP = BIT(0),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
> + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
> + HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
> + HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
> + HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
> + HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
> + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
> + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
> + HDMI_IH_AHBDMAAUD_STAT0_ALL =
> + HDMI_IH_AHBDMAAUD_STAT0_ERROR |
> + HDMI_IH_AHBDMAAUD_STAT0_LOST |
> + HDMI_IH_AHBDMAAUD_STAT0_RETRY |
> + HDMI_IH_AHBDMAAUD_STAT0_DONE |
> + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
> + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
> + HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
> + HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
> + HDMI_AHB_DMA_CONF0_INCR4 = 0,
> + HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
> + HDMI_AHB_DMA_MASK_DONE = BIT(7),
> + HDMI_REVISION_ID = 0x0001,
> + 

[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-10 Thread Russell King - ARM Linux
On Mon, Aug 10, 2015 at 12:05:07PM +0200, Takashi Iwai wrote:
> On Sat, 08 Aug 2015 18:10:06 +0200,
> Russell King wrote:
> > +static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
> > +{
> > +   struct snd_dw_hdmi *dw = data;
> > +   struct snd_pcm_substream *substream;
> > +   unsigned stat;
> > +
> > +   stat = readb_relaxed(dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > +   if (!stat)
> > +   return IRQ_NONE;
> > +
> > +   writeb_relaxed(stat, dw->data.base + HDMI_IH_AHBDMAAUD_STAT0);
> > +
> > +   substream = dw->substream;
> > +   if (stat & HDMI_IH_AHBDMAAUD_STAT0_DONE && substream) {
> > +   snd_pcm_period_elapsed(substream);
> > +   if (dw->substream)
> > +   dw_hdmi_start_dma(dw);
> > +   }
> 
> Don't we need locking?

Possibly.

> In theory, the trigger can be issued while the irq is being handled.

Well, we can't have a lock around the whole of the above, because that
results in deadlock (as snd_pcm_period_elapsed() can end up calling into
the trigger method.)  I'm not happy to throw a spinlock around this
because of the in-built format conversion (something else I'm really not
happy about - which has to exist here because alsalib is soo painful
to add custom sample reformatting to - such modules have to be built
as part of alsalib itself rather than an add-on module.)

> > +static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
> > +{
> > +   struct snd_dw_hdmi *dw = substream->private_data;
> > +   int ret = 0;
> > +
> > +   switch (cmd) {
> > +   case SNDRV_PCM_TRIGGER_START:
> > +   dw->buf_offset = 0;
> > +   dw->substream = substream;
> > +   dw_hdmi_start_dma(dw);
> > +   dw_hdmi_audio_enable(dw->data.hdmi);
> > +   substream->runtime->delay = substream->runtime->period_size;
> > +   break;
> > +
> > +   case SNDRV_PCM_TRIGGER_STOP:
> > +   dw_hdmi_stop_dma(dw);
> > +   dw_hdmi_audio_disable(dw->data.hdmi);
> > +   break;
> > +
> > +   default:
> > +   ret = -EINVAL;
> > +   break;
> 
> SNDRV_PCM_TRIGGER_SUSPEND may be passed at suspend, too.

I think rather than adding code which would be difficult for me to test,
I'd instead remove the suspend/resume callbacks, or at least disable them
until someone can test that feature, or is willing to implement it.

> > +static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream 
> > *substream)
> > +{
> > +   struct snd_pcm_runtime *runtime = substream->runtime;
> > +   struct snd_dw_hdmi *dw = substream->private_data;
> > +
> > +   return bytes_to_frames(runtime, dw->buf_offset);
> 
> So, this returns the offset that has been reformatted.  Does the
> hardware support any better position reporting?  We may give the delay
> from the driver if possible.

Basically, no.  Reading a 32-bit DMA position as separate bytes while
DMA is active is racy.

This is the best we can do, and the way we report the position has been
arrived at after what's getting on for two years of testing with
pulseaudio, vlc direct access & spdif pass-through, aplay, etc:

Author: Russell King 
Date:   Thu Nov 7 16:01:45 2013 +

drm: bridge/dw_hdmi-ahb-audio: add audio driver

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.


[PATCH 1/9] drm: bridge/dw_hdmi-ahb-audio: add audio driver

2015-08-08 Thread Russell King
Add ALSA based HDMI AHB audio driver for dw_hdmi.  The only buffer
format supported by the hardware is its own special IEC958 based format,
which is not compatible with any ALSA format.  To avoid doing too much
data manipulation within the driver, we support only ALSAs IEC958 LE and
24-bit PCM formats for 2 to 6 channels, which we convert to its hardware
format.

A more desirable solution would be to have this conversion in userspace,
but ALSA does not appear to allow such transformations outside of
libasound itself.

Signed-off-by: Russell King 
---
 drivers/gpu/drm/bridge/Kconfig |  10 +
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c | 561 +
 drivers/gpu/drm/bridge/dw_hdmi-audio.h |  13 +
 drivers/gpu/drm/bridge/dw_hdmi.c   |  24 ++
 drivers/gpu/drm/bridge/dw_hdmi.h   |   3 +
 6 files changed, 612 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
 create mode 100644 drivers/gpu/drm/bridge/dw_hdmi-audio.h

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index acef3223772c..56ed35fe0734 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -3,6 +3,16 @@ config DRM_DW_HDMI
depends on DRM
select DRM_KMS_HELPER

+config DRM_DW_HDMI_AHB_AUDIO
+   tristate "Synopsis Designware AHB Audio interface"
+   depends on DRM_DW_HDMI && SND
+   select SND_PCM
+   select SND_PCM_IEC958
+   help
+ Support the AHB Audio interface which is part of the Synopsis
+ Designware HDMI block.  This is used in conjunction with
+ the i.MX6 HDMI driver.
+
 config DRM_PTN3460
tristate "PTN3460 DP/LVDS bridge"
depends on DRM
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 8dfebd984370..eb80dbbb8365 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -3,3 +3,4 @@ ccflags-y := -Iinclude/drm
 obj-$(CONFIG_DRM_PS8622) += ps8622.o
 obj-$(CONFIG_DRM_PTN3460) += ptn3460.o
 obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o
+obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw_hdmi-ahb-audio.o
diff --git a/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c 
b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
new file mode 100644
index ..22bbbc5c2393
--- /dev/null
+++ b/drivers/gpu/drm/bridge/dw_hdmi-ahb-audio.c
@@ -0,0 +1,561 @@
+/*
+ * DesignWare HDMI audio driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Written and tested against the Designware HDMI Tx found in iMX6.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "dw_hdmi-audio.h"
+
+#define DRIVER_NAME "dw-hdmi-ahb-audio"
+
+/* Provide some bits rather than bit offsets */
+enum {
+   HDMI_AHB_DMA_CONF0_SW_FIFO_RST = BIT(7),
+   HDMI_AHB_DMA_CONF0_EN_HLOCK = BIT(3),
+   HDMI_AHB_DMA_START_START = BIT(0),
+   HDMI_AHB_DMA_STOP_STOP = BIT(0),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR = BIT(5),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST = BIT(4),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY = BIT(3),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE = BIT(2),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL =
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR |
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST |
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY |
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE |
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL |
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY,
+   HDMI_IH_AHBDMAAUD_STAT0_ERROR = BIT(5),
+   HDMI_IH_AHBDMAAUD_STAT0_LOST = BIT(4),
+   HDMI_IH_AHBDMAAUD_STAT0_RETRY = BIT(3),
+   HDMI_IH_AHBDMAAUD_STAT0_DONE = BIT(2),
+   HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL = BIT(1),
+   HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY = BIT(0),
+   HDMI_IH_AHBDMAAUD_STAT0_ALL =
+   HDMI_IH_AHBDMAAUD_STAT0_ERROR |
+   HDMI_IH_AHBDMAAUD_STAT0_LOST |
+   HDMI_IH_AHBDMAAUD_STAT0_RETRY |
+   HDMI_IH_AHBDMAAUD_STAT0_DONE |
+   HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL |
+   HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY,
+   HDMI_AHB_DMA_CONF0_INCR16 = 2 << 1,
+   HDMI_AHB_DMA_CONF0_INCR8 = 1 << 1,
+   HDMI_AHB_DMA_CONF0_INCR4 = 0,
+   HDMI_AHB_DMA_CONF0_BURST_MODE = BIT(0),
+   HDMI_AHB_DMA_MASK_DONE = BIT(7),
+   HDMI_REVISION_ID = 0x0001,
+   HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
+   HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
+   HDMI_AHB_DMA_CONF0 = 0x3600,
+   HDMI_AHB_DMA_START = 0x3601,
+   HDMI_AHB_DMA_STOP = 0x3602,
+   HDMI_AHB_DMA_THRSLD =