You are viewing tirdc

 
 
19 June 2011 @ 10:52 am
Setting the power_profile for your Radeon graphics card using systemd  
As of now pretty much everyone has heard of systemd, the next generation init system for Linux. Next to the fact that if provides a really fast boot (on different systems tested approximately 50% of the original boot time) and a clean solution for dependencies of services it also offers the capability to write services in a very simple manner. So today we are going to write a simple service to set your power profile (as introduced last year). Note that you (obviously) need a systemd enabled system like Fedora 15.

First of all we need to know how to set set power profile. This requires three things: a fairly recent kernel, a Radeon graphics card that supports power modes on Linux and sysfs enabled in your kernel. A simple way to test this is to execute the following command:

test -f /sys/class/drm/card0/device/power_profile && echo "power_profile supported" || echo "power_profile NOT supported"

Note: This assumes that your Radeon card is the "first card" (i.e. "card0"). This might vary from system to system.

The will show you if the power modes are supported by your system. If your system is supported you need two files:

1.) The systemd service file in /etc/systemd/system/radeon-power_profile
[Unit]
Description=Radeon Power Profile

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/radeon-power_profile low

[Install]
WantedBy=multi-user.target

2.) A small helper script to set the power mode in /usr/local/sbin/radeon-power_profile
#!/bin/sh

EXEC_NAME=`basename $0`;

TARGET="/sys/class/drm/card0/device/power_profile"
CURRENT_PROFILE=`cat ${TARGET}`

append_profile() {
        local PROFILE=$1
        echo -n "  ${PROFILE}"
        if [ "x${CURRENT_PROFILE}x" == "x${PROFILE}x" ]; then
                echo -n " (current)"
        fi
        echo
}

if [ $# != 1 ]; then
        echo "usage: ${EXEC_NAME} "
        echo
        echo "Valid profiles:"
        for AVAILABLE_PROFILE in low high default auto; do
                append_profile ${AVAILABLE_PROFILE}
        done
        exit 0
fi

PROFILE="$1"

if [ "x${PROFILE}x" == "xlowx" ] || [ "x${PROFILE}x" == "xhighx" ] || [ "x${PROFILE}x" == "xautox" ] || [ "x${PROFILE}x" == "xdefaultx" ]; then
        echo "${PROFILE}" > ${TARGET}
else
        logger "[${EXEC_NAME}] WARN: Invalid power_profile '${PROFILE}'"
        exit 1
fi

exit 0

Note: If your card is not "card0" you need to change the value of TARGET to the proper value.

After you create the scripts you should test if this works for you. The service is meant to set your power mode to low which is the best for mobile devices running on battery or to cool down your system. To test the service call:

/usr/local/sbin/radeon-power_profile

This will print out which profile is currently active ("default" in most cases). Now you can start the service

systemctl start radeon-power_profile.service

This will most likely cause a single flicker of the display (this might be a bug as it does not happen when GPU and memory clock changes happen on Microsoft Windows). After that a second call to /usr/local/sbin/radeon-power_profile should show your clock is now at "low". Verify that your system is running stable and smooth as before. Note: Setting the power mode to low will obviously cause your 3D rendering to be slower. If everything works as expected you can enable the service by default using

systemctl enable radeon-power_profile.service

Now your system will set the power mode during boot. On my systems it really extended the battery life time and my passive (fan-less) card went from 70°C to 45°C.
 
 
( 3 comments — Leave a comment )
(Anonymous) on June 25th, 2011 05:31 pm (UTC)
udev?
This seems like something that ought to get handled via udev in response to the device appearing, rather than via systemd when the system boots.
tirdctirdc on July 9th, 2011 12:02 pm (UTC)
Re: udev?
You are right, udev would really suite this task. I haven't had the time to experiment with this yet, so feel free to provide a small howto and I will put it here.
dronord on March 27th, 2012 10:50 pm (UTC)
Tested in Fedora 16 x86_64
$ sudo -s
# vim /etc/udev/rules.d/30-local.rules
KERNEL=="card0", SUBSYSTEM=="drm", DRIVERS=="radeon", ATTRS{device}=="0x6718", ATTR{device/power_method}="profile", ATTR{device/power_profile}="low"

Change ATTRS{device} value.
You can try without this param. Like:
KERNEL=="card0", SUBSYSTEM=="drm", DRIVERS=="radeon", ATTR{device/power_method}="profile", ATTR{device/power_profile}="low"

Find:
# udevadm info -an /dev/dri/card0
.............................................................................
looking at parent device '/devices/pci0000:00/0000:00:02.0/0000:01:00.0':
KERNELS=="0000:01:00.0"
SUBSYSTEMS=="pci"
DRIVERS=="radeon"
ATTRS{vendor}=="0x1002"
ATTRS{device}=="0x6718"
ATTRS{subsystem_vendor}=="0x174b"
.............................................................................
( 3 comments — Leave a comment )