1 /* 2 * Copyright (c) 2026 Abdelkader Boudih <seuros@FreeBSD.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #ifndef _ACPI_APPLE_H_ 8 #define _ACPI_APPLE_H_ 9 10 #include <sys/param.h> 11 #include <sys/bus.h> 12 #include <sys/eventhandler.h> 13 #include <sys/kernel.h> 14 #include <sys/lock.h> 15 #include <sys/module.h> 16 #include <sys/mutex.h> 17 #include <sys/sysctl.h> 18 19 #include <contrib/dev/acpica/include/acpi.h> 20 21 #include <dev/acpica/acpivar.h> 22 #include <dev/backlight/backlight.h> 23 24 enum acpi_apple_mode { 25 ACPI_APPLE_PLATFORM, /* WoL + lid (APP000B/APP9876) */ 26 ACPI_APPLE_BACKLIGHT, /* panel backlight (APP0002) */ 27 }; 28 29 /* 30 * Apple GMUX (GPU multiplexer) registers. 31 * On dual-GPU MacBook Pros, the GMUX owns the backlight PWM. 32 * Port offsets are relative to the GMUX resource base, consumed from 33 * the APP000B device's _CRS. 34 * 35 * Three I/O protocols exist: 36 * Classic (PIO) - pre-Retina Macs: direct inb/outb at base+port. 37 * Indexed - Retina Macs (2012-2015): write port number to 38 * GMUX_PORT_READ/WRITE, data at GMUX_PORT_VALUE. 39 * MMIO - T2 Macs: memory-mapped, select port+direction via 40 * GMUX_MMIO_PORT_SELECT, trigger with 41 * GMUX_MMIO_COMMAND_SEND, data at the resource base 42 * as a big-endian 32-bit value. 43 */ 44 #define GMUX_PORT_VERSION_MAJOR 0x04 45 #define GMUX_PORT_VERSION_MINOR 0x05 46 #define GMUX_PORT_VERSION_RELEASE 0x06 47 #define GMUX_PORT_MAX_BRIGHTNESS 0x70 48 #define GMUX_PORT_BRIGHTNESS 0x74 49 #define GMUX_BRIGHTNESS_MASK 0x00ffffff 50 51 /* A version read returns major, minor and release packed into 32 bits. */ 52 #define GMUX_VERSION_MAJOR(v) (((v) >> 24) & 0xff) 53 #define GMUX_VERSION_MINOR(v) (((v) >> 16) & 0xff) 54 #define GMUX_VERSION_RELEASE(v) (((v) >> 8) & 0xff) 55 56 /* 57 * An absent GMUX floats the bus high, so a read of all ones means the 58 * protocol under test is not the one this machine speaks. 59 */ 60 #define GMUX_FLOATING 0xff 61 62 /* Handshake polling: microseconds per iteration, and iteration limits. */ 63 #define GMUX_POLL_DELAY 100 64 #define GMUX_INDEXED_RETRIES 100 65 #define GMUX_MMIO_RETRIES 200 66 67 /* Indexed GMUX registers */ 68 #define GMUX_PORT_VALUE 0xc2 69 #define GMUX_PORT_READ 0xd0 70 #define GMUX_PORT_WRITE 0xd4 71 72 /* Bit 0 of GMUX_PORT_WRITE: command outstanding, cleared once complete. */ 73 #define GMUX_INDEXED_BUSY 0x01 74 75 /* 76 * Indexed-GMUX detection: write a fixed 3-byte unlock sequence to 77 * PORT_INDEXED_{MAGIC1,MAGIC2,MAGIC3}, then read the same two ports 78 * back and expect them to echo GMUX_INDEXED_SIGNATURE. 79 */ 80 #define GMUX_PORT_INDEXED_MAGIC1 0xcc 81 #define GMUX_PORT_INDEXED_MAGIC2 0xcd 82 #define GMUX_PORT_INDEXED_MAGIC3 0xce 83 #define GMUX_INDEXED_UNLOCK1 0xaa 84 #define GMUX_INDEXED_UNLOCK2 0x55 85 #define GMUX_INDEXED_UNLOCK3 0x00 86 #define GMUX_INDEXED_SIGNATURE 0x55aa 87 88 /* MMIO GMUX registers */ 89 #define GMUX_MMIO_PORT_SELECT 0x0e 90 #define GMUX_MMIO_COMMAND_SEND 0x0f 91 #define GMUX_MMIO_READ 0x00 92 #define GMUX_MMIO_WRITE 0x40 93 94 /* Minimum resource length needed to reach GMUX_PORT_BRIGHTNESS+4. */ 95 #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) 96 97 #define GMUX_TYPE_PIO 0 98 #define GMUX_TYPE_INDEXED 1 99 #define GMUX_TYPE_MMIO 2 100 101 struct apple_bl_reg { 102 uint32_t offset; 103 uint32_t mask; 104 uint8_t shift; 105 }; 106 107 struct apple_bl_hw { 108 const char *name; 109 int bar; 110 vm_size_t mapsize; 111 struct apple_bl_reg ctrl; 112 struct apple_bl_reg enable; 113 uint32_t enable_val; 114 struct apple_bl_reg max_reg; 115 uint32_t max; 116 }; 117 118 struct acpi_apple_softc { 119 device_t dev; 120 ACPI_HANDLE handle; 121 enum acpi_apple_mode mode; 122 123 /* Backlight */ 124 struct mtx bl_mtx; /* protects hw access + cache */ 125 struct cdev *bl_cdev; 126 const struct apple_bl_hw *bl_hw; 127 void *bl_mmio; /* GPU BAR MMIO (non-GMUX) */ 128 uint16_t bl_gmux_base; /* GMUX I/O port base, 0=none */ 129 void *bl_gmux_mmio; /* GMUX MMIO base, NULL=none */ 130 uint8_t bl_gmux_type; /* GMUX_TYPE_* */ 131 uint32_t bl_max; 132 uint32_t bl_brightness; /* cached percent 0..100 */ 133 }; 134 135 /* acpi_apple_platform.c */ 136 int acpi_apple_platform_attach(struct acpi_apple_softc *sc); 137 void acpi_apple_platform_detach(struct acpi_apple_softc *sc); 138 139 /* acpi_apple_bl.c */ 140 int acpi_apple_backlight_attach(struct acpi_apple_softc *sc); 141 void acpi_apple_backlight_detach(struct acpi_apple_softc *sc); 142 void acpi_apple_backlight_restore(void); 143 void acpi_apple_backlight_off(void); 144 int acpi_apple_bl_update_status(device_t dev, 145 struct backlight_props *props); 146 int acpi_apple_bl_get_status(device_t dev, 147 struct backlight_props *props); 148 int acpi_apple_bl_get_info(device_t dev, 149 struct backlight_info *info); 150 151 #endif /* _ACPI_APPLE_H_ */ 152