[alsa-devel] Nvidia HDMI and four codecs
I've seen a few Nvidia HDMI's recently which have four HDMI codecs connected to the same HDA controller. The problem is that we don't know which one(s) of these four that is the real one. So people will have to try devices "hdmi:Nvidia,0", "hdmi:Nvidia,1", "hdmi:Nvidia,2" and "hdmi:Nvidia,3" to figure out which one is the right one. (And by empirical testing we know that it isn't always the first one.)
Thinking PulseAudio and/or "Just Works", this is not good enough, so is there a way to know beforehand which one of these four that is actually physically connected?
I'd love BIOS to provide a good codec probe mask, a pin config default, or something similar, but given a codec-proc I can't see any difference between the real ones and the unconnected ones, so I don't know how to fix up the driver without hardcoding/quirking every one of them. Any hints?
David Henningsson wrote at Tuesday, February 01, 2011 1:10 AM:
I've seen a few Nvidia HDMI's recently which have four HDMI codecs connected to the same HDA controller.
This is the case for any NVIDIA GPU that supports HDA, and also our most recent chipset.
The problem is that we don't know which one(s) of these four that is the real one. So people will have to try devices "hdmi:Nvidia,0", "hdmi:Nvidia,1", "hdmi:Nvidia,2" and "hdmi:Nvidia,3" to figure out which one is the right one. (And by empirical testing we know that it isn't always the first one.)
/proc/asound/card<n>/eld* will tell you which one to use; the ELD file numbering should match the hdmi: device numbering.
eld 0,1,2,3 also match hw:$card:$device with device=3,7,8,9.
I do have an audio document that's aimed at technical end-users to explain all of this. However, I haven't quite finished it, and issues with the publication mechanism have stopped me publishing it so far.
Thinking PulseAudio and/or "Just Works", this is not good enough, so is there a way to know beforehand which one of these four that is actually physically connected?
I don't believe it's possible to determine which of the codecs are physically connected to actual connectors on the graphics board. This would be a static facet of the board design.
Beyond that, the ELD files will indicate which codecs/pins are routed to a connector with an audio-capable display attached and that X is actually sending a signal to. This can dynamically change as the X server is reconfigured, either when X restarts, or dynamically through our management protocol or application.
I'd love BIOS to provide a good codec probe mask, a pin config default, or something similar, but given a codec-proc I can't see any difference between the real ones and the unconnected ones, so I don't know how to fix up the driver without hardcoding/quirking every one of them. Any hints?
ALSA now exposes a logical device (hdmi:Nvidia,n) for each pin complex[1] (equivalently each codec since there's a 1:1 mapping in our GPUs right now). However, PulseAudio still only offers the user the first of these devices, thus causing users to resort to probe masks to select which ALSA device they wish to use.
If PulseAudio were to offer all HDMI devices in its UI, at least the user Could configure their system using the regular GUI tools. I did suggest this on the PulseAudio list, and I think the maintainers agreed this would be a good idea in principle. However, I haven't taken the time to drive this.
http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg07433.htm...
[1] Concentrating abstractions on pin complexes rather than codecs will ensure ALSA etc. are more ready for other codec/converter/pin combinations that may be seen on other or future GPUs.
On 2011-02-01 17:36, Stephen Warren wrote:
David Henningsson wrote at Tuesday, February 01, 2011 1:10 AM:
I've seen a few Nvidia HDMI's recently which have four HDMI codecs connected to the same HDA controller.
This is the case for any NVIDIA GPU that supports HDA, and also our most recent chipset.
The problem is that we don't know which one(s) of these four that is the real one. So people will have to try devices "hdmi:Nvidia,0", "hdmi:Nvidia,1", "hdmi:Nvidia,2" and "hdmi:Nvidia,3" to figure out which one is the right one. (And by empirical testing we know that it isn't always the first one.)
/proc/asound/card<n>/eld* will tell you which one to use; the ELD file numbering should match the hdmi: device numbering.
eld 0,1,2,3 also match hw:$card:$device with device=3,7,8,9.
I do have an audio document that's aimed at technical end-users to explain all of this. However, I haven't quite finished it, and issues with the publication mechanism have stopped me publishing it so far.
Thinking PulseAudio and/or "Just Works", this is not good enough, so is there a way to know beforehand which one of these four that is actually physically connected?
I don't believe it's possible to determine which of the codecs are physically connected to actual connectors on the graphics board. This would be a static facet of the board design.
Ok, thanks for confirming.
As you might have seen, for Intel HDMI I made a patch that makes it act upon the pin config default register. I'd love it if things could work out the same way for Nvidia HDMI. I don't know enough about the BIOS/HW side of things to know for sure, but I guess this will be something up to whoever makes the board (e g Asus) to set inside the GPU somehow.
Failing that, we could try hiding things in the driver by quirking, either at the codec level or at the pin complex level.
Beyond that, the ELD files will indicate which codecs/pins are routed to a connector with an audio-capable display attached and that X is actually sending a signal to. This can dynamically change as the X server is reconfigured, either when X restarts, or dynamically through our management protocol or application.
I'd love BIOS to provide a good codec probe mask, a pin config default, or something similar, but given a codec-proc I can't see any difference between the real ones and the unconnected ones, so I don't know how to fix up the driver without hardcoding/quirking every one of them. Any hints?
ALSA now exposes a logical device (hdmi:Nvidia,n) for each pin complex[1] (equivalently each codec since there's a 1:1 mapping in our GPUs right now). However, PulseAudio still only offers the user the first of these devices, thus causing users to resort to probe masks to select which ALSA device they wish to use.
If PulseAudio were to offer all HDMI devices in its UI, at least the user Could configure their system using the regular GUI tools. I did suggest this on the PulseAudio list, and I think the maintainers agreed this would be a good idea in principle. However, I haven't taken the time to drive this.
http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg07433.htm...
Thanks, reading that thread made a few things clearer.
As for PulseAudio, showing four HDMI devices is quite simple [1] but I still think it would be a little confusing to show four devices to choose from and would wish for something more intuitive.
[1] Concentrating abstractions on pin complexes rather than codecs will ensure ALSA etc. are more ready for other codec/converter/pin combinations that may be seen on other or future GPUs.
I agree.
So let's sum up the options here:
1) Board manufacturer sets a codec probe mask.
2) Board manufacturer sets pin config default register. This might require some support in the driver as well.
1) and 2) won't work for existing boards and I don't know how difficult it would be to persuade the board manufacturers to do it for future boards.
3) Quirking in the driver - codec probe mask
This was my primary option until yesterday, when I saw a machine which had the same PCI SSID for both the primary HDA controller and the Nvidia HDA controller.
4) Quirking in the driver - pin config default register. Will need some work in the driver, but I guess it's doable.
3) and 4) gives us a lot of quirking to do.
5) Show all four devices in PulseAudio. Simple, but confusing for the user.
6) Proper jack detection in PulseAudio, which might be based on ELD information. This is what would need the most work to do, and things will still be confusing for people not using PulseAudio. It might be the long path to go anyway, as it would enable features such as auto-moving to HDMI when HDMI is plugged in, etc.
David Henningsson wrote at Wednesday, February 02, 2011 1:04 AM:
On 2011-02-01 17:36, Stephen Warren wrote:
David Henningsson wrote at Tuesday, February 01, 2011 1:10 AM:
I've seen a few Nvidia HDMI's recently which have four HDMI codecs connected to the same HDA controller. ... The problem is that we don't know which one(s) of these four that is the real one. ...
(oh, and note that there can be multiple displays active, and hence there can be more than one "real one").
I don't believe it's possible to determine which of the codecs are physically connected to actual connectors on the graphics board. This would be a static facet of the board design.
... As you might have seen, for Intel HDMI I made a patch that makes it act upon the pin config default register. ...
I'd love BIOS to provide a good codec probe mask, a pin config default, or something similar, but given a codec-proc I can't see any difference between the real ones and the unconnected ones, so I don't know how to fix up the driver without hardcoding/quirking every one of them. Any hints?
ALSA now exposes a logical device (hdmi:Nvidia,n) for each pin complex ... If PulseAudio were to offer all HDMI devices in its UI, at least the user could configure their system using the regular GUI tools. ... http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg07433.htm...
Thanks, reading that thread made a few things clearer.
As for PulseAudio, showing four HDMI devices is quite simple [1] but I still think it would be a little confusing to show four devices to choose from and would wish for something more intuitive.
I'm not sure if that will work.
Note: My observations are based on adding the following to /etc/pulse/default.pa:
load-module module-alsa-sink device=hw:1,7 load-module module-alsa-sink device=hw:1,8 load-module module-alsa-sink device=hw:1,9
With the above, at least during startup (and perhaps long-term during operation), PulseAudio opens all the devices at once. This exceeds the maximum number of streams our audio controller can support (2), and hence the load-module fails, and hence the PulseAudio daemon fails to start.
Perhaps the mechanism you presented avoids that?
If you know which specific subset you want, adding fewer of those entries to the file does work, and can be an alternative to a probe mask.
So let's sum up the options here:
- Board manufacturer sets a codec probe mask.
I'm not sure how they'd do that, since the probe mask is a Linux-specific kernel command-line option.
- Board manufacturer sets pin config default register. This might
require some support in the driver as well.
- and 2) won't work for existing boards and I don't know how difficult
it would be to persuade the board manufacturers to do it for future boards.
Yes, this isn't possible with any current boards.
However, for some future designs, it sounds like we may be setting the pin config default register to indicate which pin complexes are actually connected to a physical connector on the board.
- Quirking in the driver - codec probe mask
This was my primary option until yesterday, when I saw a machine which had the same PCI SSID for both the primary HDA controller and the Nvidia HDA controller.
The 3D/VGA controller and the HD-Audio controller will always be different PCI functions (same domain/bus/device, different function address), and appropriately marked as either a 3D or audio controller. Perhaps that can help apply any quirk to the appropriate device/driver.
In practice for all the GPUs I've seen the 3D controller is function 0 and the HD-audio controller is function 1. However, it would be unwise to assume those specific numbers will apply in all cases.
- Quirking in the driver - pin config default register. Will need some
work in the driver, but I guess it's doable.
This is probably better than quirking a probe_mask; it'd be more similar to the case where this register was already filled in by the HW/BIOS.
and 4) gives us a lot of quirking to do.
Show all four devices in PulseAudio. Simple, but confusing for the
user.
And there is the issue I mentioned above to work out.
- Proper jack detection in PulseAudio, which might be based on ELD
information. This is what would need the most work to do, and things will still be confusing for people not using PulseAudio. It might be the long path to go anyway, as it would enable features such as auto-moving to HDMI when HDMI is plugged in, etc.
-- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic
[1] I haven't tested it, but I guess the following addition to /usr/shared/pulseaudio/alsa-mixer/profile-sets/default.conf should do it:
[Mapping hdmi-stereo-extra1] description = HDMI out extra 1 device-strings = hdmi:%f,1 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra2] description = HDMI out extra 2 device-strings = hdmi:%f,2 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra3] description = HDMI out extra 3 device-strings = hdmi:%f,3 channel-map = left,right priority = 2 direction = output
On 2011-02-03 21:35, Stephen Warren wrote:
David Henningsson wrote at Wednesday, February 02, 2011 1:04 AM:
On 2011-02-01 17:36, Stephen Warren wrote:
David Henningsson wrote at Tuesday, February 01, 2011 1:10 AM:
I've seen a few Nvidia HDMI's recently which have four HDMI codecs connected to the same HDA controller. ... The problem is that we don't know which one(s) of these four that is the real one. ...
(oh, and note that there can be multiple displays active, and hence there can be more than one "real one").
True. On the ALSA level, we should support everything we can, however PulseAudio has a somewhat simplified focus so at that level, it is acceptable that only one HDMI display is active at a time (audio-wise). At least if anything is still possible by configuration changes in e g /etc/pulse/default.pa.
I don't believe it's possible to determine which of the codecs are physically connected to actual connectors on the graphics board. This would be a static facet of the board design.
... As you might have seen, for Intel HDMI I made a patch that makes it act upon the pin config default register. ...
I'd love BIOS to provide a good codec probe mask, a pin config default, or something similar, but given a codec-proc I can't see any difference between the real ones and the unconnected ones, so I don't know how to fix up the driver without hardcoding/quirking every one of them. Any hints?
ALSA now exposes a logical device (hdmi:Nvidia,n) for each pin complex ... If PulseAudio were to offer all HDMI devices in its UI, at least the user could configure their system using the regular GUI tools. ... http://www.mail-archive.com/pulseaudio-discuss@mail.0pointer.de/msg07433.htm...
Thanks, reading that thread made a few things clearer.
As for PulseAudio, showing four HDMI devices is quite simple [1] but I still think it would be a little confusing to show four devices to choose from and would wish for something more intuitive.
I'm not sure if that will work.
Note: My observations are based on adding the following to /etc/pulse/default.pa:
load-module module-alsa-sink device=hw:1,7 load-module module-alsa-sink device=hw:1,8 load-module module-alsa-sink device=hw:1,9
With the above, at least during startup (and perhaps long-term during operation), PulseAudio opens all the devices at once. This exceeds the maximum number of streams our audio controller can support (2), and hence the load-module fails, and hence the PulseAudio daemon fails to start.
Perhaps the mechanism you presented avoids that?
I don't have the hardware here, so I can't test, but I believe so - with this configuration, they will open one at a time and selectable through setting the profile (in gnome-volume-control, that would correspond to four different "Profiles" on the "Hardware" tab).
Thinking of it, it might make sense to add the below as an interim solution even in standard PulseAudio and/or Ubuntu.
If you know which specific subset you want, adding fewer of those entries to the file does work, and can be an alternative to a probe mask.
So let's sum up the options here:
- Board manufacturer sets a codec probe mask.
I'm not sure how they'd do that, since the probe mask is a Linux-specific kernel command-line option.
Hmm, you're probably right. Linux reads this from the STATESTS register on reset (see hda_intel.c:azx_reset) but unless you have some internal method of turning off the codecs completely (this might also save power?) this might not be an option.
- Board manufacturer sets pin config default register. This might
require some support in the driver as well.
- and 2) won't work for existing boards and I don't know how difficult
it would be to persuade the board manufacturers to do it for future boards.
Yes, this isn't possible with any current boards.
However, for some future designs, it sounds like we may be setting the pin config default register to indicate which pin complexes are actually connected to a physical connector on the board.
Sounds good to me - then at least we have some way of autodiscovering connections before they are active.
- Quirking in the driver - codec probe mask
This was my primary option until yesterday, when I saw a machine which had the same PCI SSID for both the primary HDA controller and the Nvidia HDA controller.
The 3D/VGA controller and the HD-Audio controller will always be different PCI functions (same domain/bus/device, different function address), and appropriately marked as either a 3D or audio controller. Perhaps that can help apply any quirk to the appropriate device/driver.
In practice for all the GPUs I've seen the 3D controller is function 0 and the HD-audio controller is function 1. However, it would be unwise to assume those specific numbers will apply in all cases.
- Quirking in the driver - pin config default register. Will need some
work in the driver, but I guess it's doable.
This is probably better than quirking a probe_mask; it'd be more similar to the case where this register was already filled in by the HW/BIOS.
Ok, this seems reasonable, although somewhat more work in the driver compared to the probe_mask approach.
We usually use the PCI SSID as key to selecting a quirk - are two cards with different layout (as in different codecs physically connected), guaranteed to have different PCI Subsystem IDs?
and 4) gives us a lot of quirking to do.
Show all four devices in PulseAudio. Simple, but confusing for the
user.
And there is the issue I mentioned above to work out.
- Proper jack detection in PulseAudio, which might be based on ELD
information. This is what would need the most work to do, and things will still be confusing for people not using PulseAudio. It might be the long path to go anyway, as it would enable features such as auto-moving to HDMI when HDMI is plugged in, etc.
-- David Henningsson, Canonical Ltd. http://launchpad.net/~diwic
[1] I haven't tested it, but I guess the following addition to /usr/shared/pulseaudio/alsa-mixer/profile-sets/default.conf should do it:
[Mapping hdmi-stereo-extra1] description = HDMI out extra 1 device-strings = hdmi:%f,1 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra2] description = HDMI out extra 2 device-strings = hdmi:%f,2 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra3] description = HDMI out extra 3 device-strings = hdmi:%f,3 channel-map = left,right priority = 2 direction = output
David Henningsson wrote at Wednesday, February 02, 2011 1:04 AM:
As for PulseAudio, showing four HDMI devices is quite simple [1] but I still think it would be a little confusing to show four devices to choose from and would wish for something more intuitive. ... [1] I haven't tested it, but I guess the following addition to /usr/shared/pulseaudio/alsa-mixer/profile-sets/default.conf should do it:
[Mapping hdmi-stereo-extra1] description = HDMI out extra 1 device-strings = hdmi:%f,1 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra2] description = HDMI out extra 2 device-strings = hdmi:%f,2 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra3] description = HDMI out extra 3 device-strings = hdmi:%f,3 channel-map = left,right priority = 2 direction = output
This kinda works, but is pretty broken.
I tested on: * Ubuntu Lucid with all updates * Your audio PPA, so the latest ALSA kernel driver * alsa-lib 1.0.24.1
I tested earlier on Karmic too, and saw the same behavior. Unfortunately, Maverick is having issues on my test machine, so I didn't test it.
When I log in, there is only 1 display by default, and hence only one pin complex with valid ELD information (eld#0.0 in my case).
In the Gnome volume applet, Hardware tab, I do see those extra sinks show up. However, as soon as I select one of the new extra options, the entry on the Output tab for the GPU gets removed, so I can't actually route audio over HDMI anymore.
pavucontrol is similar; the Configuration tab shows the new profile, but the Output Devices tab doesn't show any entry for the GPU.
Now, if I use nvidia-settings to light up another display, in TwinView mode, there are now two pin complexes with valid ELD information (eld#0.0 and eld#3.0 in my case).
There is no immediate change to the Gnome volume applet or pavucontrol.
However, if I kill the PulseAudio daemon, and let it restart, then both the Gnome volume applet and pavucontrol start behaving more as expected; I can use either to change the GPU's profile selection, and audio will get moved between the two monitors, or /dev/null if I select a non-connected profile.
I assume this is an issue within PulseAudio. Unfortunately, I doubt I'll be able to find time to look into this in detail.
-- nvpublic
On 2011-02-05 00:25, Stephen Warren wrote:
David Henningsson wrote at Wednesday, February 02, 2011 1:04 AM:
As for PulseAudio, showing four HDMI devices is quite simple [1] but I still think it would be a little confusing to show four devices to choose from and would wish for something more intuitive. ... [1] I haven't tested it, but I guess the following addition to /usr/shared/pulseaudio/alsa-mixer/profile-sets/default.conf should do it:
[Mapping hdmi-stereo-extra1] description = HDMI out extra 1 device-strings = hdmi:%f,1 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra2] description = HDMI out extra 2 device-strings = hdmi:%f,2 channel-map = left,right priority = 2 direction = output
[Mapping hdmi-stereo-extra3] description = HDMI out extra 3 device-strings = hdmi:%f,3 channel-map = left,right priority = 2 direction = output
This kinda works, but is pretty broken.
I tested on:
- Ubuntu Lucid with all updates
- Your audio PPA, so the latest ALSA kernel driver
- alsa-lib 1.0.24.1
I tested earlier on Karmic too, and saw the same behavior. Unfortunately, Maverick is having issues on my test machine, so I didn't test it.
When I log in, there is only 1 display by default, and hence only one pin complex with valid ELD information (eld#0.0 in my case).
In the Gnome volume applet, Hardware tab, I do see those extra sinks show up. However, as soon as I select one of the new extra options, the entry on the Output tab for the GPU gets removed, so I can't actually route audio over HDMI anymore.
pavucontrol is similar; the Configuration tab shows the new profile, but the Output Devices tab doesn't show any entry for the GPU.
Now, if I use nvidia-settings to light up another display, in TwinView mode, there are now two pin complexes with valid ELD information (eld#0.0 and eld#3.0 in my case).
There is no immediate change to the Gnome volume applet or pavucontrol.
However, if I kill the PulseAudio daemon, and let it restart, then both the Gnome volume applet and pavucontrol start behaving more as expected; I can use either to change the GPU's profile selection, and audio will get moved between the two monitors, or /dev/null if I select a non-connected profile.
I assume this is an issue within PulseAudio. Unfortunately, I doubt I'll be able to find time to look into this in detail.
Ok, thanks for testing. Let me know when/if you have time to test newer PulseAudio versions, give me logs etc to see if we can track down the problem of the NVidia card disappearing from PulseAudio.
participants (2)
-
David Henningsson
-
Stephen Warren