GTX 1060 - No Audio over HDMI - Only HDA Intel detected - Azalia

Hello!

So I get no audio over HDMI, not only that, apparently I can’t get any HDMI audio output to show. I followed this guide but didn’t make any difference https://download.nvidia.com/XFree86/gpu-hdmi-audio-document/#_azalia

Kernel 4.12.13 (tried with 4.13, made no difference)
nvidia driver 384.69

################
aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC255 Analog [ALC255 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
################
lspci | grep -i audio
00:1f.3 Audio device: Intel Corporation Device a171 (rev 31)
################
aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
pulse
PulseAudio Sound Server
default
Default ALSA Output (currently PulseAudio Sound Server)
sysdefault:CARD=PCH
HDA Intel PCH, ALC255 Analog
Default Audio Device
front:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
Front speakers
surround21:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
4.0 Surround output to Front and Rear speakers
surround41:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=PCH,DEV=0
HDA Intel PCH, ALC255 Analog
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
################

I’m loading snd_hda_codec_hdmi as suggested in your article, that didn’t make a difference:

lsmod | grep hdmi
snd_hda_codec_hdmi 49152 0
snd_hda_codec 106496 4 snd_hda_intel,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_hda_core 65536 5 snd_hda_intel,snd_hda_codec,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek
snd_pcm 86016 4 snd_hda_intel,snd_hda_codec,snd_hda_core,snd_hda_codec_hdmi
snd 69632 20 snd_hda_intel,snd_hwdep,snd_hda_codec,snd_timer,snd_hda_codec_hdmi,snd_hda_codec_generic,snd_hda_codec_realtek,snd_pcm
nvidia-bug-report.log.gz (121 KB)

For some reason, a lot of recent laptops are set up to boot with the GPU’s PCI audio function disabled. I haven’t done much investigation, but you can turn on the audio function and make the kernel see it by setting the appropriate PCI configuration bit and then telling the kernel to rescan the PCI bus on the PCI bridge the GPU is connected to.

Unfortunately, the kernel won’t see the audio function unless you remove the graphics function first, which temporarily breaks the console. Because of that, it works best if you write a script to do it so you don’t have to SSH into the system or try to type the commands into the console blind. Obviously, you have to stop the X server first so that you can unload the NVIDIA drivers.

For example, on my system, the GPU is at 01:00.0 and its parent PCI bridge is 00:01.0. So the script I use is:

setpci -s 01:00.0 0x488.l=0x2000000:0x2000000
rmmod nvidia-drm nvidia-modeset nvidia
echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove
echo 1 > /sys/bus/pci/devices/0000:00:01.0/rescan
modprobe nvidia-drm
xinit -- -retro

You can figure out your PCI topology with “lspci -t” but interpreting the results is pretty tricky.

What is this magic register, is there any chance to get more documentation on this? Could you post your lspci -s1: -nnxxxx output (as root, to dump the full config space)? On my laptop with a GTX965M the address is a bit past the AER capability and contains all zeroes.

To learn about the parent, you can also examine the output of readlink /sys/bus/pci/devices/0000:01:00.0 which contains the parent device:

../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0

This did it for me. I had to start with no nvidia modules loaded as rmmod refused to remove them once loaded. My configuration is similar to yours so the script ran without problems (other than the rmmod).

Is it possible to get to a permanent fix for this in the long run? Like maybe forcing the nvidia gpu to believe it is connected to HDMI all the time?

can you specify how exactly the script needs to look? I tried using your code since my setup seems to be the same as yours but I’m getting error messages when I try to rmmod nvidia-drm …

See this for a possible cause:
https://devtalk.nvidia.com/default/topic/1024407/linux/nvidia_drm-remains-in-use-for-no-apparent-reason-after-xorg-shutdown-/post/5211176/#5211176

Any suggestions regarding how to automate this script so that it runs on boot before X.org starts?

Once you have the script running correctly, you could use it as a systemd service that must run before display-manager.service.

Somebody here had the smart idea to use grub for that:
https://bugs.freedesktop.org/show_bug.cgi?id=75985#c16
Would avoid the hassle with removing the modules and rescanning.

This script works for me under Ubuntu 17.10 if I run from a non-graphical terminal (e.g., tty3 by pressing CTRL+ALT+F3):

#!/bin/sh
sudo systemctl stop systemd-logind
sudo systemctl stop gdm
sudo setpci -s 01:00.0 0x488.l=0x2000000:0x2000000
sudo rmmod nvidia-drm nvidia-modeset nvidia
sudo sh -c 'echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove'
sudo sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:01.0/rescan'
sudo modprobe nvidia-drm
sudo systemctl start system-logind
sudo systemctl start gdm

I have tried to place this on GRUB:

insmod setpci
setpci -s 01:00.0 0x488.l=0x2000000:0x2000000

But it doesn’t work! Or maybe I’m putting in the wrong place. I should place it just before the kernel is loaded, right?

Regarding the systemd option. I have to look into it. I’ll probably have to make sure that my service runs before systemd-logind and gdm services. However, I don’t have any experience writing systemd services, so I’ll have to read a bit about it before I try it. If someone can point me to a good place where I can learn how to do this, I’d be very thankful.

I’ll give that a try (the GRUB thing) and report back.

I was able to automatically have this work upon boot by using the legacy rc.local file, which is run by systemd upon boot. This is the content of the file:

#!/bin/bash
setpci -s 01:00.0 0x488.l=0x2000000:0x2000000
rmmod nvidia-drm nvidia-modeset nvidia
echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove
echo 1 > /sys/bus/pci/devices/0000:00:01.0/rescan
modprobe nvidia-drm
exit 0

The only downside I have noticed with this approach, but that ALSO happens when I do it manually, is that the backlight control for my laptop’s screen disappears. Apparently “/sys/class/backlight/acpi_video0” and “/sys/class/backlight/acpi_video0” point to non-existing devices after the commands are run. Do you have any idea why and how to fix this?

It’s not really a big deal for me since the backlight was not working correctly under GNOME anyway (or any other DE for that matter). I have to resort to xbacklight to change my screen brightness.

As a side note/offtopic:
If I use the free drivers (nouveau) under Xorg, instead of the proprietary ones, not even xbacklight works. Has anyone else come across something similar and found an universal solution of having backlight working on their GTX 1060 powered laptops regardless of the Desktop Environment, proprietary vs open-source drivers, or if you’re running Xorg or Wayland?

1 Like

I made a better workaround using systemd unit files.
The service file i have created is now a dependency of getty , so i t runs before nvidia is loaded so nothing break and you only set the PCI value and rescan.

Its important not to have early KMS enabled or you will have to unload the modules and load them back.

cat /etc/systemd/system/hdmi-audio.service 
[Unit]
Description=Enable HDMI audio then reload nvidia module

[Service]
Type=oneshot
ExecStart=/usr/bin/hdmi-audio-workaround

[Install]
WantedBy=getty.target
cat /usr/bin/hdmi-audio-workaround 
#!/bin/sh
setpci -s 01:00.0 0x488.l=0x2000000:0x2000000
sh -c 'echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove'
sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:01.0/rescan'

Finally i wanted to say that i also tried using grub for this but for some reason setpci has no effect on the register value , its always FFFFFFFF, so until a fix is released not sure who is responsible for a fix this workaround will do.

I’ll give it a try at your approach.

However, I have noticed a problem that should happen no matter how do you use the setpci workaround. When I resume my laptop after putting it to sleep the HDMI outputs go crazy. I end up with 3 outputs (1 HDMI and 2 DisplayPorts) but none of them work. Has anyone else faced the same issue?

I tried using this approach just as a prove of concept but on my machine (running Ubuntu 16.04 on a mobile GTX 1050) it doesn’t work. My PCI config seems to be the same:

lspci

00:00.0 Host bridge: Intel Corporation Device 5910 (rev 05)
<b>00:01.0 PCI bridge: Intel Corporation Sky Lake PCIe Controller (x16) (rev 05)</b>
00:02.0 VGA compatible controller: Intel Corporation Device 591b (rev 04)
00:04.0 Signal processing controller: Intel Corporation Skylake Processor Thermal Subsystem (rev 05)
00:14.0 USB controller: Intel Corporation Sunrise Point-H USB 3.0 xHCI Controller (rev 31)
00:14.2 Signal processing controller: Intel Corporation Sunrise Point-H Thermal subsystem (rev 31)
00:16.0 Communication controller: Intel Corporation Sunrise Point-H CSME HECI #1 (rev 31)
00:17.0 SATA controller: Intel Corporation Sunrise Point-H SATA Controller [AHCI mode] (rev 31)
00:1c.0 PCI bridge: Intel Corporation Sunrise Point-H PCI Express Root Port #1 (rev f1)
00:1c.4 PCI bridge: Intel Corporation Sunrise Point-H PCI Express Root Port #5 (rev f1)
00:1c.5 PCI bridge: Intel Corporation Sunrise Point-H PCI Express Root Port #6 (rev f1)
00:1c.6 PCI bridge: Intel Corporation Sunrise Point-H PCI Express Root Port #7 (rev f1)
00:1f.0 ISA bridge: Intel Corporation Sunrise Point-H LPC Controller (rev 31)
00:1f.2 Memory controller: Intel Corporation Sunrise Point-H PMC (rev 31)
00:1f.3 Audio device: Intel Corporation Device a171 (rev 31)
00:1f.4 SMBus: Intel Corporation Sunrise Point-H SMBus (rev 31)
<b>01:00.0 3D controller: NVIDIA Corporation Device 1c8d (rev a1)</b>
03:00.0 Unassigned class [ff00]: Realtek Semiconductor Co., Ltd. RTS522A PCI Express Card Reader (rev 01)
04:00.0 Network controller: Intel Corporation Wireless 7265 (rev 61)
05:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 15)

even though I replaced gdm with lightdm so my script looks like this

cat ~/HDMI-fix

#!/bin/sh
sudo systemctl stop systemd-logind
sudo systemctl stop lightdm
sudo setpci -s 01:00.0 0x488.l=0x2000000:0x2000000
sudo rmmod nvidia-drm nvidia-modeset nvidia
sudo sh -c 'echo 1 > /sys/bus/pci/devices/0000:01:00.0/remove'
sudo sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:01.0/rescan'
sudo modprobe nvidia-drm
sudo systemctl start system-logind
sudo systemctl start lightdm

when I run this script on a non graphical terminal (e.g. tty3) I get this output:

sudo ./HDMI-fix

rmmod: ERROR: module nvidia is in use by: nvidia_uvm
Failed to start system-logind.service: Unit system_logind.service not found

Does anyone know what the problem might be?

change

sudo rmmod nvidia-drm nvidia-modeset nvidia

to

sudo rmmod nvidia-uvm nvidia-drm nvidia-modeset nvidia

This didn’t work. I inserted the setpci module in grub and added the entry. Made no difference. Did anyone manage too get this approach working? Making it as a service works better for me.

that got me a little further thank you!
now I’m down to this error message

[b]

Failed to start system-logind.service: Unit system_logind.service not found

[/b]

But the good news is, my system’s sound settings now shows the HDMI Output. But when I select it, sound still plays through my laptop’s speakers.

But I figured out that I had to open HDAJackRetask and tick Set model=auto (in options) and apply for the sound to really be played via HDMI.

Did anybody else experience this behavior?

change

sudo systemctl start system-logind

to

sudo systemctl start systemd-logind

systemd is missing the letter d.

“3D controller” here means that this GPU doesn’t have a display engine, presumably because it’s an Optimus laptop. Audio and display are both Intel’s responsibility there.