Hybrid Graphics

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

  1. Ensure that you have installed java and git, if not install these packages: git and openjdk-7-jre

  2. 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.)

HybridGraphics (last edited 2015-09-16 06:33:06 by 78-134-10-140)