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