echo 命令在手动执行时有效,但作为 bash 脚本插入时无效

echo 命令在手动执行时有效,但作为 bash 脚本插入时无效

我正在使用 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

相关内容