xref: /freebsd/sys/dev/acpi_apple/acpi_apple.h (revision 4a059dac78157e6163d6e8ed6e7be5ec65a78a5f)
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