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 */ 9 10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12 #include <linux/module.h> 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/backlight.h> 16 #include <linux/acpi.h> 17 #include <linux/pnp.h> 18 #include <linux/apple_bl.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 <asm/io.h> 25 26 /** 27 * DOC: Overview 28 * 29 * gmux is a microcontroller built into the MacBook Pro to support dual GPUs: 30 * A `Lattice XP2`_ on pre-retinas, a `Renesas R4F2113`_ on retinas. 31 * 32 * (The MacPro6,1 2013 also has a gmux, however it is unclear why since it has 33 * dual GPUs but no built-in display.) 34 * 35 * gmux is connected to the LPC bus of the southbridge. Its I/O ports are 36 * accessed differently depending on the microcontroller: Driver functions 37 * to access a pre-retina gmux are infixed ``_pio_``, those for a retina gmux 38 * are infixed ``_index_``. 39 * 40 * .. _Lattice XP2: 41 * http://www.latticesemi.com/en/Products/FPGAandCPLD/LatticeXP2.aspx 42 * .. _Renesas R4F2113: 43 * http://www.renesas.com/products/mpumcu/h8s/h8s2100/h8s2113/index.jsp 44 */ 45 46 struct apple_gmux_data { 47 unsigned long iostart; 48 unsigned long iolen; 49 bool indexed; 50 struct mutex index_lock; 51 52 struct backlight_device *bdev; 53 54 /* switcheroo data */ 55 acpi_handle dhandle; 56 int gpe; 57 bool external_switchable; 58 enum vga_switcheroo_client_id switch_state_display; 59 enum vga_switcheroo_client_id switch_state_ddc; 60 enum vga_switcheroo_client_id switch_state_external; 61 enum vga_switcheroo_state power_state; 62 struct completion powerchange_done; 63 }; 64 65 static struct apple_gmux_data *apple_gmux_data; 66 67 #define GMUX_INTERRUPT_ENABLE 0xff 68 #define GMUX_INTERRUPT_DISABLE 0x00 69 70 #define GMUX_INTERRUPT_STATUS_ACTIVE 0 71 #define GMUX_INTERRUPT_STATUS_DISPLAY (1 << 0) 72 #define GMUX_INTERRUPT_STATUS_POWER (1 << 2) 73 #define GMUX_INTERRUPT_STATUS_HOTPLUG (1 << 3) 74 75 #define GMUX_BRIGHTNESS_MASK 0x00ffffff 76 #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK 77 78 static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) 79 { 80 return inb(gmux_data->iostart + port); 81 } 82 83 static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port, 84 u8 val) 85 { 86 outb(val, gmux_data->iostart + port); 87 } 88 89 static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port) 90 { 91 return inl(gmux_data->iostart + port); 92 } 93 94 static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, 95 u32 val) 96 { 97 int i; 98 u8 tmpval; 99 100 for (i = 0; i < 4; i++) { 101 tmpval = (val >> (i * 8)) & 0xff; 102 outb(tmpval, gmux_data->iostart + port + i); 103 } 104 } 105 106 static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data) 107 { 108 int i = 200; 109 u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); 110 111 while (i && (gwr & 0x01)) { 112 inb(gmux_data->iostart + GMUX_PORT_READ); 113 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); 114 udelay(100); 115 i--; 116 } 117 118 return !!i; 119 } 120 121 static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data) 122 { 123 int i = 200; 124 u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); 125 126 while (i && !(gwr & 0x01)) { 127 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); 128 udelay(100); 129 i--; 130 } 131 132 if (gwr & 0x01) 133 inb(gmux_data->iostart + GMUX_PORT_READ); 134 135 return !!i; 136 } 137 138 static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) 139 { 140 u8 val; 141 142 mutex_lock(&gmux_data->index_lock); 143 gmux_index_wait_ready(gmux_data); 144 outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); 145 gmux_index_wait_complete(gmux_data); 146 val = inb(gmux_data->iostart + GMUX_PORT_VALUE); 147 mutex_unlock(&gmux_data->index_lock); 148 149 return val; 150 } 151 152 static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port, 153 u8 val) 154 { 155 mutex_lock(&gmux_data->index_lock); 156 outb(val, gmux_data->iostart + GMUX_PORT_VALUE); 157 gmux_index_wait_ready(gmux_data); 158 outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); 159 gmux_index_wait_complete(gmux_data); 160 mutex_unlock(&gmux_data->index_lock); 161 } 162 163 static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) 164 { 165 u32 val; 166 167 mutex_lock(&gmux_data->index_lock); 168 gmux_index_wait_ready(gmux_data); 169 outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); 170 gmux_index_wait_complete(gmux_data); 171 val = inl(gmux_data->iostart + GMUX_PORT_VALUE); 172 mutex_unlock(&gmux_data->index_lock); 173 174 return val; 175 } 176 177 static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port, 178 u32 val) 179 { 180 int i; 181 u8 tmpval; 182 183 mutex_lock(&gmux_data->index_lock); 184 185 for (i = 0; i < 4; i++) { 186 tmpval = (val >> (i * 8)) & 0xff; 187 outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i); 188 } 189 190 gmux_index_wait_ready(gmux_data); 191 outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); 192 gmux_index_wait_complete(gmux_data); 193 mutex_unlock(&gmux_data->index_lock); 194 } 195 196 static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) 197 { 198 if (gmux_data->indexed) 199 return gmux_index_read8(gmux_data, port); 200 else 201 return gmux_pio_read8(gmux_data, port); 202 } 203 204 static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val) 205 { 206 if (gmux_data->indexed) 207 gmux_index_write8(gmux_data, port, val); 208 else 209 gmux_pio_write8(gmux_data, port, val); 210 } 211 212 static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) 213 { 214 if (gmux_data->indexed) 215 return gmux_index_read32(gmux_data, port); 216 else 217 return gmux_pio_read32(gmux_data, port); 218 } 219 220 static void gmux_write32(struct apple_gmux_data *gmux_data, int port, 221 u32 val) 222 { 223 if (gmux_data->indexed) 224 gmux_index_write32(gmux_data, port, val); 225 else 226 gmux_pio_write32(gmux_data, port, val); 227 } 228 229 /** 230 * DOC: Backlight control 231 * 232 * On single GPU MacBooks, the PWM signal for the backlight is generated by 233 * the GPU. On dual GPU MacBook Pros by contrast, either GPU may be suspended 234 * to conserve energy. Hence the PWM signal needs to be generated by a separate 235 * backlight driver which is controlled by gmux. The earliest generation 236 * MBP5 2008/09 uses a `TI LP8543`_ backlight driver. All newer models 237 * use a `TI LP8545`_. 238 * 239 * .. _TI LP8543: https://www.ti.com/lit/ds/symlink/lp8543.pdf 240 * .. _TI LP8545: https://www.ti.com/lit/ds/symlink/lp8545.pdf 241 */ 242 243 static int gmux_get_brightness(struct backlight_device *bd) 244 { 245 struct apple_gmux_data *gmux_data = bl_get_data(bd); 246 return gmux_read32(gmux_data, GMUX_PORT_BRIGHTNESS) & 247 GMUX_BRIGHTNESS_MASK; 248 } 249 250 static int gmux_update_status(struct backlight_device *bd) 251 { 252 struct apple_gmux_data *gmux_data = bl_get_data(bd); 253 u32 brightness = backlight_get_brightness(bd); 254 255 gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); 256 257 return 0; 258 } 259 260 static const struct backlight_ops gmux_bl_ops = { 261 .options = BL_CORE_SUSPENDRESUME, 262 .get_brightness = gmux_get_brightness, 263 .update_status = gmux_update_status, 264 }; 265 266 /** 267 * DOC: Graphics mux 268 * 269 * On pre-retinas, the LVDS outputs of both GPUs feed into gmux which muxes 270 * either of them to the panel. One of the tricks gmux has up its sleeve is 271 * to lengthen the blanking interval of its output during a switch to 272 * synchronize it with the GPU switched to. This allows for a flicker-free 273 * switch that is imperceptible by the user (`US 8,687,007 B2`_). 274 * 275 * On retinas, muxing is no longer done by gmux itself, but by a separate 276 * chip which is controlled by gmux. The chip is triple sourced, it is 277 * either an `NXP CBTL06142`_, `TI HD3SS212`_ or `Pericom PI3VDP12412`_. 278 * The panel is driven with eDP instead of LVDS since the pixel clock 279 * required for retina resolution exceeds LVDS' limits. 280 * 281 * Pre-retinas are able to switch the panel's DDC pins separately. 282 * This is handled by a `TI SN74LV4066A`_ which is controlled by gmux. 283 * The inactive GPU can thus probe the panel's EDID without switching over 284 * the entire panel. Retinas lack this functionality as the chips used for 285 * eDP muxing are incapable of switching the AUX channel separately (see 286 * the linked data sheets, Pericom would be capable but this is unused). 287 * However the retina panel has the NO_AUX_HANDSHAKE_LINK_TRAINING bit set 288 * in its DPCD, allowing the inactive GPU to skip the AUX handshake and 289 * set up the output with link parameters pre-calibrated by the active GPU. 290 * 291 * The external DP port is only fully switchable on the first two unibody 292 * MacBook Pro generations, MBP5 2008/09 and MBP6 2010. This is done by an 293 * `NXP CBTL06141`_ which is controlled by gmux. It's the predecessor of the 294 * eDP mux on retinas, the difference being support for 2.7 versus 5.4 Gbit/s. 295 * 296 * The following MacBook Pro generations replaced the external DP port with a 297 * combined DP/Thunderbolt port and lost the ability to switch it between GPUs, 298 * connecting it either to the discrete GPU or the Thunderbolt controller. 299 * Oddly enough, while the full port is no longer switchable, AUX and HPD 300 * are still switchable by way of an `NXP CBTL03062`_ (on pre-retinas 301 * MBP8 2011 and MBP9 2012) or two `TI TS3DS10224`_ (on retinas) under the 302 * control of gmux. Since the integrated GPU is missing the main link, 303 * external displays appear to it as phantoms which fail to link-train. 304 * 305 * gmux receives the HPD signal of all display connectors and sends an 306 * interrupt on hotplug. On generations which cannot switch external ports, 307 * the discrete GPU can then be woken to drive the newly connected display. 308 * The ability to switch AUX on these generations could be used to improve 309 * reliability of hotplug detection by having the integrated GPU poll the 310 * ports while the discrete GPU is asleep, but currently we do not make use 311 * of this feature. 312 * 313 * Our switching policy for the external port is that on those generations 314 * which are able to switch it fully, the port is switched together with the 315 * panel when IGD / DIS commands are issued to vga_switcheroo. It is thus 316 * possible to drive e.g. a beamer on battery power with the integrated GPU. 317 * The user may manually switch to the discrete GPU if more performance is 318 * needed. 319 * 320 * On all newer generations, the external port can only be driven by the 321 * discrete GPU. If a display is plugged in while the panel is switched to 322 * the integrated GPU, *both* GPUs will be in use for maximum performance. 323 * To decrease power consumption, the user may manually switch to the 324 * discrete GPU, thereby suspending the integrated GPU. 325 * 326 * gmux' initial switch state on bootup is user configurable via the EFI 327 * variable ``gpu-power-prefs-fa4ce28d-b62f-4c99-9cc3-6815686e30f9`` (5th byte, 328 * 1 = IGD, 0 = DIS). Based on this setting, the EFI firmware tells gmux to 329 * switch the panel and the external DP connector and allocates a framebuffer 330 * for the selected GPU. 331 * 332 * .. _US 8,687,007 B2: https://pimg-fpiw.uspto.gov/fdd/07/870/086/0.pdf 333 * .. _NXP CBTL06141: https://www.nxp.com/documents/data_sheet/CBTL06141.pdf 334 * .. _NXP CBTL06142: https://www.nxp.com/documents/data_sheet/CBTL06141.pdf 335 * .. _TI HD3SS212: https://www.ti.com/lit/ds/symlink/hd3ss212.pdf 336 * .. _Pericom PI3VDP12412: https://www.pericom.com/assets/Datasheets/PI3VDP12412.pdf 337 * .. _TI SN74LV4066A: https://www.ti.com/lit/ds/symlink/sn74lv4066a.pdf 338 * .. _NXP CBTL03062: http://pdf.datasheetarchive.com/indexerfiles/Datasheets-SW16/DSASW00308511.pdf 339 * .. _TI TS3DS10224: https://www.ti.com/lit/ds/symlink/ts3ds10224.pdf 340 */ 341 342 static void gmux_read_switch_state(struct apple_gmux_data *gmux_data) 343 { 344 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DDC) == 1) 345 gmux_data->switch_state_ddc = VGA_SWITCHEROO_IGD; 346 else 347 gmux_data->switch_state_ddc = VGA_SWITCHEROO_DIS; 348 349 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) 350 gmux_data->switch_state_display = VGA_SWITCHEROO_IGD; 351 else 352 gmux_data->switch_state_display = VGA_SWITCHEROO_DIS; 353 354 if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL) == 2) 355 gmux_data->switch_state_external = VGA_SWITCHEROO_IGD; 356 else 357 gmux_data->switch_state_external = VGA_SWITCHEROO_DIS; 358 } 359 360 static void gmux_write_switch_state(struct apple_gmux_data *gmux_data) 361 { 362 if (gmux_data->switch_state_ddc == VGA_SWITCHEROO_IGD) 363 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 1); 364 else 365 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DDC, 2); 366 367 if (gmux_data->switch_state_display == VGA_SWITCHEROO_IGD) 368 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); 369 else 370 gmux_write8(gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); 371 372 if (gmux_data->switch_state_external == VGA_SWITCHEROO_IGD) 373 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); 374 else 375 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); 376 } 377 378 static int gmux_switchto(enum vga_switcheroo_client_id id) 379 { 380 apple_gmux_data->switch_state_ddc = id; 381 apple_gmux_data->switch_state_display = id; 382 if (apple_gmux_data->external_switchable) 383 apple_gmux_data->switch_state_external = id; 384 385 gmux_write_switch_state(apple_gmux_data); 386 387 return 0; 388 } 389 390 static int gmux_switch_ddc(enum vga_switcheroo_client_id id) 391 { 392 enum vga_switcheroo_client_id old_ddc_owner = 393 apple_gmux_data->switch_state_ddc; 394 395 if (id == old_ddc_owner) 396 return id; 397 398 pr_debug("Switching DDC from %d to %d\n", old_ddc_owner, id); 399 apple_gmux_data->switch_state_ddc = id; 400 401 if (id == VGA_SWITCHEROO_IGD) 402 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); 403 else 404 gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); 405 406 return old_ddc_owner; 407 } 408 409 /** 410 * DOC: Power control 411 * 412 * gmux is able to cut power to the discrete GPU. It automatically takes care 413 * of the correct sequence to tear down and bring up the power rails for 414 * core voltage, VRAM and PCIe. 415 */ 416 417 static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, 418 enum vga_switcheroo_state state) 419 { 420 reinit_completion(&gmux_data->powerchange_done); 421 422 if (state == VGA_SWITCHEROO_ON) { 423 gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); 424 gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); 425 pr_debug("Discrete card powered up\n"); 426 } else { 427 gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); 428 gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); 429 pr_debug("Discrete card powered down\n"); 430 } 431 432 gmux_data->power_state = state; 433 434 if (gmux_data->gpe >= 0 && 435 !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done, 436 msecs_to_jiffies(200))) 437 pr_warn("Timeout waiting for gmux switch to complete\n"); 438 439 return 0; 440 } 441 442 static int gmux_set_power_state(enum vga_switcheroo_client_id id, 443 enum vga_switcheroo_state state) 444 { 445 if (id == VGA_SWITCHEROO_IGD) 446 return 0; 447 448 return gmux_set_discrete_state(apple_gmux_data, state); 449 } 450 451 static enum vga_switcheroo_client_id gmux_get_client_id(struct pci_dev *pdev) 452 { 453 /* 454 * Early Macbook Pros with switchable graphics use nvidia 455 * integrated graphics. Hardcode that the 9400M is integrated. 456 */ 457 if (pdev->vendor == PCI_VENDOR_ID_INTEL) 458 return VGA_SWITCHEROO_IGD; 459 else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && 460 pdev->device == 0x0863) 461 return VGA_SWITCHEROO_IGD; 462 else 463 return VGA_SWITCHEROO_DIS; 464 } 465 466 static const struct vga_switcheroo_handler gmux_handler_indexed = { 467 .switchto = gmux_switchto, 468 .power_state = gmux_set_power_state, 469 .get_client_id = gmux_get_client_id, 470 }; 471 472 static const struct vga_switcheroo_handler gmux_handler_classic = { 473 .switchto = gmux_switchto, 474 .switch_ddc = gmux_switch_ddc, 475 .power_state = gmux_set_power_state, 476 .get_client_id = gmux_get_client_id, 477 }; 478 479 /** 480 * DOC: Interrupt 481 * 482 * gmux is also connected to a GPIO pin of the southbridge and thereby is able 483 * to trigger an ACPI GPE. On the MBP5 2008/09 it's GPIO pin 22 of the Nvidia 484 * MCP79, on all following generations it's GPIO pin 6 of the Intel PCH. 485 * The GPE merely signals that an interrupt occurred, the actual type of event 486 * is identified by reading a gmux register. 487 */ 488 489 static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) 490 { 491 gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, 492 GMUX_INTERRUPT_DISABLE); 493 } 494 495 static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data) 496 { 497 gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, 498 GMUX_INTERRUPT_ENABLE); 499 } 500 501 static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data) 502 { 503 return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS); 504 } 505 506 static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data) 507 { 508 u8 status; 509 510 /* to clear interrupts write back current status */ 511 status = gmux_interrupt_get_status(gmux_data); 512 gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status); 513 } 514 515 static void gmux_notify_handler(acpi_handle device, u32 value, void *context) 516 { 517 u8 status; 518 struct pnp_dev *pnp = (struct pnp_dev *)context; 519 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 520 521 status = gmux_interrupt_get_status(gmux_data); 522 gmux_disable_interrupts(gmux_data); 523 pr_debug("Notify handler called: status %d\n", status); 524 525 gmux_clear_interrupts(gmux_data); 526 gmux_enable_interrupts(gmux_data); 527 528 if (status & GMUX_INTERRUPT_STATUS_POWER) 529 complete(&gmux_data->powerchange_done); 530 } 531 532 static int gmux_suspend(struct device *dev) 533 { 534 struct pnp_dev *pnp = to_pnp_dev(dev); 535 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 536 537 gmux_disable_interrupts(gmux_data); 538 return 0; 539 } 540 541 static int gmux_resume(struct device *dev) 542 { 543 struct pnp_dev *pnp = to_pnp_dev(dev); 544 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 545 546 gmux_enable_interrupts(gmux_data); 547 gmux_write_switch_state(gmux_data); 548 if (gmux_data->power_state == VGA_SWITCHEROO_OFF) 549 gmux_set_discrete_state(gmux_data, gmux_data->power_state); 550 return 0; 551 } 552 553 static int is_thunderbolt(struct device *dev, void *data) 554 { 555 return to_pci_dev(dev)->is_thunderbolt; 556 } 557 558 static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) 559 { 560 struct apple_gmux_data *gmux_data; 561 struct resource *res; 562 struct backlight_properties props; 563 struct backlight_device *bdev; 564 u8 ver_major, ver_minor, ver_release; 565 int ret = -ENXIO; 566 acpi_status status; 567 unsigned long long gpe; 568 bool indexed = false; 569 u32 version; 570 571 if (apple_gmux_data) 572 return -EBUSY; 573 574 if (!apple_gmux_detect(pnp, &indexed)) { 575 pr_info("gmux device not present\n"); 576 return -ENODEV; 577 } 578 579 gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); 580 if (!gmux_data) 581 return -ENOMEM; 582 pnp_set_drvdata(pnp, gmux_data); 583 584 res = pnp_get_resource(pnp, IORESOURCE_IO, 0); 585 gmux_data->iostart = res->start; 586 gmux_data->iolen = resource_size(res); 587 588 if (!request_region(gmux_data->iostart, gmux_data->iolen, 589 "Apple gmux")) { 590 pr_err("gmux I/O already in use\n"); 591 goto err_free; 592 } 593 594 if (indexed) { 595 mutex_init(&gmux_data->index_lock); 596 gmux_data->indexed = true; 597 version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR); 598 ver_major = (version >> 24) & 0xff; 599 ver_minor = (version >> 16) & 0xff; 600 ver_release = (version >> 8) & 0xff; 601 } else { 602 ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); 603 ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); 604 ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); 605 } 606 pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, 607 ver_release, (gmux_data->indexed ? "indexed" : "classic")); 608 609 memset(&props, 0, sizeof(props)); 610 props.type = BACKLIGHT_PLATFORM; 611 props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); 612 613 /* 614 * Currently it's assumed that the maximum brightness is less than 615 * 2^24 for compatibility with old gmux versions. Cap the max 616 * brightness at this value, but print a warning if the hardware 617 * reports something higher so that it can be fixed. 618 */ 619 if (WARN_ON(props.max_brightness > GMUX_MAX_BRIGHTNESS)) 620 props.max_brightness = GMUX_MAX_BRIGHTNESS; 621 622 bdev = backlight_device_register("gmux_backlight", &pnp->dev, 623 gmux_data, &gmux_bl_ops, &props); 624 if (IS_ERR(bdev)) { 625 ret = PTR_ERR(bdev); 626 goto err_release; 627 } 628 629 gmux_data->bdev = bdev; 630 bdev->props.brightness = gmux_get_brightness(bdev); 631 backlight_update_status(bdev); 632 633 /* 634 * The backlight situation on Macs is complicated. If the gmux is 635 * present it's the best choice, because it always works for 636 * backlight control and supports more levels than other options. 637 * Disable the other backlight choices. 638 */ 639 apple_bl_unregister(); 640 641 gmux_data->power_state = VGA_SWITCHEROO_ON; 642 643 gmux_data->dhandle = ACPI_HANDLE(&pnp->dev); 644 if (!gmux_data->dhandle) { 645 pr_err("Cannot find acpi handle for pnp device %s\n", 646 dev_name(&pnp->dev)); 647 ret = -ENODEV; 648 goto err_notify; 649 } 650 651 status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe); 652 if (ACPI_SUCCESS(status)) { 653 gmux_data->gpe = (int)gpe; 654 655 status = acpi_install_notify_handler(gmux_data->dhandle, 656 ACPI_DEVICE_NOTIFY, 657 &gmux_notify_handler, pnp); 658 if (ACPI_FAILURE(status)) { 659 pr_err("Install notify handler failed: %s\n", 660 acpi_format_exception(status)); 661 ret = -ENODEV; 662 goto err_notify; 663 } 664 665 status = acpi_enable_gpe(NULL, gmux_data->gpe); 666 if (ACPI_FAILURE(status)) { 667 pr_err("Cannot enable gpe: %s\n", 668 acpi_format_exception(status)); 669 goto err_enable_gpe; 670 } 671 } else { 672 pr_warn("No GPE found for gmux\n"); 673 gmux_data->gpe = -1; 674 } 675 676 /* 677 * If Thunderbolt is present, the external DP port is not fully 678 * switchable. Force its AUX channel to the discrete GPU. 679 */ 680 gmux_data->external_switchable = 681 !bus_for_each_dev(&pci_bus_type, NULL, NULL, is_thunderbolt); 682 if (!gmux_data->external_switchable) 683 gmux_write8(gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); 684 685 apple_gmux_data = gmux_data; 686 init_completion(&gmux_data->powerchange_done); 687 gmux_enable_interrupts(gmux_data); 688 gmux_read_switch_state(gmux_data); 689 690 /* 691 * Retina MacBook Pros cannot switch the panel's AUX separately 692 * and need eDP pre-calibration. They are distinguishable from 693 * pre-retinas by having an "indexed" gmux. 694 * 695 * Pre-retina MacBook Pros can switch the panel's DDC separately. 696 */ 697 if (gmux_data->indexed) 698 ret = vga_switcheroo_register_handler(&gmux_handler_indexed, 699 VGA_SWITCHEROO_NEEDS_EDP_CONFIG); 700 else 701 ret = vga_switcheroo_register_handler(&gmux_handler_classic, 702 VGA_SWITCHEROO_CAN_SWITCH_DDC); 703 if (ret) { 704 pr_err("Failed to register vga_switcheroo handler\n"); 705 goto err_register_handler; 706 } 707 708 return 0; 709 710 err_register_handler: 711 gmux_disable_interrupts(gmux_data); 712 apple_gmux_data = NULL; 713 if (gmux_data->gpe >= 0) 714 acpi_disable_gpe(NULL, gmux_data->gpe); 715 err_enable_gpe: 716 if (gmux_data->gpe >= 0) 717 acpi_remove_notify_handler(gmux_data->dhandle, 718 ACPI_DEVICE_NOTIFY, 719 &gmux_notify_handler); 720 err_notify: 721 backlight_device_unregister(bdev); 722 err_release: 723 release_region(gmux_data->iostart, gmux_data->iolen); 724 err_free: 725 kfree(gmux_data); 726 return ret; 727 } 728 729 static void gmux_remove(struct pnp_dev *pnp) 730 { 731 struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); 732 733 vga_switcheroo_unregister_handler(); 734 gmux_disable_interrupts(gmux_data); 735 if (gmux_data->gpe >= 0) { 736 acpi_disable_gpe(NULL, gmux_data->gpe); 737 acpi_remove_notify_handler(gmux_data->dhandle, 738 ACPI_DEVICE_NOTIFY, 739 &gmux_notify_handler); 740 } 741 742 backlight_device_unregister(gmux_data->bdev); 743 744 release_region(gmux_data->iostart, gmux_data->iolen); 745 apple_gmux_data = NULL; 746 kfree(gmux_data); 747 748 apple_bl_register(); 749 } 750 751 static const struct pnp_device_id gmux_device_ids[] = { 752 {GMUX_ACPI_HID, 0}, 753 {"", 0} 754 }; 755 756 static const struct dev_pm_ops gmux_dev_pm_ops = { 757 .suspend = gmux_suspend, 758 .resume = gmux_resume, 759 }; 760 761 static struct pnp_driver gmux_pnp_driver = { 762 .name = "apple-gmux", 763 .probe = gmux_probe, 764 .remove = gmux_remove, 765 .id_table = gmux_device_ids, 766 .driver = { 767 .pm = &gmux_dev_pm_ops, 768 }, 769 }; 770 771 module_pnp_driver(gmux_pnp_driver); 772 MODULE_AUTHOR("Seth Forshee <seth.forshee@canonical.com>"); 773 MODULE_DESCRIPTION("Apple Gmux Driver"); 774 MODULE_LICENSE("GPL"); 775 MODULE_DEVICE_TABLE(pnp, gmux_device_ids); 776