xref: /linux/drivers/platform/x86/apple-gmux.c (revision 34dc1baba215b826e454b8d19e4f24adbeb7d00d)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Gmux driver for Apple laptops
4  *
5  *  Copyright (C) Canonical Ltd. <seth.forshee@canonical.com>
6  *  Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de>
7  *  Copyright (C) 2015 Lukas Wunner <lukas@wunner.de>
8  *  Copyright (C) 2023 Orlando Chamberlain <orlandoch.dev@gmail.com>
9  */
10 
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/backlight.h>
17 #include <linux/acpi.h>
18 #include <linux/pnp.h>
19 #include <linux/apple-gmux.h>
20 #include <linux/slab.h>
21 #include <linux/delay.h>
22 #include <linux/pci.h>
23 #include <linux/vga_switcheroo.h>
24 #include <linux/debugfs.h>
25 #include <acpi/video.h>
26 #include <asm/io.h>
27 
28 /**
29  * DOC: Overview
30  *
31  * gmux is a microcontroller built into the MacBook Pro to support dual GPUs:
32  * A `Lattice XP2`_ on pre-retinas, a `Renesas R4F2113`_ on pre-T2 retinas.
33  *
34  * On T2 Macbooks, the gmux is part of the T2 Coprocessor's SMC. The SMC has
35  * an I2C connection to a `NXP PCAL6524` GPIO expander, which enables/disables
36  * the voltage regulators of the discrete GPU, drives the display panel power,
37  * and has a GPIO to switch the eDP mux. The Intel CPU can interact with
38  * gmux through MMIO, similar to how the main SMC interface is controlled.
39  *
40  * (The MacPro6,1 2013 also has a gmux, however it is unclear why since it has
41  * dual GPUs but no built-in display.)
42  *
43  * gmux is connected to the LPC bus of the southbridge. Its I/O ports are
44  * accessed differently depending on the microcontroller: Driver functions
45  * to access a pre-retina gmux are infixed ``_pio_``, those for a pre-T2
46  * retina gmux are infixed ``_index_``, and those on T2 Macs are infixed
47  * with ``_mmio_``.
48  *
49  * .. _Lattice XP2:
50  *     http://www.latticesemi.com/en/Products/FPGAandCPLD/LatticeXP2.aspx
51  * .. _Renesas R4F2113:
52  *     http://www.renesas.com/products/mpumcu/h8s/h8s2100/h8s2113/index.jsp
53  * .. _NXP PCAL6524:
54  *     https://www.nxp.com/docs/en/data-sheet/PCAL6524.pdf
55  */
56 
57 struct apple_gmux_config;
58 
59 struct apple_gmux_data {
60 	u8 __iomem *iomem_base;
61 	unsigned long iostart;
62 	unsigned long iolen;
63 	const struct apple_gmux_config *config;
64 	struct mutex index_lock;
65 
66 	struct backlight_device *bdev;
67 
68 	/* switcheroo data */
69 	acpi_handle dhandle;
70 	int gpe;
71 	bool external_switchable;
72 	enum vga_switcheroo_client_id switch_state_display;
73 	enum vga_switcheroo_client_id switch_state_ddc;
74 	enum vga_switcheroo_client_id switch_state_external;
75 	enum vga_switcheroo_state power_state;
76 	struct completion powerchange_done;
77 
78 	/* debugfs data */
79 	u8 selected_port;
80 	struct dentry *debug_dentry;
81 };
82 
83 static struct apple_gmux_data *apple_gmux_data;
84 
85 struct apple_gmux_config {
86 	u8 (*read8)(struct apple_gmux_data *gmux_data, int port);
87 	void (*write8)(struct apple_gmux_data *gmux_data, int port, u8 val);
88 	u32 (*read32)(struct apple_gmux_data *gmux_data, int port);
89 	void (*write32)(struct apple_gmux_data *gmux_data, int port, u32 val);
90 	const struct vga_switcheroo_handler *gmux_handler;
91 	enum vga_switcheroo_handler_flags_t handler_flags;
92 	unsigned long resource_type;
93 	bool read_version_as_u32;
94 	char *name;
95 };
96 
97 #define GMUX_INTERRUPT_ENABLE		0xff
98 #define GMUX_INTERRUPT_DISABLE		0x00
99 
100 #define GMUX_INTERRUPT_STATUS_ACTIVE	0
101 #define GMUX_INTERRUPT_STATUS_DISPLAY	(1 << 0)
102 #define GMUX_INTERRUPT_STATUS_POWER	(1 << 2)
103 #define GMUX_INTERRUPT_STATUS_HOTPLUG	(1 << 3)
104 
105 #define GMUX_BRIGHTNESS_MASK		0x00ffffff
106 #define GMUX_MAX_BRIGHTNESS		GMUX_BRIGHTNESS_MASK
107 
108 static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port)
109 {
110 	return inb(gmux_data->iostart + port);
111 }
112 
113 static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port,
114 			       u8 val)
115 {
116 	outb(val, gmux_data->iostart + port);
117 }
118 
119 static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port)
120 {
121 	return inl(gmux_data->iostart + port);
122 }
123 
124 static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
125 			     u32 val)
126 {
127 	int i;
128 	u8 tmpval;
129 
130 	for (i = 0; i < 4; i++) {
131 		tmpval = (val >> (i * 8)) & 0xff;
132 		outb(tmpval, gmux_data->iostart + port + i);
133 	}
134 }
135 
136 static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data)
137 {
138 	int i = 200;
139 	u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
140 
141 	while (i && (gwr & 0x01)) {
142 		inb(gmux_data->iostart + GMUX_PORT_READ);
143 		gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
144 		udelay(100);
145 		i--;
146 	}
147 
148 	return !!i;
149 }
150 
151 static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data)
152 {
153 	int i = 200;
154 	u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
155 
156 	while (i && !(gwr & 0x01)) {
157 		gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE);
158 		udelay(100);
159 		i--;
160 	}
161 
162 	if (gwr & 0x01)
163 		inb(gmux_data->iostart + GMUX_PORT_READ);
164 
165 	return !!i;
166 }
167 
168 static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port)
169 {
170 	u8 val;
171 
172 	mutex_lock(&gmux_data->index_lock);
173 	gmux_index_wait_ready(gmux_data);
174 	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
175 	gmux_index_wait_complete(gmux_data);
176 	val = inb(gmux_data->iostart + GMUX_PORT_VALUE);
177 	mutex_unlock(&gmux_data->index_lock);
178 
179 	return val;
180 }
181 
182 static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port,
183 			      u8 val)
184 {
185 	mutex_lock(&gmux_data->index_lock);
186 	outb(val, gmux_data->iostart + GMUX_PORT_VALUE);
187 	gmux_index_wait_ready(gmux_data);
188 	outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
189 	gmux_index_wait_complete(gmux_data);
190 	mutex_unlock(&gmux_data->index_lock);
191 }
192 
193 static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port)
194 {
195 	u32 val;
196 
197 	mutex_lock(&gmux_data->index_lock);
198 	gmux_index_wait_ready(gmux_data);
199 	outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ);
200 	gmux_index_wait_complete(gmux_data);
201 	val = inl(gmux_data->iostart + GMUX_PORT_VALUE);
202 	mutex_unlock(&gmux_data->index_lock);
203 
204 	return val;
205 }
206 
207 static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
208 			       u32 val)
209 {
210 	int i;
211 	u8 tmpval;
212 
213 	mutex_lock(&gmux_data->index_lock);
214 
215 	for (i = 0; i < 4; i++) {
216 		tmpval = (val >> (i * 8)) & 0xff;
217 		outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i);
218 	}
219 
220 	gmux_index_wait_ready(gmux_data);
221 	outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
222 	gmux_index_wait_complete(gmux_data);
223 	mutex_unlock(&gmux_data->index_lock);
224 }
225 
226 static int gmux_mmio_wait(struct apple_gmux_data *gmux_data)
227 {
228 	int i = 200;
229 	u8 gwr = ioread8(gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
230 
231 	while (i && gwr) {
232 		gwr = ioread8(gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
233 		udelay(100);
234 		i--;
235 	}
236 
237 	return !!i;
238 }
239 
240 static u8 gmux_mmio_read8(struct apple_gmux_data *gmux_data, int port)
241 {
242 	u8 val;
243 
244 	mutex_lock(&gmux_data->index_lock);
245 	gmux_mmio_wait(gmux_data);
246 	iowrite8((port & 0xff), gmux_data->iomem_base + GMUX_MMIO_PORT_SELECT);
247 	iowrite8(GMUX_MMIO_READ | sizeof(val),
248 		gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
249 	gmux_mmio_wait(gmux_data);
250 	val = ioread8(gmux_data->iomem_base);
251 	mutex_unlock(&gmux_data->index_lock);
252 
253 	return val;
254 }
255 
256 static void gmux_mmio_write8(struct apple_gmux_data *gmux_data, int port,
257 			      u8 val)
258 {
259 	mutex_lock(&gmux_data->index_lock);
260 	gmux_mmio_wait(gmux_data);
261 	iowrite8(val, gmux_data->iomem_base);
262 
263 	iowrite8(port & 0xff, gmux_data->iomem_base + GMUX_MMIO_PORT_SELECT);
264 	iowrite8(GMUX_MMIO_WRITE | sizeof(val),
265 		gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
266 
267 	gmux_mmio_wait(gmux_data);
268 	mutex_unlock(&gmux_data->index_lock);
269 }
270 
271 static u32 gmux_mmio_read32(struct apple_gmux_data *gmux_data, int port)
272 {
273 	u32 val;
274 
275 	mutex_lock(&gmux_data->index_lock);
276 	gmux_mmio_wait(gmux_data);
277 	iowrite8((port & 0xff), gmux_data->iomem_base + GMUX_MMIO_PORT_SELECT);
278 	iowrite8(GMUX_MMIO_READ | sizeof(val),
279 		gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
280 	gmux_mmio_wait(gmux_data);
281 	val = ioread32be(gmux_data->iomem_base);
282 	mutex_unlock(&gmux_data->index_lock);
283 
284 	return val;
285 }
286 
287 static void gmux_mmio_write32(struct apple_gmux_data *gmux_data, int port,
288 			       u32 val)
289 {
290 	mutex_lock(&gmux_data->index_lock);
291 	iowrite32be(val, gmux_data->iomem_base);
292 	iowrite8(port & 0xff, gmux_data->iomem_base + GMUX_MMIO_PORT_SELECT);
293 	iowrite8(GMUX_MMIO_WRITE | sizeof(val),
294 		gmux_data->iomem_base + GMUX_MMIO_COMMAND_SEND);
295 	gmux_mmio_wait(gmux_data);
296 	mutex_unlock(&gmux_data->index_lock);
297 }
298 
299 static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port)
300 {
301 	return gmux_data->config->read8(gmux_data, port);
302 }
303 
304 static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val)
305 {
306 	return gmux_data->config->write8(gmux_data, port, val);
307 }
308 
309 static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port)
310 {
311 	return gmux_data->config->read32(gmux_data, port);
312 }
313 
314 static void gmux_write32(struct apple_gmux_data *gmux_data, int port,
315 			     u32 val)
316 {
317 	return gmux_data->config->write32(gmux_data, port, val);
318 }
319 
320 /**
321  * DOC: Backlight control
322  *
323  * On single GPU MacBooks, the PWM signal for the backlight is generated by
324  * the GPU. On dual GPU MacBook Pros by contrast, either GPU may be suspended
325  * to conserve energy. Hence the PWM signal needs to be generated by a separate
326  * backlight driver which is controlled by gmux. The earliest generation
327  * MBP5 2008/09 uses a `TI LP8543`_ backlight driver. Newer models
328  * use a `TI LP8545`_ or a TI LP8548.
329  *
330  * .. _TI LP8543: https://www.ti.com/lit/ds/symlink/lp8543.pdf
331  * .. _TI LP8545: https://www.ti.com/lit/ds/symlink/lp8545.pdf
332  */
333 
334 static int gmux_get_brightness(struct backlight_device *bd)
335 {
336 	struct apple_gmux_data *gmux_data = bl_get_data(bd);
337 	return gmux_read32(gmux_data, GMUX_PORT_BRIGHTNESS) &
338 	       GMUX_BRIGHTNESS_MASK;
339 }
340 
341 static int gmux_update_status(struct backlight_device *bd)
342 {
343 	struct apple_gmux_data *gmux_data = bl_get_data(bd);
344 	u32 brightness = backlight_get_brightness(bd);
345 
346 	gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness);
347 
348 	return 0;
349 }
350 
351 static const struct backlight_ops gmux_bl_ops = {
352 	.options = BL_CORE_SUSPENDRESUME,
353 	.get_brightness = gmux_get_brightness,
354 	.update_status = gmux_update_status,
355 };
356 
357 /**
358  * DOC: Graphics mux
359  *
360  * On pre-retinas, the LVDS outputs of both GPUs feed into gmux which muxes
361  * either of them to the panel. One of the tricks gmux has up its sleeve is
362  * to lengthen the blanking interval of its output during a switch to
363  * synchronize it with the GPU switched to. This allows for a flicker-free
364  * switch that is imperceptible by the user (`US 8,687,007 B2`_).
365  *
366  * On retinas, muxing is no longer done by gmux itself, but by a separate
367  * chip which is controlled by gmux. The chip is triple sourced, it is
368  * either an `NXP CBTL06142`_, `TI HD3SS212`_ or `Pericom PI3VDP12412`_.
369  * The panel is driven with eDP instead of LVDS since the pixel clock
370  * required for retina resolution exceeds LVDS' limits.
371  *
372  * Pre-retinas are able to switch the panel's DDC pins separately.
373  * This is handled by a `TI SN74LV4066A`_ which is controlled by gmux.
374  * The inactive GPU can thus probe the panel's EDID without switching over
375  * the entire panel. Retinas lack this functionality as the chips used for
376  * eDP muxing are incapable of switching the AUX channel separately (see
377  * the linked data sheets, Pericom would be capable but this is unused).
378  * However the retina panel has the NO_AUX_HANDSHAKE_LINK_TRAINING bit set
379  * in its DPCD, allowing the inactive GPU to skip the AUX handshake and
380  * set up the output with link parameters pre-calibrated by the active GPU.
381  *
382  * The external DP port is only fully switchable on the first two unibody
383  * MacBook Pro generations, MBP5 2008/09 and MBP6 2010. This is done by an
384  * `NXP CBTL06141`_ which is controlled by gmux. It's the predecessor of the
385  * eDP mux on retinas, the difference being support for 2.7 versus 5.4 Gbit/s.
386  *
387  * The following MacBook Pro generations replaced the external DP port with a
388  * combined DP/Thunderbolt port and lost the ability to switch it between GPUs,
389  * connecting it either to the discrete GPU or the Thunderbolt controller.
390  * Oddly enough, while the full port is no longer switchable, AUX and HPD
391  * are still switchable by way of an `NXP CBTL03062`_ (on pre-retinas
392  * MBP8 2011 and MBP9 2012) or two `TI TS3DS10224`_ (on pre-t2 retinas) under
393  * the control of gmux. Since the integrated GPU is missing the main link,
394  * external displays appear to it as phantoms which fail to link-train.
395  *
396  * gmux receives the HPD signal of all display connectors and sends an
397  * interrupt on hotplug. On generations which cannot switch external ports,
398  * the discrete GPU can then be woken to drive the newly connected display.
399  * The ability to switch AUX on these generations could be used to improve
400  * reliability of hotplug detection by having the integrated GPU poll the
401  * ports while the discrete GPU is asleep, but currently we do not make use
402  * of this feature.
403  *
404  * Our switching policy for the external port is that on those generations
405  * which are able to switch it fully, the port is switched together with the
406  * panel when IGD / DIS commands are issued to vga_switcheroo. It is thus
407  * possible to drive e.g. a beamer on battery power with the integrated GPU.
408  * The user may manually switch to the discrete GPU if more performance is
409  * needed.
410  *
411  * On all newer generations, the external port can only be driven by the
412  * discrete GPU. If a display is plugged in while the panel is switched to
413  * the integrated GPU, *both* GPUs will be in use for maximum performance.
414  * To decrease power consumption, the user may manually switch to the
415  * discrete GPU, thereby suspending the integrated GPU.
416  *
417  * gmux' initial switch state on bootup is user configurable via the EFI
418  * variable ``gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9`` (5th byte,
419  * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to
420  * switch the panel and the external DP connector and allocates a framebuffer
421  * for the selected GPU.
422  *
423  * .. _US 8,687,007 B2: https://pimg-fpiw.uspto.gov/fdd/07/870/086/0.pdf
424  * .. _NXP CBTL06141:   https://www.nxp.com/documents/data_sheet/CBTL06141.pdf
425  * .. _NXP CBTL06142:   https://www.nxp.com/documents/data_sheet/CBTL06141.pdf
426  * .. _TI HD3SS212:     https://www.ti.com/lit/ds/symlink/hd3ss212.pdf
427  * .. _Pericom PI3VDP12412: https://www.pericom.com/assets/Datasheets/PI3VDP12412.pdf
428  * .. _TI SN74LV4066A:  https://www.ti.com/lit/ds/symlink/sn74lv4066a.pdf
429  * .. _NXP CBTL03062:   http://pdf.datasheetarchive.com/indexerfiles/Datasheets-SW16/DSASW00308511.pdf
430  * .. _TI TS3DS10224:   https://www.ti.com/lit/ds/symlink/ts3ds10224.pdf
431  */
432 
433 static void gmux_read_switch_state(struct apple_gmux_data *gmux_data)
434 {
435 	if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DDC) == 1)
436 		gmux_data->switch_state_ddc = VGA_SWITCHEROO_IGD;
437 	else
438 		gmux_data->switch_state_ddc = VGA_SWITCHEROO_DIS;
439 
440 	if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) & 1)
441 		gmux_data->switch_state_display = VGA_SWITCHEROO_DIS;
442 	else
443 		gmux_data->switch_state_display = VGA_SWITCHEROO_IGD;
444 
445 	if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL) == 2)
446 		gmux_data->switch_state_external = VGA_SWITCHEROO_IGD;
447 	else
448 		gmux_data->switch_state_external = VGA_SWITCHEROO_DIS;
449 }
450 
451 static void gmux_write_switch_state(struct apple_gmux_data *gmux_data)
452 {
453 	if (gmux_data->switch_state_ddc == VGA_SWITCHEROO_IGD)
454 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 1);
455 	else
456 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 2);
457 
458 	if (gmux_data->switch_state_display == VGA_SWITCHEROO_IGD)
459 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2);
460 	else
461 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3);
462 
463 	if (gmux_data->switch_state_external == VGA_SWITCHEROO_IGD)
464 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2);
465 	else
466 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
467 }
468 
469 static int gmux_switchto(enum vga_switcheroo_client_id id)
470 {
471 	apple_gmux_data->switch_state_ddc = id;
472 	apple_gmux_data->switch_state_display = id;
473 	if (apple_gmux_data->external_switchable)
474 		apple_gmux_data->switch_state_external = id;
475 
476 	gmux_write_switch_state(apple_gmux_data);
477 
478 	return 0;
479 }
480 
481 static int gmux_switch_ddc(enum vga_switcheroo_client_id id)
482 {
483 	enum vga_switcheroo_client_id old_ddc_owner =
484 		apple_gmux_data->switch_state_ddc;
485 
486 	if (id == old_ddc_owner)
487 		return id;
488 
489 	pr_debug("Switching DDC from %d to %d\n", old_ddc_owner, id);
490 	apple_gmux_data->switch_state_ddc = id;
491 
492 	if (id == VGA_SWITCHEROO_IGD)
493 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1);
494 	else
495 		gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2);
496 
497 	return old_ddc_owner;
498 }
499 
500 /**
501  * DOC: Power control
502  *
503  * gmux is able to cut power to the discrete GPU. It automatically takes care
504  * of the correct sequence to tear down and bring up the power rails for
505  * core voltage, VRAM and PCIe.
506  */
507 
508 static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data,
509 				   enum vga_switcheroo_state state)
510 {
511 	reinit_completion(&gmux_data->powerchange_done);
512 
513 	if (state == VGA_SWITCHEROO_ON) {
514 		gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1);
515 		gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3);
516 		pr_debug("Discrete card powered up\n");
517 	} else {
518 		gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1);
519 		gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0);
520 		pr_debug("Discrete card powered down\n");
521 	}
522 
523 	gmux_data->power_state = state;
524 
525 	if (gmux_data->gpe >= 0 &&
526 	    !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done,
527 						       msecs_to_jiffies(200)))
528 		pr_warn("Timeout waiting for gmux switch to complete\n");
529 
530 	return 0;
531 }
532 
533 static int gmux_set_power_state(enum vga_switcheroo_client_id id,
534 				enum vga_switcheroo_state state)
535 {
536 	if (id == VGA_SWITCHEROO_IGD)
537 		return 0;
538 
539 	return gmux_set_discrete_state(apple_gmux_data, state);
540 }
541 
542 static enum vga_switcheroo_client_id gmux_get_client_id(struct pci_dev *pdev)
543 {
544 	/*
545 	 * Early Macbook Pros with switchable graphics use nvidia
546 	 * integrated graphics. Hardcode that the 9400M is integrated.
547 	 */
548 	if (pdev->vendor == PCI_VENDOR_ID_INTEL)
549 		return VGA_SWITCHEROO_IGD;
550 	else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
551 		 pdev->device == 0x0863)
552 		return VGA_SWITCHEROO_IGD;
553 	else
554 		return VGA_SWITCHEROO_DIS;
555 }
556 
557 static const struct vga_switcheroo_handler gmux_handler_no_ddc = {
558 	.switchto = gmux_switchto,
559 	.power_state = gmux_set_power_state,
560 	.get_client_id = gmux_get_client_id,
561 };
562 
563 static const struct vga_switcheroo_handler gmux_handler_ddc = {
564 	.switchto = gmux_switchto,
565 	.switch_ddc = gmux_switch_ddc,
566 	.power_state = gmux_set_power_state,
567 	.get_client_id = gmux_get_client_id,
568 };
569 
570 static const struct apple_gmux_config apple_gmux_pio = {
571 	.read8 = &gmux_pio_read8,
572 	.write8 = &gmux_pio_write8,
573 	.read32 = &gmux_pio_read32,
574 	.write32 = &gmux_pio_write32,
575 	.gmux_handler = &gmux_handler_ddc,
576 	.handler_flags = VGA_SWITCHEROO_CAN_SWITCH_DDC,
577 	.resource_type = IORESOURCE_IO,
578 	.read_version_as_u32 = false,
579 	.name = "classic"
580 };
581 
582 static const struct apple_gmux_config apple_gmux_index = {
583 	.read8 = &gmux_index_read8,
584 	.write8 = &gmux_index_write8,
585 	.read32 = &gmux_index_read32,
586 	.write32 = &gmux_index_write32,
587 	.gmux_handler = &gmux_handler_no_ddc,
588 	.handler_flags = VGA_SWITCHEROO_NEEDS_EDP_CONFIG,
589 	.resource_type = IORESOURCE_IO,
590 	.read_version_as_u32 = true,
591 	.name = "indexed"
592 };
593 
594 static const struct apple_gmux_config apple_gmux_mmio = {
595 	.read8 = &gmux_mmio_read8,
596 	.write8 = &gmux_mmio_write8,
597 	.read32 = &gmux_mmio_read32,
598 	.write32 = &gmux_mmio_write32,
599 	.gmux_handler = &gmux_handler_no_ddc,
600 	.handler_flags = VGA_SWITCHEROO_NEEDS_EDP_CONFIG,
601 	.resource_type = IORESOURCE_MEM,
602 	.read_version_as_u32 = true,
603 	.name = "T2"
604 };
605 
606 
607 /**
608  * DOC: Interrupt
609  *
610  * gmux is also connected to a GPIO pin of the southbridge and thereby is able
611  * to trigger an ACPI GPE. ACPI name GMGP holds this GPIO pin's number. On the
612  * MBP5 2008/09 it's GPIO pin 22 of the Nvidia MCP79, on following generations
613  * it's GPIO pin 6 of the Intel PCH, on MMIO gmux's it's pin 21.
614  *
615  * The GPE merely signals that an interrupt occurred, the actual type of event
616  * is identified by reading a gmux register.
617  *
618  * In addition to the GMGP name, gmux's ACPI device also has two methods GMSP
619  * and GMLV. GMLV likely means "GMUX Level", and reads the value of the GPIO,
620  * while GMSP likely means "GMUX Set Polarity", and seems to write to the GPIO's
621  * value. On newer Macbooks (This was introduced with or sometime before the
622  * MacBookPro14,3), the ACPI GPE method differentiates between the OS type: On
623  * Darwin, only a notification is signaled, whereas on other OSes, the GPIO's
624  * value is read and then inverted.
625  *
626  * Because Linux masquerades as Darwin, it ends up in the notification-only code
627  * path. On MMIO gmux's, this seems to lead to us being unable to clear interrupts,
628  * unless we call GMSP(0). Without this, there is a flood of status=0 interrupts
629  * that can't be cleared. This issue seems to be unique to MMIO gmux's.
630  */
631 
632 static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data)
633 {
634 	gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE,
635 		    GMUX_INTERRUPT_DISABLE);
636 }
637 
638 static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data)
639 {
640 	gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE,
641 		    GMUX_INTERRUPT_ENABLE);
642 }
643 
644 static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data)
645 {
646 	return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS);
647 }
648 
649 static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data)
650 {
651 	u8 status;
652 
653 	/* to clear interrupts write back current status */
654 	status = gmux_interrupt_get_status(gmux_data);
655 	gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status);
656 	/* Prevent flood of status=0 interrupts */
657 	if (gmux_data->config == &apple_gmux_mmio)
658 		acpi_execute_simple_method(gmux_data->dhandle, "GMSP", 0);
659 }
660 
661 static void gmux_notify_handler(acpi_handle device, u32 value, void *context)
662 {
663 	u8 status;
664 	struct pnp_dev *pnp = (struct pnp_dev *)context;
665 	struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
666 
667 	status = gmux_interrupt_get_status(gmux_data);
668 	gmux_disable_interrupts(gmux_data);
669 	pr_debug("Notify handler called: status %d\n", status);
670 
671 	gmux_clear_interrupts(gmux_data);
672 	gmux_enable_interrupts(gmux_data);
673 
674 	if (status & GMUX_INTERRUPT_STATUS_POWER)
675 		complete(&gmux_data->powerchange_done);
676 }
677 
678 /**
679  * DOC: Debugfs Interface
680  *
681  * gmux ports can be accessed from userspace as a debugfs interface. For example:
682  *
683  * # echo 4 > /sys/kernel/debug/apple_gmux/selected_port
684  * # cat /sys/kernel/debug/apple_gmux/selected_port_data | xxd -p
685  * 00000005
686  *
687  * Reads 4 bytes from port 4 (GMUX_PORT_VERSION_MAJOR).
688  *
689  * 1 and 4 byte writes are also allowed.
690  */
691 
692 static ssize_t gmux_selected_port_data_write(struct file *file,
693 		const char __user *userbuf, size_t count, loff_t *ppos)
694 {
695 	struct apple_gmux_data *gmux_data = file->private_data;
696 
697 	if (*ppos)
698 		return -EINVAL;
699 
700 	if (count == 1) {
701 		u8 data;
702 
703 		if (copy_from_user(&data, userbuf, 1))
704 			return -EFAULT;
705 
706 		gmux_write8(gmux_data, gmux_data->selected_port, data);
707 	} else if (count == 4) {
708 		u32 data;
709 
710 		if (copy_from_user(&data, userbuf, 4))
711 			return -EFAULT;
712 
713 		gmux_write32(gmux_data, gmux_data->selected_port, data);
714 	} else
715 		return -EINVAL;
716 
717 	return count;
718 }
719 
720 static ssize_t gmux_selected_port_data_read(struct file *file,
721 		char __user *userbuf, size_t count, loff_t *ppos)
722 {
723 	struct apple_gmux_data *gmux_data = file->private_data;
724 	u32 data;
725 
726 	data = gmux_read32(gmux_data, gmux_data->selected_port);
727 
728 	return simple_read_from_buffer(userbuf, count, ppos, &data, sizeof(data));
729 }
730 
731 static const struct file_operations gmux_port_data_ops = {
732 	.open = simple_open,
733 	.write = gmux_selected_port_data_write,
734 	.read = gmux_selected_port_data_read
735 };
736 
737 static void gmux_init_debugfs(struct apple_gmux_data *gmux_data)
738 {
739 	gmux_data->debug_dentry = debugfs_create_dir(KBUILD_MODNAME, NULL);
740 
741 	debugfs_create_u8("selected_port", 0644, gmux_data->debug_dentry,
742 			&gmux_data->selected_port);
743 	debugfs_create_file("selected_port_data", 0644, gmux_data->debug_dentry,
744 			gmux_data, &gmux_port_data_ops);
745 }
746 
747 static void gmux_fini_debugfs(struct apple_gmux_data *gmux_data)
748 {
749 	debugfs_remove_recursive(gmux_data->debug_dentry);
750 }
751 
752 static int gmux_suspend(struct device *dev)
753 {
754 	struct pnp_dev *pnp = to_pnp_dev(dev);
755 	struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
756 
757 	gmux_disable_interrupts(gmux_data);
758 	return 0;
759 }
760 
761 static int gmux_resume(struct device *dev)
762 {
763 	struct pnp_dev *pnp = to_pnp_dev(dev);
764 	struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
765 
766 	gmux_enable_interrupts(gmux_data);
767 	gmux_write_switch_state(gmux_data);
768 	if (gmux_data->power_state == VGA_SWITCHEROO_OFF)
769 		gmux_set_discrete_state(gmux_data, gmux_data->power_state);
770 	return 0;
771 }
772 
773 static int is_thunderbolt(struct device *dev, void *data)
774 {
775 	return to_pci_dev(dev)->is_thunderbolt;
776 }
777 
778 static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
779 {
780 	struct apple_gmux_data *gmux_data;
781 	struct resource *res;
782 	struct backlight_properties props;
783 	struct backlight_device *bdev = NULL;
784 	u8 ver_major, ver_minor, ver_release;
785 	bool register_bdev = true;
786 	int ret = -ENXIO;
787 	acpi_status status;
788 	unsigned long long gpe;
789 	enum apple_gmux_type type;
790 	u32 version;
791 
792 	if (apple_gmux_data)
793 		return -EBUSY;
794 
795 	if (!apple_gmux_detect(pnp, &type)) {
796 		pr_info("gmux device not present\n");
797 		return -ENODEV;
798 	}
799 
800 	gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL);
801 	if (!gmux_data)
802 		return -ENOMEM;
803 	pnp_set_drvdata(pnp, gmux_data);
804 
805 	switch (type) {
806 	case APPLE_GMUX_TYPE_MMIO:
807 		gmux_data->config = &apple_gmux_mmio;
808 		mutex_init(&gmux_data->index_lock);
809 
810 		res = pnp_get_resource(pnp, IORESOURCE_MEM, 0);
811 		gmux_data->iostart = res->start;
812 		/* Although the ACPI table only allocates 8 bytes, we need 16. */
813 		gmux_data->iolen = 16;
814 		if (!request_mem_region(gmux_data->iostart, gmux_data->iolen,
815 					"Apple gmux")) {
816 			pr_err("gmux I/O already in use\n");
817 			goto err_free;
818 		}
819 		gmux_data->iomem_base = ioremap(gmux_data->iostart, gmux_data->iolen);
820 		if (!gmux_data->iomem_base) {
821 			pr_err("couldn't remap gmux mmio region");
822 			goto err_release;
823 		}
824 		goto get_version;
825 	case APPLE_GMUX_TYPE_INDEXED:
826 		gmux_data->config = &apple_gmux_index;
827 		mutex_init(&gmux_data->index_lock);
828 		break;
829 	case APPLE_GMUX_TYPE_PIO:
830 		gmux_data->config = &apple_gmux_pio;
831 		break;
832 	}
833 
834 	res = pnp_get_resource(pnp, IORESOURCE_IO, 0);
835 	gmux_data->iostart = res->start;
836 	gmux_data->iolen = resource_size(res);
837 
838 	if (!request_region(gmux_data->iostart, gmux_data->iolen,
839 			    "Apple gmux")) {
840 		pr_err("gmux I/O already in use\n");
841 		goto err_free;
842 	}
843 
844 get_version:
845 	if (gmux_data->config->read_version_as_u32) {
846 		version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR);
847 		ver_major = (version >> 24) & 0xff;
848 		ver_minor = (version >> 16) & 0xff;
849 		ver_release = (version >> 8) & 0xff;
850 	} else {
851 		ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
852 		ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
853 		ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
854 	}
855 	pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
856 		ver_release, gmux_data->config->name);
857 
858 	memset(&props, 0, sizeof(props));
859 	props.type = BACKLIGHT_PLATFORM;
860 	props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS);
861 
862 #if IS_REACHABLE(CONFIG_ACPI_VIDEO)
863 	register_bdev = acpi_video_get_backlight_type() == acpi_backlight_apple_gmux;
864 #endif
865 	if (register_bdev) {
866 		/*
867 		 * Currently it's assumed that the maximum brightness is less than
868 		 * 2^24 for compatibility with old gmux versions. Cap the max
869 		 * brightness at this value, but print a warning if the hardware
870 		 * reports something higher so that it can be fixed.
871 		 */
872 		if (WARN_ON(props.max_brightness > GMUX_MAX_BRIGHTNESS))
873 			props.max_brightness = GMUX_MAX_BRIGHTNESS;
874 
875 		bdev = backlight_device_register("gmux_backlight", &pnp->dev,
876 						 gmux_data, &gmux_bl_ops, &props);
877 		if (IS_ERR(bdev)) {
878 			ret = PTR_ERR(bdev);
879 			goto err_unmap;
880 		}
881 
882 		gmux_data->bdev = bdev;
883 		bdev->props.brightness = gmux_get_brightness(bdev);
884 		backlight_update_status(bdev);
885 	}
886 
887 	gmux_data->power_state = VGA_SWITCHEROO_ON;
888 
889 	gmux_data->dhandle = ACPI_HANDLE(&pnp->dev);
890 	if (!gmux_data->dhandle) {
891 		pr_err("Cannot find acpi handle for pnp device %s\n",
892 		       dev_name(&pnp->dev));
893 		ret = -ENODEV;
894 		goto err_notify;
895 	}
896 
897 	status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe);
898 	if (ACPI_SUCCESS(status)) {
899 		gmux_data->gpe = (int)gpe;
900 
901 		status = acpi_install_notify_handler(gmux_data->dhandle,
902 						     ACPI_DEVICE_NOTIFY,
903 						     &gmux_notify_handler, pnp);
904 		if (ACPI_FAILURE(status)) {
905 			pr_err("Install notify handler failed: %s\n",
906 			       acpi_format_exception(status));
907 			ret = -ENODEV;
908 			goto err_notify;
909 		}
910 
911 		status = acpi_enable_gpe(NULL, gmux_data->gpe);
912 		if (ACPI_FAILURE(status)) {
913 			pr_err("Cannot enable gpe: %s\n",
914 			       acpi_format_exception(status));
915 			goto err_enable_gpe;
916 		}
917 	} else {
918 		pr_warn("No GPE found for gmux\n");
919 		gmux_data->gpe = -1;
920 	}
921 
922 	/*
923 	 * If Thunderbolt is present, the external DP port is not fully
924 	 * switchable. Force its AUX channel to the discrete GPU.
925 	 */
926 	gmux_data->external_switchable =
927 		!bus_for_each_dev(&pci_bus_type, NULL, NULL, is_thunderbolt);
928 	if (!gmux_data->external_switchable)
929 		gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3);
930 
931 	apple_gmux_data = gmux_data;
932 	init_completion(&gmux_data->powerchange_done);
933 	gmux_enable_interrupts(gmux_data);
934 	gmux_read_switch_state(gmux_data);
935 
936 	/*
937 	 * Retina MacBook Pros cannot switch the panel's AUX separately
938 	 * and need eDP pre-calibration. They are distinguishable from
939 	 * pre-retinas by having an "indexed" or "T2" gmux.
940 	 *
941 	 * Pre-retina MacBook Pros can switch the panel's DDC separately.
942 	 */
943 	ret = vga_switcheroo_register_handler(gmux_data->config->gmux_handler,
944 			gmux_data->config->handler_flags);
945 	if (ret) {
946 		pr_err("Failed to register vga_switcheroo handler\n");
947 		goto err_register_handler;
948 	}
949 
950 	gmux_init_debugfs(gmux_data);
951 	return 0;
952 
953 err_register_handler:
954 	gmux_disable_interrupts(gmux_data);
955 	apple_gmux_data = NULL;
956 	if (gmux_data->gpe >= 0)
957 		acpi_disable_gpe(NULL, gmux_data->gpe);
958 err_enable_gpe:
959 	if (gmux_data->gpe >= 0)
960 		acpi_remove_notify_handler(gmux_data->dhandle,
961 					   ACPI_DEVICE_NOTIFY,
962 					   &gmux_notify_handler);
963 err_notify:
964 	backlight_device_unregister(bdev);
965 err_unmap:
966 	if (gmux_data->iomem_base)
967 		iounmap(gmux_data->iomem_base);
968 err_release:
969 	if (gmux_data->config->resource_type == IORESOURCE_MEM)
970 		release_mem_region(gmux_data->iostart, gmux_data->iolen);
971 	else
972 		release_region(gmux_data->iostart, gmux_data->iolen);
973 err_free:
974 	kfree(gmux_data);
975 	return ret;
976 }
977 
978 static void gmux_remove(struct pnp_dev *pnp)
979 {
980 	struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp);
981 
982 	gmux_fini_debugfs(gmux_data);
983 	vga_switcheroo_unregister_handler();
984 	gmux_disable_interrupts(gmux_data);
985 	if (gmux_data->gpe >= 0) {
986 		acpi_disable_gpe(NULL, gmux_data->gpe);
987 		acpi_remove_notify_handler(gmux_data->dhandle,
988 					   ACPI_DEVICE_NOTIFY,
989 					   &gmux_notify_handler);
990 	}
991 
992 	backlight_device_unregister(gmux_data->bdev);
993 
994 	if (gmux_data->iomem_base) {
995 		iounmap(gmux_data->iomem_base);
996 		release_mem_region(gmux_data->iostart, gmux_data->iolen);
997 	} else
998 		release_region(gmux_data->iostart, gmux_data->iolen);
999 	apple_gmux_data = NULL;
1000 	kfree(gmux_data);
1001 }
1002 
1003 static const struct pnp_device_id gmux_device_ids[] = {
1004 	{GMUX_ACPI_HID, 0},
1005 	{"", 0}
1006 };
1007 
1008 static const struct dev_pm_ops gmux_dev_pm_ops = {
1009 	.suspend = gmux_suspend,
1010 	.resume = gmux_resume,
1011 };
1012 
1013 static struct pnp_driver gmux_pnp_driver = {
1014 	.name		= "apple-gmux",
1015 	.probe		= gmux_probe,
1016 	.remove		= gmux_remove,
1017 	.id_table	= gmux_device_ids,
1018 	.driver		= {
1019 			.pm = &gmux_dev_pm_ops,
1020 	},
1021 };
1022 
1023 module_pnp_driver(gmux_pnp_driver);
1024 MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>");
1025 MODULE_DESCRIPTION("Apple Gmux Driver");
1026 MODULE_LICENSE("GPL");
1027 MODULE_DEVICE_TABLE(pnp, gmux_device_ids);
1028