File amdgpu-power.sh of Package amd-dgpu-pwr

#!/bin/bash
# 61‑amdgpu‑power – early‑boot helper for discrete AMD GPUs
# shellcheck shell=sh

. /lib/dracut-lib.sh       # getarg(), warn(), etc.
set -ux
# set -e
# ───────────── 0 – fast‑bail conditions ────────────────
[ -n "${resume-}" ] && exit 0    # resume (from hibernate), do nothing

case "$(cat /proc/cmdline)" in
  *modprobe.blacklist=amdgpu*|*modprobe.blacklist=*amdgpu*) exit 0 ;;
esac

# ───────────── 1 – defaults + cmdline overrides ────────
PCI_BASE="0000:03:00"   #Base dGPU device
PCI_SLOT="0" # For hot reset using /sys/bus/pci/slots/X
POWER1CAP="50000000"   # µW
TIMEOUT=20             # seconds total before we give up

arg=$(getarg rd.amdgpu_pci=) && PCI_BASE="${arg#*=}"
arg=$(getarg rd.amdgpu_pci_slot=) && PCI_SLOT="${arg#*=}"
arg=$(getarg rd.amdgpu_cap=) && POWER1CAP="${arg#*=}"
arg=$(getarg rd.amdgpu_wait=) && TIMEOUT="${arg#*=}"

GPUPATH="/sys/bus/pci/devices/${PCI_BASE}.0"
SLOTPATH="/sys/bus/pci/slots/${PCI_SLOT}"


# ───────────── 2 – ensure device & driver exist ────────


echo 0 > "$SLOTPATH/power"


sleep "2s"

echo 1 > "$SLOTPATH/power"
sleep "2s"
(
#     echo 1 > /sys/bus/pci/rescan

    modprobe -v -a snd_hda_intel amdgpu || {
        warn "amdgpu-power: modules not loadable (code $?), giving up"
        exit -1; # does not work due to subshell
    }
    
#     wait
) 1>&2


# helper: wait until a file/dir appears or TIMEOUT expires
wait_path() {
    local path=$1 i=0
    while [ $i -lt "$TIMEOUT" ] && [ ! -e "$path" ]; do
        i=$((i+1))
        sleep 1
    done
    [ -e "$path" ]
}

# ───────────── 3 – main work ────────────
(
    #  wait for GPU directory
    if ! wait_path "$GPUPATH"; then
        warn "amdgpu‑power: GPU path $GPUPATH not found"
        exit 0
    fi

    cd "$GPUPATH" || exit 1

    # wait for PM knobs
    for knob in power/control d3cold_allowed; do
        if ! wait_path "$knob"; then
            warn "amdgpu‑power: $knob missing, giving up"
            exit 0
        fi
    done
    
    
    #  wait for pp_features
    if ! wait_path "pp_features"; then
        warn "amdgpu‑power: pp_features missing, giving up"
        exit 0
    fi

    # snapshot current PM state
    POWER_CTRL=$(cat power/control 2>/dev/null || echo auto)
    D3COLD=$(cat d3cold_allowed 2>/dev/null || echo 1)



    #  wait for hwmon/power1_cap and write the cap
    i=0
    PWRCAP_RET="-1"
    while true; do
        [[ "$i" -ge "$TIMEOUT" ]] && {
            [[ "$PWRCAP_RET" != "0" ]] && warn "amdgpu-power: retries exceeded"
            break
        }
        i=$((i+1))
        sleep "1.1s"
        cd "$GPUPATH" || exit 1
#         ls -l
#         ls -l hwmon || :
#         ls -l hwmon/* || :

        echo on > power/control
        echo 0  > d3cold_allowed
        { 
            grep -E 'PPT.*enabled' pp_features || {
                warn "amdgpu-power: PPT disabled or not present!"
                continue ;
            }
            
            CAP_PATH="$(echo -n hwmon/*/power1_cap)"
            [[ "$CAP_PATH" == 'hwmon/*/power1_cap' ]] && {
                warn "amdgpu-power: hwmon power1_cap not available yet"
                continue;
            }
            #"$(readlink -f hwmon/*/power1_cap)"
    #         echo "$CAP_PATH"
    #         ls -l "$CAP_PATH"
            echo "$POWER1CAP" > "$CAP_PATH" ;
            PWRCAP_RET=$?
        } #&& break
        
        [[ "$PWRCAP_RET" == "0" ]] && {
#             break
            TIMEOUT='3'
        } 
        

        
        
    done
    [[ "$PWRCAP_RET" != "0" ]] && {
        warn "amdgpu‑power: power1_cap not writable (code $PWRCAP_RET)"
    }
    
    sleep 1
    
    # restore previous PM policy
   echo "$POWER_CTRL" > power/control
   echo "$D3COLD"     > d3cold_allowed
) 1>&2

#     (
#         modprobe -v snd_hda_intel || {
#             warn "snd_hda_intel: not loadable (code $?), giving up"
#             exit -1; # does not work due to subshell
#         }
#     )

wait || warn "Got modprobe status $?"

# Reload audio devices, seems like this doesn't work until graphics come up?

AUD_DRV_PATH="/sys/module/snd_hda_intel/drivers/pci:snd_hda_intel/"
# 
# for dev in "$AUD_DRV_PATH"/????:??:??.? ; do 
#     echo 1 > "$dev/remove"
# done
# wait
# sleep "2s"
# echo 1 > /sys/bus/pci/rescan &


exit 0
openSUSE Build Service is sponsored by