2013-10-01 20:37:43

by Anssi Hannula

[permalink] [raw]
Subject: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

Hi all!

Here is a second revision of the ATI/AMD multichannel patch, now a
patchset.

Since the last revision from a bit over the week ago, AMD has released
more documentation ( http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf ),
so the patchset contains new additions:

- HBR bitstreaming support (HD passthrough, for DTS-HD and Dolby TrueHD)
o This completes the set, now we have HBR on NVIDIA, Intel and AMD :)

- More complete ELD emulation on revision 3+ (0x100300) codecs
o Untested, though from what I can see the newly added fields may not
be filled in yet by the radeon driver.

- Ramp up/down configuration according to non-pcm bit on rev3+
o I guess this means gradual fade-in/out? Untested.

Other changes since the previous post:
- ELD emulation moved to hda_eld.c and cleaned up a bit
- Some fixes to hdmi_chmap_ctl_tlv() changes
(and maybe something else I forgot - if so, sorry)

Also, the pairwise channel mapping code has been tested to work with
custom channel maps. The TLV contents are shown as follows by amixer:
| chmap-paired=FL,FR
| chmap-paired=FL,FR,NA,LFE
| chmap-paired=FL,FR,FC,NA
| chmap-paired=FL,FR,RL,RR
| chmap-paired=FL,FR,FC,LFE
| chmap-paired=FL,FR,NA,LFE,RL,RR
| chmap-paired=FL,FR,FC,NA,RL,RR
[etc]

Rafał, do you know about the missing (AFAICS) support for lipsync (F7B)
and sink information (F81) in radeon driver?

This patchset requires at least more testing before it should be applied.

A few other somewhat open things:
- I named everything ati/ATI except for is_amdhdmi_rev3() and
has_amd_full_remap_support() that are AMD-only, though AMD-only verbs
I still named ATI to have similar names to other verbs. Does that
seem sensible or how should this be done?
- Currently setup_audio_infoframe() writes the channel mapping every
time for ATI/AMD, should we try to avoid that? If so, any
suggestions?
(argh, just noticed this is broken for manual channel maps on non-ATI;
if just the chmap is changed, channel mapping is not updated;
so this requires fixes in the generic side as well)

I'm especially interested in testers with:

- Older codecs other than 0x1002aa01. My best guess still is that the
new code works on them as well.
o On these I'd like to know if multichannel and the new formats
work, i.e. e.g.
speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE

- Codec 0x1002aa01 revisions 0x100300 (Rev ID 3) or later (see
/proc/asound/cardX/codec#Y). These are HD7750+ I think. Stuff to be
tested on these:
o The ramp up/down stuff, i.e. patch 4. Is there any difference seen
with these, in the beginning/end (i.e. fade-out/in):
speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000
speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000
Also, is there a difference in the beginning of these
(maybe garbage sound and/or slightly slower startup?):
aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2 testi.dts.cut.spdif
aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2 testi.dts.cut.spdif

o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
both with radeon and with the proprietary fglrx driver in use

Olivier, can you test again on your rev3 hw? :)

The patchset can be found in combined form (for e.g. testing purposes) at:
http://onse.fi/files/atihdmi5.patch

The test file referenced above can be found at:
http://onse.fi/files/testi.dts.cut.spdif.gz (just regular DTS)

Anssi Hannula (4):
ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support
ALSA: hda - hdmi: Add ELD emulation for ATI/AMD codecs
ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs
ALSA: hda - hdmi: Disable ramp-up/down for non-PCM on AMD codecs

sound/pci/hda/hda_eld.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sound/pci/hda/hda_local.h | 5 +++
sound/pci/hda/patch_hdmi.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
3 files changed, 547 insertions(+), 39 deletions(-)

--
Anssi Hannula


2013-10-01 20:37:11

by Anssi Hannula

[permalink] [raw]
Subject: [PATCH 4/4] ALSA: hda - hdmi: Disable ramp-up/down for non-PCM on AMD codecs

Recent AMD HDMI codecs (revision ID 3 and later, 0x100300 as reported by
procfs codec#0) have a configurable ramp-up/down functionality.

The documentation ( http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf )
specifies that 180 (meaning 180/256 =~ 0.7) is recommended for PCM and 0
for non-PCM.

Apply the recommended values according to provided S/PDIF AES0 settings.

Signed-off-by: Anssi Hannula <[email protected]>
---
sound/pci/hda/patch_hdmi.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index c0cd4ca..22f30fe 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2673,6 +2673,10 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
#define ATI_VERB_GET_MULTICHANNEL_7 0xf88
#define ATI_VERB_GET_MULTICHANNEL_MODE 0xf89

+/* AMD specific HDA cvt verbs */
+#define ATI_VERB_SET_RAMP_RATE 0x770
+#define ATI_VERB_GET_RAMP_RATE 0xf70
+
#define ATI_OUT_ENABLE 0x1

#define ATI_HBR_CAPABLE 0x01
@@ -2824,6 +2828,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
unsigned int format,
struct snd_pcm_substream *substream)
{
+ hda_nid_t cvt_nid = hinfo->nid;
struct hdmi_spec *spec = codec->spec;
int pin_idx = hinfo_to_pin_index(spec, hinfo);
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
@@ -2853,6 +2858,15 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
return -EINVAL;
}

+ if (is_amdhdmi_rev3(codec)) {
+ int ramp_rate = 180; /* default as per spec */
+ /* disable ramp-up/down for non-pcm as per spec */
+ if (format & AC_FMT_TYPE_NON_PCM)
+ ramp_rate = 0;
+
+ snd_hda_codec_write(codec, cvt_nid, 0, ATI_VERB_SET_RAMP_RATE, ramp_rate);
+ }
+
return generic_hdmi_playback_pcm_prepare(hinfo, codec, stream_tag, format, substream);
}

--
1.8.1.5

2013-10-01 20:39:16

by Anssi Hannula

[permalink] [raw]
Subject: [PATCH 2/4] ALSA: hda - hdmi: Add ELD emulation for ATI/AMD codecs

ATI/AMD HDMI/DP codecs do not include standard HDA ELD (EDID-like data)
support.

In place of providing access to an ELD buffer, various vendor-specific
verbs are provided to provide the relevant information. Revision ID 3
and later (0x100300 as reported by procfs codec#X) have support for
providing more information than the previous revisions (but only if
supported by the display driver).

Generate ELD from the information provided by the vendor-specific verbs
on ATI/AMD codecs.

The specification is available at:
http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf

Signed-off-by: Anssi Hannula <[email protected]>
Tested-by: Peter Frühberger <[email protected]>
---
sound/pci/hda/hda_eld.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 157 insertions(+)

diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index d0d7ac1e..750841e 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -2,6 +2,7 @@
* Generic routines and proc interface for ELD(EDID Like Data) information
*
* Copyright(c) 2008 Intel Corporation.
+ * Copyright (c) 2013 Anssi Hannula <[email protected]>
*
* Authors:
* Wu Fengguang <[email protected]>
@@ -316,6 +317,9 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
AC_DIPSIZE_ELD_BUF);
}

+static int atihdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char *buf, int *eld_size);
+
int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
unsigned char *buf, int *eld_size)
{
@@ -323,6 +327,9 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
int ret = 0;
int size;

+ if (is_atihdmi(codec))
+ return atihdmi_get_eld(codec, nid, buf, eld_size);
+
/*
* ELD size is initialized to zero in caller function. If no errors and
* ELD is valid, actual eld_size is assigned.
@@ -671,3 +678,153 @@ void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
hinfo->maxbps = min(hinfo->maxbps, maxbps);
hinfo->channels_max = min(hinfo->channels_max, channels_max);
}
+
+
+/* ATI/AMD specific stuff (ELD emulation) */
+
+#define ATI_VERB_SET_AUDIO_DESCRIPTOR 0x776
+#define ATI_VERB_SET_SINK_INFO_INDEX 0x780
+#define ATI_VERB_GET_SPEAKER_ALLOCATION 0xf70
+#define ATI_VERB_GET_AUDIO_DESCRIPTOR 0xf76
+#define ATI_VERB_GET_AUDIO_VIDEO_DELAY 0xf7b
+#define ATI_VERB_GET_SINK_INFO_INDEX 0xf80
+#define ATI_VERB_GET_SINK_INFO_DATA 0xf81
+
+#define ATI_SPKALLOC_SPKALLOC 0x007f
+#define ATI_SPKALLOC_TYPE_HDMI 0x0100
+#define ATI_SPKALLOC_TYPE_DISPLAYPORT 0x0200
+
+/* first three bytes are just standard SAD */
+#define ATI_AUDIODESC_CHANNELS 0x00000007
+#define ATI_AUDIODESC_RATES 0x0000ff00
+#define ATI_AUDIODESC_LPCM_STEREO_RATES 0xff000000
+
+/* in standard HDMI VSDB format */
+#define ATI_DELAY_VIDEO_LATENCY 0x000000ff
+#define ATI_DELAY_AUDIO_LATENCY 0x0000ff00
+
+enum ati_sink_info_idx {
+ ATI_INFO_IDX_MANUFACTURER_ID = 0,
+ ATI_INFO_IDX_PRODUCT_ID = 1,
+ ATI_INFO_IDX_SINK_DESC_LEN = 2,
+ ATI_INFO_IDX_PORT_ID_LOW = 3,
+ ATI_INFO_IDX_PORT_ID_HIGH = 4,
+ ATI_INFO_IDX_SINK_DESC_FIRST = 5,
+ ATI_INFO_IDX_SINK_DESC_LAST = 22, /* max len 18 bytes */
+};
+
+static int atihdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
+ unsigned char *buf, int *eld_size)
+{
+ int spkalloc, ati_sad, aud_synch;
+ int sink_desc_len = 0;
+ int pos, i;
+
+ /* ATI/AMD does not have ELD, emulate it */
+
+ spkalloc = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SPEAKER_ALLOCATION, 0);
+
+ if (!spkalloc) {
+ snd_printd(KERN_INFO "HDMI ATI/AMD: no speaker allocation for ELD\n");
+ return -EINVAL;
+ }
+
+ memset(buf, 0, ELD_FIXED_BYTES + ELD_MAX_MNL + ELD_MAX_SAD * 3);
+
+ /* version */
+ buf[0] = ELD_VER_CEA_861D << 3;
+
+ /* speaker allocation from EDID */
+ buf[7] = spkalloc & ATI_SPKALLOC_SPKALLOC;
+
+ /* is DisplayPort? */
+ if (spkalloc & ATI_SPKALLOC_TYPE_DISPLAYPORT)
+ buf[5] |= 0x04;
+
+ pos = ELD_FIXED_BYTES;
+
+ if (is_amdhdmi_rev3(codec)) {
+ int sink_info;
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PORT_ID_LOW);
+ sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+ put_unaligned_le32(sink_info, buf + 8);
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PORT_ID_HIGH);
+ sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+ put_unaligned_le32(sink_info, buf + 12);
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_MANUFACTURER_ID);
+ sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+ put_unaligned_le16(sink_info, buf + 16);
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_PRODUCT_ID);
+ sink_info = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+ put_unaligned_le16(sink_info, buf + 18);
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_SINK_DESC_LEN);
+ sink_desc_len = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+
+ if (sink_desc_len > ELD_MAX_MNL) {
+ snd_printd(KERN_INFO "HDMI ATI/AMD: Truncating HDMI sink description with length %d\n",
+ sink_desc_len);
+ sink_desc_len = ELD_MAX_MNL;
+ }
+
+ buf[4] |= sink_desc_len;
+
+ for (i = 0; i < sink_desc_len; i++) {
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_SINK_INFO_INDEX, ATI_INFO_IDX_SINK_DESC_FIRST + i);
+ buf[pos++] = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_SINK_INFO_DATA, 0);
+ }
+ }
+
+ for (i = AUDIO_CODING_TYPE_LPCM; i <= AUDIO_CODING_TYPE_WMAPRO; i++) {
+ if (i == AUDIO_CODING_TYPE_SACD || i == AUDIO_CODING_TYPE_DST)
+ continue; /* not handled by ATI/AMD */
+
+ snd_hda_codec_write(codec, nid, 0, ATI_VERB_SET_AUDIO_DESCRIPTOR, i << 3);
+ ati_sad = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_DESCRIPTOR, 0);
+
+ if (ati_sad & ATI_AUDIODESC_RATES) {
+ /* format is supported, copy SAD as-is */
+ buf[pos++] = (ati_sad & 0x0000ff) >> 0;
+ buf[pos++] = (ati_sad & 0x00ff00) >> 8;
+ buf[pos++] = (ati_sad & 0xff0000) >> 16;
+ }
+
+ if (i == AUDIO_CODING_TYPE_LPCM
+ && (ati_sad & ATI_AUDIODESC_LPCM_STEREO_RATES)
+ && (ati_sad & ATI_AUDIODESC_LPCM_STEREO_RATES) >> 16 != (ati_sad & ATI_AUDIODESC_RATES)) {
+ /* for PCM there is a separate stereo rate mask */
+ buf[pos++] = ((ati_sad & 0x000000ff) & ~ATI_AUDIODESC_CHANNELS) | 0x1;
+ /* rates from the extra byte */
+ buf[pos++] = (ati_sad & 0xff000000) >> 24;
+ buf[pos++] = (ati_sad & 0x00ff0000) >> 16;
+ }
+ }
+
+ if (pos == ELD_FIXED_BYTES + sink_desc_len) {
+ snd_printd(KERN_INFO "HDMI ATI/AMD: no audio descriptors for ELD\n");
+ return -EINVAL;
+ }
+
+ aud_synch = snd_hda_codec_read(codec, nid, 0, ATI_VERB_GET_AUDIO_VIDEO_DELAY, 0);
+ if ((aud_synch & ATI_DELAY_VIDEO_LATENCY) && (aud_synch & ATI_DELAY_AUDIO_LATENCY)) {
+ int video_latency = (aud_synch & ATI_DELAY_VIDEO_LATENCY) - 1;
+ int audio_latency = ((aud_synch & ATI_DELAY_AUDIO_LATENCY) >> 8) - 1;
+
+ if (video_latency > audio_latency)
+ buf[6] = min(video_latency - audio_latency, 0xfa);
+ }
+
+ /* Baseline length */
+ buf[2] = pos - 4;
+
+ /* SAD count */
+ buf[5] |= ((pos - ELD_FIXED_BYTES - sink_desc_len) / 3) << 4;
+
+ *eld_size = pos;
+
+ return 0;
+}
--
1.8.1.5

2013-10-01 20:39:19

by Anssi Hannula

[permalink] [raw]
Subject: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

ATI/AMD codecs do not support all the standard HDA HDMI/DP functions,
instead various vendor-specific verbs are provided.

This commit addresses these missing functions:
- standard channel mapping support
- standard infoframe configuration support

ATI/AMD provides their own verbs that allow the following:
- setting CA for infoframe
- setting down-mix information for infoframe
- channel pair remapping
- individual channel remapping (revision ID 3+, 0x100300+)

The documentation for the verbs has now been released by AMD:
http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf

Add support for the ATI/AMD specific verbs and use them instead of the
generic methods on ATI/AMD codecs. This allows multi-channel PCM audio
to work.

Channel remapping is restricted to pairwise mapping on codecs with
revision ID 2 (0x100200 as reported by procfs codec#X) or lower. This
means cards up to Radeon HD7670 as far as I know. This will not affect
standard multi-channel modes since these codecs support automatic
FC-LFE swapping for HDMI.

ATI/AMD codecs do not advertise all of their supported rates, formats
and channel counts, therefore that information is forced accordingly so
that all HDMI 1.x PCM parameters are marked as supported.

Support for multiple ports is also added to patch_atihdmi so that
0x1002aa01 codecs with multiple ports will work properly when switched
back to that patch.

Signed-off-by: Anssi Hannula <[email protected]>
Tested-by: Peter Frühberger <[email protected]>
---
sound/pci/hda/hda_local.h | 5 +
sound/pci/hda/patch_hdmi.c | 355 +++++++++++++++++++++++++++++++++++++++------
2 files changed, 317 insertions(+), 43 deletions(-)

diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 2e7493e..7c0b89e 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -786,4 +786,9 @@ static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);

+/* shared with patch_hdmi.c and hda_eld.c */
+#define is_atihdmi(codec) (((codec)->vendor_id & 0xffff0000) == 0x10020000)
+#define is_amdhdmi_rev3(codec) \
+ ((codec)->vendor_id == 0x1002791a && ((codec)->revision_id & 0xff00) >= 0x0300)
+
#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 3d8cd044..19adb01 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -6,6 +6,7 @@
* Copyright (c) 2006 ATI Technologies Inc.
* Copyright (c) 2008 NVIDIA Corp. All rights reserved.
* Copyright (c) 2008 Wei Ni <[email protected]>
+ * Copyright (c) 2013 Anssi Hannula <[email protected]>
*
* Authors:
* Wu Fengguang <[email protected]>
@@ -46,6 +47,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");

#define is_haswell(codec) ((codec)->vendor_id == 0x80862807)

+/* is_atihdmi() and is_amdhdmi_rev3() are in hda_local.h */
+#define has_amd_full_remap_support(codec) is_amdhdmi_rev3(codec)
+
struct hdmi_spec_per_cvt {
hda_nid_t cvt_nid;
int assigned;
@@ -89,7 +93,7 @@ struct hdmi_spec {

struct hdmi_eld temp_eld;
/*
- * Non-generic ATI/NVIDIA specific
+ * Non-generic VIA/NVIDIA specific
*/
struct hda_multi_out multiout;
struct hda_pcm_stream pcm_playback;
@@ -573,6 +577,20 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
return ca;
}

+#ifdef CONFIG_SND_DEBUG_VERBOSE
+static int atihdmi_get_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid, int asp_slot);
+
+static int hdmi_get_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid, int asp_slot)
+{
+ if (is_atihdmi(codec))
+ return atihdmi_get_chan_slot(codec, pin_nid, asp_slot);
+
+ return snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_CHAN_SLOT,
+ asp_slot);
+}
+#endif
+
static void hdmi_debug_channel_mapping(struct hda_codec *codec,
hda_nid_t pin_nid)
{
@@ -581,14 +599,26 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
int slot;

for (i = 0; i < 8; i++) {
- slot = snd_hda_codec_read(codec, pin_nid, 0,
- AC_VERB_GET_HDMI_CHAN_SLOT, i);
+ slot = hdmi_get_chan_slot(codec, pin_nid, i);
printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
slot >> 4, slot & 0xf);
}
#endif
}

+static int atihdmi_set_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid,
+ int chanslot_setup);
+
+static int hdmi_set_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid,
+ int chanslot_setup)
+{
+ if (is_atihdmi(codec))
+ return atihdmi_set_chan_slot(codec, pin_nid, chanslot_setup);
+
+ return snd_hda_codec_write(codec, pin_nid, 0,
+ AC_VERB_SET_HDMI_CHAN_SLOT,
+ chanslot_setup);
+}

static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
hda_nid_t pin_nid,
@@ -617,9 +647,8 @@ static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
}

for (i = 0; i < 8; i++) {
- err = snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT,
- non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]);
+ err = hdmi_set_chan_slot(codec, pin_nid,
+ non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]);
if (err) {
snd_printdd(KERN_NOTICE
"HDMI: channel mapping failed\n");
@@ -728,8 +757,7 @@ static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
else
val = 0xf;
val |= (i << 4);
- err = snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT, val);
+ err = hdmi_set_chan_slot(codec, pin_nid, val);
if (err)
return -EINVAL;
}
@@ -883,6 +911,8 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
return true;
}

+static void atihdmi_set_ca(struct hda_codec *codec, hda_nid_t pin_nid, int ca);
+
static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
struct hdmi_spec_per_pin *per_pin,
bool non_pcm)
@@ -912,6 +942,16 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
if (ca < 0)
ca = 0;

+ if (is_atihdmi(codec)) {
+ /* for ATI/AMD we just want to map channels and set ca */
+ hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+ channels, per_pin->chmap,
+ per_pin->chmap_set);
+ atihdmi_set_ca(codec, pin_nid, ca);
+ per_pin->non_pcm = non_pcm;
+ return;
+ }
+
memset(&ai, 0, sizeof(ai));
if (eld->info.conn_type == 0) { /* HDMI */
struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
@@ -1603,6 +1643,8 @@ static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
return 0;
}

+static int atihdmi_swap_fc_lfe(int pos);
+
static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *tlv)
{
@@ -1613,6 +1655,10 @@ static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
FL | FR | RL | RR | LFE | FC | RLC | RRC;
unsigned int __user *dst;
int chs, count = 0;
+ int tlv_type = SNDRV_CTL_TLVT_CHMAP_VAR;
+
+ if (is_atihdmi(codec) && !has_amd_full_remap_support(codec))
+ tlv_type = SNDRV_CTL_TLVT_CHMAP_PAIRED;

if (size < 8)
return -ENOMEM;
@@ -1620,19 +1666,35 @@ static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
return -EFAULT;
size -= 8;
dst = tlv + 2;
- for (chs = 2; chs <= spec->channels_max; chs++) {
+ for (chs = 2; chs <= spec->channels_max;
+ chs += (tlv_type == SNDRV_CTL_TLVT_CHMAP_PAIRED) ? 2 : 1) {
int i, c;
struct cea_channel_speaker_allocation *cap;
cap = channel_allocations;
for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
int chs_bytes = chs * 4;
- if (cap->channels != chs)
+
+ if (tlv_type == SNDRV_CTL_TLVT_CHMAP_PAIRED) {
+ int chanpairs = 0;
+ /* in paired mode we need to take into account
+ * the occupied channel pairs instead of just the
+ * channel count */
+ for (c = 0; c < 7; c += 2) {
+ if (cap->speakers[c] || cap->speakers[c+1])
+ chanpairs++;
+ }
+ if (chanpairs * 2 != chs)
+ continue;
+
+ } else if (cap->channels != chs)
continue;
+
if (cap->spk_mask & ~valid_mask)
continue;
if (size < 8)
return -ENOMEM;
- if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) ||
+
+ if (put_user(tlv_type, dst) ||
put_user(chs_bytes, dst + 1))
return -EFAULT;
dst += 2;
@@ -1643,10 +1705,27 @@ static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
size -= chs_bytes;
count += chs_bytes;
for (c = 7; c >= 0; c--) {
- int spk = cap->speakers[c];
- if (!spk)
- continue;
- if (put_user(spk_to_chmap(spk), dst))
+ int spk;
+ int chan = c;
+ int chpos;
+
+ if (tlv_type == SNDRV_CTL_TLVT_CHMAP_PAIRED)
+ chan = 7 - atihdmi_swap_fc_lfe(7 - chan);
+
+ spk = cap->speakers[chan];
+ if (spk)
+ chpos = spk_to_chmap(spk);
+ else {
+ /* We need to reserve an N/A channel in paired mode
+ * if the companion channel is occupied. */
+ if (tlv_type == SNDRV_CTL_TLVT_CHMAP_PAIRED
+ && cap->speakers[chan + (chan % 2 ? -1 : 1)])
+ chpos = SNDRV_CHMAP_NA;
+ else
+ continue;
+ }
+
+ if (put_user(chpos, dst))
return -EFAULT;
dst++;
}
@@ -1672,6 +1751,18 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}

+static int atihdmi_pairwise_chmap_check_order(struct hda_codec *codec, int ca,
+ int chs, unsigned char *map);
+
+static int hdmi_chmap_check_order(struct hda_codec *codec, int ca,
+ int chs, unsigned char *map)
+{
+ if (is_atihdmi(codec) && !has_amd_full_remap_support(codec))
+ return atihdmi_pairwise_chmap_check_order(codec, ca, chs, map);
+
+ return 0; /* anything can be remapped as needed */
+}
+
static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1683,7 +1774,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
unsigned int ctl_idx;
struct snd_pcm_substream *substream;
unsigned char chmap[8];
- int i, ca, prepared = 0;
+ int i, err, ca, prepared = 0;

ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
substream = snd_pcm_chmap_substream(info, ctl_idx);
@@ -1707,6 +1798,9 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
if (ca < 0)
return -EINVAL;
+ err = hdmi_chmap_check_order(codec, ca, ARRAY_SIZE(chmap), chmap);
+ if (err < 0)
+ return -EINVAL;
per_pin->chmap_set = true;
memcpy(per_pin->chmap, chmap, sizeof(chmap));
if (prepared)
@@ -2551,48 +2645,223 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)

/*
* ATI-specific implementations
- *
- * FIXME: we may omit the whole this and use the generic code once after
- * it's confirmed to work.
*/

-#define ATIHDMI_CVT_NID 0x02 /* audio converter */
-#define ATIHDMI_PIN_NID 0x03 /* HDMI output pin */
+/* ATI/AMD specific HDA pin verbs, see the AMD HDA Verbs specification */
+#define ATI_VERB_SET_CHANNEL_ALLOCATION 0x771
+#define ATI_VERB_SET_DOWNMIX_INFO 0x772
+#define ATI_VERB_SET_MULTICHANNEL_01 0x777
+#define ATI_VERB_SET_MULTICHANNEL_23 0x778
+#define ATI_VERB_SET_MULTICHANNEL_45 0x779
+#define ATI_VERB_SET_MULTICHANNEL_67 0x77a
+#define ATI_VERB_SET_MULTICHANNEL_1 0x785
+#define ATI_VERB_SET_MULTICHANNEL_3 0x786
+#define ATI_VERB_SET_MULTICHANNEL_5 0x787
+#define ATI_VERB_SET_MULTICHANNEL_7 0x788
+#define ATI_VERB_SET_MULTICHANNEL_MODE 0x789
+#define ATI_VERB_GET_CHANNEL_ALLOCATION 0xf71
+#define ATI_VERB_GET_DOWNMIX_INFO 0xf72
+#define ATI_VERB_GET_MULTICHANNEL_01 0xf77
+#define ATI_VERB_GET_MULTICHANNEL_23 0xf78
+#define ATI_VERB_GET_MULTICHANNEL_45 0xf79
+#define ATI_VERB_GET_MULTICHANNEL_67 0xf7a
+#define ATI_VERB_GET_MULTICHANNEL_1 0xf85
+#define ATI_VERB_GET_MULTICHANNEL_3 0xf86
+#define ATI_VERB_GET_MULTICHANNEL_5 0xf87
+#define ATI_VERB_GET_MULTICHANNEL_7 0xf88
+#define ATI_VERB_GET_MULTICHANNEL_MODE 0xf89
+
+#define ATI_OUT_ENABLE 0x1
+
+static void atihdmi_set_ca(struct hda_codec *codec, hda_nid_t pin_nid, int ca)
+{
+ printk("ATI: setting ca %d\n", ca);
+ snd_hda_codec_write(codec, pin_nid, 0, ATI_VERB_SET_CHANNEL_ALLOCATION, ca);
+}
+
+static int atihdmi_swap_fc_lfe(int pos)
+{
+ /*
+ * Older ATI/AMD without channel-wise mapping
+ * have automatic FC/LFE swap built-in.
+ */
+
+ switch (pos) {
+ /* see channel_allocations[].speakers[] */
+ case 2: return 3;
+ case 3: return 2;
+ default: break;
+ }
+
+ return pos;
+}

-static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
- struct snd_pcm_substream *substream)
+static int atihdmi_pairwise_chmap_check_order(struct hda_codec *codec, int ca,
+ int chs, unsigned char *map)
+{
+ struct cea_channel_speaker_allocation *cap;
+ int i, j;
+
+ /* check that only channel pairs need to be remapped on old ATI/AMD */
+
+ cap = &channel_allocations[get_channel_allocation_order(ca)];
+ for (i = 0; i < chs; ++i) {
+ int mask = to_spk_mask(map[i]);
+ bool ok = false;
+ bool companion_ok = false;
+
+ if (!mask)
+ continue;
+
+ for (j = 0 + i % 2; j < 8; j += 2) {
+ int chan_idx = 7 - atihdmi_swap_fc_lfe(j);
+ if (cap->speakers[chan_idx] == mask) {
+ /* channel is in a supported position */
+ ok = true;
+
+ if (i % 2 == 0 && i + 1 < chs) {
+ /* even channel, check the odd companion */
+ int comp_chan_idx = 7 - atihdmi_swap_fc_lfe(j + 1);
+ int comp_mask_req = to_spk_mask(map[i+1]);
+ int comp_mask_act = cap->speakers[comp_chan_idx];
+
+ if (comp_mask_req == comp_mask_act)
+ companion_ok = true;
+ else
+ return -EINVAL;
+ }
+ break;
+ }
+ }
+
+ if (!ok)
+ return -EINVAL;
+
+ if (companion_ok)
+ i++; /* companion channel already checked */
+ }
+
+ return 0;
+}
+
+static int atihdmi_set_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid,
+ int chanslot_setup)
+{
+ int hdmi_slot = chanslot_setup & 0xf;
+ int stream_channel = chanslot_setup >> 4;
+ int verb;
+ int ati_channel_setup = 0;
+
+ if (hdmi_slot > 7)
+ return -EINVAL;
+
+ if (!has_amd_full_remap_support(codec)) {
+ hdmi_slot = atihdmi_swap_fc_lfe(hdmi_slot);
+
+ /* In case this is an odd slot but without stream channel, do not
+ * disable the slot since the corresponding even slot could have a
+ * channel. In case neither have a channel, the slot pair will be
+ * disabled when this function is called for the even slot. */
+ if (hdmi_slot % 2 != 0 && stream_channel == 0xf)
+ return 0;
+
+ hdmi_slot -= hdmi_slot % 2;
+
+ if (stream_channel != 0xf)
+ stream_channel -= stream_channel % 2;
+ }
+
+ verb = ATI_VERB_SET_MULTICHANNEL_01 + hdmi_slot/2 + (hdmi_slot % 2) * 0x00e;
+
+ /* ati_channel_setup format: [7..4] = stream_channel_id, [1] = mute, [0] = enable */
+
+ if (stream_channel != 0xf)
+ ati_channel_setup = (stream_channel << 4) | ATI_OUT_ENABLE;
+
+ return snd_hda_codec_write(codec, pin_nid, 0, verb, ati_channel_setup);
+}
+
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+static int atihdmi_get_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid, int asp_slot)
+{
+ bool was_odd = false;
+ int ati_asp_slot = asp_slot;
+ int verb;
+ int ati_channel_setup;
+
+ /* emulate AC_VERB_GET_HDMI_CHAN_SLOT */
+
+ if (asp_slot > 7)
+ return -EINVAL;
+
+ if (!has_amd_full_remap_support(codec)) {
+ ati_asp_slot = atihdmi_swap_fc_lfe(asp_slot);
+ if (ati_asp_slot % 2 != 0) {
+ ati_asp_slot -= 1;
+ was_odd = true;
+ }
+ }
+
+ verb = ATI_VERB_GET_MULTICHANNEL_01 + ati_asp_slot/2 + (ati_asp_slot % 2) * 0x00e;
+
+ ati_channel_setup = snd_hda_codec_read(codec, pin_nid, 0, verb, 0);
+
+ if (!(ati_channel_setup & ATI_OUT_ENABLE))
+ return (0xf << 4) | asp_slot;
+
+ return ((ati_channel_setup & 0xf0) + ((!!was_odd) << 4)) | asp_slot;
+}
+#endif
+
+static int atihdmi_init(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
- struct hdmi_spec_per_cvt *per_cvt = get_cvt(spec, 0);
- int chans = substream->runtime->channels;
- int i, err;
+ int pin_idx, err;

- err = simple_playback_pcm_prepare(hinfo, codec, stream_tag, format,
- substream);
- if (err < 0)
+ err = generic_hdmi_init(codec);
+
+ if (err)
return err;
- snd_hda_codec_write(codec, per_cvt->cvt_nid, 0,
- AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
- /* FIXME: XXX */
- for (i = 0; i < chans; i++) {
- snd_hda_codec_write(codec, per_cvt->cvt_nid, 0,
- AC_VERB_SET_HDMI_CHAN_SLOT,
- (i << 4) | i);
+
+ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+
+ /* make sure downmix information in infoframe is zero */
+ snd_hda_codec_write(codec, per_pin->pin_nid, 0, ATI_VERB_SET_DOWNMIX_INFO, 0);
+
+ /* enable channel-wise remap mode if supported */
+ if (has_amd_full_remap_support(codec))
+ snd_hda_codec_write(codec, per_pin->pin_nid, 0, ATI_VERB_SET_MULTICHANNEL_MODE, 1);
}
+
return 0;
}

static int patch_atihdmi(struct hda_codec *codec)
{
struct hdmi_spec *spec;
- int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID);
- if (err < 0)
+ struct hdmi_spec_per_cvt *per_cvt;
+ int err, cvt_idx;
+
+ err = patch_generic_hdmi(codec);
+
+ if (err)
return err;
+
+ codec->patch_ops.init = atihdmi_init;
+
+ /* ATI/AMD converters do not advertise all of their capabilities */
spec = codec->spec;
- spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare;
+ for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
+ per_cvt = get_cvt(spec, cvt_idx);
+ per_cvt->channels_max = max(per_cvt->channels_max, 8u);
+ per_cvt->rates |= SUPPORTED_RATES;
+ per_cvt->formats |= SUPPORTED_FORMATS;
+ per_cvt->maxbps = max(per_cvt->maxbps, 24u);
+ }
+
+ spec->channels_max = max(spec->channels_max, 8u);
+
return 0;
}

@@ -2612,7 +2881,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
-{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
+{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
--
1.8.1.5

2013-10-01 20:42:09

by Anssi Hannula

[permalink] [raw]
Subject: [PATCH 3/4] ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs

ATI/AMD HDMI codecs do not include standard HDA HDMI HBR support (which
is required for bitstreaming DTS-HD and Dolby TrueHD), instead they have
custom verbs for checking and enabling it.

Add support for the ATI/AMD HDMI HBR verbs.

The specification is available at:
http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf

Signed-off-by: Anssi Hannula <[email protected]>
Tested-by: Peter Frühberger <[email protected]>
---
sound/pci/hda/patch_hdmi.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 64 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 19adb01..c0cd4ca 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -1140,7 +1140,7 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
new_pinctl);

}
- if (is_hbr_format(format) && !new_pinctl) {
+ if (is_hbr_format(format) && !new_pinctl && !is_atihdmi(codec)) {
snd_printdd("hdmi_setup_stream: HBR is not supported\n");
return -EINVAL;
}
@@ -2654,6 +2654,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
#define ATI_VERB_SET_MULTICHANNEL_23 0x778
#define ATI_VERB_SET_MULTICHANNEL_45 0x779
#define ATI_VERB_SET_MULTICHANNEL_67 0x77a
+#define ATI_VERB_SET_HBR_CONTROL 0x77c
#define ATI_VERB_SET_MULTICHANNEL_1 0x785
#define ATI_VERB_SET_MULTICHANNEL_3 0x786
#define ATI_VERB_SET_MULTICHANNEL_5 0x787
@@ -2665,6 +2666,7 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
#define ATI_VERB_GET_MULTICHANNEL_23 0xf78
#define ATI_VERB_GET_MULTICHANNEL_45 0xf79
#define ATI_VERB_GET_MULTICHANNEL_67 0xf7a
+#define ATI_VERB_GET_HBR_CONTROL 0xf7c
#define ATI_VERB_GET_MULTICHANNEL_1 0xf85
#define ATI_VERB_GET_MULTICHANNEL_3 0xf86
#define ATI_VERB_GET_MULTICHANNEL_5 0xf87
@@ -2673,6 +2675,9 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)

#define ATI_OUT_ENABLE 0x1

+#define ATI_HBR_CAPABLE 0x01
+#define ATI_HBR_ENABLE 0x10
+
static void atihdmi_set_ca(struct hda_codec *codec, hda_nid_t pin_nid, int ca)
{
printk("ATI: setting ca %d\n", ca);
@@ -2813,6 +2818,63 @@ static int atihdmi_get_chan_slot(struct hda_codec *codec, hda_nid_t pin_nid, int
}
#endif

+static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
+ struct snd_pcm_substream *substream)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int pin_idx = hinfo_to_pin_index(spec, hinfo);
+ struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
+ hda_nid_t pin_nid = per_pin->pin_nid;
+ int hbr_ctl, hbr_ctl_new;
+
+ hbr_ctl = snd_hda_codec_read(codec, pin_nid, 0, ATI_VERB_GET_HBR_CONTROL, 0);
+ if (hbr_ctl & ATI_HBR_CAPABLE) {
+ if (is_hbr_format(format))
+ hbr_ctl_new = hbr_ctl | ATI_HBR_ENABLE;
+ else
+ hbr_ctl_new = hbr_ctl & ~ATI_HBR_ENABLE;
+
+ snd_printdd("atihdmi_playback_pcm_prepare: "
+ "NID=0x%x, %shbr-ctl=0x%x\n",
+ pin_nid,
+ hbr_ctl == hbr_ctl_new ? "" : "new-",
+ hbr_ctl_new);
+
+ if (hbr_ctl != hbr_ctl_new)
+ snd_hda_codec_write(codec, pin_nid, 0,
+ ATI_VERB_SET_HBR_CONTROL,
+ hbr_ctl_new);
+
+ } else if (is_hbr_format(format)) {
+ snd_printdd("atihdmi_playback_pcm_prepare: HBR is not supported\n");
+ return -EINVAL;
+ }
+
+ return generic_hdmi_playback_pcm_prepare(hinfo, codec, stream_tag, format, substream);
+}
+
+static int atihdmi_build_pcms(struct hda_codec *codec)
+{
+ struct hdmi_spec *spec = codec->spec;
+ int err, pin_idx;
+
+ err = generic_hdmi_build_pcms(codec);
+
+ if (err)
+ return err;
+
+ for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+ struct hda_pcm *info = get_pcm_rec(spec, pin_idx);
+
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].ops.prepare = atihdmi_playback_pcm_prepare;
+ }
+
+ return 0;
+}
+
static int atihdmi_init(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
@@ -2849,6 +2911,7 @@ static int patch_atihdmi(struct hda_codec *codec)
return err;

codec->patch_ops.init = atihdmi_init;
+ codec->patch_ops.build_pcms = atihdmi_build_pcms;

/* ATI/AMD converters do not advertise all of their capabilities */
spec = codec->spec;
--
1.8.1.5

2013-10-02 14:31:39

by Takashi Iwai

[permalink] [raw]
Subject: Re: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

At Tue, 1 Oct 2013 23:30:52 +0300,
Anssi Hannula wrote:
>
> Hi all!
>
> Here is a second revision of the ATI/AMD multichannel patch, now a
> patchset.
>
> Since the last revision from a bit over the week ago, AMD has released
> more documentation ( http://www.x.org/docs/AMD/AMD_HDA_verbs_v2.pdf ),
> so the patchset contains new additions:
>
> - HBR bitstreaming support (HD passthrough, for DTS-HD and Dolby TrueHD)
> o This completes the set, now we have HBR on NVIDIA, Intel and AMD :)
>
> - More complete ELD emulation on revision 3+ (0x100300) codecs
> o Untested, though from what I can see the newly added fields may not
> be filled in yet by the radeon driver.
>
> - Ramp up/down configuration according to non-pcm bit on rev3+
> o I guess this means gradual fade-in/out? Untested.
>
> Other changes since the previous post:
> - ELD emulation moved to hda_eld.c and cleaned up a bit
> - Some fixes to hdmi_chmap_ctl_tlv() changes
> (and maybe something else I forgot - if so, sorry)
>
> Also, the pairwise channel mapping code has been tested to work with
> custom channel maps. The TLV contents are shown as follows by amixer:
> | chmap-paired=FL,FR
> | chmap-paired=FL,FR,NA,LFE
> | chmap-paired=FL,FR,FC,NA
> | chmap-paired=FL,FR,RL,RR
> | chmap-paired=FL,FR,FC,LFE
> | chmap-paired=FL,FR,NA,LFE,RL,RR
> | chmap-paired=FL,FR,FC,NA,RL,RR
> [etc]
>
> Rafał, do you know about the missing (AFAICS) support for lipsync (F7B)
> and sink information (F81) in radeon driver?
>
> This patchset requires at least more testing before it should be applied.
>
> A few other somewhat open things:
> - I named everything ati/ATI except for is_amdhdmi_rev3() and
> has_amd_full_remap_support() that are AMD-only, though AMD-only verbs
> I still named ATI to have similar names to other verbs. Does that
> seem sensible or how should this be done?
> - Currently setup_audio_infoframe() writes the channel mapping every
> time for ATI/AMD, should we try to avoid that? If so, any
> suggestions?
> (argh, just noticed this is broken for manual channel maps on non-ATI;
> if just the chmap is changed, channel mapping is not updated;
> so this requires fixes in the generic side as well)
>
> I'm especially interested in testers with:
>
> - Older codecs other than 0x1002aa01. My best guess still is that the
> new code works on them as well.
> o On these I'd like to know if multichannel and the new formats
> work, i.e. e.g.
> speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE
>
> - Codec 0x1002aa01 revisions 0x100300 (Rev ID 3) or later (see
> /proc/asound/cardX/codec#Y). These are HD7750+ I think. Stuff to be
> tested on these:
> o The ramp up/down stuff, i.e. patch 4. Is there any difference seen
> with these, in the beginning/end (i.e. fade-out/in):
> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000
> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000
> Also, is there a difference in the beginning of these
> (maybe garbage sound and/or slightly slower startup?):
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2 testi.dts.cut.spdif
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2 testi.dts.cut.spdif
>
> o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
> both with radeon and with the proprietary fglrx driver in use
>
> Olivier, can you test again on your rev3 hw? :)
>
> The patchset can be found in combined form (for e.g. testing purposes) at:
> http://onse.fi/files/atihdmi5.patch
>
> The test file referenced above can be found at:
> http://onse.fi/files/testi.dts.cut.spdif.gz (just regular DTS)
>
> Anssi Hannula (4):
> ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support
> ALSA: hda - hdmi: Add ELD emulation for ATI/AMD codecs
> ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs
> ALSA: hda - hdmi: Disable ramp-up/down for non-PCM on AMD codecs


The patches generally look good, but I'm thinking whether it's cleaner
to create a new ops items. Maybe it can be specific to HDMI codec,
e.g.

struct hda_hdmi_ops {
int (*get_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int slot);
int (*set_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int setup);
int (*set_ca)(struct hda_codec *codec, hda_nid_t pin, int ca);
....
}

It's not sexy to have a thing like is_atihdmi() in the common header
and see it in everywhere.


thanks,

Takashi

>
> sound/pci/hda/hda_eld.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> sound/pci/hda/hda_local.h | 5 +++
> sound/pci/hda/patch_hdmi.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
> 3 files changed, 547 insertions(+), 39 deletions(-)
>
> --
> Anssi Hannula
>

2013-10-02 16:51:31

by Anssi Hannula

[permalink] [raw]
Subject: Re: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

02.10.2013 17:34, Takashi Iwai kirjoitti:
> At Tue, 1 Oct 2013 23:30:52 +0300,
> Anssi Hannula wrote:
[...]
>> Anssi Hannula (4):
>> ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support
>> ALSA: hda - hdmi: Add ELD emulation for ATI/AMD codecs
>> ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs
>> ALSA: hda - hdmi: Disable ramp-up/down for non-PCM on AMD codecs
>
>
> The patches generally look good, but I'm thinking whether it's cleaner
> to create a new ops items. Maybe it can be specific to HDMI codec,
> e.g.
>
> struct hda_hdmi_ops {
> int (*get_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int slot);
> int (*set_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int setup);
> int (*set_ca)(struct hda_codec *codec, hda_nid_t pin, int ca);
> ....
> }
>
> It's not sexy to have a thing like is_atihdmi() in the common header
> and see it in everywhere.

OK, will do that for next version.

Regarding hda_eld.c, I guess I'll add struct hda_hdmi_ops to struct
hdmi_spec, then keep snd_hdmi_ati_get_eld() in hda_eld.c but make it
non-static, so I can assign the correct _get_eld in patch_hdmi.c?


P.S. I asked whether new callbacks should be added in the previous RFC
message, but I guess that was easy to overlook as the message was a bit
incoherent... :)

--
Anssi Hannula

> thanks,
>
> Takashi
>
>>
>> sound/pci/hda/hda_eld.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> sound/pci/hda/hda_local.h | 5 +++
>> sound/pci/hda/patch_hdmi.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
>> 3 files changed, 547 insertions(+), 39 deletions(-)
>>
>> --
>> Anssi Hannula
>>


--
Anssi Hannula

2013-10-04 07:32:55

by Olivier Langlois

[permalink] [raw]
Subject: Re: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

Anssi,

Your patch has been applied on 3.11.3


>
> I'm especially interested in testers with:
>
> - Older codecs other than 0x1002aa01. My best guess still is that the
> new code works on them as well.
> o On these I'd like to know if multichannel and the new formats
> work, i.e. e.g.
> speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE

This is working with Codec 0x1002aa01 revisions 0x100300 (Rev ID 3)
except for a small detail. I cannot tell if it is a regression from v1
of the patch or it was there and I did not noticed when I tested.

Rear left and rear right channels are flipped.

>
> - Codec 0x1002aa01 revisions 0x100300 (Rev ID 3) or later (see
> /proc/asound/cardX/codec#Y). These are HD7750+ I think. Stuff to be
> tested on these:
> o The ramp up/down stuff, i.e. patch 4. Is there any difference seen
> with these, in the beginning/end (i.e. fade-out/in):
> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000

No noticeable difference than when it is run without the AES0 param

> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000

>From the application the sound is sent normally but no sound at all is
outputed from the speakers.

> Also, is there a difference in the beginning of these
> (maybe garbage sound and/or slightly slower startup?):
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2 testi.dts.cut.spdif
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2 testi.dts.cut.spdif

Both works. No garbage is heard from neither of them. maybe maybe AES04
starts playing few ms earlier but if there is a difference, it is
extremely subtle.
>
> o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
> both with radeon and with the proprietary fglrx driver in use
>
With fglrx 13.10 Beta 2:

lano1106@whippet2 /proc/asound/card0 $ cat codec#0
Codec: ATI R6xx HDMI
Address: 0
AFG Function Id: 0x1 (unsol 0)
Vendor Id: 0x1002aa01
Subsystem Id: 0x00aa0100
Revision Id: 0x100300
No Modem Function Group found
Default PCM:
rates [0x70]: 32000 44100 48000
bits [0x2]: 16
formats [0x5]: PCM AC3
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
Power states: D0 D3 CLKSTOP EPSS
Power: setting=D0, actual=D0, Clock-stop-OK
GPIO: io=0, o=0, i=0, unsolicited=0, wake=0
Node 0x02 [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=1, channel=0
Digital: Enabled
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x03 [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=3 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=0, device=0
Control: name="IEC958 Playback Pro Mask", index=0, device=0
Control: name="IEC958 Playback Default", index=0, device=0
Control: name="IEC958 Playback Switch", index=0, device=0
Control: name="ELD", index=0, device=3
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=01, enabled=1
Connection: 1
0x02
Node 0x04 [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=0, channel=0
Digital:
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x05 [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=7 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=1, device=0
Control: name="IEC958 Playback Pro Mask", index=1, device=0
Control: name="IEC958 Playback Default", index=1, device=0
Control: name="IEC958 Playback Switch", index=1, device=0
Control: name="ELD", index=0, device=7
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=02, enabled=1
Connection: 1
0x04
Node 0x06 [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=0, channel=0
Digital:
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x07 [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=8 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=2, device=0
Control: name="IEC958 Playback Pro Mask", index=2, device=0
Control: name="IEC958 Playback Default", index=2, device=0
Control: name="IEC958 Playback Switch", index=2, device=0
Control: name="ELD", index=0, device=8
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=03, enabled=1
Connection: 1
0x06
Node 0x08 [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=0, channel=0
Digital:
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x09 [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=9 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=3, device=0
Control: name="IEC958 Playback Pro Mask", index=3, device=0
Control: name="IEC958 Playback Default", index=3, device=0
Control: name="IEC958 Playback Switch", index=3, device=0
Control: name="ELD", index=0, device=9
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=04, enabled=1
Connection: 1
0x08
Node 0x0a [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=0, channel=0
Digital:
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x0b [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=10 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=4, device=0
Control: name="IEC958 Playback Pro Mask", index=4, device=0
Control: name="IEC958 Playback Default", index=4, device=0
Control: name="IEC958 Playback Switch", index=4, device=0
Control: name="ELD", index=0, device=10
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=05, enabled=1
Connection: 1
0x0a
Node 0x0c [Audio Output] wcaps 0x221: Stereo Digital Stripe
Converter: stream=0, channel=0
Digital:
Digital category: 0x0
IEC Coding Type: 0x0
Node 0x0d [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=11 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=5, device=0
Control: name="IEC958 Playback Pro Mask", index=5, device=0
Control: name="IEC958 Playback Default", index=5, device=0
Control: name="IEC958 Playback Switch", index=5, device=0
Control: name="ELD", index=0, device=11
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x185600f0: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0xf, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=06, enabled=1
Connection: 1
0x0c

2013-10-04 23:40:00

by Anssi Hannula

[permalink] [raw]
Subject: Re: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

04.10.2013 10:06, Olivier Langlois kirjoitti:
> Anssi,
>
> Your patch has been applied on 3.11.3

OK.

>>
>> I'm especially interested in testers with:
>>
>> - Older codecs other than 0x1002aa01. My best guess still is that the
>> new code works on them as well.
>> o On these I'd like to know if multichannel and the new formats
>> work, i.e. e.g.
>> speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE
>
> This is working with Codec 0x1002aa01 revisions 0x100300 (Rev ID 3)
> except for a small detail. I cannot tell if it is a regression from v1
> of the patch or it was there and I did not noticed when I tested.
>
> Rear left and rear right channels are flipped.

Thanks for testing.

That seems a bit strange, I would've expected everything to be flipped
if there was a bug there.

Are you sure about that? Note that speaker-test speaker order is
reversed in the rear when compared to front, i.e. "front left, front
right, center, rear right, rear left", since it uses a circular pattern.

If you can confirm this, could you enable SND_CONFIG_DEBUG and
SND_CONFIG_DEBUG_VERBOSE and CONFIG_SND_VERBOSE_PRINTK, and then provide
the dmesg during playback?

Thanks.

>>
>> - Codec 0x1002aa01 revisions 0x100300 (Rev ID 3) or later (see
>> /proc/asound/cardX/codec#Y). These are HD7750+ I think. Stuff to be
>> tested on these:
>> o The ramp up/down stuff, i.e. patch 4. Is there any difference seen
>> with these, in the beginning/end (i.e. fade-out/in):
>> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000
>
> No noticeable difference than when it is run without the AES0 param
>
>> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000
>
> From the application the sound is sent normally but no sound at all is
> outputed from the speakers.
>
>> Also, is there a difference in the beginning of these
>> (maybe garbage sound and/or slightly slower startup?):
>> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2 testi.dts.cut.spdif
>> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2 testi.dts.cut.spdif
>
> Both works. No garbage is heard from neither of them. maybe maybe AES04
> starts playing few ms earlier but if there is a difference, it is
> extremely subtle.

OK, that is actually reverse what I would've expected.

Takashi, do you think we should add the ramp-up/down setting (to spec
recommended pcm/non-pcm values) anyway?

>>
>> o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
>> both with radeon and with the proprietary fglrx driver in use
>>
> With fglrx 13.10 Beta 2:
>
> lano1106@whippet2 /proc/asound/card0 $ cat codec#0

Note I said eld#0, not codec#0 :)

Though I guess the correct filename is actually eld#0.0.

[...]

--
Anssi Hannula

2013-10-06 03:55:41

by Olivier Langlois

[permalink] [raw]
Subject: Re: [alsa-devel] [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support


> >
> > Rear left and rear right channels are flipped.
>
> Thanks for testing.
>
> That seems a bit strange, I would've expected everything to be flipped
> if there was a bug there.
>
Anssi, you were right to be suspicious. The bug was in my wiring.
>
> >>
> >> o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
> >> both with radeon and with the proprietary fglrx driver in use
> >>
> > With fglrx 13.10 Beta 2:
> >
> > lano1106@whippet2 /proc/asound/card0 $ cat codec#0
>
> Note I said eld#0, not codec#0 :)
>
> Though I guess the correct filename is actually eld#0.0.
>
> [...]
>
My mistake.

Here is the good content:

monitor_present 1
eld_valid 1
monitor_name
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x0] no CEA EDID Timing Extension block present
manufacture_id 0x0
product_id 0x0
port_id 0x0
support_hdcp 0
support_ai 0
audio_sync_delay 0
speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
sad_count 7
sad0_coding_type [0x1] LPCM
sad0_channels 8
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x2] AC-3
sad1_channels 6
sad1_rates [0xe0] 32000 44100 48000
sad1_max_bitrate 640000
sad2_coding_type [0x7] DTS
sad2_channels 7
sad2_rates [0x6c0] 44100 48000 88200 96000
sad2_max_bitrate 1536000
sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad4_coding_type [0xb] DTS-HD
sad4_channels 8
sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad5_coding_type [0xc] MLP (Dolby TrueHD)
sad5_channels 8
sad5_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad6_coding_type [0xe] WMAPro
sad6_channels 8
sad6_rates [0x6e0] 32000 44100 48000 88200 96000
sad6_profile 3

2013-10-06 12:07:49

by Anssi Hannula

[permalink] [raw]
Subject: Re: [alsa-devel] [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

06.10.2013 06:48, Olivier Langlois kirjoitti:
>
>>>>
>>>> o Contents of /proc/asound/cardX/eld#0. I'd like to see the contents
>>>> both with radeon and with the proprietary fglrx driver in use
>>>>
>>> With fglrx 13.10 Beta 2:
>>>
>>> lano1106@whippet2 /proc/asound/card0 $ cat codec#0
>>
>> Note I said eld#0, not codec#0 :)
>>
>> Though I guess the correct filename is actually eld#0.0.
>>
>> [...]
>>
> My mistake.
>
> Here is the good content:
[...]

Does not look right. And after looking at the code I saw quite a big bug
which caused all of the rev3+ features to not work :)

Please change 0x1002791a to 0x1002aa01 in this part in the end of
sound/pci/hda/hda_local.h:

#define is_amdhdmi_rev3(codec) \
((codec)->vendor_id == 0x1002791a && ((codec)->revisi

Then please test everything again. I.e.
o speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE

o Is there any difference seen
with these, in the beginning/end (i.e. fade-out/in):
speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000
speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000

o Also, is there a difference in the beginning of these
(maybe garbage sound and/or slightly slower startup?):
aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2
testi.dts.cut.spdif
aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2
testi.dts.cut.spdif

o Contents of /proc/asound/cardX/eld#0.0

Thanks a lot :)

--
Anssi Hannula

2013-10-07 07:30:59

by Takashi Iwai

[permalink] [raw]
Subject: Re: [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support

At Wed, 02 Oct 2013 19:42:53 +0300,
Anssi Hannula wrote:
>
> 02.10.2013 17:34, Takashi Iwai kirjoitti:
> > At Tue, 1 Oct 2013 23:30:52 +0300,
> > Anssi Hannula wrote:
> [...]
> >> Anssi Hannula (4):
> >> ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support
> >> ALSA: hda - hdmi: Add ELD emulation for ATI/AMD codecs
> >> ALSA: hda - hdmi: Add HBR bitstreaming support for ATI/AMD HDMI codecs
> >> ALSA: hda - hdmi: Disable ramp-up/down for non-PCM on AMD codecs
> >
> >
> > The patches generally look good, but I'm thinking whether it's cleaner
> > to create a new ops items. Maybe it can be specific to HDMI codec,
> > e.g.
> >
> > struct hda_hdmi_ops {
> > int (*get_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int slot);
> > int (*set_chan_slot)(struct hda_codec *codec, hda_nid_t pin, int setup);
> > int (*set_ca)(struct hda_codec *codec, hda_nid_t pin, int ca);
> > ....
> > }
> >
> > It's not sexy to have a thing like is_atihdmi() in the common header
> > and see it in everywhere.
>
> OK, will do that for next version.
>
> Regarding hda_eld.c, I guess I'll add struct hda_hdmi_ops to struct
> hdmi_spec, then keep snd_hdmi_ati_get_eld() in hda_eld.c but make it
> non-static, so I can assign the correct _get_eld in patch_hdmi.c?

Yes, that'd be OK.

> P.S. I asked whether new callbacks should be added in the previous RFC
> message, but I guess that was easy to overlook as the message was a bit
> incoherent... :)

Oh, indeed :)


thanks,

Takashi

>
> --
> Anssi Hannula
>
> > thanks,
> >
> > Takashi
> >
> >>
> >> sound/pci/hda/hda_eld.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >> sound/pci/hda/hda_local.h | 5 +++
> >> sound/pci/hda/patch_hdmi.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
> >> 3 files changed, 547 insertions(+), 39 deletions(-)
> >>
> >> --
> >> Anssi Hannula
> >>
>
>
> --
> Anssi Hannula
>

2013-10-09 04:38:58

by Olivier Langlois

[permalink] [raw]
Subject: Re: [alsa-devel] [RFC/RFT v2 0/4] ALSA: hda - hdmi: ATI/AMD multi-channel and HBR support


>
> Then please test everything again. I.e.
> o speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S32_LE
>
this work fine

> o Is there any difference seen
> with these, in the beginning/end (i.e. fade-out/in):
> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x04 -c2 -r48000
> speaker-test -D hdmi:CARD=Generic,DEV=0,AES0=0x06 -c2 -r48000
>
I have the same result as before the last fix. AES0=0x04 works
AES0=0x06 doesn't. No error is emitted from speaker-test but no sound is
coming out speakers.

> o Also, is there a difference in the beginning of these
> (maybe garbage sound and/or slightly slower startup?):
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=4 -r44100 -f s16_le -c2
> testi.dts.cut.spdif
> aplay -Dhdmi:CARD=Generic,DEV=0,AES0=6 -r44100 -f s16_le -c2
> testi.dts.cut.spdif

no garbage. Maybe slightly slower startup with AES0=0x6.
>
> o Contents of /proc/asound/cardX/eld#0.0
>
> Thanks a lot :)
>
monitor_present 1
eld_valid 1
monitor_name SC-09TX
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x0] no CEA EDID Timing Extension block present
manufacture_id 0x2f41
product_id 0x0
port_id 0x10000000005
support_hdcp 0
support_ai 0
audio_sync_delay 0
speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
sad_count 7
sad0_coding_type [0x1] LPCM
sad0_channels 8
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x2] AC-3
sad1_channels 6
sad1_rates [0xe0] 32000 44100 48000
sad1_max_bitrate 640000
sad2_coding_type [0x7] DTS
sad2_channels 7
sad2_rates [0x6c0] 44100 48000 88200 96000
sad2_max_bitrate 1536000
sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad4_coding_type [0xb] DTS-HD
sad4_channels 8
sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad5_coding_type [0xc] MLP (Dolby TrueHD)
sad5_channels 8
sad5_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad6_coding_type [0xe] WMAPro
sad6_channels 8
sad6_rates [0x6e0] 32000 44100 48000 88200 96000
sad6_profile 3

2013-10-30 15:35:22

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

2013/10/1 Anssi Hannula <[email protected]>:
> ATI/AMD codecs do not support all the standard HDA HDMI/DP functions,
> instead various vendor-specific verbs are provided.

I've just tried my HD6970M (BARTS, DCE5) in my Samsung NP700G7A-S01PL.

> cat /proc/asound/card1/eld#0.0
monitor_present 1
eld_valid 1
monitor_name
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x0] no CEA EDID Timing Extension block present
manufacture_id 0x0
product_id 0x0
port_id 0x0
support_hdcp 0
support_ai 0
audio_sync_delay 0
speakers [0x5f] FL/FR LFE FC RL/RR RC RLC/RRC
sad_count 6
sad0_coding_type [0x1] LPCM
sad0_channels 8
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x2] AC-3
sad1_channels 6
sad1_rates [0xe0] 32000 44100 48000
sad1_max_bitrate 640000
sad2_coding_type [0x7] DTS
sad2_channels 6
sad2_rates [0x6c0] 44100 48000 88200 96000
sad2_max_bitrate 1536000
sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad4_coding_type [0xb] DTS-HD
sad4_channels 8
sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad5_coding_type [0xc] MLP (Dolby TrueHD)
sad5_channels 8
sad5_rates [0x1ec0] 44100 48000 88200 96000 176400 192000

Command:
speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S16_LE
works, I just have 5.1 (not 7.1), so Side left goes to the Read left
and Side right goes to the Rear right. But they were working!

Next I've used howto from
http://phoronix.com/forums/showthread.php?27348-TrueHD-DTS-HD-E-AC3-Over-HDMI-On-Linux
to test DTS MA and TrueHD.

In the file from howto I've used:
card Generic
and then tested:

zajec@linux-samsung700g7a:~> aplay -D hdmihdtest0 -c8 -fs16_le
-r192000 thd.spdif
Playing raw data 'thd.spdif' : Signed 16 bit Little Endian, Rate
192000 Hz, Channels 8
zajec@linux-samsung700g7a:~> aplay -D hdmihdtest0 -c8 -fs16_le
-r192000 dts.spdif
Playing raw data 'dts.spdif' : Signed 16 bit Little Endian, Rate
192000 Hz, Channels 8

Hooray! I got
DOLBY HD
and
DTS-HD MA
on my Denon 1912 display!

Now the main question... do you have any experience on using DTS-HD MA
(or TrueHD) with mplayer? :|

2013-10-30 15:59:11

by Anssi Hannula

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

Rafał Miłecki kirjoitti 2013-10-30 17:35:
> 2013/10/1 Anssi Hannula <[email protected]>:
> ATI/AMD codecs do not support all the standard HDA HDMI/DP functions,
> instead various vendor-specific verbs are provided.
>
> I've just tried my HD6970M (BARTS, DCE5) in my Samsung NP700G7A-S01PL.
>
> cat /proc/asound/card1/eld#0.0
> monitor_present 1
> eld_valid 1
> monitor_name
> connection_type HDMI
> eld_version [0x2] CEA-861D or below
> edid_version [0x0] no CEA EDID Timing Extension block present
> manufacture_id 0x0
> product_id 0x0
> port_id 0x0
> support_hdcp 0
> support_ai 0
> audio_sync_delay 0
> speakers [0x5f] FL/FR LFE FC RL/RR RC RLC/RRC
> sad_count 6
> sad0_coding_type [0x1] LPCM
> sad0_channels 8
> sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
> sad0_bits [0xe0000] 16 20 24
> sad1_coding_type [0x2] AC-3
> sad1_channels 6
> sad1_rates [0xe0] 32000 44100 48000
> sad1_max_bitrate 640000
> sad2_coding_type [0x7] DTS
> sad2_channels 6
> sad2_rates [0x6c0] 44100 48000 88200 96000
> sad2_max_bitrate 1536000
> sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
> sad3_channels 8
> sad3_rates [0xc0] 44100 48000
> sad4_coding_type [0xb] DTS-HD
> sad4_channels 8
> sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
> sad5_coding_type [0xc] MLP (Dolby TrueHD)
> sad5_channels 8
> sad5_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
>
> Command:
> speaker-test -D hdmi:CARD=Generic,DEV=0 -c8 -r192000 -F S16_LE
> works, I just have 5.1 (not 7.1), so Side left goes to the Read left
> and Side right goes to the Rear right. But they were working!

Good :)

BTW, there is a newer version (which was actually applied) of this
patchset in alsa-devel@, seems you were missing from CC on that one.

> Next I've used howto from
> http://phoronix.com/forums/showthread.php?27348-TrueHD-DTS-HD-E-AC3-Over-HDMI-On-Linux
> to test DTS MA and TrueHD.
>
> In the file from howto I've used:
> card Generic
> and then tested:
>
> zajec@linux-samsung700g7a:~> aplay -D hdmihdtest0 -c8 -fs16_le
> -r192000 thd.spdif
> Playing raw data 'thd.spdif' : Signed 16 bit Little Endian, Rate
> 192000 Hz, Channels 8
> zajec@linux-samsung700g7a:~> aplay -D hdmihdtest0 -c8 -fs16_le
> -r192000 dts.spdif
> Playing raw data 'dts.spdif' : Signed 16 bit Little Endian, Rate
> 192000 Hz, Channels 8

For the record, the "howto" is mostly a workaround for missing
DEV=[1..3] on (now) very old systems, instead of messing around with
asoundrc you can just use "-D hdmi:CARD=Generic,DEV=0,AES0=6" instead of
-DhdmihdtestX. (in AES0 the 0x2 is non-PCM flag, 0x4 is non-copyright
flag IIRC - ALSA default is 0x4).

> Hooray! I got
> DOLBY HD
> and
> DTS-HD MA
> on my Denon 1912 display!
>
> Now the main question... do you have any experience on using DTS-HD MA
> (or TrueHD) with mplayer? :|

Nope (well, any that I still remember). Support is there, though, so I
guess it should work.

--
Anssi Hannula

2013-10-31 16:22:50

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

2013/10/30 Anssi Hannula <[email protected]>:
> BTW, there is a newer version (which was actually applied) of this patchset
> in alsa-devel@, seems you were missing from CC on that one.

I didn't try that updated version yet, but I'm afraid I discovered
some problem. I've switched from my Denon 1912 to the older Onkyo
TX-SR605 and there is problem with multichannel playback. I've tried:
> speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r192000 -F S16_LE

speaker-test 1.0.25

Playback device is hdmi:CARD=Generic,DEV=0
Stream parameters are 192000Hz, S16_LE, 6 channels
Using 16 octaves of pink noise
Rate set to 192000Hz (requested 192000Hz)
Buffer size range from 64 to 87360
Period size range from 32 to 43680
Using max buffer size 87360
Periods = 4
was set period_size = 17472
was set buffer_size = 87360
0 - Front Left
4 - Center
1 - Front Right
3 - Rear Right
2 - Rear Left
5 - LFE
Time per period = 17.027360

But I can hear sound for rear right and rear left only :(

Is there anything more I can provide to help resolve this? Do you have
any idea how we can resolve this?

zajec@linux-samsung700g7a:/proc/asound/card1> cat eld#0.0
monitor_present 1
eld_valid 1
monitor_name
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x0] no CEA EDID Timing Extension block present
manufacture_id 0x0
product_id 0x0
port_id 0x0
support_hdcp 0
support_ai 0
audio_sync_delay 0
speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
sad_count 6
sad0_coding_type [0x1] LPCM
sad0_channels 2
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x2] AC-3
sad1_channels 8
sad1_rates [0xe0] 32000 44100 48000
sad1_max_bitrate 640000
sad2_coding_type [0x7] DTS
sad2_channels 8
sad2_rates [0xc0] 44100 48000
sad2_max_bitrate 1536000
sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad4_coding_type [0xb] DTS-HD
sad4_channels 8
sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad5_coding_type [0xc] MLP (Dolby TrueHD)
sad5_channels 8
sad5_rates [0x6c0] 44100 48000 88200 96000
zajec@linux-samsung700g7a:/proc/asound/card1> ls
codec#0 eld#0.0 id pcm3p
zajec@linux-samsung700g7a:/proc/asound/card1> cat codec#0
Codec: ATI R6xx HDMI
Address: 0
AFG Function Id: 0x1 (unsol 0)
Vendor Id: 0x1002aa01
Subsystem Id: 0x00aa0100
Revision Id: 0x100200
No Modem Function Group found
Default PCM:
rates [0x70]: 32000 44100 48000
bits [0x2]: 16
formats [0x1]: PCM
Default Amp-In caps: N/A
Default Amp-Out caps: N/A
State of AFG node 0x01:
Power states: D0 D3
Power: setting=D0, actual=D0
GPIO: io=0, o=0, i=0, unsolicited=0, wake=0
Node 0x02 [Audio Output] wcaps 0x201: Stereo Digital
Converter: stream=0, channel=0
Digital: Enabled GenLevel
Digital category: 0x2
IEC Coding Type: 0x0
Node 0x03 [Pin Complex] wcaps 0x400381: Stereo Digital
Control: name="HDMI/DP,pcm=3 Jack", index=0, device=0
Control: name="IEC958 Playback Con Mask", index=0, device=0
Control: name="IEC958 Playback Pro Mask", index=0, device=0
Control: name="IEC958 Playback Default", index=0, device=0
Control: name="IEC958 Playback Switch", index=0, device=0
Control: name="ELD", index=0, device=3
Pincap 0x00000094: OUT Detect HDMI
Pin Default 0x18560010: [Jack] Digital Out at Int HDMI
Conn = Digital, Color = Unknown
DefAssociation = 0x1, Sequence = 0x0
Pin-ctls: 0x40: OUT
Unsolicited: tag=01, enabled=1
Connection: 1
0x02
zajec@linux-samsung700g7a:/proc/asound/card1> cat eld#0.0
monitor_present 1
eld_valid 1
monitor_name
connection_type HDMI
eld_version [0x2] CEA-861D or below
edid_version [0x0] no CEA EDID Timing Extension block present
manufacture_id 0x0
product_id 0x0
port_id 0x0
support_hdcp 0
support_ai 0
audio_sync_delay 0
speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
sad_count 6
sad0_coding_type [0x1] LPCM
sad0_channels 2
sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
sad0_bits [0xe0000] 16 20 24
sad1_coding_type [0x2] AC-3
sad1_channels 8
sad1_rates [0xe0] 32000 44100 48000
sad1_max_bitrate 640000
sad2_coding_type [0x7] DTS
sad2_channels 8
sad2_rates [0xc0] 44100 48000
sad2_max_bitrate 1536000
sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
sad3_channels 8
sad3_rates [0xc0] 44100 48000
sad4_coding_type [0xb] DTS-HD
sad4_channels 8
sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
sad5_coding_type [0xc] MLP (Dolby TrueHD)
sad5_channels 8
sad5_rates [0x6c0] 44100 48000 88200 96000


>> Now the main question... do you have any experience on using DTS-HD MA
>> (or TrueHD) with mplayer? :|
>
>
> Nope (well, any that I still remember). Support is there, though, so I guess
> it should work.

After some testing I found out that xbmc works very nice :)

--
Rafał

2013-10-31 20:26:20

by Anssi Hannula

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

31.10.2013 18:22, Rafał Miłecki kirjoitti:
> 2013/10/30 Anssi Hannula <[email protected]>:
>> BTW, there is a newer version (which was actually applied) of this patchset
>> in alsa-devel@, seems you were missing from CC on that one.
>
> I didn't try that updated version yet, but I'm afraid I discovered
> some problem. I've switched from my Denon 1912 to the older Onkyo
> TX-SR605 and there is problem with multichannel playback. I've tried:
>> speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r192000 -F S16_LE
>
> speaker-test 1.0.25
>
> Playback device is hdmi:CARD=Generic,DEV=0
> Stream parameters are 192000Hz, S16_LE, 6 channels
> Using 16 octaves of pink noise
> Rate set to 192000Hz (requested 192000Hz)
> Buffer size range from 64 to 87360
> Period size range from 32 to 43680
> Using max buffer size 87360
> Periods = 4
> was set period_size = 17472
> was set buffer_size = 87360
> 0 - Front Left
> 4 - Center
> 1 - Front Right
> 3 - Rear Right
> 2 - Rear Left
> 5 - LFE
> Time per period = 17.027360
>
> But I can hear sound for rear right and rear left only :(
>
> Is there anything more I can provide to help resolve this? Do you have
> any idea how we can resolve this?

According to the below the receiver has separate PCM SADs for 2-channel
and multichannel playback. However, due to a radeon driver bug (see
"[PATCH] drm/radeon/audio: fix missing multichannel PCM SAD in some
cases", you were CCd) the multichannel SAD is lost and not shown below.

However, that is not (or at least should not be) the reason you are not
getting audio.
I suspect that the receiver does not support 192kHz multichannel audio
(which would be indicated in the missing multichannel PCM SAD). Does it
work with 48kHz or 96kHz?
(TODO: refuse PCM playback in such cases)

If it does not work with 48kHz or 96kHz either, then we have a bug to
solve :)

> zajec@linux-samsung700g7a:/proc/asound/card1> cat eld#0.0
> monitor_present 1
> eld_valid 1
> monitor_name
> connection_type HDMI
> eld_version [0x2] CEA-861D or below
> edid_version [0x0] no CEA EDID Timing Extension block present
> manufacture_id 0x0
> product_id 0x0
> port_id 0x0
> support_hdcp 0
> support_ai 0
> audio_sync_delay 0
> speakers [0x4f] FL/FR LFE FC RL/RR RLC/RRC
> sad_count 6
> sad0_coding_type [0x1] LPCM
> sad0_channels 2
> sad0_rates [0x1ee0] 32000 44100 48000 88200 96000 176400 192000
> sad0_bits [0xe0000] 16 20 24
> sad1_coding_type [0x2] AC-3
> sad1_channels 8
> sad1_rates [0xe0] 32000 44100 48000
> sad1_max_bitrate 640000
> sad2_coding_type [0x7] DTS
> sad2_channels 8
> sad2_rates [0xc0] 44100 48000
> sad2_max_bitrate 1536000
> sad3_coding_type [0xa] E-AC-3/DD+ (Dolby Digital Plus)
> sad3_channels 8
> sad3_rates [0xc0] 44100 48000
> sad4_coding_type [0xb] DTS-HD
> sad4_channels 8
> sad4_rates [0x1ec0] 44100 48000 88200 96000 176400 192000
> sad5_coding_type [0xc] MLP (Dolby TrueHD)
> sad5_channels 8
> sad5_rates [0x6c0] 44100 48000 88200 96000
> zajec@linux-samsung700g7a:/proc/asound/card1> ls
> codec#0 eld#0.0 id pcm3p
> zajec@linux-samsung700g7a:/proc/asound/card1> cat codec#0
> Codec: ATI R6xx HDMI
> Address: 0
> AFG Function Id: 0x1 (unsol 0)
> Vendor Id: 0x1002aa01
> Subsystem Id: 0x00aa0100
> Revision Id: 0x100200
> No Modem Function Group found
> Default PCM:
> rates [0x70]: 32000 44100 48000
> bits [0x2]: 16
> formats [0x1]: PCM
> Default Amp-In caps: N/A
> Default Amp-Out caps: N/A
> State of AFG node 0x01:
> Power states: D0 D3
> Power: setting=D0, actual=D0
> GPIO: io=0, o=0, i=0, unsolicited=0, wake=0
> Node 0x02 [Audio Output] wcaps 0x201: Stereo Digital
> Converter: stream=0, channel=0
> Digital: Enabled GenLevel
> Digital category: 0x2
> IEC Coding Type: 0x0
> Node 0x03 [Pin Complex] wcaps 0x400381: Stereo Digital
> Control: name="HDMI/DP,pcm=3 Jack", index=0, device=0
> Control: name="IEC958 Playback Con Mask", index=0, device=0
> Control: name="IEC958 Playback Pro Mask", index=0, device=0
> Control: name="IEC958 Playback Default", index=0, device=0
> Control: name="IEC958 Playback Switch", index=0, device=0
> Control: name="ELD", index=0, device=3
> Pincap 0x00000094: OUT Detect HDMI
> Pin Default 0x18560010: [Jack] Digital Out at Int HDMI
> Conn = Digital, Color = Unknown
> DefAssociation = 0x1, Sequence = 0x0
> Pin-ctls: 0x40: OUT
> Unsolicited: tag=01, enabled=1
> Connection: 1
> 0x02
[...]

--
Anssi Hannula

2013-10-31 23:25:46

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

2013/10/31 Anssi Hannula <[email protected]>:
>> But I can hear sound for rear right and rear left only :(
>>
>> Is there anything more I can provide to help resolve this? Do you have
>> any idea how we can resolve this?
>
> According to the below the receiver has separate PCM SADs for 2-channel
> and multichannel playback. However, due to a radeon driver bug (see
> "[PATCH] drm/radeon/audio: fix missing multichannel PCM SAD in some
> cases", you were CCd) the multichannel SAD is lost and not shown below.
>
> However, that is not (or at least should not be) the reason you are not
> getting audio.
> I suspect that the receiver does not support 192kHz multichannel audio
> (which would be indicated in the missing multichannel PCM SAD). Does it
> work with 48kHz or 96kHz?
> (TODO: refuse PCM playback in such cases)
>
> If it does not work with 48kHz or 96kHz either, then we have a bug to
> solve :)

First of all, you're right about 2 SADs for PCM.

The weird thing is that 192kHz support... According to the EDID (SADs)
it should be supported:
Format: 1 (PCM) Channels:1 Freq:0x7F (32-192) B2:0x07 (16-24b)
Format: 1 (PCM) Channels:7 Freq:0x7F (32-192) B2:0x07 (16-24b)
Format: 2 (AC3) Channels:7 Freq:0x07 (32-48) B2:0x50 (640?)
Format: 7 (DTS) Channels:7 Freq:0x06 (44-48) B2:0xC0 (1536?)
Format: 10 (EAC3) Channels:7 Freq:0x06 (44-48) B2:0x00
Format: 11 (DTS_HD) Channels:7 Freq:0x7E (44-192) B2:0x01
Format: 12 (MLP) Channels:7 Freq:0x1E (44-96) B2:0x00

So I performed more tests and:

1) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r192000 -F S16_LE
A nice noise for rear right and rear left, silent for the rest

2) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r176400 -F S16_LE
A nice noise for rear right and rear left, short "bump" sound for the rest

3) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r96000 -F S16_LE
A nice noise for all speakers (the same applies to 88200, 48000, 44100, 32000)

I don't get it. Onkyo reports support for 192kHz and it supports it,
but only for 2 rear speakers... does it make any sense do you?

--
Rafał

2013-10-31 23:35:16

by Anssi Hannula

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

01.11.2013 01:25, Rafał Miłecki kirjoitti:
> 2013/10/31 Anssi Hannula <[email protected]>:
>>> But I can hear sound for rear right and rear left only :(
>>>
>>> Is there anything more I can provide to help resolve this? Do you have
>>> any idea how we can resolve this?
>>
>> According to the below the receiver has separate PCM SADs for 2-channel
>> and multichannel playback. However, due to a radeon driver bug (see
>> "[PATCH] drm/radeon/audio: fix missing multichannel PCM SAD in some
>> cases", you were CCd) the multichannel SAD is lost and not shown below.
>>
>> However, that is not (or at least should not be) the reason you are not
>> getting audio.
>> I suspect that the receiver does not support 192kHz multichannel audio
>> (which would be indicated in the missing multichannel PCM SAD). Does it
>> work with 48kHz or 96kHz?
>> (TODO: refuse PCM playback in such cases)
>>
>> If it does not work with 48kHz or 96kHz either, then we have a bug to
>> solve :)
>
> First of all, you're right about 2 SADs for PCM.
>
> The weird thing is that 192kHz support... According to the EDID (SADs)
> it should be supported:
> Format: 1 (PCM) Channels:1 Freq:0x7F (32-192) B2:0x07 (16-24b)
> Format: 1 (PCM) Channels:7 Freq:0x7F (32-192) B2:0x07 (16-24b)
> Format: 2 (AC3) Channels:7 Freq:0x07 (32-48) B2:0x50 (640?)
> Format: 7 (DTS) Channels:7 Freq:0x06 (44-48) B2:0xC0 (1536?)
> Format: 10 (EAC3) Channels:7 Freq:0x06 (44-48) B2:0x00
> Format: 11 (DTS_HD) Channels:7 Freq:0x7E (44-192) B2:0x01
> Format: 12 (MLP) Channels:7 Freq:0x1E (44-96) B2:0x00
>
> So I performed more tests and:
>
> 1) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r192000 -F S16_LE
> A nice noise for rear right and rear left, silent for the rest
>
> 2) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r176400 -F S16_LE
> A nice noise for rear right and rear left, short "bump" sound for the rest
>
> 3) speaker-test -D hdmi:CARD=Generic,DEV=0 -c6 -r96000 -F S16_LE
> A nice noise for all speakers (the same applies to 88200, 48000, 44100, 32000)
>
> I don't get it. Onkyo reports support for 192kHz and it supports it,
> but only for 2 rear speakers... does it make any sense do you?

Just to check, is the display mode 720p50 or higher (as per HDMI spec
7.3.3)? Though I guess too small mode would cause something else, not
this...

Also, does DTS-HD/TrueHD work with this receiver (interesting since
those require 8-channel 192kHz link)?

Would be interesting to check if this works in Windows I guess (or maybe
even just fglrx, though I can't think of a reason it'd make a difference).

--
Anssi Hannula

2013-10-31 23:51:39

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

2013/11/1 Anssi Hannula <[email protected]>:
> Just to check, is the display mode 720p50 or higher (as per HDMI spec
> 7.3.3)? Though I guess too small mode would cause something else, not
> this...

I'm using 1080p all the time. Do you think that
HDMI_AUDIO_PACKETS_PER_LINE may have anything to do with this issue
(see evergreen_hdmi.c)?


> Also, does DTS-HD/TrueHD work with this receiver (interesting since
> those require 8-channel 192kHz link)?

Both are working for me. I've tested it using 2 movies:
1) English TrueHD.5.1 @ 1417 kbps
2) Audio
Codec................: DTSHD-MA
Bitrate..............: 3718 kbps
kHz/bit..............: 24-bit
Channels.............: 5.1
Language.............: English


> Would be interesting to check if this works in Windows I guess (or maybe
> even just fglrx, though I can't think of a reason it'd make a difference).

Installing fglrx is an option, I can try that. Not a big chance for
Windows here.

--
Rafał

2013-10-31 23:58:46

by Anssi Hannula

[permalink] [raw]
Subject: Re: [PATCH 1/4] ALSA: hda - hdmi: Add ATI/AMD multi-channel audio support

01.11.2013 01:51, Rafał Miłecki kirjoitti:
> 2013/11/1 Anssi Hannula <[email protected]>:
>> Just to check, is the display mode 720p50 or higher (as per HDMI spec
>> 7.3.3)? Though I guess too small mode would cause something else, not
>> this...
>
> I'm using 1080p all the time. Do you think that
> HDMI_AUDIO_PACKETS_PER_LINE may have anything to do with this issue
> (see evergreen_hdmi.c)?

Well, anything is possible, but that stuff seems unlikely here, since
apparently some channels get through fine. In multichannel HDMI one
sample of each channel is carried in each audio sample packet, so just
straight "packet loss" shouldn't cause this.

>> Also, does DTS-HD/TrueHD work with this receiver (interesting since
>> those require 8-channel 192kHz link)?
>
> Both are working for me. I've tested it using 2 movies:
> 1) English TrueHD.5.1 @ 1417 kbps
> 2) Audio
> Codec................: DTSHD-MA
> Bitrate..............: 3718 kbps
> kHz/bit..............: 24-bit
> Channels.............: 5.1
> Language.............: English

Which makes it even stranger, since HBR packets look exactly like ASP
packets with a few flipped bits.

Hm, the earlier non-working speaker-test commands were with -c6. What
about -c8?

>> Would be interesting to check if this works in Windows I guess (or maybe
>> even just fglrx, though I can't think of a reason it'd make a difference).
>
> Installing fglrx is an option, I can try that. Not a big chance for
> Windows here.
>


--
Anssi Hannula