xref: /dragonfly/sys/dev/video/vga/vga_switcheroo.c (revision de5eb4c5)
1 /*
2  * vga_switcheroo.c -- vga_switcheroo driver for DragonFly
3  *
4  * Adapted from linux v4.8: linux-src/drivers/gpu/vga/vga_switcheroo.c
5  *
6  */
7 
8 /*
9  * vga_switcheroo.c - Support for laptop with dual GPU using one set of outputs
10  *
11  * Copyright (c) 2010 Red Hat Inc.
12  * Author : Dave Airlie <airlied@redhat.com>
13  *
14  * Copyright (c) 2015 Lukas Wunner <lukas@wunner.de>
15  *
16  * Permission is hereby granted, free of charge, to any person obtaining a
17  * copy of this software and associated documentation files (the "Software"),
18  * to deal in the Software without restriction, including without limitation
19  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20  * and/or sell copies of the Software, and to permit persons to whom the
21  * Software is furnished to do so, subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice (including the next
24  * paragraph) shall be included in all copies or substantial portions of the
25  * Software.
26  *
27  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
30  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33  * DEALINGS
34  * IN THE SOFTWARE.
35  *
36  */
37 
38 #include <sys/param.h>
39 #include <sys/kernel.h>
40 #include <sys/bio.h>
41 #include <sys/bus.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
44 #include <sys/proc.h>
45 #include <sys/types.h>
46 #include <sys/systm.h>
47 #include <sys/device.h>
48 #include <sys/conf.h>
49 #include <sys/rman.h>
50 #include <sys/uio.h>
51 
52 #define pr_fmt(fmt) "vga_switcheroo: " fmt
53 
54 #include <linux/fb.h>
55 #include <linux/fs.h>
56 #include <linux/module.h>
57 #include <linux/pci.h>
58 #include <linux/pci_ids.h>
59 #include <linux/mutex.h>
60 #include <linux/list.h>
61 #include <linux/export.h>
62 
63 #define VGA_SWITCHEROO
64 #include <linux/vga_switcheroo.h>
65 
66 /**
67  * DOC: Overview
68  *
69  * vga_switcheroo is the Linux subsystem for laptop hybrid graphics.
70  * These come in two flavors:
71  *
72  * * muxed: Dual GPUs with a multiplexer chip to switch outputs between GPUs.
73  * * muxless: Dual GPUs but only one of them is connected to outputs.
74  * 	The other one is merely used to offload rendering, its results
75  * 	are copied over PCIe into the framebuffer. On Linux this is
76  * 	supported with DRI PRIME.
77  *
78  * Hybrid graphics started to appear in the late Naughties and were initially
79  * all muxed. Newer laptops moved to a muxless architecture for cost reasons.
80  * A notable exception is the MacBook Pro which continues to use a mux.
81  * Muxes come with varying capabilities: Some switch only the panel, others
82  * can also switch external displays. Some switch all display pins at once
83  * while others can switch just the DDC lines. (To allow EDID probing
84  * for the inactive GPU.) Also, muxes are often used to cut power to the
85  * discrete GPU while it is not used.
86  *
87  * DRM drivers register GPUs with vga_switcheroo, these are henceforth called
88  * clients. The mux is called the handler. Muxless machines also register a
89  * handler to control the power state of the discrete GPU, its ->switchto
90  * callback is a no-op for obvious reasons. The discrete GPU is often equipped
91  * with an HDA controller for the HDMI/DP audio signal, this will also
92  * register as a client so that vga_switcheroo can take care of the correct
93  * suspend/resume order when changing the discrete GPU's power state. In total
94  * there can thus be up to three clients: Two vga clients (GPUs) and one audio
95  * client (on the discrete GPU). The code is mostly prepared to support
96  * machines with more than two GPUs should they become available.
97  *
98  * The GPU to which the outputs are currently switched is called the
99  * active client in vga_switcheroo parlance. The GPU not in use is the
100  * inactive client. When the inactive client's DRM driver is loaded,
101  * it will be unable to probe the panel's EDID and hence depends on
102  * VBIOS to provide its display modes. If the VBIOS modes are bogus or
103  * if there is no VBIOS at all (which is common on the MacBook Pro),
104  * a client may alternatively request that the DDC lines are temporarily
105  * switched to it, provided that the handler supports this. Switching
106  * only the DDC lines and not the entire output avoids unnecessary
107  * flickering.
108  */
109 
110 /**
111  * struct vga_switcheroo_client - registered client
112  * @pdev: client pci device
113  * @fb_info: framebuffer to which console is remapped on switching
114  * @pwr_state: current power state
115  * @ops: client callbacks
116  * @id: client identifier. Determining the id requires the handler,
117  * 	so gpus are initially assigned VGA_SWITCHEROO_UNKNOWN_ID
118  * 	and later given their true id in vga_switcheroo_enable()
119  * @active: whether the outputs are currently switched to this client
120  * @driver_power_control: whether power state is controlled by the driver's
121  * 	runtime pm. If true, writing ON and OFF to the vga_switcheroo debugfs
122  * 	interface is a no-op so as not to interfere with runtime pm
123  * @list: client list
124  *
125  * Registered client. A client can be either a GPU or an audio device on a GPU.
126  * For audio clients, the @fb_info, @active and @driver_power_control members
127  * are bogus.
128  */
129 struct vga_switcheroo_client {
130 	struct pci_dev *pdev;
131 	struct fb_info *fb_info;
132 	enum vga_switcheroo_state pwr_state;
133 	const struct vga_switcheroo_client_ops *ops;
134 	enum vga_switcheroo_client_id id;
135 	bool active;
136 	bool driver_power_control;
137 	struct list_head list;
138 };
139 
140 /*
141  * protects access to struct vgasr_priv
142  */
143 static DEFINE_MUTEX(vgasr_mutex);
144 
145 /**
146  * struct vgasr_priv - vga_switcheroo private data
147  * @active: whether vga_switcheroo is enabled.
148  * 	Prerequisite is the registration of two GPUs and a handler
149  * @delayed_switch_active: whether a delayed switch is pending
150  * @delayed_client_id: client to which a delayed switch is pending
151  * @debugfs_root: directory for vga_switcheroo debugfs interface
152  * @switch_file: file for vga_switcheroo debugfs interface
153  * @registered_clients: number of registered GPUs
154  * 	(counting only vga clients, not audio clients)
155  * @clients: list of registered clients
156  * @handler: registered handler
157  * @handler_flags: flags of registered handler
158  * @mux_hw_lock: protects mux state
159  *	(in particular while DDC lines are temporarily switched)
160  * @old_ddc_owner: client to which DDC lines will be switched back on unlock
161  *
162  * vga_switcheroo private data. Currently only one vga_switcheroo instance
163  * per system is supported.
164  */
165 struct vgasr_priv {
166 	bool active;
167 	bool delayed_switch_active;
168 	enum vga_switcheroo_client_id delayed_client_id;
169 
170 	struct dentry *debugfs_root;
171 	struct dentry *switch_file;
172 
173 	int registered_clients;
174 	struct list_head clients;
175 
176 	const struct vga_switcheroo_handler *handler;
177 	enum vga_switcheroo_handler_flags_t handler_flags;
178 	struct lock mux_hw_lk;
179 	int old_ddc_owner;
180 };
181 
182 #define ID_BIT_AUDIO		0x100
183 #define client_is_audio(c)	((c)->id & ID_BIT_AUDIO)
184 #define client_is_vga(c)	((c)->id == VGA_SWITCHEROO_UNKNOWN_ID || \
185 				 !client_is_audio(c))
186 #define client_id(c)		((c)->id & ~ID_BIT_AUDIO)
187 
188 #if 0
189 static int vga_switcheroo_debugfs_init(struct vgasr_priv *priv);
190 static void vga_switcheroo_debugfs_fini(struct vgasr_priv *priv);
191 #endif
192 
193 /* only one switcheroo per system */
194 static struct vgasr_priv *vgasr_priv;
195 
196 static bool
197 vga_switcheroo_ready(void)
198 {
199 	/* we're ready if we get two clients + handler */
200 	return !vgasr_priv->active &&
201 	       vgasr_priv->registered_clients == 2 && vgasr_priv->handler;
202 }
203 
204 static void
205 vga_switcheroo_enable(void)
206 {
207 	int ret;
208 	struct vga_switcheroo_client *client;
209 
210 	/* call the handler to init */
211 	if (vgasr_priv->handler->init)
212 		vgasr_priv->handler->init();
213 
214 	list_for_each_entry(client, &vgasr_priv->clients, list) {
215 		if (client->id != VGA_SWITCHEROO_UNKNOWN_ID)
216 			continue;
217 		ret = vgasr_priv->handler->get_client_id(client->pdev);
218 		if (ret < 0)
219 			return;
220 
221 		client->id = ret;
222 	}
223 	//XXX: TODO
224 	//vga_switcheroo_debugfs_init(&vgasr_priv);
225 	vgasr_priv->active = true;
226 }
227 
228 /**
229  * vga_switcheroo_register_handler() - register handler
230  * @handler: handler callbacks
231  * @handler_flags: handler flags
232  *
233  * Register handler. Enable vga_switcheroo if two vga clients have already
234  * registered.
235  *
236  * Return: 0 on success, -EINVAL if a handler was already registered.
237  */
238 int
239 vga_switcheroo_register_handler(const struct vga_switcheroo_handler *handler,
240 				    enum vga_switcheroo_handler_flags_t handler_flags)
241 {
242 	mutex_lock(&vgasr_mutex);
243 	if (vgasr_priv->handler) {
244 		mutex_unlock(&vgasr_mutex);
245 		return -EINVAL;
246 	}
247 
248 	vgasr_priv->handler = handler;
249 	vgasr_priv->handler_flags = handler_flags;
250 	if (vga_switcheroo_ready()) {
251 		pr_info("enabled\n");
252 		vga_switcheroo_enable();
253 	}
254 	mutex_unlock(&vgasr_mutex);
255 	return 0;
256 }
257 EXPORT_SYMBOL(vga_switcheroo_register_handler);
258 
259 /**
260  * vga_switcheroo_unregister_handler() - unregister handler
261  *
262  * Unregister handler. Disable vga_switcheroo.
263  */
264 void
265 vga_switcheroo_unregister_handler(void)
266 {
267 	mutex_lock(&vgasr_mutex);
268 	mutex_lock(&vgasr_priv->mux_hw_lk);
269 	vgasr_priv->handler_flags = 0;
270 	vgasr_priv->handler = NULL;
271 	if (vgasr_priv->active) {
272 		pr_info("disabled\n");
273 		//XXX TODO:
274 		//vga_switcheroo_debugfs_fini(&vgasr_priv);
275 		vgasr_priv->active = false;
276 	}
277 	mutex_unlock(&vgasr_priv->mux_hw_lk);
278 	mutex_unlock(&vgasr_mutex);
279 }
280 EXPORT_SYMBOL(vga_switcheroo_unregister_handler);
281 
282 /**
283  * vga_switcheroo_handler_flags() - obtain handler flags
284  *
285  * Helper for clients to obtain the handler flags bitmask.
286  *
287  * Return: Handler flags. A value of 0 means that no handler is registered
288  * or that the handler has no special capabilities.
289  */
290 enum vga_switcheroo_handler_flags_t
291 vga_switcheroo_handler_flags(void)
292 {
293 	return vgasr_priv->handler_flags;
294 }
295 EXPORT_SYMBOL(vga_switcheroo_handler_flags);
296 
297 MALLOC_DECLARE(M_VGA_SWITCHEROO_CLIENT);
298 MALLOC_DEFINE(M_VGA_SWITCHEROO_CLIENT, "vga_switcheroo_client", "vga_switcheroo client data");
299 
300 static int
301 register_client(struct pci_dev *pdev,
302 			   const struct vga_switcheroo_client_ops *ops,
303 			   enum vga_switcheroo_client_id id, bool active,
304 			   bool driver_power_control)
305 {
306 	struct vga_switcheroo_client *client;
307 
308 	client = kmalloc(sizeof(*client), M_VGA_SWITCHEROO_CLIENT, M_WAITOK | M_ZERO);
309 	if (!client)
310 		return -ENOMEM;
311 
312 	client->pwr_state = VGA_SWITCHEROO_ON;
313 	client->pdev = pdev;
314 	client->ops = ops;
315 	client->id = id;
316 	client->active = active;
317 	client->driver_power_control = driver_power_control;
318 
319 	mutex_lock(&vgasr_mutex);
320 	list_add_tail(&client->list, &vgasr_priv->clients);
321 	if (client_is_vga(client))
322 		vgasr_priv->registered_clients++;
323 
324 	if (vga_switcheroo_ready()) {
325 		pr_info("enabled\n");
326 		vga_switcheroo_enable();
327 	}
328 	mutex_unlock(&vgasr_mutex);
329 	return 0;
330 }
331 
332 /**
333  * vga_switcheroo_register_client - register vga client
334  * @pdev: client pci device
335  * @ops: client callbacks
336  * @driver_power_control: whether power state is controlled by the driver's
337  * 	runtime pm
338  *
339  * Register vga client (GPU). Enable vga_switcheroo if another GPU and a
340  * handler have already registered. The power state of the client is assumed
341  * to be ON.
342  *
343  * Return: 0 on success, -ENOMEM on memory allocation error.
344  */
345 int
346 vga_switcheroo_register_client(struct pci_dev *pdev,
347 				   const struct vga_switcheroo_client_ops *ops,
348 				   bool driver_power_control)
349 {
350 	int error = 0;
351 	int unit, default_vgapci_unit;
352 	size_t len;
353 
354 	/*
355 	 * We need to find out if video device pci_dev is
356 	 * the active (default) video device: will determine
357 	 * if the pci_dev unit is the default_vgapci_unit
358 	 */
359 	unit = device_get_unit(pdev->dev.bsddev);
360 
361 	len = sizeof(default_vgapci_unit);
362 	error = kernel_sysctlbyname("hw.pci.default_vgapci_unit", &default_vgapci_unit, &len, NULL, 0, NULL);
363 	if (error) {
364 		pr_err("kernel_sysctlbyname: error %d\n", error);
365 		return (error);
366 	}
367 
368 	return register_client(pdev, ops, VGA_SWITCHEROO_UNKNOWN_ID,
369 			       unit == default_vgapci_unit,
370 			       driver_power_control);
371 }
372 EXPORT_SYMBOL(vga_switcheroo_register_client);
373 
374 /**
375  * vga_switcheroo_register_audio_client - register audio client
376  * @pdev: client pci device
377  * @ops: client callbacks
378  * @id: client identifier
379  *
380  * Register audio client (audio device on a GPU). The power state of the
381  * client is assumed to be ON.
382  *
383  * Return: 0 on success, -ENOMEM on memory allocation error.
384  */
385 int
386 vga_switcheroo_register_audio_client(struct pci_dev *pdev,
387 					 const struct vga_switcheroo_client_ops *ops,
388 					 enum vga_switcheroo_client_id id)
389 {
390 	return register_client(pdev, ops, id | ID_BIT_AUDIO, false, false);
391 }
392 EXPORT_SYMBOL(vga_switcheroo_register_audio_client);
393 
394 static struct vga_switcheroo_client *
395 find_client_from_pci(struct list_head *head, struct pci_dev *pdev)
396 {
397 	struct vga_switcheroo_client *client;
398 
399 	list_for_each_entry(client, head, list)
400 		if (client->pdev == pdev)
401 			return client;
402 	return NULL;
403 }
404 
405 static struct vga_switcheroo_client *
406 find_client_from_id(struct list_head *head,
407 		    enum vga_switcheroo_client_id client_id)
408 {
409 	struct vga_switcheroo_client *client;
410 
411 	list_for_each_entry(client, head, list)
412 		if (client->id == client_id)
413 			return client;
414 	return NULL;
415 }
416 
417 static struct vga_switcheroo_client *
418 find_active_client(struct list_head *head)
419 {
420 	struct vga_switcheroo_client *client;
421 
422 	list_for_each_entry(client, head, list)
423 		if (client->active)
424 			return client;
425 	return NULL;
426 }
427 
428 /**
429  * vga_switcheroo_client_probe_defer() - whether to defer probing a given client
430  * @pdev: client pci device
431  *
432  * Determine whether any prerequisites are not fulfilled to probe a given
433  * client. Drivers shall invoke this early on in their ->probe callback
434  * and return %-EPROBE_DEFER if it evaluates to %true. Thou shalt not
435  * register the client ere thou hast called this.
436  *
437  * Return: %true if probing should be deferred, otherwise %false.
438  */
439  #if 0
440 bool vga_switcheroo_client_probe_defer(struct pci_dev *pdev)
441 {
442 	if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
443 		/*
444 		 * apple-gmux is needed on pre-retina MacBook Pro
445 		 * to probe the panel if pdev is the inactive GPU.
446 		 */
447 		if (apple_gmux_present() && pdev != vga_default_device() &&
448 		    !vgasr_priv.handler_flags)
449 			return true;
450 	}
451 
452 	return false;
453 }
454 EXPORT_SYMBOL(vga_switcheroo_client_probe_defer);
455 #endif
456 
457 /**
458  * vga_switcheroo_get_client_state() - obtain power state of a given client
459  * @pdev: client pci device
460  *
461  * Obtain power state of a given client as seen from vga_switcheroo.
462  * The function is only called from hda_intel.c.
463  *
464  * Return: Power state.
465  */
466 enum vga_switcheroo_state
467 vga_switcheroo_get_client_state(struct pci_dev *pdev)
468 {
469 	struct vga_switcheroo_client *client;
470 	enum vga_switcheroo_state ret;
471 
472 	mutex_lock(&vgasr_mutex);
473 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
474 	if (!client)
475 		ret = VGA_SWITCHEROO_NOT_FOUND;
476 	else
477 		ret = client->pwr_state;
478 	mutex_unlock(&vgasr_mutex);
479 	return ret;
480 }
481 EXPORT_SYMBOL(vga_switcheroo_get_client_state);
482 
483 /**
484  * vga_switcheroo_unregister_client() - unregister client
485  * @pdev: client pci device
486  *
487  * Unregister client. Disable vga_switcheroo if this is a vga client (GPU).
488  */
489 void
490 vga_switcheroo_unregister_client(struct pci_dev *pdev)
491 {
492 	struct vga_switcheroo_client *client;
493 
494 	mutex_lock(&vgasr_mutex);
495 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
496 	if (client) {
497 		if (client_is_vga(client))
498 			vgasr_priv->registered_clients--;
499 		list_del(&client->list);
500 		kfree(client, M_VGA_SWITCHEROO_CLIENT);
501 	}
502 	if (vgasr_priv->active && vgasr_priv->registered_clients < 2) {
503 		pr_info("disabled\n");
504 		//XXX: TODO
505 		//vga_switcheroo_debugfs_fini(&vgasr_priv);
506 		vgasr_priv->active = false;
507 	}
508 	mutex_unlock(&vgasr_mutex);
509 }
510 EXPORT_SYMBOL(vga_switcheroo_unregister_client);
511 
512 /**
513  * vga_switcheroo_client_fb_set() - set framebuffer of a given client
514  * @pdev: client pci device
515  * @info: framebuffer
516  *
517  * Set framebuffer of a given client. The console will be remapped to this
518  * on switching.
519  */
520 void
521 vga_switcheroo_client_fb_set(struct pci_dev *pdev,
522 				 struct fb_info *info)
523 {
524 	struct vga_switcheroo_client *client;
525 
526 	mutex_lock(&vgasr_mutex);
527 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
528 	if (client)
529 		client->fb_info = info;
530 	mutex_unlock(&vgasr_mutex);
531 }
532 EXPORT_SYMBOL(vga_switcheroo_client_fb_set);
533 
534 /**
535  * vga_switcheroo_lock_ddc() - temporarily switch DDC lines to a given client
536  * @pdev: client pci device
537  *
538  * Temporarily switch DDC lines to the client identified by @pdev
539  * (but leave the outputs otherwise switched to where they are).
540  * This allows the inactive client to probe EDID. The DDC lines must
541  * afterwards be switched back by calling vga_switcheroo_unlock_ddc(),
542  * even if this function returns an error.
543  *
544  * Return: Previous DDC owner on success or a negative int on error.
545  * Specifically, %-ENODEV if no handler has registered or if the handler
546  * does not support switching the DDC lines. Also, a negative value
547  * returned by the handler is propagated back to the caller.
548  * The return value has merely an informational purpose for any caller
549  * which might be interested in it. It is acceptable to ignore the return
550  * value and simply rely on the result of the subsequent EDID probe,
551  * which will be %NULL if DDC switching failed.
552  */
553 int
554 vga_switcheroo_lock_ddc(struct pci_dev *pdev)
555 {
556 	enum vga_switcheroo_client_id id;
557 
558 	mutex_lock(&vgasr_priv->mux_hw_lk);
559 	if (!vgasr_priv->handler || !vgasr_priv->handler->switch_ddc) {
560 		vgasr_priv->old_ddc_owner = -ENODEV;
561 		return -ENODEV;
562 	}
563 
564 	id = vgasr_priv->handler->get_client_id(pdev);
565 	vgasr_priv->old_ddc_owner = vgasr_priv->handler->switch_ddc(id);
566 	return vgasr_priv->old_ddc_owner;
567 }
568 EXPORT_SYMBOL(vga_switcheroo_lock_ddc);
569 
570 /**
571  * vga_switcheroo_unlock_ddc() - switch DDC lines back to previous owner
572  * @pdev: client pci device
573  *
574  * Switch DDC lines back to the previous owner after calling
575  * vga_switcheroo_lock_ddc(). This must be called even if
576  * vga_switcheroo_lock_ddc() returned an error.
577  *
578  * Return: Previous DDC owner on success (i.e. the client identifier of @pdev)
579  * or a negative int on error.
580  * Specifically, %-ENODEV if no handler has registered or if the handler
581  * does not support switching the DDC lines. Also, a negative value
582  * returned by the handler is propagated back to the caller.
583  * Finally, invoking this function without calling vga_switcheroo_lock_ddc()
584  * first is not allowed and will result in %-EINVAL.
585  */
586 int
587 vga_switcheroo_unlock_ddc(struct pci_dev *pdev)
588 {
589 	enum vga_switcheroo_client_id id;
590 	int ret = vgasr_priv->old_ddc_owner;
591 
592 	if (WARN_ON_ONCE(!mutex_is_locked(&vgasr_priv->mux_hw_lk)))
593 		return -EINVAL;
594 
595 	if (vgasr_priv->old_ddc_owner >= 0) {
596 		id = vgasr_priv->handler->get_client_id(pdev);
597 		if (vgasr_priv->old_ddc_owner != id)
598 			ret = vgasr_priv->handler->switch_ddc(
599 						     vgasr_priv->old_ddc_owner);
600 	}
601 	mutex_unlock(&vgasr_priv->mux_hw_lk);
602 	return ret;
603 }
604 EXPORT_SYMBOL(vga_switcheroo_unlock_ddc);
605 
606 /**
607  * DOC: Manual switching and manual power control
608  *
609  * In this mode of use, the file /sys/kernel/debug/vgaswitcheroo/switch
610  * can be read to retrieve the current vga_switcheroo state and commands
611  * can be written to it to change the state. The file appears as soon as
612  * two GPU drivers and one handler have registered with vga_switcheroo.
613  * The following commands are understood:
614  *
615  * * OFF: Power off the device not in use.
616  * * ON: Power on the device not in use.
617  * * IGD: Switch to the integrated graphics device.
618  * 	Power on the integrated GPU if necessary, power off the discrete GPU.
619  * 	Prerequisite is that no user space processes (e.g. Xorg, alsactl)
620  * 	have opened device files of the GPUs or the audio client. If the
621  * 	switch fails, the user may invoke lsof(8) or fuser(1) on /dev/dri/
622  * 	and /dev/snd/controlC1 to identify processes blocking the switch.
623  * * DIS: Switch to the discrete graphics device.
624  * * DIGD: Delayed switch to the integrated graphics device.
625  * 	This will perform the switch once the last user space process has
626  * 	closed the device files of the GPUs and the audio client.
627  * * DDIS: Delayed switch to the discrete graphics device.
628  * * MIGD: Mux-only switch to the integrated graphics device.
629  * 	Does not remap console or change the power state of either gpu.
630  * 	If the integrated GPU is currently off, the screen will turn black.
631  * 	If it is on, the screen will show whatever happens to be in VRAM.
632  * 	Either way, the user has to blindly enter the command to switch back.
633  * * MDIS: Mux-only switch to the discrete graphics device.
634  *
635  * For GPUs whose power state is controlled by the driver's runtime pm,
636  * the ON and OFF commands are a no-op (see next section).
637  *
638  * For muxless machines, the IGD/DIS, DIGD/DDIS and MIGD/MDIS commands
639  * should not be used.
640  */
641 
642 #if 0  /* debugfs 1 */
643 static int
644 vga_switcheroo_show(struct seq_file *m, void *v)
645 {
646 	struct vga_switcheroo_client *client;
647 	int i = 0;
648 
649 	mutex_lock(&vgasr_mutex);
650 	list_for_each_entry(client, &vgasr_priv.clients, list) {
651 		seq_printf(m, "%d:%s%s:%c:%s%s:%s\n", i,
652 			   client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" :
653 								     "IGD",
654 			   client_is_vga(client) ? "" : "-Audio",
655 			   client->active ? '+' : ' ',
656 			   client->driver_power_control ? "Dyn" : "",
657 			   client->pwr_state ? "Pwr" : "Off",
658 			   pci_name(client->pdev));
659 		i++;
660 	}
661 	mutex_unlock(&vgasr_mutex);
662 	return 0;
663 }
664 
665 static int
666 vga_switcheroo_debugfs_open(struct inode *inode, struct file *file)
667 {
668 	return single_open(file, vga_switcheroo_show, NULL);
669 }
670 #endif /* debugfs 1 */
671 
672 static int
673 vga_switchon(struct vga_switcheroo_client *client)
674 {
675 	if (client->driver_power_control)
676 		return 0;
677 	if (vgasr_priv->handler->power_state)
678 		vgasr_priv->handler->power_state(client->id, VGA_SWITCHEROO_ON);
679 	/* call the driver callback to turn on device */
680 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_ON);
681 	client->pwr_state = VGA_SWITCHEROO_ON;
682 	return 0;
683 }
684 
685 static int
686 vga_switchoff(struct vga_switcheroo_client *client)
687 {
688 	if (client->driver_power_control)
689 		return 0;
690 	/* call the driver callback to turn off device */
691 	client->ops->set_gpu_state(client->pdev, VGA_SWITCHEROO_OFF);
692 	if (vgasr_priv->handler->power_state)
693 		vgasr_priv->handler->power_state(client->id, VGA_SWITCHEROO_OFF);
694 	client->pwr_state = VGA_SWITCHEROO_OFF;
695 	return 0;
696 }
697 
698 static void
699 set_audio_state(enum vga_switcheroo_client_id id,
700 			    enum vga_switcheroo_state state)
701 {
702 	struct vga_switcheroo_client *client;
703 
704 	client = find_client_from_id(&vgasr_priv->clients, id | ID_BIT_AUDIO);
705 	if (client && client->pwr_state != state) {
706 		client->ops->set_gpu_state(client->pdev, state);
707 		client->pwr_state = state;
708 	}
709 }
710 
711 /* stage one happens before delay */
712 static int
713 vga_switchto_stage1(struct vga_switcheroo_client *new_client)
714 {
715 	struct vga_switcheroo_client *active;
716 
717 	active = find_active_client(&vgasr_priv->clients);
718 	if (!active)
719 		return 0;
720 
721 	if (new_client->pwr_state == VGA_SWITCHEROO_OFF)
722 		vga_switchon(new_client);
723 
724 	//XXX CRITICAL TODO:
725 	//vga_set_default_device(new_client->pdev);
726 
727 	return 0;
728 }
729 
730 /* post delay */
731 static int
732 vga_switchto_stage2(struct vga_switcheroo_client *new_client)
733 {
734 	int ret;
735 	struct vga_switcheroo_client *active;
736 
737 	active = find_active_client(&vgasr_priv->clients);
738 	if (!active)
739 		return 0;
740 
741 	active->active = false;
742 
743 	set_audio_state(active->id, VGA_SWITCHEROO_OFF);
744 
745 	/* XXX CRITICAL TODO: set new fb
746 
747 	if (new_client->fb_info) {
748 		struct fb_event event;
749 
750 		console_lock();
751 		event.info = new_client->fb_info;
752 		fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event);
753 		console_unlock();
754 	}
755 	*/
756 
757 	mutex_lock(&vgasr_priv->mux_hw_lk);
758 	ret = vgasr_priv->handler->switchto(new_client->id);
759 	mutex_unlock(&vgasr_priv->mux_hw_lk);
760 	if (ret)
761 		return ret;
762 
763 	if (new_client->ops->reprobe)
764 		new_client->ops->reprobe(new_client->pdev);
765 
766 	if (active->pwr_state == VGA_SWITCHEROO_ON)
767 		vga_switchoff(active);
768 
769 	set_audio_state(new_client->id, VGA_SWITCHEROO_ON);
770 
771 	new_client->active = true;
772 	return 0;
773 }
774 
775 static bool
776 check_can_switch(void)
777 {
778 	struct vga_switcheroo_client *client;
779 
780 	list_for_each_entry(client, &vgasr_priv->clients, list) {
781 		if (!client->ops->can_switch(client->pdev)) {
782 			pr_err("client %x refused switch\n", client->id);
783 			return false;
784 		}
785 	}
786 	return true;
787 }
788 
789 #if 0  /* debugfs 2 */
790 static ssize_t
791 vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf,
792 			     size_t cnt, loff_t *ppos)
793 {
794 	char usercmd[64];
795 	int ret;
796 	bool delay = false, can_switch;
797 	bool just_mux = false;
798 	enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
799 	struct vga_switcheroo_client *client = NULL;
800 
801 	if (cnt > 63)
802 		cnt = 63;
803 
804 	if (copy_from_user(usercmd, ubuf, cnt))
805 		return -EFAULT;
806 
807 	mutex_lock(&vgasr_mutex);
808 
809 	if (!vgasr_priv.active) {
810 		cnt = -EINVAL;
811 		goto out;
812 	}
813 
814 	/* pwr off the device not in use */
815 	if (strncmp(usercmd, "OFF", 3) == 0) {
816 		list_for_each_entry(client, &vgasr_priv.clients, list) {
817 			if (client->active || client_is_audio(client))
818 				continue;
819 			if (client->driver_power_control)
820 				continue;
821 			set_audio_state(client->id, VGA_SWITCHEROO_OFF);
822 			if (client->pwr_state == VGA_SWITCHEROO_ON)
823 				vga_switchoff(client);
824 		}
825 		goto out;
826 	}
827 	/* pwr on the device not in use */
828 	if (strncmp(usercmd, "ON", 2) == 0) {
829 		list_for_each_entry(client, &vgasr_priv.clients, list) {
830 			if (client->active || client_is_audio(client))
831 				continue;
832 			if (client->driver_power_control)
833 				continue;
834 			if (client->pwr_state == VGA_SWITCHEROO_OFF)
835 				vga_switchon(client);
836 			set_audio_state(client->id, VGA_SWITCHEROO_ON);
837 		}
838 		goto out;
839 	}
840 
841 	/* request a delayed switch - test can we switch now */
842 	if (strncmp(usercmd, "DIGD", 4) == 0) {
843 		client_id = VGA_SWITCHEROO_IGD;
844 		delay = true;
845 	}
846 
847 	if (strncmp(usercmd, "DDIS", 4) == 0) {
848 		client_id = VGA_SWITCHEROO_DIS;
849 		delay = true;
850 	}
851 
852 	if (strncmp(usercmd, "IGD", 3) == 0)
853 		client_id = VGA_SWITCHEROO_IGD;
854 
855 	if (strncmp(usercmd, "DIS", 3) == 0)
856 		client_id = VGA_SWITCHEROO_DIS;
857 
858 	if (strncmp(usercmd, "MIGD", 4) == 0) {
859 		just_mux = true;
860 		client_id = VGA_SWITCHEROO_IGD;
861 	}
862 	if (strncmp(usercmd, "MDIS", 4) == 0) {
863 		just_mux = true;
864 		client_id = VGA_SWITCHEROO_DIS;
865 	}
866 
867 	if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
868 		goto out;
869 	client = find_client_from_id(&vgasr_priv.clients, client_id);
870 	if (!client)
871 		goto out;
872 
873 	vgasr_priv.delayed_switch_active = false;
874 
875 	if (just_mux) {
876 		mutex_lock(&vgasr_priv.mux_hw_lock);
877 		ret = vgasr_priv.handler->switchto(client_id);
878 		mutex_unlock(&vgasr_priv.mux_hw_lock);
879 		goto out;
880 	}
881 
882 	if (client->active)
883 		goto out;
884 
885 	/* okay we want a switch - test if devices are willing to switch */
886 	can_switch = check_can_switch();
887 
888 	if (can_switch == false && delay == false)
889 		goto out;
890 
891 	if (can_switch) {
892 		ret = vga_switchto_stage1(client);
893 		if (ret)
894 			pr_err("switching failed stage 1 %d\n", ret);
895 
896 		ret = vga_switchto_stage2(client);
897 		if (ret)
898 			pr_err("switching failed stage 2 %d\n", ret);
899 
900 	} else {
901 		pr_info("setting delayed switch to client %d\n", client->id);
902 		vgasr_priv.delayed_switch_active = true;
903 		vgasr_priv.delayed_client_id = client_id;
904 
905 		ret = vga_switchto_stage1(client);
906 		if (ret)
907 			pr_err("delayed switching stage 1 failed %d\n", ret);
908 	}
909 
910 out:
911 	mutex_unlock(&vgasr_mutex);
912 	return cnt;
913 }
914 
915 #if 0  /* linux specific */
916 static const struct file_operations vga_switcheroo_debugfs_fops = {
917 	.owner = THIS_MODULE,
918 	.open = vga_switcheroo_debugfs_open,
919 	.write = vga_switcheroo_debugfs_write,
920 	.read = seq_read,
921 	.llseek = seq_lseek,
922 	.release = single_release,
923 };
924 #endif
925 
926 static void
927 vga_switcheroo_debugfs_fini(struct vgasr_priv *priv)
928 {
929 	debugfs_remove(priv->switch_file);
930 	priv->switch_file = NULL;
931 
932 	debugfs_remove(priv->debugfs_root);
933 	priv->debugfs_root = NULL;
934 }
935 
936 static int
937 vga_switcheroo_debugfs_init(struct vgasr_priv *priv)
938 {
939 	static const char mp[] = "/sys/kernel/debug";
940 
941 	/* already initialised */
942 	if (priv->debugfs_root)
943 		return 0;
944 	priv->debugfs_root = debugfs_create_dir("vgaswitcheroo", NULL);
945 
946 	if (!priv->debugfs_root) {
947 		pr_err("Cannot create %s/vgaswitcheroo\n", mp);
948 		goto fail;
949 	}
950 
951 	priv->switch_file = debugfs_create_file("switch", 0644,
952 						priv->debugfs_root, NULL,
953 						&vga_switcheroo_debugfs_fops);
954 	if (!priv->switch_file) {
955 		pr_err("cannot create %s/vgaswitcheroo/switch\n", mp);
956 		goto fail;
957 	}
958 	return 0;
959 fail:
960 	vga_switcheroo_debugfs_fini(priv);
961 	return -1;
962 }
963 #endif  /* debugfs 2 */
964 
965 /*
966  * Device infrastructure
967  */
968 #define BUFFERSIZE 255
969 
970 static d_open_t      vga_switcheroo_open;
971 static d_close_t     vga_switcheroo_close;
972 static d_read_t      vga_switcheroo_read;
973 static d_write_t     vga_switcheroo_write;
974 
975 static struct dev_ops vga_switcheroo_ops = {
976 	{ "vga_switcheroo", 0, 0 },
977 	.d_open =	vga_switcheroo_open,
978 	.d_close =	vga_switcheroo_close,
979 	.d_read =	vga_switcheroo_read,
980 	.d_write =	vga_switcheroo_write,
981 };
982 
983 struct s_vga_switcheroo {
984 	char msg[BUFFERSIZE + 1];
985 	int len;
986 };
987 
988 static cdev_t vga_switcheroo_dev;
989 static struct s_vga_switcheroo *vga_switcheroo_buf;
990 
991 MALLOC_DECLARE(M_VGA_SWITCHEROO_BUF);
992 MALLOC_DEFINE(M_VGA_SWITCHEROO_BUF, "vga_switcheroo_buf", "buffer for vga_switcheroo");
993 MALLOC_DECLARE(M_VGA_SWITCHEROO_VGASR_PRIV);
994 MALLOC_DEFINE(M_VGA_SWITCHEROO_VGASR_PRIV, "vga_switcheroo_vgasr_priv", "private data of vga_switcheroo");
995 
996 static int
997 vga_switcheroo_handler(struct module *m __unused, int what, void *arg __unused)
998 {
999 	int error = 0;
1000 
1001 	switch (what) {
1002 	case MOD_LOAD:                /* kldload */
1003 		vga_switcheroo_dev = make_dev(
1004 		    &vga_switcheroo_ops,
1005 		    0,
1006 		    UID_ROOT,
1007 		    GID_WHEEL,
1008 		    0600,
1009 		    "vga_switcheroo");
1010 		reference_dev(vga_switcheroo_dev);
1011 		if (error != 0)
1012 			break;
1013 
1014 		vga_switcheroo_buf = kmalloc(sizeof(*vga_switcheroo_buf), M_VGA_SWITCHEROO_BUF, M_WAITOK | M_ZERO);
1015 
1016 		//init vgasr_priv
1017 		vgasr_priv = kmalloc(sizeof(*vgasr_priv), M_VGA_SWITCHEROO_VGASR_PRIV, M_WAITOK | M_ZERO);
1018 		vgasr_priv->clients = (struct list_head) { &(vgasr_priv->clients), &(vgasr_priv->clients) };
1019 		lockinit(&vgasr_priv->mux_hw_lk, "mux_hw_lk", 0, LK_CANRECURSE);
1020 		kprintf("vga_switcheroo device loaded\n");
1021 		break;
1022 
1023 	case MOD_UNLOAD:
1024 	case MOD_SHUTDOWN:
1025 		destroy_dev(vga_switcheroo_dev);
1026 		kfree(vga_switcheroo_buf, M_VGA_SWITCHEROO_BUF);
1027 		kfree(vgasr_priv, M_VGA_SWITCHEROO_VGASR_PRIV);
1028 		kprintf("vga_switcheroo device unloaded\n");
1029 		break;
1030 
1031 	default:
1032 		error = EOPNOTSUPP;
1033 		break;
1034 	}
1035 
1036 	return (error);
1037 }
1038 
1039 static int
1040 vga_switcheroo_open(struct dev_open_args *ap)
1041 {
1042 	int error = 0;
1043 
1044 	return (error);
1045 }
1046 
1047 static int
1048 vga_switcheroo_close(struct dev_close_args *ap)
1049 {
1050 	return (0);
1051 }
1052 
1053 static int
1054 vga_switcheroo_read(struct dev_read_args *ap)
1055 {
1056 	struct vga_switcheroo_client *client;
1057 	int i = 0;
1058 
1059 	mutex_lock(&vgasr_mutex);
1060 	list_for_each_entry(client, &vgasr_priv->clients, list) {
1061 		uprintf("%d:%s%s:%c:%s%s:%s\n", i,
1062 			client_id(client) == VGA_SWITCHEROO_DIS ? "DIS" : "IGD",
1063 			client_is_vga(client) ? "" : "-Audio",
1064 			client->active ? '+' : ' ',
1065 			client->driver_power_control ? "Dyn" : "",
1066 			client->pwr_state ? "Pwr" : "Off",
1067 			device_get_nameunit(client->pdev->dev.bsddev));
1068 		i++;
1069 	}
1070 	mutex_unlock(&vgasr_mutex);
1071 	return 0;
1072 }
1073 
1074 static int
1075 vga_switcheroo_write(struct dev_write_args *ap)
1076 {
1077 	struct uio *uio = ap->a_uio;
1078 	size_t amt;
1079 	int error = 0;
1080 	int cnt;
1081 	int ret;
1082 	bool can_switch;
1083 	bool delay = false;
1084 	bool just_mux = false;
1085 	enum vga_switcheroo_client_id client_id = VGA_SWITCHEROO_UNKNOWN_ID;
1086 	struct vga_switcheroo_client *client = NULL;
1087 
1088 	/*
1089 	 * We either write from the beginning or are appending -- do
1090 	 * not allow random access.
1091 	 */
1092 	if (uio->uio_offset != 0 && (uio->uio_offset != vga_switcheroo_buf->len))
1093 		return (EINVAL);
1094 
1095 	/* This is a new message, reset length */
1096 	if (uio->uio_offset == 0)
1097 		vga_switcheroo_buf->len = 0;
1098 
1099 	/* Copy the string in from user memory to kernel memory */
1100 	amt = MIN(uio->uio_resid, (BUFFERSIZE - vga_switcheroo_buf->len));
1101 	cnt = amt;
1102 
1103 	error = uiomove(vga_switcheroo_buf->msg + uio->uio_offset, amt, uio);
1104 
1105 	vga_switcheroo_buf->len = uio->uio_offset;
1106 	vga_switcheroo_buf->msg[vga_switcheroo_buf->len] = 0;
1107 
1108 	if (error != 0)
1109 		uprintf("Write failed: bad address!\n");
1110 
1111 	mutex_lock(&vgasr_mutex);
1112 
1113 	if (!vgasr_priv->active) {
1114 		error = -EINVAL;
1115 		goto out;
1116 	}
1117 
1118 	/*
1119 	 * START PROCESSING COMMANDS
1120 	 */
1121 
1122 	/* pwr off the device not in use */
1123 	if (strncmp(vga_switcheroo_buf->msg, "OFF", 3) == 0) {
1124 		list_for_each_entry(client, &vgasr_priv->clients, list) {
1125 			if (client->active || client_is_audio(client))
1126 				continue;
1127 			if (client->driver_power_control)
1128 				continue;
1129 			set_audio_state(client->id, VGA_SWITCHEROO_OFF);
1130 			if (client->pwr_state == VGA_SWITCHEROO_ON)
1131 				vga_switchoff(client);
1132 		}
1133 		goto out;
1134 	}
1135 
1136 	/* pwr on the device not in use */
1137 	if (strncmp(vga_switcheroo_buf->msg, "ON", 2) == 0) {
1138 		list_for_each_entry(client, &vgasr_priv->clients, list) {
1139 			if (client->active || client_is_audio(client))
1140 				continue;
1141 			if (client->driver_power_control)
1142 				continue;
1143 			if (client->pwr_state == VGA_SWITCHEROO_OFF)
1144 				vga_switchon(client);
1145 			set_audio_state(client->id, VGA_SWITCHEROO_ON);
1146 		}
1147 		goto out;
1148 	}
1149 
1150 	/* request a delayed switch - test can we switch now */
1151 	if (strncmp(vga_switcheroo_buf->msg, "DIGD", 4) == 0) {
1152 		client_id = VGA_SWITCHEROO_IGD;
1153 		delay = true;
1154 	}
1155 
1156 	if (strncmp(vga_switcheroo_buf->msg, "DDIS", 4) == 0) {
1157 		client_id = VGA_SWITCHEROO_DIS;
1158 		delay = true;
1159 	}
1160 
1161 	if (strncmp(vga_switcheroo_buf->msg, "IGD", 3) == 0)
1162 		client_id = VGA_SWITCHEROO_IGD;
1163 
1164 	if (strncmp(vga_switcheroo_buf->msg, "DIS", 3) == 0)
1165 		client_id = VGA_SWITCHEROO_DIS;
1166 
1167 	if (strncmp(vga_switcheroo_buf->msg, "MIGD", 4) == 0) {
1168 		just_mux = true;
1169 		client_id = VGA_SWITCHEROO_IGD;
1170 	}
1171 
1172 	if (strncmp(vga_switcheroo_buf->msg, "MDIS", 4) == 0) {
1173 		just_mux = true;
1174 		client_id = VGA_SWITCHEROO_DIS;
1175 	}
1176 
1177 	if (client_id == VGA_SWITCHEROO_UNKNOWN_ID)
1178 		goto out;
1179 	client = find_client_from_id(&vgasr_priv->clients, client_id);
1180 	if (!client)
1181 		goto out;
1182 
1183 	vgasr_priv->delayed_switch_active = false;
1184 
1185 	if (just_mux) {
1186 		mutex_lock(&vgasr_priv->mux_hw_lk);
1187 		ret = vgasr_priv->handler->switchto(client_id);
1188 		mutex_unlock(&vgasr_priv->mux_hw_lk);
1189 		goto out;
1190 	}
1191 
1192 	if (client->active)
1193 		goto out;
1194 
1195 	/* okay we want a switch - test if devices are willing to switch */
1196 	can_switch = check_can_switch();
1197 
1198 	if (can_switch == false && delay == false)
1199 		goto out;
1200 
1201 	if (can_switch) {
1202 		ret = vga_switchto_stage1(client);
1203 		if (ret)
1204 			pr_err("switching failed stage 1 %d\n", ret);
1205 
1206 		ret = vga_switchto_stage2(client);
1207 		if (ret)
1208 			pr_err("switching failed stage 2 %d\n", ret);
1209 
1210 	} else {
1211 		pr_info("setting delayed switch to client %d\n", client->id);
1212 		vgasr_priv->delayed_switch_active = true;
1213 		vgasr_priv->delayed_client_id = client_id;
1214 
1215 		ret = vga_switchto_stage1(client);
1216 		if (ret)
1217 			pr_err("delayed switching stage 1 failed %d\n", ret);
1218 	}
1219 
1220 out:
1221 	mutex_unlock(&vgasr_mutex);
1222 	return (error);
1223 }
1224 
1225 MODULE_VERSION(vga_switcheroo, 1);
1226 DEV_MODULE(vga_switcheroo, vga_switcheroo_handler, NULL);
1227 
1228 /**
1229  * vga_switcheroo_process_delayed_switch() - helper for delayed switching
1230  *
1231  * Process a delayed switch if one is pending. DRM drivers should call this
1232  * from their ->lastclose callback.
1233  *
1234  * Return: 0 on success. -EINVAL if no delayed switch is pending, if the client
1235  * has unregistered in the meantime or if there are other clients blocking the
1236  * switch. If the actual switch fails, an error is reported and 0 is returned.
1237  */
1238 int
1239 vga_switcheroo_process_delayed_switch(void)
1240 {
1241 	struct vga_switcheroo_client *client;
1242 	int ret;
1243 	int err = -EINVAL;
1244 
1245 	mutex_lock(&vgasr_mutex);
1246 	if (!vgasr_priv->delayed_switch_active)
1247 		goto err;
1248 
1249 	pr_info("processing delayed switch to %d\n",
1250 		vgasr_priv->delayed_client_id);
1251 
1252 	client = find_client_from_id(&vgasr_priv->clients,
1253 				     vgasr_priv->delayed_client_id);
1254 	if (!client || !check_can_switch())
1255 		goto err;
1256 
1257 	ret = vga_switchto_stage2(client);
1258 	if (ret)
1259 		pr_err("delayed switching failed stage 2 %d\n", ret);
1260 
1261 	vgasr_priv->delayed_switch_active = false;
1262 	err = 0;
1263 err:
1264 	mutex_unlock(&vgasr_mutex);
1265 	return err;
1266 }
1267 EXPORT_SYMBOL(vga_switcheroo_process_delayed_switch);
1268 
1269 /**
1270  * DOC: Driver power control
1271  *
1272  * In this mode of use, the discrete GPU automatically powers up and down at
1273  * the discretion of the driver's runtime pm. On muxed machines, the user may
1274  * still influence the muxer state by way of the debugfs interface, however
1275  * the ON and OFF commands become a no-op for the discrete GPU.
1276  *
1277  * This mode is the default on Nvidia HybridPower/Optimus and ATI PowerXpress.
1278  * Specifying nouveau.runpm=0, radeon.runpm=0 or amdgpu.runpm=0 on the kernel
1279  * command line disables it.
1280  *
1281  * When the driver decides to power up or down, it notifies vga_switcheroo
1282  * thereof so that it can (a) power the audio device on the GPU up or down,
1283  * and (b) update its internal power state representation for the device.
1284  * This is achieved by vga_switcheroo_set_dynamic_switch().
1285  *
1286  * After the GPU has been suspended, the handler needs to be called to cut
1287  * power to the GPU. Likewise it needs to reinstate power before the GPU
1288  * can resume. This is achieved by vga_switcheroo_init_domain_pm_ops(),
1289  * which augments the GPU's suspend/resume functions by the requisite
1290  * calls to the handler.
1291  *
1292  * When the audio device resumes, the GPU needs to be woken. This is achieved
1293  * by vga_switcheroo_init_domain_pm_optimus_hdmi_audio(), which augments the
1294  * audio device's resume function.
1295  *
1296  * On muxed machines, if the mux is initially switched to the discrete GPU,
1297  * the user ends up with a black screen when the GPU powers down after boot.
1298  * As a workaround, the mux is forced to the integrated GPU on runtime suspend,
1299  * cf. https://bugs.freedesktop.org/show_bug.cgi?id=75917
1300  */
1301 
1302 #if 0  /* used in: runtime_suspend/resume() */
1303 static void
1304 vga_switcheroo_power_switch(struct pci_dev *pdev,
1305 					enum vga_switcheroo_state state)
1306 {
1307 	struct vga_switcheroo_client *client;
1308 
1309 	if (!vgasr_priv->handler->power_state)
1310 		return;
1311 
1312 	client = find_client_from_pci(&vgasr_priv->clients, pdev);
1313 	if (!client)
1314 		return;
1315 
1316 	if (!client->driver_power_control)
1317 		return;
1318 
1319 	vgasr_priv->handler->power_state(client->id, state);
1320 }
1321 #endif  /* used in: runtime_suspend/resume() */
1322 
1323 /**
1324  * vga_switcheroo_set_dynamic_switch() - helper for driver power control
1325  * @pdev: client pci device
1326  * @dynamic: new power state
1327  *
1328  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1329  * When the driver decides to power up or down, it notifies vga_switcheroo
1330  * thereof using this helper so that it can (a) power the audio device on
1331  * the GPU up or down, and (b) update its internal power state representation
1332  * for the device.
1333  */
1334 #if 0  /* TODO: no dynamic_switch yet */
1335 void
1336 vga_switcheroo_set_dynamic_switch(struct pci_dev *pdev,
1337 				       enum vga_switcheroo_state dynamic)
1338 {
1339 	struct vga_switcheroo_client *client;
1340 
1341 	mutex_lock(&vgasr_mutex);
1342 	client = find_client_from_pci(&vgasr_priv.clients, pdev);
1343 	if (!client || !client->driver_power_control) {
1344 		mutex_unlock(&vgasr_mutex);
1345 		return;
1346 	}
1347 
1348 	client->pwr_state = dynamic;
1349 	set_audio_state(client->id, dynamic);
1350 	mutex_unlock(&vgasr_mutex);
1351 }
1352 EXPORT_SYMBOL(vga_switcheroo_set_dynamic_switch);
1353 
1354 /* switcheroo power domain */
1355 static int
1356 vga_switcheroo_runtime_suspend(struct device *dev)
1357 {
1358 	struct pci_dev *pdev = to_pci_dev(dev);
1359 	int ret;
1360 
1361 	ret = dev->bus->pm->runtime_suspend(dev);
1362 	if (ret)
1363 		return ret;
1364 	mutex_lock(&vgasr_mutex);
1365 	if (vgasr_priv.handler->switchto) {
1366 		mutex_lock(&vgasr_priv.mux_hw_lock);
1367 		vgasr_priv.handler->switchto(VGA_SWITCHEROO_IGD);
1368 		mutex_unlock(&vgasr_priv.mux_hw_lock);
1369 	}
1370 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_OFF);
1371 	mutex_unlock(&vgasr_mutex);
1372 	return 0;
1373 }
1374 
1375 static int
1376 vga_switcheroo_runtime_resume(struct device *dev)
1377 {
1378 	struct pci_dev *pdev = to_pci_dev(dev);
1379 	int ret;
1380 
1381 	mutex_lock(&vgasr_mutex);
1382 	vga_switcheroo_power_switch(pdev, VGA_SWITCHEROO_ON);
1383 	mutex_unlock(&vgasr_mutex);
1384 	ret = dev->bus->pm->runtime_resume(dev);
1385 	if (ret)
1386 		return ret;
1387 
1388 	return 0;
1389 }
1390 #endif  /* TODO: no dynamic_switch yet */
1391 
1392 /**
1393  * vga_switcheroo_init_domain_pm_ops() - helper for driver power control
1394  * @dev: vga client device
1395  * @domain: power domain
1396  *
1397  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1398  * After the GPU has been suspended, the handler needs to be called to cut
1399  * power to the GPU. Likewise it needs to reinstate power before the GPU
1400  * can resume. To this end, this helper augments the suspend/resume functions
1401  * by the requisite calls to the handler. It needs only be called on platforms
1402  * where the power switch is separate to the device being powered down.
1403  */
1404 #if 0 /* TODO: no pm_ops */
1405 int
1406 vga_switcheroo_init_domain_pm_ops(struct device *dev,
1407 				      struct dev_pm_domain *domain)
1408 {
1409 	/* copy over all the bus versions */
1410 	if (dev->bus && dev->bus->pm) {
1411 		domain->ops = *dev->bus->pm;
1412 		domain->ops.runtime_suspend = vga_switcheroo_runtime_suspend;
1413 		domain->ops.runtime_resume = vga_switcheroo_runtime_resume;
1414 
1415 		dev_pm_domain_set(dev, domain);
1416 		return 0;
1417 	}
1418 	dev_pm_domain_set(dev, NULL);
1419 	return -EINVAL;
1420 }
1421 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_ops);
1422 
1423 void
1424 vga_switcheroo_fini_domain_pm_ops(struct device *dev)
1425 {
1426 	dev_pm_domain_set(dev, NULL);
1427 }
1428 EXPORT_SYMBOL(vga_switcheroo_fini_domain_pm_ops);
1429 
1430 static int
1431 vga_switcheroo_runtime_resume_hdmi_audio(struct device *dev)
1432 {
1433 	struct pci_dev *pdev = to_pci_dev(dev);
1434 	struct vga_switcheroo_client *client;
1435 	struct device *video_dev = NULL;
1436 	int ret;
1437 
1438 	/* we need to check if we have to switch back on the video
1439 	   device so the audio device can come back */
1440 	mutex_lock(&vgasr_mutex);
1441 	list_for_each_entry(client, &vgasr_priv.clients, list) {
1442 		if (PCI_SLOT(client->pdev->devfn) == PCI_SLOT(pdev->devfn) &&
1443 		    client_is_vga(client)) {
1444 			video_dev = &client->pdev->dev;
1445 			break;
1446 		}
1447 	}
1448 	mutex_unlock(&vgasr_mutex);
1449 
1450 	if (video_dev) {
1451 		ret = pm_runtime_get_sync(video_dev);
1452 		if (ret && ret != 1)
1453 			return ret;
1454 	}
1455 	ret = dev->bus->pm->runtime_resume(dev);
1456 
1457 	/* put the reference for the gpu */
1458 	if (video_dev) {
1459 		pm_runtime_mark_last_busy(video_dev);
1460 		pm_runtime_put_autosuspend(video_dev);
1461 	}
1462 	return ret;
1463 }
1464 #endif  /* TODO: no pm_ops */
1465 
1466 /**
1467  * vga_switcheroo_init_domain_pm_optimus_hdmi_audio() - helper for driver
1468  * 	power control
1469  * @dev: audio client device
1470  * @domain: power domain
1471  *
1472  * Helper for GPUs whose power state is controlled by the driver's runtime pm.
1473  * When the audio device resumes, the GPU needs to be woken. This helper
1474  * augments the audio device's resume function to do that.
1475  *
1476  * Return: 0 on success, -EINVAL if no power management operations are
1477  * defined for this device.
1478  */
1479 #if 0  /* TODO: no pm */
1480 int
1481 vga_switcheroo_init_domain_pm_optimus_hdmi_audio(struct device *dev,
1482 						 struct dev_pm_domain *domain)
1483 {
1484 	/* copy over all the bus versions */
1485 	if (dev->bus && dev->bus->pm) {
1486 		domain->ops = *dev->bus->pm;
1487 		domain->ops.runtime_resume =
1488 			vga_switcheroo_runtime_resume_hdmi_audio;
1489 
1490 		dev_pm_domain_set(dev, domain);
1491 		return 0;
1492 	}
1493 	dev_pm_domain_set(dev, NULL);
1494 	return -EINVAL;
1495 }
1496 EXPORT_SYMBOL(vga_switcheroo_init_domain_pm_optimus_hdmi_audio);
1497 #endif /* TODO: no pm */
1498