📜 ⬆️ ⬇️

Cooking Linux on Asus U31SD / P31SD and the like


After purchasing the Asus P31SD and installing Linux on it, it was a shame to see only 6 hours of battery life instead of the desired 10-12. It was not possible to return back to Windows (even cywgin did not help here), so it was decided to stock up on coffee and take the next weekend to solve these problems.

We consider the solution on the example of Ubuntu 11.10.

PS In theory, the guide is suitable for all laptops with Sandybridge and Nvidia Optimus.

An important, for us, part of the laptop configuration:
Processor : Intel Core i3-2310M ( Sandybridge )
Video adapter : Nvidia Geforce 520M ( Nvidia Optimus )
')
So, immediately after installing Linux, we see the following problems:
  1. Crazy brightness.
  2. Increased energy consumption is our primary goal.
  3. Sleep does not work - to make life easier, make it work

Brightness


Symptom: the backlight tries to simultaneously control the hardware module and the software module from the DE, resulting in jumps in a random direction.

Problems with brightness in laptops are very common and varied, but almost everything is solved by one method: adding core to the kernel boot parameters acpi_backlight=vendor , which signals that the hardware controls the brightness and does not need to programmatically climb there.

Open /etc/default/grub and enter the parameter in GRUB_CMDLINE_LINUX , you get:
 GRUB_CMDLINE_LINUX="acpi_backlight=vendor" 

We save, update the grub configuration ( sudo update-grub ), reboot and enjoy the highlight behavior.

Sleeping mode


Symptom: when sending a laptop to sleep, the device violently resists and eventually freezes.

After a brief search, we find the culprits: badly falling asleep USB hubs. And next we find the solution for the pm-utils hook:
/etc/pm/sleep.d/20_custom-asus-u31sd:
 #!/bin/sh BUSES="0000:00:1a.0 0000:00:1d.0" case "${1}" in hibernate|suspend) # Switch USB buses off for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/unbind done ;; resume|thaw) # Switch USB buses back on for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/bind done ;; esac 

Save, make executable ( sudo chmod +x /etc/pm/sleep.d/20_custom-asus-u31sd ), check.
Works? Nearly. After getting out of sleep, the display brightness drops to a minimum ... You can correct the mistake in the same hook. You can get the brightness value somewhere from / sys. Most drivers call the parameters trite so just look for backlight there:
 $ find /sys -name backlight /sys/devices/platform/asus-nb-wmi/backlight 

Found! After studying the viscera, the brightness value was in /sys/devices/platform/asus-nb-wmi/backlight/asus-nb-wmi/brightness . Let's add to the previous hook its saving and restoring:
 #!/bin/sh BUSES="0000:00:1a.0 0000:00:1d.0" case "${1}" in hibernate|suspend) # Switch USB buses off for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/unbind done # Saving brightness to /tmp/br cat /sys/devices/platform/asus-nb-wmi/backlight/asus-nb-wmi/brightness > /tmp/br ;; resume|thaw) # Switch USB buses back on for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/bind done # Restoring brightness from /tmp/br cat /tmp/br > /sys/devices/platform/asus-nb-wmi/backlight/asus-nb-wmi/brightness ;; esac 

Check it again and ... it works! Now let's get down to the main enemy, power consumption.

Increased energy consumption


Shoot the appetites of Linux will be already in 3 stages.

1. Discrete graphics


The laptop is equipped with two video adapters: integrated (Intel) and discrete (Nvidia). But not a simple Nvidia, and working on technology Nvidia Optimus. That same Optimus, whose support in the foreseeable future in Linux is not expected.

But the glory of the open-sourc world is full of enthusiasts. Bumblebee deals with Optimus (and sometimes friendship). They have made good progress:

Naturally the project is full of crutches, but it's still better than nothing.
Let's install:
 $ sudo add-apt-repository ppa:bumblebee/stable $ sudo apt-get update $ sudo apt-get install bumblebee 

Unfortunately, virtually every laptop has a different ACPI video card on / off command (a large table is compiled here ), so power management in Bumblebee is turned off by default. From the table above, take the commands and write them in /etc/bumblebee/cardoff and /etc/bumblebee/cardon respectively:
/etc/bumblebee/cardoff:
\_SB.PCI0.PEG0.GFX0.DOFF

/etc/bumblebee/cardon:
\_SB.PCI0.PEG0.GFX0.DON

Then in /etc/bumblebee/bumblebee.conf power management:
 ENABLE_POWER_MANAGEMENT=Y 

and force the service to terminate (and turn off the discrete video card accordingly) if nobody uses it:
 STOP_SERVICE_ON_EXIT=Y 

We save, reboot, look at the energy consumption - significantly decreased.
Before we go further, we fix the waiting mode again: the fact is that when going to sleep, the active video driver (nvidia or nouveau) will try to prepare a card, but the card is turned off. Let's just decide and "in the forehead": add 2 commands to the previously used hook:

The hook will look like this:
 #!/bin/sh BUSES="0000:00:1a.0 0000:00:1d.0" case "${1}" in hibernate|suspend) # Switch USB buses off for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/unbind done cat /sys/devices/platform/asus-nb-wmi/backlight/asus-nb-wmi/brightness > /tmp/br # Switch optimus back on before going to sleep, avoids the "constant on" # bug that occurs after 2 suspend/resume cycles (thanks kos888) echo `cat /etc/bumblebee/cardon` | tee /proc/acpi/call ;; resume|thaw) # Switch USB buses back on for bus in $BUSES; do echo -n $bus | tee /sys/bus/pci/drivers/ehci_hcd/bind done cat /tmp/br > /sys/devices/platform/asus-nb-wmi/backlight/asus-nb-wmi/brightness # Switch optimus off before resuming, avoids unneccessary power draw echo `cat /etc/bumblebee/cardoff` | tee /proc/acpi/call ;; esac 


2. Integrated video card


Having played with different versions of the cores, I accidentally noticed a reduced power consumption on versions up to 2.6.39 inclusive. Having rushed to search in these parameters I in the guess was not mistaken.
The problem was discovered: the patch adopted in the i915 driver in the 3.0 kernel is to blame. But, fortunately, it can be circumvented without consequences.
In the already known /etc/default/grub add the parameter i915.i915_enable_rc6=1 . The line will expand to:
 GRUB_CMDLINE_LINUX="acpi_backlight=vendor i915.i915_enable_rc6=1" 

We update the grub configuration, reboot and look at the battery readings. Now you can live. And you can reduce more!

3. Additional small tweaks


By running the powertop and applying all the recommended tweaks, you can squeeze another 0.5-1 Wh, which on this gland can additionally give up to an hour of battery life. But not to be played every time with powertop? We automate all this business through pm-utils. We have 4 separate scripts:

1. One of the main tweaks, for unknown reasons, not included in the standard package. Change the processor frequency control mode:
/etc/pm/power.d/cpu-governor
 #!/bin/bash cpu_powersave() { for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo $1 > $i && echo Done. || echo Failed. done } case $1 in true) cpu_powersave "ondemand" ;; false) cpu_powersave "performance" ;; *) exit $NA esac exit 0 

2. Change the power management mode of USB devices:
/etc/pm/power.d/usb-autosuspend
 #!/usr/bin/env python from os import listdir, path from sys import argv status = argv[1] USB_PATH = '/sys/bus/usb/devices/' def powersave(status): devices = listdir(USB_PATH) devices = filter(lambda x: ':' not in x, devices) for device in devices: b = listdir(path.join(USB_PATH, device)) b = filter(lambda x: ':' in x, b) is_mouse = False for i in b: if open(path.join(USB_PATH, device, i, 'bInterfaceProtocol')).read().strip() == '02': is_mouse = True break if not is_mouse: open(path.join(USB_PATH, device, 'power/control'), 'w').write(status) if status == 'true': powersave('auto') elif status == 'false': powersave('on') 

The script can detect the mouse and will not extinguish them.

3, 4. Change the power management mode of other devices:
/etc/pm/power.d/scsi_host-link_power_management
 #!/bin/bash powersave() { for i in /sys/class/scsi_host/host?/link_power_management_policy; do echo $1 > $i && echo Done. || echo Failed. done } case $1 in true) powersave "min_power" ;; false) powersave "max_performance" ;; *) exit $NA esac exit 0 

/etc/pm/power.d/pci-power-control
 #!/bin/bash powersave() { for i in /sys/bus/pci/devices/*/power/control; do echo $1 > $i && echo Done. || echo Failed. done } case $1 in true) powersave "auto" ;; false) powersave "on" ;; *) exit $NA esac exit 0 

We make these files executable and apply in one fell swoop: sudo pm-powersave true .

Setup is over. Official proof:
image
And the results chart:

Source: https://habr.com/ru/post/134968/


All Articles