Part III. vga_switcheroo

vga_switcheroo is the Linux subsystem for laptop hybrid graphics. These come in two flavors:

* muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs. * muxless: Dual GPUs but only one of them is connected to outputs. The other one is merely used to offload rendering, its results are copied over PCIe into the framebuffer. On Linux this is supported with DRI PRIME.

Hybrid graphics started to appear in the late Naughties and were initially all muxed. Newer laptops moved to a muxless architecture for cost reasons. A notable exception is the MacBook Pro which continues to use a mux. Muxes come with varying capabilities: Some switch only the panel, others can also switch external displays. Some switch all display pins at once while others can switch just the DDC lines. (To allow EDID probing for the inactive GPU.) Also, muxes are often used to cut power to the discrete GPU while it is not used.

DRM drivers register GPUs with vga_switcheroo, these are heretoforth called clients. The mux is called the handler. Muxless machines also register a handler to control the power state of the discrete GPU, its ->switchto callback is a no-op for obvious reasons. The discrete GPU is often equipped with an HDA controller for the HDMI/DP audio signal, this will also register as a client so that vga_switcheroo can take care of the correct suspend/resume order when changing the discrete GPU's power state. In total there can thus be up to three clients: Two vga clients (GPUs) and one audio client (on the discrete GPU). The code is mostly prepared to support machines with more than two GPUs should they become available. The GPU to which the outputs are currently switched is called the active client in vga_switcheroo parlance. The GPU not in use is the inactive client.

Table of Contents

5. Modes of Use
Manual switching and manual power control
Driver power control
6. Public functions
vga_switcheroo_register_handler — register handler
vga_switcheroo_unregister_handler — unregister handler
vga_switcheroo_register_client — register vga client
vga_switcheroo_register_audio_client — register audio client
vga_switcheroo_get_client_state — obtain power state of a given client
vga_switcheroo_unregister_client — unregister client
vga_switcheroo_client_fb_set — set framebuffer of a given client
vga_switcheroo_process_delayed_switch — helper for delayed switching
vga_switcheroo_set_dynamic_switch — helper for driver power control
vga_switcheroo_init_domain_pm_ops — helper for driver power control
vga_switcheroo_init_domain_pm_optimus_hdmi_audio — helper for driver power control
7. Public structures
struct vga_switcheroo_handler — handler callbacks
struct vga_switcheroo_client_ops — client callbacks
8. Public constants
enum vga_switcheroo_client_id — client identifier
enum vga_switcheroo_state — client power state
9. Private structures
struct vgasr_priv — vga_switcheroo private data
struct vga_switcheroo_client — registered client