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