Hybrid Graphics
Contents |
Introduction
Some laptops come with two graphics cards: one for use in applications that require a lot of computing power such as games, called the discrete GPU, and one that is less powerful, but conserves energy, called the integrated GPU. The integrated GPU is often embedded in the CPU, hence the name. This concept is called Hybrid Graphics.
How to switch the GPU
The kernel shipped in Ubuntu 10.10 supports hybrid graphics by means of the vga_switcheroo flag. See vga_switcheroo below.
Enabling vga_switcheroo
vga_switcheroo is the kernel mechanism that allows you to switch between GPUs if your machine has a hardware mux. Note that this method is not supported by all machines and only works if you are using the opensource driver (nouveau, radeon) and not the proprietary ones (nvidia, fglrx).
To check whether your kernel is compiled with the proper option you can examine the file config-2.6.nn-mm-generic in the /boot directory:
sudo grep -i switcheroo /boot/config-*
this is an example of the result, with kernel version 4.1
/boot/config-4.1.0-1-amd64:CONFIG_VGA_SWITCHEROO=y
If there is CONFIG_VGA_SWITCHEROO=y then what we need is there and we can proceed.
The vga_switcheroo mechanism will only be active when the kernel is booted with either the "modeset=1" kernel option, and/or the "nomodeset" option being absent.
These settings are stored in grub's (the bootloader) own setting files in /etc/default/grub
Open that file with a text editor with root/admin privileges. This is a sample command line that opens the file with gedit text editor with root/admin privileges
sudo gedit /etc/default/grub
In that text file there should be a
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
which must become
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash XXX.modeset=1"
where XXX = can be: "radeon" if you have a AMD/ATI card (most likely option since Intel and NVIDIA cards in dual-GPU notebooks have better ways of dealing with hybrid graphics, like bumblebee)
"noveau" for NVIDIA GPU
"i915" for Intel GPU
Then you need to write
sudo update-grub
to update boot parameters
and then reboot the PC.
To test if vga_switcheroo is enabled, look for the switch file:
sudo ls -l /sys/kernel/debug/vgaswitcheroo/switch
Using vga_switcheroo
Once you've ensured that vga_switcheroo is available, you can use these options to switch between GPUs. Be prepared for a lockup (either immediately, or after a minute), the existence of this file does not mean that the machine is supported.
sudo cat /sys/kernel/debug/vgaswitcheroo/switch
Allows you to verify the current state of the hybrid graphics. Typically, there will be two lines of output - one should indicate "Pwr" and the other should indicate "Off".
sudo echo ON > /sys/kernel/debug/vgaswitcheroo/switch
Turns on the GPU that is disconnected (not currently driving outputs), but does not switch outputs.
sudo echo IGD > /sys/kernel/debug/vgaswitcheroo/switch
Connects integrated graphics with outputs.
sudo echo DIS > /sys/kernel/debug/vgaswitcheroo/switch
Connects discrete graphics with outputs.
sudo echo OFF > /sys/kernel/debug/vgaswitcheroo/switch
Turns off the graphics card that is currently disconnected.
There are also a couple of options that are useful from inside an X-Windows session:
sudo echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch
Queues a switch to integrated graphics to occur when the X server is next restarted.
sudo echo DDIS > /sys/kernel/debug/vgaswitcheroo/switch
Queues a switch to discrete graphics to occur when the X server is next restarted.
Script for use inside an X session
Roberto Martinez has created a script which creates a graphical interface to switch between the graphics cards. He has released it over here. But you have to replace all the killall -u "$USER"" commands in his script with gnome-session-save --logout
To use this script, non-root users need permissions to write to /sys/kernel/debug/vgaswitcheroo/switch. If you run the script with sudo, it will just freeze the computer, since the script will then not end the current gnome session correctly.
To have permanent write permissions to the switch file, add the following line, replacing USERNAME with your username, to /etc/init.d/rc.local:
chown USERNAME /sys/kernel/debug/vgaswitcheroo/switch
right before the "exit 0" line. This gives you exclusive permission to switch GPUs.
You can also assign this script a global hotkey using the keyboard shortcuts menu (System > Preferences > Keyboard Shortcuts). You'll need to rename the script from Roberto Martinez to something without a .sh extension and place it into /usr/bin (as root) and make sure it is executable. Test it by running "switch_between_cards" without quotes from the terminal.
You may assign it any key combo you like so long as it's not already defined (See Keyboard Shortcuts). Super + G or Ctrl + Alt + G work well.
Script for use during bootup
You may want to switch to a given graphics adapter during boot, for example to enable output for the GPU that Linux uses to query for passwords to decrypt the root volume (and other boot-time messages) or you may wish to instead disable one of the adapters during the boot process to conserve battery power.
There are currently no kernel options to control the vga_switcheroo mechanism, but here is an initramfs script that will accomplish the same task. Put that in a file named /etc/initramfs-tools/scripts/local-top/hybrid_boot_options:
# # Standard initramfs preamble # prereqs() { : } case $1 in prereqs) prereqs exit 0 ;; esac # source for log_*_msg() functions, see LP: #272301 . /scripts/functions # # Helper functions # message() { if [ -x /bin/plymouth ] && plymouth --ping; then plymouth message --text="$@" elif [ -p /dev/.initramfs/usplash_outfifo ] && [ -x /sbin/usplash_write ]; then usplash_write "TEXT-URGENT $@" else echo "$@" >&2 fi return 0 } run_switcheroo() { local hybridopts hybridopts="$1" if [ -z "$hybridopts" ]; then return 1 fi local IFS=" ," for x in $hybridopts; do message "Switching hybrid graphics to $x" echo $x > /sys/kernel/debug/vgaswitcheroo/switch done return 0 } # # Begin real processing # # Do we have any kernel boot arguments? for opt in $(cat /proc/cmdline); do case $opt in hybridopts=*) run_switcheroo "${opt#hybridopts=}" ;; esac done exit 0
Set it executable, and create new initramfs files with initramfs-tools:
chmod +x /etc/initramfs-tools/scripts/local-top/hybrid_boot_options initramfs-tools -c -k all
or, if the command initramfs-tools doesn't exist, use:
update-initramfs -c -k all
Now, you can add a command line to your kernel boot options in /etc/default/grub:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash modeset=1 hybridopts=ON,IGD,OFF"
The above example enables both GPUs, switches to the integrated GPU, and finally turns off the discrete GPU.
Finally, the options needs to be actually applied to GRUB (since the above is just a template), which is done with grub-update:
update-grub
And we're done! You can also experiment with options during boot-time by pressing "e" in GRUB and adding/removing commands (separated by comma) from the "hybridopts=" option.
acpi_call
If you just want to have long battery life and slow temperature, you can use acpi_call: a linux kernel module that enables calls to ACPI. With acpi_call_GUI you can easily install and configure it via graphic interface.
It is a java program that allows you to:
- install the acpi_call kernel module (kernel would be recompiled automatically after each update);
- Deactivate discrete GPU;
- Automatically deactivate discrete GPU on every boot.
If you have enabled systemd, or if you're using other linux distros that support it, you can use acpi_call_GUI_systemd.
See here: https://github.com/marcoDallas/acpi_call_GUI_systemd
Installation
Ensure that you have installed java and git, if not install these packages: git and openjdk-7-jre
After that open a terminal and type the following commands:
git clone https://github.com/marcoDallas/acpi_call_GUI.git cd acpi_call_GUI sudo chmod +x install.sh sudo ./install.sh
How to use
To launch acpi_call_GUI search it in yuor dash and click on the icon, or type in a terminal:
sudo java -jar $HOME/acpi_call_GUI.jar
If you have a separate /home partition, you may need to use this command to launch acpi_call_GUI:
sudo java -jar /usr/local/bin/acpi_call_GUI/acpi_call_GUI.jar
Here's a step-by-step video tutorial that shows how to use this software
NVIDIA Optimus
vga_switcheroo is likely not going to work on these kind of machines. Most Optimus laptops do not have a hardware multiplexer. If you are lucky, you may find an option to disable the NVIDIA card for saving power or stick to the NVIDIA card for performance. See also How well do laptops with Nvidia Optimus work?
There are other methods to turn the device off and use the discrete video card. Such a method is called Bumblebee.
Various small fixes
Fix fans running at full speed
Roberto Martinez explains in his blog post, that he ran into a problem where his graphics card's fan would run at full speed, if he didn't have both graphics cards turned ON before shutting down his computer. He provides a script to fix it. All it does is run
echo ON > /sys/kernel/debug/vgaswitcheroo/switch
before shutdown. See the blog post for more details.
Fix brightness
The brightness of the laptop display upon boot may be turned very low. If you have a nearly black screen during boot, you may be lucky and just need to press the correct key to increase brightness.
Fix Suspend/Wake Freezing
After having turned off the unused discrete card, if your laptop freezes after suspending and trying to wake, make a new file called "11_switcheroo_suspend" under /etc/pm/sleep.d and make sure the file is executable.
#!/bin/bash PATH=/bin:/usr/bin switchfile=/sys/kernel/debug/vgaswitcheroo/switch [[ -n "$1" && -f "$switchfile" ]] || exit 1 retval=0 case "$1" in hibernate|suspend) echo ON > /sys/kernel/debug/vgaswitcheroo/switch retval=$? ;; resume|thaw) echo OFF > /sys/kernel/debug/vgaswitcheroo/switch retval=$? ;; *) [ -x /bin/logger ] && /bin/logger -i -t switcheroo_suspend -p user.info "Unknown mode: $1" retval=$? ;; esac exit $retval
Default GPU
The GPU that is enabled by the BIOS during boot may be dependent on whether the laptop is plugged into AC power or not.
Console FB
You can select which device the linux kernel uses for the boot-time console using the kernel command line option fbcon, such as "fbcon=map:1" for /dev/fb1.
(Alternatively, if you want to keep one GPU disabled at all times, there is also the option of just blacklisting the relevant driver and update initramfs and thereby get rid of one of the fb devices.)