Dell Power Management
This page describes how to tweak the operation of your Dell laptop's power management facilities to work a little better than normal under Linux. The document has been written based on my experiences with Timon, a Dell Latitude C840 with a P4-M/1800 and 256MB RAM, but most of the suggestions presented here should work well with other Dell laptops, and some would even work well with other non-Dell laptops.
ACPI operation
There are quite a few documents out there on the Internet that describe how to get APM based power management working on a Dell laptop under Linux. I'm more interested in getting ACPI to work, as I quite like the event driven interface that's almost completely customisable. However, with ACPI support as it stands (kernel 2.6.6 at the time of writing), there are a few limitations. Most notably:
- Low-level management does not currently work with an ACPI enabled operating system. This means that features such as post-boot BIOS setup (Fn-F1) and the BIOS battery meter (Fn-F3) will not work with ACPI turned on. This is not too much of a problem for me, as these are still available right up until the kernel is booted, still longer than most other computers.
- Suspend to RAM is not currently supported very well under ACPI. This is documented, and as such I've not currently had a good play around with this feature.
- Certain ACPI hotkeys are not recognised (generally the unlabelled ones, Fn-D, Fn-Z, etc).
- The control component of ACPI is not currently very well supported. As such, it probably won't be a good idea at present to go changing things in the modular bay during operation (with the exception of batteries, which are supported under ACPI power management).
Most other things work quite well, though. An ACPI-based Dell Latitude C840 running Linux is certainly a decent system to take on the road.
It's probably worth noting at this point that I would suggest checking if there are any ACPI patches available for the kernel version you're using. If you're still using the 2.4 kernel tree, this is definitely a good idea. Things seem to be kept up-to-date in 2.6, though, but it's still something to consider.
Kernel configuration
The first thing you'll need to do is enable ACPI support in your kernel. I'll assume you have some knowledge of kernel compilation — this is probably a reasonably assumption given that running Linux on a laptop efficiently is not quite as straightforward as trying to run it on a desktop. If you have no experience of this there are plenty of documents out there describing this process, such as the Kernel Rebuild Guide, desgined to replace the old Kernel-HOWTO.
You'll want to set turn off APM support and turn on ACPI support. For your reference, I have the following ACPI components configured:
Component name | Config tag | State |
---|---|---|
ACPI Support | CONFIG_ACPI | Built in |
Sleep States | CONFIG_ACPI_SLEEP | Built in |
AC Adapter | CONFIG_ACPI_AC | Built in |
Battery | CONFIG_ACPI_BATTERY | Built in |
Button | CONFIG_ACPI_BUTTON | Built in |
Fan | CONFIG_ACPI_FAN | Built in |
Processor | CONFIG_ACPI_PROCESSOR | Built in |
Thermal Zone | CONFIG_ACPI_THERMAL | Built in |
ASUS/Medion Laptop Extras | CONFIG_ACPI_ASUS | Disabled |
Toshiba Laptop Extras | CONFIG_ACPI_TOSHIBA | Disabled |
Debug Statements | CONFIG_ACPI_DEBUG | Disabled |
Power Management Timer Support | CONFIG_X86_PM_TIMER | Built in1 |
1 This is not strictly necessary, I was just trying it at the time. It's up to you. I don't think removing it would cause problems, even with processor speed scaling, but it's something to bear in mind.
All being well you system will next start up and provide the ACPI interface to you. You can check by running something like "dmesg|less
" and looking for lines containing "ACPI".
ACPI software support
Just building ACPI support into the kernel will enable CPU idling by ACPI and basic CPU thermal protection, but some events require external handing, such as response to pressing the power button. For this, I'd recommend acpid, which is available in Debian or from the acpid SourceForge site. You could use this to shut down (or software suspend if you get this working satisfactorily), the computer on pressing the power button, for example. All ACPI events should be handlable by acpid, all you have to do is decide what you'd like them to do.
What to do when the power button is pressed is reasonably straightforward. It's also fairly logical that pressing the power button generates an ACPI event that can be handled by the operating system. It might not be entirely as obvious that opening and closing the lid also generated ACPI events. These are very similar to the button events with the added bonus that the current state of the lid (open or closed) can be read. The sleep key (Fn-ESC) also generates ACPI sleep button events that you can progrem responses for.
Lid events
It's interesting to note that unlike other laptops I've seen, when ACPI is enabled on the Dell it won't automatically turn off the backlight when the lid is closed. The result is more power being used and heat being generated than necessary.
I've developed a short script which works around this problem. It currently only works when X is enabled (although just silently exits when X is not running). This script has been set up as the event handler for the lid event. Since the script is set up for my own personal needs, certain assumptions are made. You're welcome to modify the script for your own needs if you'd like to. Currently, the script makes the following assumptions:
- Only one X server will be running at once.
- The X server is started with "startx". This could be altered to use display managers if required.
- The following programs are installed (they are fairly fundamental):
- Bash
- GNU ps
- su
- xset
- sed
- It assumes that xscreensaver is started with the X server, or at least will always be running when X is running. This is important, as xscreensaver somewhat forcefully takes over DPMS control, so we have to jump through a few hoops here. If you don't use xscreensaver, just using "xset dpms force off" and "xset dpms force on" should work.
This actually works better than the laptop automatically shutting down the backlight when the lid is closed, as when the display goes into DPMS off mode, xscreensaver will not even attempt to run a hack in the background, thereby reducing CPU load and saving more power, leading on to longer battery life and reduced heat generation. It also locks the screen as the lid is closed.
As it stands, the script is as follows:
#!/bin/bash XUSER=`ps -C startx -o user h` [[ 0$XUSER == 0 ]] && XUSER=none if [[ 0`cat /proc/acpi/button/lid/LID/state|cut -c 13-16` == 0open ]] then # Lid has been opened if [[ $XUSER != none ]] then su - $XUSER -c DISPLAY=:0.0 xset dpms force on su - $XUSER -c "/bin/sed -i 's/^dpmsOff:.*$/dpmsOff: 0:30:00/' ~$XUSER/.xscreensaver" su - $XUSER -c "DISPLAY=:0.0 /usr/bin/xscreensaver-command -restart" su - $XUSER -c "DISPLAY=:0.0 /usr/bin/xscreensaver-command -cycle" fi else # Lid has been closed if [[ $XUSER != none ]] then su - $XUSER -c "/bin/sed -i 's/^dpmsOff:.*$/dpmsOff: 0:00:10/' ~$XUSER/.xscreensaver" su - $XUSER -c "DISPLAY=:0.0 /usr/bin/xscreensaver-command -restart" su - $XUSER -c DISPLAY=:0.0 xset dpms force off su - $XUSER -c "DISPLAY=:0.0 /usr/bin/xscreensaver-command -lock" fi fi
The script will send the display into DPMS off mode when the lid is shut, resulting in the backlight being turned off. Actually, it asks the X server to do this after 10 seconds of inactivity, because this is the smallest figure that xscreensaver will accept, for some reason. This is done indirectly, by changing the .xscreensaver file of the person in charge of the X server. The screen is then locked, but will not display a hack because it will detect the DPMS off state. On opening the lid, the display is forced on and the DPMS timout is set to 30 minutes. Xscreensaver is then told to cycle the hack, which will start displaying the hack as the screen is now not in a DPMS power saving mode.
Software Suspend kernel support
Software suspend does not work nearly as well with my Dell as with my old Sony VAIO. This has been traced down to a problem with the nVidia acceleration. I'll look into this in more detail in the future and write back with my findings.
CPU frequency scaling
One thing that CPU manufacturers today seem to be pushing above all else is the clock speed of their processors. This is a good thing if you need the extra speed, but most of the time, most people don't. The extra speed just drains batteries and generates heat. The major processor manufacturers realised this some time ago and started building in facilities to slow down their processors if required. In fact, both AMD and Intel are now doing this in their desktop processors.
The Dell Latitude C840 has an Intel P4-M processor in it (1.8GHz in my case, although various different options are available). This supports Intel's Enhanced SpeedStep, apparently, but the Linux ESS driver doesn't seem to think so. It does, however, work quite nicely with the "Intel Speedstep on ICH-M chipsets (ioport interface)" option. Obviously, the setup you need depends on your CPU and chipset, but these options work for me:
Component name | Config tag | State |
---|---|---|
CPU Frequency Scaling | CONFIG_CPU_FREQ | Built in |
Default CPUFreq governor | CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE | Userspace |
CPU frequency table helpers | CONFIG_CPU_FREQ_TABLE | Built in |
Intel Speedstep on ICH-M chipsets (ioport interface) | CONFIG_X86_SPEEDSTEP_ICH | Built in |
That sorts out the kernel side of things, but you'll still need to change the speed. You could do this manually, but there are a few programs out there that will do this automatically. One that I would particularly recommend is powernowd, which uses several alrgorithms to decide the CPU speed, but basically runs it in slow mode when not needed, speeding up when applications demand more processing power. It can be downloaded as a Debian package or from the powernowd web site.