#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2023 JELOS (https://github.com/JustEnoughLinuxOS)

get_gpu_power_profile() {
  cat /sys/class/drm/card0/device/power_dpm_state 2>/dev/null
}

gpu_power_profile() {
  for card in /sys/class/drm/card*/device/power_dpm_state
  do
    if [ -e "${card}" ]
    then
      echo ${1} >${card} 2>/dev/null
    fi
  done
}

get_gpu_performance_level() {
  case ${HW_ARCH} in
    x86_64)
      cat /sys/class/drm/card0/device/power_dpm_force_performance_level 2>/dev/null
    ;;
    aarch64)
      get_setting system.gpuperf
    ;;
    esac
}

gpu_performance_level() {
  case ${HW_ARCH} in
    x86_64)
      for card in /sys/class/drm/card*/device/power_dpm_force_performance_level
      do
        if [ -e "${card}" ]
        then
          echo ${1} >${card} 2>/dev/null
        fi
      done
    ;;
    aarch64)
      case ${1} in
        profile_peak)
          set_gpu_gov performance
        ;;
        auto|profile_standard)
          set_gpu_gov ondemand
        ;;
        low)
          set_gpu_gov powersave
        ;;
      esac
    ;;
  esac
}

pcie_aspm_policy() {
  PCIEPOWERSAVE=$(get_setting system.power.pcie)
  POWERSAVEENABLED=$(get_setting system.powersave)
  if [ "${PCIEPOWERSAVE}" = "1" ] &&
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    if [ -e "/sys/module/pcie_aspm/parameters/policy" ]
    then
      echo ${1} >/sys/module/pcie_aspm/parameters/policy 2>/dev/null
    fi
  fi
}

cpu_perftune() {
  if [ -n "${1}" ]
  then
    DESIRED_EPP=${1}
  fi
  CPUPOWERSAVE=$(get_setting system.power.cpu)
  POWERSAVEENABLED=$(get_setting system.powersave)
  CPU="$(awk '/vendor_id/ {print $3;exit}' /proc/cpuinfo)"

  if [ "${CPUPOWERSAVE}" = "1" ] && \
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    case ${CPU} in
      AuthenticAMD)
        if [ "${1}" = "battery" ]
        then
          ryzenadj --power-saving >/dev/null 2>&1
        else
          ryzenadj --max-performance >/dev/null 2>&1
        fi
      ;;
    esac
  fi

  case ${CPU} in
    AuthenticAMD)
      PSTATE="amd_pstate"
      STATUS="active"
      WARM="passive"
    ;;
    GenuineIntel)
      PSTATE="intel_pstate"
      STATUS="passive"
      WARM="active"
    ;;
  esac

  if [ -f "/sys/devices/system/cpu/${PSTATE}/status" ]
  then
    if [ -n "${WARM}" ]
    then
      # Some devices need to switch before the handles are writeable (AYANEO).
      echo ${WARM} >/sys/devices/system/cpu/${PSTATE}/status
    fi
    echo ${STATUS} >/sys/devices/system/cpu/${PSTATE}/status
    while [ ! -f /sys/devices/system/cpu/cpufreq/policy0/energy_performance_preference ]
    do
      sleep .25
    done
    for policy in $(find /sys/devices/system/cpu/cpufreq/policy*/ -name energy_performance_preference)
    do
      EPP=$(get_setting system.power.epp)
      if [ -z "${EPP}" ]
      then
        EPP="balance_performance"
        set_setting system.power.epp ${EPP}
      fi
      if [ -n "${DESIRED_EPP}" ]
      then
        EPP="${DESIRED_EPP}"
      fi
      echo ${EPP} >${policy} 2>/dev/null
    done
  fi
}

audio_powersave() {
  POWERSAVEENABLED=$(get_setting system.powersave)
  AUDIOPOWERSAVE=$(get_setting system.power.audio)
  if [ "${AUDIOPOWERSAVE}" = "1" ] &&
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    for MODULE in snd_hda_intel snd_ac97_codec
    do
      if [ -e "/sys/module/${MODULE}/parameters/power_save" ]
      then
        echo ${1} >/sys/module/${MODULE}/parameters/power_save 2>/dev/null
      fi
    done
  fi
}

runtime_power_management() {
  POWERSAVEENABLED=$(get_setting system.powersave)
  RTPM=$(get_setting system.power.rtpm)
  if [ "${RTPM}" = "1" ] &&
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    find /sys/devices/{platform,pci*} -type f -name control -print0 2>/dev/null | \
    while read -r -d '' DEVICE
    do
      echo ${1} >"${DEVICE}" 2>/dev/null
      echo ${2} >"${DEVICE/control/autosuspend_delay_ms}" 2>/dev/null
    done
  fi
}

scsi_link_power_management() {
  POWERSAVEENABLED=$(get_setting system.powersave)
  RTPM=$(get_setting system.power.rtpm)
  if [ "${RTPM}" = "1" ] &&
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    find /sys/class/scsi_host/host*/ -type f -name link_power_management_policy -print0 2>/dev/null | \
    while read -r -d '' DEVICE
    do
      echo "${1}" >"${DEVICE}" 2>/dev/null
    done
  fi
}

wake_events() {
  POWERSAVEENABLED=$(get_setting system.powersave)
  WAKEEVENTS=$(get_setting system.power.wakeevents)
  if [ "${WAKEEVENTS}" = "1" ] && \
     [ "${POWERSAVEENABLED}" = "1" ]
  then
    for device in $(find /sys/devices/{platform,pci*} -type f -name wakeup 2>/dev/null)
    do
      echo ${1} >${device} 2>/dev/null
    done
  fi
}
