我正在使用 Ubuntu 19.04,并且使用 AMD RX460 连接到我的 LG LED 电视时,HDMI 上有声音噼啪作响。
这可能与 AMD GPU 驱动程序有关,因为我在 Windows 10 pro 上遇到了完全相同的问题。在 Windows 上,我使用 AMD Adrenaline GUI 来解决问题,方法是不让 GPU 进入 p-State 0(214 MHz,0.8v)。在那里,我将 p-State 1 设置为最小状态,并修改频率和电压以匹配 p-State 0。可能 p-State 0 应用了一些其他省电设置,这就是为什么为 p-state 1 设置相同的频率和电压会产生相同的噼啪声。
现在我尝试在 Ubuntu 19.04 上做同样的事情,但使用 amdgpu 驱动程序。我创建了文件 hdmi-audio-crack-fix 和 hdmi-audio-crack-fix.service,如下所示:
1- 将 hdmi-audio-crack-fix 放置在 /usr/bin 中,并具有适当的权限。
#!/bin/bash
# This simple script disables pstate 0 for amdgpu to fix audio crackling over hdmi.
# Then pstate 1 is modified to match pstate 0 voltage and frequency.
# Also a little bit of undervolting is introduced.
# Copy to /usr/bin/ and then copy .service file to /etc/systemd/system/
# Using Ubuntu echo located inside /bin instead of bash built-in echo
amdgpu_echo="/bin/echo"
# Change amdgpu dpm performance level to manual
$amdgpu_echo "manual" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/power_dpm_force_performance_level
# Disable pstate 0 as this is causing the crackling over hdmi
$amdgpu_echo "1 2 3 4 5 6 7" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_dpm_sclk
$amdgpu_echo "1 2 3 4 5 6 7" > /sys/class/drm/card0/device/pp_dpm_sclk
# Now reduce pstate 1 clock to reduce temperature on idle
$amdgpu_echo "s 1 220 800" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
# Undervolting gpu for highest pstates
$amdgpu_echo "s 5 1138 992" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
$amdgpu_echo "s 6 1172 1005" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
$amdgpu_echo "s 7 1212 1050" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
# Now sync new core/voltage table with GPU
$amdgpu_echo 'c' > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
2- 将 hdmi-audio-crack-fix.service 放在 /etc/systemd/system/ 内并执行sudo systemctl enable hdmi-audio-crack-fix.service
。
[Unit]
Description=Temporary fix for amdgpu HDMI audio crackling
[Service]
Type=oneshot
ExecStart=/usr/bin/hdmi-audio-crack-fix
[Install]
WantedBy=multi-user.target
一切都按预期工作,但以下行似乎没有任何效果,并且 GPU 仍然进入 p-State 0:
$amdgpu_echo "1 2 3 4 5 6 7" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_dpm_sclk
或者
$amdgpu_echo "1 2 3 4 5 6 7" > /sys/class/drm/card0/device/pp_dpm_sclk
问题是,当我使用以下命令通过终端手动执行此命令时,它可以正常工作:
sudo su -
echo "1 2 3 4 5 6 7" > /sys/class/drm/card0/device/pp_dpm_sclk
更新:
这是服务状态的输出:
● hdmi-audio-crack-fix.service - Temporarly fix for amdgpu HDMI audio crackling
Loaded: loaded (/etc/systemd/system/hdmi-audio-crack-fix.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Sat 2019-05-04 21:24:25 +0430; 4h 14min ago
Main PID: 1004 (code=exited, status=0/SUCCESS)
May 04 21:24:24 Rivendell systemd[1]: Starting Temporarly fix for amdgpu HDMI audio crackling...
May 04 21:24:25 Rivendell systemd[1]: hdmi-audio-crack-fix.service: Succeeded.
May 04 21:24:25 Rivendell systemd[1]: Started Temporarly fix for amdgpu HDMI audio crackling.
答案1
好吧,我找到了问题,它与 bash 脚本无关。我说的无法产生 gpu 所需行为的命令实际上正在运行。
我不知道的是,每当 pp_od_clk_voltage 被修改时,pp_dpm_sclk 都会重置为默认值。因此,在修改 pp_od_clk_voltage 之前的任何更改都是无用的。
我只需要在执行与 pp_od_clk_voltage 相关的命令后执行与 pp_dpm_sclk 相关的命令即可。如果有人感兴趣的话,最终的工作脚本如下(AMD RX460):
#!/bin/bash
# **************************************Info************************************* #
# #
# This simple script disables p-State 0 for amdgpu: fix audio-crackling over hdmi.#
# Then p-State 1 is modified to match p-State 0 voltage and frequency. #
# Also a little bit of undervolting is also introduced to keep gpu happy. #
# #
# *************************************README************************************ #
# #
# Inside the directory containing hdmi-audio-crack-fix and .service files, run: #
# #
# sudo cp hdmi-audio-crack-fix /usr/bin/ #
# sudo chmod 755 /usr/bin/hdmi-audio-crack-fix #
# sudo cp hdmi-audio-crack-fix.service /etc/systemd/system/ #
# sudo systemctl enable hdmi-audio-crack-fix.service #
# #
# Check if everything is working as intended: #
# cat /sys/class/drm/card0/device/pp_od_clk_voltage #
# cat /sys/class/drm/card0/device/pp_dpm_sclk #
# #
# **************************************END************************************** #
# Change amdgpu dpm performance level to manual
echo "manual" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/power_dpm_force_performance_level
# Reduceing p-State 1 and 2 clock to reduce temperature on idle
echo "s 1 220 800" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
echo "s 2 620 810" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
# Undervolting gpu for the highest p-States: 5, 6, 7
echo "s 5 1138 992" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
echo "s 6 1172 1005" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
echo "s 7 1212 1050" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
# Now sync new core/voltage table with GPU
echo "c" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_od_clk_voltage
# Finally, Disable pstate 0 as this is causing the crackling over hdmi
# This step should run after any modification to pp_od_clk_voltage, otherwise it gets reset.
echo "1 2 3 4 5 6 7" > /sys/devices/pci0000:64/0000:64:00.0/0000:65:00.0/pp_dpm_sclk