xref: /openbsd/sys/dev/acpi/amdgpio.c (revision 4bdff4be)
1 /*	$OpenBSD: amdgpio.c,v 1.10 2022/10/20 20:40:57 kettenis Exp $	*/
2 /*
3  * Copyright (c) 2016 Mark Kettenis
4  * Copyright (c) 2019 James Hastings
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/malloc.h>
21 #include <sys/systm.h>
22 
23 #include <dev/acpi/acpireg.h>
24 #include <dev/acpi/acpivar.h>
25 #include <dev/acpi/acpidev.h>
26 #include <dev/acpi/amltypes.h>
27 #include <dev/acpi/dsdt.h>
28 
29 #define AMDGPIO_CONF_LEVEL		0x00000100
30 #define AMDGPIO_CONF_ACTLO		0x00000200
31 #define AMDGPIO_CONF_ACTBOTH		0x00000400
32 #define AMDGPIO_CONF_MASK		0x00000600
33 #define AMDGPIO_CONF_INT_EN		0x00000800
34 #define AMDGPIO_CONF_INT_MASK		0x00001000
35 #define AMDGPIO_CONF_RXSTATE		0x00010000
36 #define AMDGPIO_CONF_TXSTATE		0x00400000
37 #define AMDGPIO_CONF_TXSTATE_EN		0x00800000
38 #define AMDGPIO_CONF_INT_STS		0x10000000
39 #define AMDGPIO_IRQ_MASTER_EOI		0x20000000
40 #define AMDGPIO_IRQ_BITS		46
41 #define AMDGPIO_IRQ_PINS		4
42 
43 #define AMDGPIO_IRQ_MASTER		0xfc
44 #define AMDGPIO_IRQ_STS			0x2f8
45 
46 struct amdgpio_intrhand {
47 	int (*ih_func)(void *);
48 	void *ih_arg;
49 };
50 
51 struct amdgpio_pincfg {
52 	/* Modeled after pchgpio but we only have one value to save/restore */
53 	uint32_t	pin_cfg;
54 };
55 
56 struct amdgpio_softc {
57 	struct device sc_dev;
58 	struct acpi_softc *sc_acpi;
59 	struct aml_node *sc_node;
60 
61 	bus_space_tag_t sc_memt;
62 	bus_space_handle_t sc_memh;
63 	int sc_irq_flags;
64 	void *sc_ih;
65 
66 	int sc_npins;
67 	struct amdgpio_pincfg *sc_pin_cfg;
68 	struct amdgpio_intrhand *sc_pin_ih;
69 
70 	struct acpi_gpio sc_gpio;
71 };
72 
73 int	amdgpio_match(struct device *, void *, void *);
74 void	amdgpio_attach(struct device *, struct device *, void *);
75 int	amdgpio_activate(struct device *, int);
76 
77 const struct cfattach amdgpio_ca = {
78 	sizeof(struct amdgpio_softc), amdgpio_match, amdgpio_attach,
79 	NULL, amdgpio_activate
80 };
81 
82 struct cfdriver amdgpio_cd = {
83 	NULL, "amdgpio", DV_DULL
84 };
85 
86 const char *amdgpio_hids[] = {
87 	"AMDI0030",
88 	"AMD0030",
89 	NULL
90 };
91 
92 int	amdgpio_read_pin(void *, int);
93 void	amdgpio_write_pin(void *, int, int);
94 void	amdgpio_intr_establish(void *, int, int, int (*)(void *), void *);
95 void	amdgpio_intr_enable(void *, int);
96 void	amdgpio_intr_disable(void *, int);
97 int	amdgpio_pin_intr(struct amdgpio_softc *, int);
98 int	amdgpio_intr(void *);
99 void	amdgpio_save_pin(struct amdgpio_softc *, int pin);
100 void	amdgpio_save(struct amdgpio_softc *);
101 void	amdgpio_restore_pin(struct amdgpio_softc *, int pin);
102 void	amdgpio_restore(struct amdgpio_softc *);
103 
104 int
105 amdgpio_match(struct device *parent, void *match, void *aux)
106 {
107 	struct acpi_attach_args *aaa = aux;
108 	struct cfdata *cf = match;
109 
110 	if (aaa->aaa_naddr < 1 || aaa->aaa_nirq < 1)
111 		return 0;
112 	return acpi_matchhids(aaa, amdgpio_hids, cf->cf_driver->cd_name);
113 }
114 
115 void
116 amdgpio_attach(struct device *parent, struct device *self, void *aux)
117 {
118 	struct acpi_attach_args *aaa = aux;
119 	struct amdgpio_softc *sc = (struct amdgpio_softc *)self;
120 	int64_t uid;
121 
122 	sc->sc_acpi = (struct acpi_softc *)parent;
123 	sc->sc_node = aaa->aaa_node;
124 	printf(" %s", sc->sc_node->name);
125 
126 	if (aml_evalinteger(sc->sc_acpi, sc->sc_node, "_UID", 0, NULL, &uid)) {
127 		printf(": can't find uid\n");
128 		return;
129 	}
130 
131 	printf(" uid %lld", uid);
132 
133 	switch (uid) {
134 	case 0:
135 		sc->sc_npins = 184;
136 		break;
137 	default:
138 		printf("\n");
139 		return;
140 	}
141 
142 	printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]);
143 	printf(" irq %d", aaa->aaa_irq[0]);
144 
145 	sc->sc_memt = aaa->aaa_bst[0];
146 	if (bus_space_map(sc->sc_memt, aaa->aaa_addr[0], aaa->aaa_size[0],
147 	    0, &sc->sc_memh)) {
148 		printf(": can't map registers\n");
149 		return;
150 	}
151 
152 	sc->sc_pin_cfg = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_cfg),
153 	    M_DEVBUF, M_WAITOK);
154 	sc->sc_pin_ih = mallocarray(sc->sc_npins, sizeof(*sc->sc_pin_ih),
155 	    M_DEVBUF, M_WAITOK | M_ZERO);
156 
157 	sc->sc_ih = acpi_intr_establish(aaa->aaa_irq[0], aaa->aaa_irq_flags[0],
158 	    IPL_BIO, amdgpio_intr, sc, sc->sc_dev.dv_xname);
159 	if (sc->sc_ih == NULL) {
160 		printf(": can't establish interrupt\n");
161 		goto unmap;
162 	}
163 
164 	sc->sc_gpio.cookie = sc;
165 	sc->sc_gpio.read_pin = amdgpio_read_pin;
166 	sc->sc_gpio.write_pin = amdgpio_write_pin;
167 	sc->sc_gpio.intr_establish = amdgpio_intr_establish;
168 	sc->sc_gpio.intr_enable = amdgpio_intr_enable;
169 	sc->sc_gpio.intr_disable = amdgpio_intr_disable;
170 	sc->sc_node->gpio = &sc->sc_gpio;
171 
172 	printf(", %d pins\n", sc->sc_npins);
173 
174 	acpi_register_gpio(sc->sc_acpi, sc->sc_node);
175 	return;
176 
177 unmap:
178 	free(sc->sc_pin_ih, M_DEVBUF, sc->sc_npins * sizeof(*sc->sc_pin_ih));
179 	bus_space_unmap(sc->sc_memt, sc->sc_memh, aaa->aaa_size[0]);
180 }
181 
182 int
183 amdgpio_activate(struct device *self, int act)
184 {
185 	struct amdgpio_softc *sc = (struct amdgpio_softc *)self;
186 
187 	switch (act) {
188 	case DVACT_SUSPEND:
189 		amdgpio_save(sc);
190 		break;
191 	case DVACT_RESUME:
192 		amdgpio_restore(sc);
193 		break;
194 	}
195 
196 	return 0;
197 }
198 
199 void
200 amdgpio_save_pin(struct amdgpio_softc *sc, int pin)
201 {
202 	sc->sc_pin_cfg[pin].pin_cfg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
203 	    pin * 4);
204 }
205 
206 void
207 amdgpio_save(struct amdgpio_softc *sc)
208 {
209 	int pin;
210 
211 	for (pin = 0; pin < sc->sc_npins; pin++)
212 		amdgpio_save_pin(sc, pin);
213 }
214 
215 void
216 amdgpio_restore_pin(struct amdgpio_softc *sc, int pin)
217 {
218 	if (!sc->sc_pin_ih[pin].ih_func)
219 		return;
220 
221 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4,
222 	    sc->sc_pin_cfg[pin].pin_cfg);
223 }
224 
225 void
226 amdgpio_restore(struct amdgpio_softc *sc)
227 {
228 	int pin;
229 
230 	for (pin = 0; pin < sc->sc_npins; pin++)
231 		amdgpio_restore_pin(sc, pin);
232 }
233 
234 int
235 amdgpio_read_pin(void *cookie, int pin)
236 {
237 	struct amdgpio_softc *sc = cookie;
238 	uint32_t reg;
239 
240 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
241 
242 	return !!(reg & AMDGPIO_CONF_RXSTATE);
243 }
244 
245 void
246 amdgpio_write_pin(void *cookie, int pin, int value)
247 {
248 	struct amdgpio_softc *sc = cookie;
249 	uint32_t reg;
250 
251 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
252 	reg |= AMDGPIO_CONF_TXSTATE_EN;
253 	if (value)
254 		reg |= AMDGPIO_CONF_TXSTATE;
255 	else
256 		reg &= ~AMDGPIO_CONF_TXSTATE;
257 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
258 }
259 
260 void
261 amdgpio_intr_establish(void *cookie, int pin, int flags,
262     int (*func)(void *), void *arg)
263 {
264 	struct amdgpio_softc *sc = cookie;
265 	uint32_t reg;
266 
267 	KASSERT(pin >= 0 && pin != 63 && pin < sc->sc_npins);
268 
269 	sc->sc_pin_ih[pin].ih_func = func;
270 	sc->sc_pin_ih[pin].ih_arg = arg;
271 
272 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
273 	reg &= ~(AMDGPIO_CONF_MASK | AMDGPIO_CONF_LEVEL |
274 	    AMDGPIO_CONF_TXSTATE_EN);
275 	if ((flags & LR_GPIO_MODE) == 0)
276 		reg |= AMDGPIO_CONF_LEVEL;
277 	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTLO)
278 		reg |= AMDGPIO_CONF_ACTLO;
279 	if ((flags & LR_GPIO_POLARITY) == LR_GPIO_ACTBOTH)
280 		reg |= AMDGPIO_CONF_ACTBOTH;
281 	reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
282 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
283 }
284 
285 void
286 amdgpio_intr_enable(void *cookie, int pin)
287 {
288 	struct amdgpio_softc *sc = cookie;
289 	uint32_t reg;
290 
291 	KASSERT(pin >= 0 && pin != 63 && pin < sc->sc_npins);
292 
293 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
294 	reg |= (AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
295 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
296 }
297 
298 void
299 amdgpio_intr_disable(void *cookie, int pin)
300 {
301 	struct amdgpio_softc *sc = cookie;
302 	uint32_t reg;
303 
304 	KASSERT(pin >= 0 && pin != 63 && pin < sc->sc_npins);
305 
306 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
307 	reg &= ~(AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
308 	bus_space_write_4(sc->sc_memt, sc->sc_memh, pin * 4, reg);
309 }
310 
311 int
312 amdgpio_pin_intr(struct amdgpio_softc *sc, int pin)
313 {
314 	uint32_t reg;
315 	int rc = 0;
316 
317 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh, pin * 4);
318 	if (reg & AMDGPIO_CONF_INT_STS) {
319 		if (sc->sc_pin_ih[pin].ih_func) {
320 			sc->sc_pin_ih[pin].ih_func(sc->sc_pin_ih[pin].ih_arg);
321 
322 			/* Clear interrupt */
323 			reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
324 			    pin * 4);
325 			bus_space_write_4(sc->sc_memt, sc->sc_memh,
326 			    pin * 4, reg);
327 			rc = 1;
328 		} else {
329 			/* Mask unhandled interrupt */
330 			reg &= ~(AMDGPIO_CONF_INT_MASK | AMDGPIO_CONF_INT_EN);
331 			bus_space_write_4(sc->sc_memt, sc->sc_memh,
332 			    pin * 4, reg);
333 		}
334 	}
335 
336 	return rc;
337 }
338 
339 int
340 amdgpio_intr(void *arg)
341 {
342 	struct amdgpio_softc *sc = arg;
343 	uint64_t status;
344 	uint32_t reg;
345 	int rc = 0, pin = 0;
346 	int i, j;
347 
348 	status = bus_space_read_4(sc->sc_memt, sc->sc_memh,
349 	    AMDGPIO_IRQ_STS + 4);
350 	status <<= 32;
351 	status |= bus_space_read_4(sc->sc_memt, sc->sc_memh,
352 	    AMDGPIO_IRQ_STS);
353 
354 	/* One status bit for every four pins */
355 	for (i = 0; i < AMDGPIO_IRQ_BITS; i++, pin += 4) {
356 		if (status & (1ULL << i)) {
357 			for (j = 0; j < AMDGPIO_IRQ_PINS; j++) {
358 				if (amdgpio_pin_intr(sc, pin + j))
359 					rc = 1;
360 			}
361 		}
362 	}
363 
364 	/* Signal end of interrupt */
365 	reg = bus_space_read_4(sc->sc_memt, sc->sc_memh,
366 	    AMDGPIO_IRQ_MASTER);
367 	reg |= AMDGPIO_IRQ_MASTER_EOI;
368 	bus_space_write_4(sc->sc_memt, sc->sc_memh,
369 	    AMDGPIO_IRQ_MASTER, reg);
370 
371 	return rc;
372 }
373