Bazzite higher idle power draw after waking from suspend

Hi, I’ve been measuring the desktop’s idle power consumption at the wall via Kill A Watt meter. After starting up, login, and letting power settle, the meter measures ~16W. Leaving the desktop to suspend [s2idle] it goes down to ~2W, but waking it up and letting the idle power consumption settle again it’s ~23W.

I looked around and found this thread ( [RESPONDED] Higher idle power consumption after resume from s2idle ) for the 13’s 7640U, diffed the /sys/kernel/debug/amd_pmf/current_power_limits and did not see anything as long as zzach’s diff on the thread.

$ diff startup.log resume.log  # files are /sys/kernel/debug/amd_pmf/current_power_limits
10c10
<       Control: I/O- Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
---
>       Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
12d11
<       Latency: 0
379c378
<       Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
---
>       Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
381d379
<       Latency: 0, Cache Line Size: 64 bytes
384,388c382,386
<       Region 0: Memory at b0a00000 (32-bit, non-prefetchable) [size=1M]
<       Region 1: Memory at b0b00000 (32-bit, non-prefetchable) [size=8K]
<       Region 2: Memory at 6820000000 (64-bit, prefetchable) [size=512K]
<       Region 4: Memory at b0b03000 (32-bit, non-prefetchable) [size=4K]
<       Region 5: Memory at b0b02000 (32-bit, non-prefetchable) [size=4K]
---
>       Region 0: Memory at b0a00000 (32-bit, non-prefetchable) [virtual] [size=1M]
>       Region 1: Memory at b0b00000 (32-bit, non-prefetchable) [virtual] [size=8K]
>       Region 2: Memory at 6820000000 (64-bit, prefetchable) [disabled] [size=512K]
>       Region 4: Memory at b0b03000 (32-bit, non-prefetchable) [virtual] [size=4K]
>       Region 5: Memory at b0b02000 (32-bit, non-prefetchable) [virtual] [size=4K]

In case hardware configuration matters I have the 128GB full desktop with a 4GB SN7100 NVME on the primary SSD slot, a 1GB Samsung 990 EVO Plus NVME in the secondary SSD slot, and swapped out the wifi card for an Intel 6E AX210.

BIOS is updated to 3.05.

Looks like after waking up from suspend the mclk is pinned at 1000Mhz and unable to downclock.

$ cat /sys/class/drm/card1/device/pp_dpm_mclk  # post waking up from suspend
0: 400Mhz 
1: 800Mhz 
2: 1000Mhz *

I wasn’t able to pin it to a lower state directly, even with power_dpm_force_performance_level=manual,

$ echo 0 | sudo tee /sys/class/drm/card1/device/pp_dpm_mclk
0
tee: /sys/class/drm/card1/device/pp_dpm_mclk: Invalid argument

but setting

$ echo low | sudo tee /sys/class/drm/card1/device/power_dpm_force_performance_level
low
$ cat /sys/class/drm/card1/device/pp_dpm_mclk 
0: 400Mhz *
1: 800Mhz 
2: 1000Mhz 

was able to bring the idle power draw back down to ~16W.

1 Like

fclk being unable to downclock might be the issue here, and mclk is just reacting to fclk. Looking at smu v14, the low performance level does not set mclk. Instead it sets fclk, and reading the fclk during startup and after resume shows it’s also getting pinned.

During startup:

$ grep '' /sys/class/drm/card1/device/pp_dpm* /sys/class/drm/card1/device/power_*
/sys/class/drm/card1/device/pp_dpm_dcefclk:
/sys/class/drm/card1/device/pp_dpm_fclk:0: 400Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:1: 1000Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:2: 1200Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:3: 1400Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:4: 1600Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:5: 1700Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:6: 1850Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:7: 2000Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:0: 400Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:1: 800Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:2: 1000Mhz 
/sys/class/drm/card1/device/pp_dpm_pcie:
/sys/class/drm/card1/device/pp_dpm_sclk:0: 600Mhz 
/sys/class/drm/card1/device/pp_dpm_sclk:1: 612Mhz *
/sys/class/drm/card1/device/pp_dpm_sclk:2: 2900Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:0: 600Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:1: 736Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:2: 883Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:3: 981Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:4: 1104Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:5: 1261Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:6: 1472Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:7: 1472Mhz 
/sys/class/drm/card1/device/power_dpm_force_performance_level:auto
/sys/class/drm/card1/device/power_dpm_state:performance
/sys/class/drm/card1/device/power_state:D0

After resuming from suspend

$ grep '' /sys/class/drm/card1/device/pp_dpm* /sys/class/drm/card1/device/power_*
/sys/class/drm/card1/device/pp_dpm_dcefclk:
/sys/class/drm/card1/device/pp_dpm_fclk:0: 400Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:1: 1000Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:2: 1200Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:3: 1400Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:4: 1600Mhz *
/sys/class/drm/card1/device/pp_dpm_fclk:5: 1700Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:6: 1850Mhz 
/sys/class/drm/card1/device/pp_dpm_fclk:7: 2000Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:0: 400Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:1: 800Mhz 
/sys/class/drm/card1/device/pp_dpm_mclk:2: 1000Mhz *
/sys/class/drm/card1/device/pp_dpm_pcie:
/sys/class/drm/card1/device/pp_dpm_sclk:0: 600Mhz 
/sys/class/drm/card1/device/pp_dpm_sclk:1: 606Mhz *
/sys/class/drm/card1/device/pp_dpm_sclk:2: 2900Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:0: 600Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:1: 736Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:2: 883Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:3: 981Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:4: 1104Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:5: 1261Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:6: 1472Mhz 
/sys/class/drm/card1/device/pp_dpm_socclk:7: 1472Mhz 
/sys/class/drm/card1/device/power_dpm_force_performance_level:auto
/sys/class/drm/card1/device/power_dpm_state:performance
/sys/class/drm/card1/device/power_state:D0

Setting fclk to level 0 did help out and brought idle power draw back to what it was during startup.

echo manual | sudo tee /sys/class/drm/card1/device/power_dpm_force_performance_level 
echo 0 | sudo tee /sys/class/drm/card1/device/pp_dpm_fclk
1 Like

Eventually ruled out this being a kernel or firmware issue. amd-s2idle test --duration 300 (see amd-debug-tools/docs/amd-s2idle.md at master · superm1/amd-debug-tools · GitHub ) was able to suspend my machine and resume it without causing mclk to stay pinned. Idle power draw also settled to the same ~16W as start up.

Instead it looks like systemd’s suspend was doing additional things that amd-s2idle was not. Of the additional hooks, it turned out to be this one

$ cat /usr/lib/systemd/system-sleep/displaylink
#!/usr/bin/bash
# Copyright (c) 2015 - 2019 DisplayLink (UK) Ltd.

suspend_displaylink-driver()
{
  #flush any bytes in pipe
  while read -n 1 -t 1 SUSPEND_RESULT < /tmp/PmMessagesPort_out; do : ; done;

  #suspend DisplayLinkManager
  echo "S" > /tmp/PmMessagesPort_in

  if [ -p /tmp/PmMessagesPort_out ]; then
    #wait until suspend of DisplayLinkManager finish
    read -n 1 -t 10 SUSPEND_RESULT < /tmp/PmMessagesPort_out
  fi
}

resume_displaylink-driver()
{
  #resume DisplayLinkManager
  echo "R" > /tmp/PmMessagesPort_in
}

main_systemd()
{
  case "$1/$2" in
  pre/*)
    suspend_displaylink-driver
    ;;
  post/*)
    resume_displaylink-driver
    ;;
  esac
}

main_pm()
{
  case "$1" in
    suspend|hibernate)
      suspend_displaylink-driver
      ;;
    resume|thaw)
      resume_displaylink-driver
      ;;
  esac
  true
}

DIR="$(cd $(dirname "$0") && pwd)"

if [[ "$DIR" =~ "systemd" ]]; then
  main_systemd "$@"
elif [[ "$DIR" =~ "pm" ]]; then
  main_pm "$@"
fi

I ended up revoking the hook’s execute permissions,

sudo rpm-ostree usroverlay  # I'm on Bazzite so cannot chmod the file directly.
sudo chmod -x /usr/lib/systemd/system-sleep/displaylink

and idle power consumption and mclk were able to come down to start up levels.

I don’t use DisplayLink so permanently disabling the hook will be my solution. My probing around ends here.