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
amdgpio_match(struct device * parent,void * match,void * aux)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
amdgpio_attach(struct device * parent,struct device * self,void * aux)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
amdgpio_activate(struct device * self,int act)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
amdgpio_save_pin(struct amdgpio_softc * sc,int pin)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
amdgpio_save(struct amdgpio_softc * sc)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
amdgpio_restore_pin(struct amdgpio_softc * sc,int pin)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
amdgpio_restore(struct amdgpio_softc * sc)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
amdgpio_read_pin(void * cookie,int pin)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
amdgpio_write_pin(void * cookie,int pin,int value)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
amdgpio_intr_establish(void * cookie,int pin,int flags,int (* func)(void *),void * arg)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
amdgpio_intr_enable(void * cookie,int pin)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
amdgpio_intr_disable(void * cookie,int pin)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
amdgpio_pin_intr(struct amdgpio_softc * sc,int pin)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
amdgpio_intr(void * arg)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