/*1* vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs2*3* Copyright (c) 2010 Red Hat Inc.4* Author : Dave Airlie <[email protected]>5*6* Copyright (c) 2015 Lukas Wunner <[email protected]>7*8* Permission is hereby granted, free of charge, to any person obtaining a9* copy of this software and associated documentation files (the "Software"),10* to deal in the Software without restriction, including without limitation11* the rights to use, copy, modify, merge, publish, distribute, sublicense,12* and/or sell copies of the Software, and to permit persons to whom the13* Software is furnished to do so, subject to the following conditions:14*15* The above copyright notice and this permission notice (including the next16* paragraph) shall be included in all copies or substantial portions of the17* Software.18*19* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR20* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,21* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL22* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER23* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING24* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER25* DEALINGS26* IN THE SOFTWARE.27*28*/2930#define pr_fmt(fmt) "vga_switcheroo: " fmt3132#include <linux/apple-gmux.h>33#include <linux/console.h>34#include <linux/debugfs.h>35#include <linux/fb.h>36#include <linux/fs.h>37#include <linux/fbcon.h>38#include <linux/module.h>39#include <linux/pci.h>40#include <linux/pm_domain.h>41#include <linux/pm_runtime.h>42#include <linux/seq_file.h>43#include <linux/uaccess.h>44#include <linux/vgaarb.h>45#include <linux/vga_switcheroo.h>4647/**48* DOC: Overview49*50* vga_switcheroo is the Linux subsystem for laptop hybrid graphics.51* These come in two flavors:52*53* * muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs.54* * muxless: Dual GPUs but only one of them is connected to outputs.55* The other one is merely used to offload rendering, its results56* are copied over PCIe into the framebuffer. On Linux this is57* supported with DRI PRIME.58*59* Hybrid graphics started to appear in the late Naughties and were initially60* all muxed. Newer laptops moved to a muxless architecture for cost reasons.61* A notable exception is the MacBook Pro which continues to use a mux.62* Muxes come with varying capabilities: Some switch only the panel, others63* can also switch external displays. Some switch all display pins at once64* while others can switch just the DDC lines. (To allow EDID probing65* for the inactive GPU.) Also, muxes are often used to cut power to the66* discrete GPU while it is not used.67*68* DRM drivers register GPUs with vga_switcheroo, these are henceforth called69* clients. The mux is called the handler. Muxless machines also register a70* handler to control the power state of the discrete GPU, its ->switchto71* callback is a no-op for obvious reasons. The discrete GPU is often equipped72* with an HDA controller for the HDMI/DP audio signal, this will also73* register as a client so that vga_switcheroo can take care of the correct74* suspend/resume order when changing the discrete GPU's power state. In total75* there can thus be up to three clients: Two vga clients (GPUs) and one audio76* client (on the discrete GPU). The code is mostly prepared to support77* machines with more than two GPUs should they become available.78*79* The GPU to which the outputs are currently switched is called the80* active client in vga_switcheroo parlance. The GPU not in use is the81* inactive client. When the inactive client's DRM driver is loaded,82* it will be unable to probe the panel's EDID and hence depends on83* VBIOS to provide its display modes. If the VBIOS modes are bogus or84* if there is no VBIOS at all (which is common on the MacBook Pro),85* a client may alternatively request that the DDC lines are temporarily86* switched to it, provided that the handler supports this. Switching87* only the DDC lines and not the entire output avoids unnecessary88* flickering.89*/9091/**92* struct vga_switcheroo_client - registered client93* @pdev: client pci device94* @fb_info: framebuffer to which console is remapped on switching95* @pwr_state: current power state if manual power control is used.96* For driver power control, call vga_switcheroo_pwr_state().97* @ops: client callbacks98* @id: client identifier. Determining the id requires the handler,99* so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID100* and later given their true id in vga_switcheroo_enable()101* @active: whether the outputs are currently switched to this client102* @driver_power_control: whether power state is controlled by the driver's103* runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs104* interface is a no-op so as not to interfere with runtime pm105* @list: client list106* @vga_dev: pci device, indicate which GPU is bound to current audio client107*108* Registered client. A client can be either a GPU or an audio device on a GPU.109* For audio clients, the @fb_info and @active members are bogus. For GPU110* clients, the @vga_dev is bogus.111*/112struct vga_switcheroo_client {113struct pci_dev *pdev;114struct fb_info *fb_info;115enum vga_switcheroo_state pwr_state;116const struct vga_switcheroo_client_ops *ops;117enum vga_switcheroo_client_id id;118bool active;119bool driver_power_control;120struct list_head list;121struct pci_dev *vga_dev;122};123124/*125* protects access to struct vgasr_priv126*/127static DEFINE_MUTEX(vgasr_mutex);128129/**130* struct vgasr_priv - vga_switcheroo private data131* @active: whether vga_switcheroo is enabled.132* Prerequisite is the registration of two GPUs and a handler133* @delayed_switch_active: whether a delayed switch is pending134* @delayed_client_id: client to which a delayed switch is pending135* @debugfs_root: directory for vga_switcheroo debugfs interface136* @registered_clients: number of registered GPUs137* (counting only vga clients, not audio clients)138* @clients: list of registered clients139* @handler: registered handler140* @handler_flags: flags of registered handler141* @mux_hw_lock: protects mux state142* (in particular while DDC lines are temporarily switched)143* @old_ddc_owner: client to which DDC lines will be switched back on unlock144*145* vga_switcheroo private data. Currently only one vga_switcheroo instance146* per system is supported.147*/148struct vgasr_priv {149bool active;150bool delayed_switch_active;151enum vga_switcheroo_client_id delayed_client_id;152153struct dentry *debugfs_root;154155int registered_clients;156struct list_head clients;157158const struct vga_switcheroo_handler *handler;159enum vga_switcheroo_handler_flags_t handler_flags;160struct mutex mux_hw_lock;161int old_ddc_owner;162};163164#define ID_BIT_AUDIO 0x100165#define client_is_audio(c) ((c)->id & ID_BIT_AUDIO)166#define client_is_vga(c) (!client_is_audio(c))167#define client_id(c) ((c)->id & ~ID_BIT_AUDIO)168169static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv);170static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);171172/* only one switcheroo per system */173static struct vgasr_priv vgasr_priv = {174.clients = LIST_HEAD_INIT(vgasr_priv.clients),175.mux_hw_lock = __MUTEX_INITIALIZER(vgasr_priv.mux_hw_lock),176};177178static bool vga_switcheroo_ready(void)179{180/* we're ready if we get two clients + handler */181return !vgasr_priv.active &&182vgasr_priv.registered_clients == 2 && vgasr_priv.handler;183}184185static void vga_switcheroo_enable(void)186{187int ret;188struct vga_switcheroo_client *client;189190/* call the handler to init */191if (vgasr_priv.handler->init)192vgasr_priv.handler->init();193194list_for_each_entry(client, &vgasr_priv.clients, list) {195if (!client_is_vga(client) ||196client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)197continue;198199ret = vgasr_priv.handler->get_client_id(client->pdev);200if (ret < 0)201return;202203client->id = ret;204}205206list_for_each_entry(client, &vgasr_priv.clients, list) {207if (!client_is_audio(client) ||208client_id(client) != VGA_SWITCHEROO_UNKNOWN_ID)209continue;210211ret = vgasr_priv.handler->get_client_id(client->vga_dev);212if (ret < 0)213return;214215client->id = ret | ID_BIT_AUDIO;216if (client->ops->gpu_bound)217client->ops->gpu_bound(client->pdev, ret);218}219220vga_switcheroo_debugfs_init(&vgasr_priv);221vgasr_priv.active = true;222}223224/**225* vga_switcheroo_register_handler() - register handler226* @handler: handler callbacks227* @handler_flags: handler flags228*229* Register handler. Enable vga_switcheroo if two vga clients have already230* registered.231*232* Return: 0 on success, -EINVAL if a handler was already registered.233*/234int vga_switcheroo_register_handler(235const struct vga_switcheroo_handler *handler,236enum vga_switcheroo_handler_flags_t handler_flags)237{238mutex_lock(&vgasr_mutex);239if (vgasr_priv.handler) {240mutex_unlock(&vgasr_mutex);241return -EINVAL;242}243244vgasr_priv.handler = handler;245vgasr_priv.handler_flags = handler_flags;246if (vga_switcheroo_ready()) {247pr_info("enabled\n");248vga_switcheroo_enable();249}250mutex_unlock(&vgasr_mutex);251return 0;252}253EXPORT_SYMBOL(vga_switcheroo_register_handler);254255/**256* vga_switcheroo_unregister_handler() - unregister handler257*258* Unregister handler. Disable vga_switcheroo.259*/260void vga_switcheroo_unregister_handler(void)261{262mutex_lock(&vgasr_mutex);263mutex_lock(&vgasr_priv.mux_hw_lock);264vgasr_priv.handler_flags = 0;265vgasr_priv.handler = NULL;266if (vgasr_priv.active) {267pr_info("disabled\n");268vga_switcheroo_debugfs_fini(&vgasr_priv);269vgasr_priv.active = false;270}271mutex_unlock(&vgasr_priv.mux_hw_lock);272mutex_unlock(&vgasr_mutex);273}274EXPORT_SYMBOL(vga_switcheroo_unregister_handler);275276/**277* vga_switcheroo_handler_flags() - obtain handler flags278*279* Helper for clients to obtain the handler flags bitmask.280*281* Return: Handler flags. A value of 0 means that no handler is registered282* or that the handler has no special capabilities.283*/284enum vga_switcheroo_handler_flags_t vga_switcheroo_handler_flags(void)285{286return vgasr_priv.handler_flags;287}288EXPORT_SYMBOL(vga_switcheroo_handler_flags);289290static int register_client(struct pci_dev *pdev,291const struct vga_switcheroo_client_ops *ops,292enum vga_switcheroo_client_id id,293struct pci_dev *vga_dev,294bool active,295bool driver_power_control)296{297struct vga_switcheroo_client *client;298299client = kzalloc(sizeof(*client), GFP_KERNEL);300if (!client)301return -ENOMEM;302303client->pwr_state = VGA_SWITCHEROO_ON;304client->pdev = pdev;305client->ops = ops;306client->id = id;307client->active = active;308client->driver_power_control = driver_power_control;309client->vga_dev = vga_dev;310311mutex_lock(&vgasr_mutex);312list_add_tail(&client->list, &vgasr_priv.clients);313if (client_is_vga(client))314vgasr_priv.registered_clients++;315316if (vga_switcheroo_ready()) {317pr_info("enabled\n");318vga_switcheroo_enable();319}320mutex_unlock(&vgasr_mutex);321return 0;322}323324/**325* vga_switcheroo_register_client - register vga client326* @pdev: client pci device327* @ops: client callbacks328* @driver_power_control: whether power state is controlled by the driver's329* runtime pm330*331* Register vga client (GPU). Enable vga_switcheroo if another GPU and a332* handler have already registered. The power state of the client is assumed333* to be ON. Beforehand, vga_switcheroo_client_probe_defer() shall be called334* to ensure that all prerequisites are met.335*336* Return: 0 on success, -ENOMEM on memory allocation error.337*/338int vga_switcheroo_register_client(struct pci_dev *pdev,339const struct vga_switcheroo_client_ops *ops,340bool driver_power_control)341{342return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID, NULL,343pdev == vga_default_device(),344driver_power_control);345}346EXPORT_SYMBOL(vga_switcheroo_register_client);347348/**349* vga_switcheroo_register_audio_client - register audio client350* @pdev: client pci device351* @ops: client callbacks352* @vga_dev: pci device which is bound to current audio client353*354* Register audio client (audio device on a GPU). The client is assumed355* to use runtime PM. Beforehand, vga_switcheroo_client_probe_defer()356* shall be called to ensure that all prerequisites are met.357*358* Return: 0 on success, -ENOMEM on memory allocation error, -EINVAL on getting359* client id error.360*/361int vga_switcheroo_register_audio_client(struct pci_dev *pdev,362const struct vga_switcheroo_client_ops *ops,363struct pci_dev *vga_dev)364{365enum vga_switcheroo_client_id id = VGA_SWITCHEROO_UNKNOWN_ID;366367/*368* if vga_switcheroo has enabled, that mean two GPU clients and also369* handler are registered. Get audio client id from bound GPU client370* id directly, otherwise, set it as VGA_SWITCHEROO_UNKNOWN_ID,371* it will set to correct id in later when vga_switcheroo_enable()372* is called.373*/374mutex_lock(&vgasr_mutex);375if (vgasr_priv.active) {376id = vgasr_priv.handler->get_client_id(vga_dev);377if (id < 0) {378mutex_unlock(&vgasr_mutex);379return -EINVAL;380}381/* notify if GPU has been already bound */382if (ops->gpu_bound)383ops->gpu_bound(pdev, id);384}385mutex_unlock(&vgasr_mutex);386387return register_client(pdev, ops, id | ID_BIT_AUDIO, vga_dev,388false, true);389}390EXPORT_SYMBOL(vga_switcheroo_register_audio_client);391392static struct vga_switcheroo_client *393find_client_from_pci(struct list_head *head, struct pci_dev *pdev)394{395struct vga_switcheroo_client *client;396397list_for_each_entry(client, head, list)398if (client->pdev == pdev)399return client;400return NULL;401}402403static struct vga_switcheroo_client *404find_client_from_id(struct list_head *head,405enum vga_switcheroo_client_id client_id)406{407struct vga_switcheroo_client *client;408409list_for_each_entry(client, head, list)410if (client->id == client_id)411return client;412return NULL;413}414415static struct vga_switcheroo_client *416find_active_client(struct list_head *head)417{418struct vga_switcheroo_client *client;419420list_for_each_entry(client, head, list)421if (client->active)422return client;423return NULL;424}425426/**427* vga_switcheroo_client_probe_defer() - whether to defer probing a given client428* @pdev: client pci device429*430* Determine whether any prerequisites are not fulfilled to probe a given431* client. Drivers shall invoke this early on in their ->probe callback432* and return %-EPROBE_DEFER if it evaluates to %true. Thou shalt not433* register the client ere thou hast called this.434*435* Return: %true if probing should be deferred, otherwise %false.436*/437bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)438{439if (pci_is_display(pdev)) {440/*441* apple-gmux is needed on pre-retina MacBook Pro442* to probe the panel if pdev is the inactive GPU.443*/444if (apple_gmux_present() && pdev != vga_default_device() &&445!vgasr_priv.handler_flags)446return true;447}448449return false;450}451EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);452453static enum vga_switcheroo_state454vga_switcheroo_pwr_state(struct vga_switcheroo_client *client)455{456if (client->driver_power_control)457if (pm_runtime_enabled(&client->pdev->dev) &&458pm_runtime_active(&client->pdev->dev))459return VGA_SWITCHEROO_ON;460else461return VGA_SWITCHEROO_OFF;462else463return client->pwr_state;464}465466/**467* vga_switcheroo_get_client_state() - obtain power state of a given client468* @pdev: client pci device469*470* Obtain power state of a given client as seen from vga_switcheroo.471* The function is only called from hda_intel.c.472*473* Return: Power state.474*/475enum vga_switcheroo_state vga_switcheroo_get_client_state(struct pci_dev *pdev)476{477struct vga_switcheroo_client *client;478enum vga_switcheroo_state ret;479480mutex_lock(&vgasr_mutex);481client = find_client_from_pci(&vgasr_priv.clients, pdev);482if (!client)483ret = VGA_SWITCHEROO_NOT_FOUND;484else485ret = vga_switcheroo_pwr_state(client);486mutex_unlock(&vgasr_mutex);487return ret;488}489EXPORT_SYMBOL(vga_switcheroo_get_client_state);490491/**492* vga_switcheroo_unregister_client() - unregister client493* @pdev: client pci device494*495* Unregister client. Disable vga_switcheroo if this is a vga client (GPU).496*/497void vga_switcheroo_unregister_client(struct pci_dev *pdev)498{499struct vga_switcheroo_client *client;500501mutex_lock(&vgasr_mutex);502client = find_client_from_pci(&vgasr_priv.clients, pdev);503if (client) {504if (client_is_vga(client))505vgasr_priv.registered_clients--;506list_del(&client->list);507kfree(client);508}509if (vgasr_priv.active && vgasr_priv.registered_clients < 2) {510pr_info("disabled\n");511vga_switcheroo_debugfs_fini(&vgasr_priv);512vgasr_priv.active = false;513}514mutex_unlock(&vgasr_mutex);515}516EXPORT_SYMBOL(vga_switcheroo_unregister_client);517518/**519* vga_switcheroo_client_fb_set() - set framebuffer of a given client520* @pdev: client pci device521* @info: framebuffer522*523* Set framebuffer of a given client. The console will be remapped to this524* on switching.525*/526void vga_switcheroo_client_fb_set(struct pci_dev *pdev,527struct fb_info *info)528{529struct vga_switcheroo_client *client;530531mutex_lock(&vgasr_mutex);532client = find_client_from_pci(&vgasr_priv.clients, pdev);533if (client)534client->fb_info = info;535mutex_unlock(&vgasr_mutex);536}537EXPORT_SYMBOL(vga_switcheroo_client_fb_set);538539/**540* vga_switcheroo_lock_ddc() - temporarily switch DDC lines to a given client541* @pdev: client pci device542*543* Temporarily switch DDC lines to the client identified by @pdev544* (but leave the outputs otherwise switched to where they are).545* This allows the inactive client to probe EDID. The DDC lines must546* afterwards be switched back by calling vga_switcheroo_unlock_ddc(),547* even if this function returns an error.548*549* Return: Previous DDC owner on success or a negative int on error.550* Specifically, %-ENODEV if no handler has registered or if the handler551* does not support switching the DDC lines. Also, a negative value552* returned by the handler is propagated back to the caller.553* The return value has merely an informational purpose for any caller554* which might be interested in it. It is acceptable to ignore the return555* value and simply rely on the result of the subsequent EDID probe,556* which will be %NULL if DDC switching failed.557*/558int vga_switcheroo_lock_ddc(struct pci_dev *pdev)559{560enum vga_switcheroo_client_id id;561562mutex_lock(&vgasr_priv.mux_hw_lock);563if (!vgasr_priv.handler || !vgasr_priv.handler->switch_ddc) {564vgasr_priv.old_ddc_owner = -ENODEV;565return -ENODEV;566}567568id = vgasr_priv.handler->get_client_id(pdev);569vgasr_priv.old_ddc_owner = vgasr_priv.handler->switch_ddc(id);570return vgasr_priv.old_ddc_owner;571}572EXPORT_SYMBOL(vga_switcheroo_lock_ddc);573574/**575* vga_switcheroo_unlock_ddc() - switch DDC lines back to previous owner576* @pdev: client pci device577*578* Switch DDC lines back to the previous owner after calling579* vga_switcheroo_lock_ddc(). This must be called even if580* vga_switcheroo_lock_ddc() returned an error.581*582* Return: Previous DDC owner on success (i.e. the client identifier of @pdev)583* or a negative int on error.584* Specifically, %-ENODEV if no handler has registered or if the handler585* does not support switching the DDC lines. Also, a negative value586* returned by the handler is propagated back to the caller.587* Finally, invoking this function without calling vga_switcheroo_lock_ddc()588* first is not allowed and will result in %-EINVAL.589*/590int vga_switcheroo_unlock_ddc(struct pci_dev *pdev)591{592enum vga_switcheroo_client_id id;593int ret = vgasr_priv.old_ddc_owner;594595if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv.mux_hw_lock)))596return -EINVAL;597598if (vgasr_priv.old_ddc_owner >= 0) {599id = vgasr_priv.handler->get_client_id(pdev);600if (vgasr_priv.old_ddc_owner != id)601ret = vgasr_priv.handler->switch_ddc(602vgasr_priv.old_ddc_owner);603}604mutex_unlock(&vgasr_priv.mux_hw_lock);605return ret;606}607EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);608609/**610* DOC: Manual switching and manual power control611*612* In this mode of use, the file /sys/kernel/debug/vgaswitcheroo/switch613* can be read to retrieve the current vga_switcheroo state and commands614* can be written to it to change the state. The file appears as soon as615* two GPU drivers and one handler have registered with vga_switcheroo.616* The following commands are understood:617*618* * OFF: Power off the device not in use.619* * ON: Power on the device not in use.620* * IGD: Switch to the integrated graphics device.621* Power on the integrated GPU if necessary, power off the discrete GPU.622* Prerequisite is that no user space processes (e.g. Xorg, alsactl)623* have opened device files of the GPUs or the audio client. If the624* switch fails, the user may invoke lsof(8) or fuser(1) on /dev/dri/625* and /dev/snd/controlC1 to identify processes blocking the switch.626* * DIS: Switch to the discrete graphics device.627* * DIGD: Delayed switch to the integrated graphics device.628* This will perform the switch once the last user space process has629* closed the device files of the GPUs and the audio client.630* * DDIS: Delayed switch to the discrete graphics device.631* * MIGD: Mux-only switch to the integrated graphics device.632* Does not remap console or change the power state of either gpu.633* If the integrated GPU is currently off, the screen will turn black.634* If it is on, the screen will show whatever happens to be in VRAM.635* Either way, the user has to blindly enter the command to switch back.636* * MDIS: Mux-only switch to the discrete graphics device.637*638* For GPUs whose power state is controlled by the driver's runtime pm,639* the ON and OFF commands are a no-op (see next section).640*641* For muxless machines, the IGD/DIS, DIGD/DDIS and MIGD/MDIS commands642* should not be used.643*/644645static int vga_switcheroo_show(struct seq_file *m, void *v)646{647struct vga_switcheroo_client *client;648int i = 0;649650mutex_lock(&vgasr_mutex);651list_for_each_entry(client, &vgasr_priv.clients, list) {652seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,653client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :654"IGD",655client_is_vga(client) ? "" : "-Audio",656client->active ? '+' : ' ',657client->driver_power_control ? "Dyn" : "",658vga_switcheroo_pwr_state(client) ? "Pwr" : "Off",659pci_name(client->pdev));660i++;661}662mutex_unlock(&vgasr_mutex);663return 0;664}665666static int vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)667{668return single_open(file, vga_switcheroo_show, NULL);669}670671static int vga_switchon(struct vga_switcheroo_client *client)672{673if (client->driver_power_control)674return 0;675if (vgasr_priv.handler->power_state)676vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_ON);677/* call the driver callback to turn on device */678client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);679client->pwr_state = VGA_SWITCHEROO_ON;680return 0;681}682683static int vga_switchoff(struct vga_switcheroo_client *client)684{685if (client->driver_power_control)686return 0;687/* call the driver callback to turn off device */688client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);689if (vgasr_priv.handler->power_state)690vgasr_priv.handler->power_state(client->id, VGA_SWITCHEROO_OFF);691client->pwr_state = VGA_SWITCHEROO_OFF;692return 0;693}694695static void set_audio_state(enum vga_switcheroo_client_id id,696enum vga_switcheroo_state state)697{698struct vga_switcheroo_client *client;699700client = find_client_from_id(&vgasr_priv.clients, id | ID_BIT_AUDIO);701if (client)702client->ops->set_gpu_state(client->pdev, state);703}704705/* stage one happens before delay */706static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)707{708struct vga_switcheroo_client *active;709710active = find_active_client(&vgasr_priv.clients);711if (!active)712return 0;713714if (vga_switcheroo_pwr_state(new_client) == VGA_SWITCHEROO_OFF)715vga_switchon(new_client);716717vga_set_default_device(new_client->pdev);718return 0;719}720721/* post delay */722static int vga_switchto_stage2(struct vga_switcheroo_client *new_client)723{724int ret;725struct vga_switcheroo_client *active;726727active = find_active_client(&vgasr_priv.clients);728if (!active)729return 0;730731active->active = false;732733/* let HDA controller autosuspend if GPU uses driver power control */734if (!active->driver_power_control)735set_audio_state(active->id, VGA_SWITCHEROO_OFF);736737if (new_client->fb_info)738fbcon_remap_all(new_client->fb_info);739740mutex_lock(&vgasr_priv.mux_hw_lock);741ret = vgasr_priv.handler->switchto(new_client->id);742mutex_unlock(&vgasr_priv.mux_hw_lock);743if (ret)744return ret;745746if (new_client->ops->reprobe)747new_client->ops->reprobe(new_client->pdev);748749if (vga_switcheroo_pwr_state(active) == VGA_SWITCHEROO_ON)750vga_switchoff(active);751752/* let HDA controller autoresume if GPU uses driver power control */753if (!new_client->driver_power_control)754set_audio_state(new_client->id, VGA_SWITCHEROO_ON);755756new_client->active = true;757return 0;758}759760static bool check_can_switch(void)761{762struct vga_switcheroo_client *client;763764list_for_each_entry(client, &vgasr_priv.clients, list) {765if (!client->ops->can_switch(client->pdev)) {766pr_err("client %x refused switch\n", client->id);767return false;768}769}770return true;771}772773static ssize_t774vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,775size_t cnt, loff_t *ppos)776{777char usercmd[64];778int ret;779bool delay = false, can_switch;780bool just_mux = false;781enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;782struct vga_switcheroo_client *client = NULL;783784if (cnt > 63)785cnt = 63;786787if (copy_from_user(usercmd, ubuf, cnt))788return -EFAULT;789790mutex_lock(&vgasr_mutex);791792if (!vgasr_priv.active) {793cnt = -EINVAL;794goto out;795}796797/* pwr off the device not in use */798if (strncmp(usercmd, "OFF", 3) == 0) {799list_for_each_entry(client, &vgasr_priv.clients, list) {800if (client->active || client_is_audio(client))801continue;802if (client->driver_power_control)803continue;804set_audio_state(client->id, VGA_SWITCHEROO_OFF);805if (client->pwr_state == VGA_SWITCHEROO_ON)806vga_switchoff(client);807}808goto out;809}810/* pwr on the device not in use */811if (strncmp(usercmd, "ON", 2) == 0) {812list_for_each_entry(client, &vgasr_priv.clients, list) {813if (client->active || client_is_audio(client))814continue;815if (client->driver_power_control)816continue;817if (client->pwr_state == VGA_SWITCHEROO_OFF)818vga_switchon(client);819set_audio_state(client->id, VGA_SWITCHEROO_ON);820}821goto out;822}823824/* request a delayed switch - test can we switch now */825if (strncmp(usercmd, "DIGD", 4) == 0) {826client_id = VGA_SWITCHEROO_IGD;827delay = true;828}829830if (strncmp(usercmd, "DDIS", 4) == 0) {831client_id = VGA_SWITCHEROO_DIS;832delay = true;833}834835if (strncmp(usercmd, "IGD", 3) == 0)836client_id = VGA_SWITCHEROO_IGD;837838if (strncmp(usercmd, "DIS", 3) == 0)839client_id = VGA_SWITCHEROO_DIS;840841if (strncmp(usercmd, "MIGD", 4) == 0) {842just_mux = true;843client_id = VGA_SWITCHEROO_IGD;844}845if (strncmp(usercmd, "MDIS", 4) == 0) {846just_mux = true;847client_id = VGA_SWITCHEROO_DIS;848}849850if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)851goto out;852client = find_client_from_id(&vgasr_priv.clients, client_id);853if (!client)854goto out;855856vgasr_priv.delayed_switch_active = false;857858if (just_mux) {859mutex_lock(&vgasr_priv.mux_hw_lock);860ret = vgasr_priv.handler->switchto(client_id);861mutex_unlock(&vgasr_priv.mux_hw_lock);862goto out;863}864865if (client->active)866goto out;867868/* okay we want a switch - test if devices are willing to switch */869can_switch = check_can_switch();870871if (can_switch == false && delay == false)872goto out;873874if (can_switch) {875ret = vga_switchto_stage1(client);876if (ret)877pr_err("switching failed stage 1 %d\n", ret);878879ret = vga_switchto_stage2(client);880if (ret)881pr_err("switching failed stage 2 %d\n", ret);882883} else {884pr_info("setting delayed switch to client %d\n", client->id);885vgasr_priv.delayed_switch_active = true;886vgasr_priv.delayed_client_id = client_id;887888ret = vga_switchto_stage1(client);889if (ret)890pr_err("delayed switching stage 1 failed %d\n", ret);891}892893out:894mutex_unlock(&vgasr_mutex);895return cnt;896}897898static const struct file_operations vga_switcheroo_debugfs_fops = {899.owner = THIS_MODULE,900.open = vga_switcheroo_debugfs_open,901.write = vga_switcheroo_debugfs_write,902.read = seq_read,903.llseek = seq_lseek,904.release = single_release,905};906907static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)908{909debugfs_remove_recursive(priv->debugfs_root);910priv->debugfs_root = NULL;911}912913static void vga_switcheroo_debugfs_init(struct vgasr_priv *priv)914{915/* already initialised */916if (priv->debugfs_root)917return;918919priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);920921debugfs_create_file("switch", 0644, priv->debugfs_root, NULL,922&vga_switcheroo_debugfs_fops);923}924925/**926* vga_switcheroo_process_delayed_switch() - helper for delayed switching927*928* Process a delayed switch if one is pending.929*930* Return: 0 on success. -EINVAL if no delayed switch is pending, if the client931* has unregistered in the meantime or if there are other clients blocking the932* switch. If the actual switch fails, an error is reported and 0 is returned.933*/934int vga_switcheroo_process_delayed_switch(void)935{936struct vga_switcheroo_client *client;937int ret;938int err = -EINVAL;939940mutex_lock(&vgasr_mutex);941if (!vgasr_priv.delayed_switch_active)942goto err;943944pr_info("processing delayed switch to %d\n",945vgasr_priv.delayed_client_id);946947client = find_client_from_id(&vgasr_priv.clients,948vgasr_priv.delayed_client_id);949if (!client || !check_can_switch())950goto err;951952ret = vga_switchto_stage2(client);953if (ret)954pr_err("delayed switching failed stage 2 %d\n", ret);955956vgasr_priv.delayed_switch_active = false;957err = 0;958err:959mutex_unlock(&vgasr_mutex);960return err;961}962EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);963964/**965* DOC: Driver power control966*967* In this mode of use, the discrete GPU automatically powers up and down at968* the discretion of the driver's runtime pm. On muxed machines, the user may969* still influence the muxer state by way of the debugfs interface, however970* the ON and OFF commands become a no-op for the discrete GPU.971*972* This mode is the default on Nvidia HybridPower/Optimus and ATI PowerXpress.973* Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel974* command line disables it.975*976* After the GPU has been suspended, the handler needs to be called to cut977* power to the GPU. Likewise it needs to reinstate power before the GPU978* can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(),979* which augments the GPU's suspend/resume functions by the requisite980* calls to the handler.981*982* When the audio device resumes, the GPU needs to be woken. This is achieved983* by a PCI quirk which calls device_link_add() to declare a dependency on the984* GPU. That way, the GPU is kept awake whenever and as long as the audio985* device is in use.986*987* On muxed machines, if the mux is initially switched to the discrete GPU,988* the user ends up with a black screen when the GPU powers down after boot.989* As a workaround, the mux is forced to the integrated GPU on runtime suspend,990* cf. https://bugs.freedesktop.org/show_bug.cgi?id=75917991*/992993static void vga_switcheroo_power_switch(struct pci_dev *pdev,994enum vga_switcheroo_state state)995{996struct vga_switcheroo_client *client;997998if (!vgasr_priv.handler->power_state)999return;10001001client = find_client_from_pci(&vgasr_priv.clients, pdev);1002if (!client)1003return;10041005if (!client->driver_power_control)1006return;10071008vgasr_priv.handler->power_state(client->id, state);1009}10101011/* switcheroo power domain */1012static int vga_switcheroo_runtime_suspend(struct device *dev)1013{1014struct pci_dev *pdev = to_pci_dev(dev);1015int ret;10161017ret = dev->bus->pm->runtime_suspend(dev);1018if (ret)1019return ret;1020mutex_lock(&vgasr_mutex);1021if (vgasr_priv.handler->switchto) {1022mutex_lock(&vgasr_priv.mux_hw_lock);1023vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);1024mutex_unlock(&vgasr_priv.mux_hw_lock);1025}1026pci_bus_set_current_state(pdev->bus, PCI_D3cold);1027vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);1028mutex_unlock(&vgasr_mutex);1029return 0;1030}10311032static int vga_switcheroo_runtime_resume(struct device *dev)1033{1034struct pci_dev *pdev = to_pci_dev(dev);10351036mutex_lock(&vgasr_mutex);1037vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);1038mutex_unlock(&vgasr_mutex);1039pci_resume_bus(pdev->bus);1040return dev->bus->pm->runtime_resume(dev);1041}10421043/**1044* vga_switcheroo_init_domain_pm_ops() - helper for driver power control1045* @dev: vga client device1046* @domain: power domain1047*1048* Helper for GPUs whose power state is controlled by the driver's runtime pm.1049* After the GPU has been suspended, the handler needs to be called to cut1050* power to the GPU. Likewise it needs to reinstate power before the GPU1051* can resume. To this end, this helper augments the suspend/resume functions1052* by the requisite calls to the handler. It needs only be called on platforms1053* where the power switch is separate to the device being powered down.1054*/1055int vga_switcheroo_init_domain_pm_ops(struct device *dev,1056struct dev_pm_domain *domain)1057{1058/* copy over all the bus versions */1059if (dev->bus && dev->bus->pm) {1060domain->ops = *dev->bus->pm;1061domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;1062domain->ops.runtime_resume = vga_switcheroo_runtime_resume;10631064dev_pm_domain_set(dev, domain);1065return 0;1066}1067dev_pm_domain_set(dev, NULL);1068return -EINVAL;1069}1070EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);10711072void vga_switcheroo_fini_domain_pm_ops(struct device *dev)1073{1074dev_pm_domain_set(dev, NULL);1075}1076EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);107710781079