1 /* $OpenBSD: aplpcie.c,v 1.19 2024/02/03 10:37:25 kettenis Exp $ */
2 /*
3 * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #include <sys/param.h>
19 #include <sys/systm.h>
20 #include <sys/device.h>
21 #include <sys/extent.h>
22 #include <sys/malloc.h>
23
24 #include <machine/intr.h>
25 #include <machine/bus.h>
26 #include <machine/fdt.h>
27
28 #include <dev/pci/pcidevs.h>
29 #include <dev/pci/pcireg.h>
30 #include <dev/pci/pcivar.h>
31
32 #include <dev/ofw/openfirm.h>
33 #include <dev/ofw/ofw_gpio.h>
34 #include <dev/ofw/ofw_misc.h>
35 #include <dev/ofw/ofw_pinctrl.h>
36 #include <dev/ofw/ofw_power.h>
37 #include <dev/ofw/fdt.h>
38
39 #define PCIE_RC_PHY_BASE(port) (0x84000 + (port) * 0x4000)
40 #define PCIE_RC_PHY_SIZE 0x4000
41
42 #define PCIE_PHY_LANE_CONF 0x0000
43 #define PCIE_PHY_LANE_CONF_REFCLK0REQ (1 << 0)
44 #define PCIE_PHY_LANE_CONF_REFCLK1REQ (1 << 1)
45 #define PCIE_PHY_LANE_CONF_REFCLK0ACK (1 << 2)
46 #define PCIE_PHY_LANE_CONF_REFCLK1ACK (1 << 3)
47 #define PCIE_PHY_LANE_CONF_REFCLK0EN (1 << 9)
48 #define PCIE_PHY_LANE_CONF_REFCLK1EN (1 << 10)
49 #define PCIE_PHY_LANE_CONF_REFCLK0CGEN (1 << 30)
50 #define PCIE_PHY_LANE_CONF_REFCLK1CGEN (1U << 31)
51 #define PCIE_PHY_LANE_CTRL 0x0004
52 #define PCIE_PHY_LANE_CTRL_CFGACC (1 << 15)
53
54 #define PCIE_PORT_LTSSM_CTRL 0x0080
55 #define PCIE_PORT_LTSSM_CTRL_START (1 << 0)
56 #define PCIE_PORT_MSI_CTRL 0x0124
57 #define PCIE_PORT_MSI_CTRL_ENABLE (1 << 0)
58 #define PCIE_PORT_MSI_CTRL_32 (5 << 4)
59 #define PCIE_PORT_MSI_REMAP 0x0128
60 #define PCIE_PORT_MSI_DOORBELL 0x0168
61 #define PCIE_PORT_LINK_STAT 0x0208
62 #define PCIE_PORT_LINK_STAT_UP (1 << 0)
63 #define PCIE_PORT_APPCLK 0x0800
64 #define PCIE_PORT_APPCLK_EN (1 << 0)
65 #define PCIE_PORT_APPCLK_CGDIS (1 << 8)
66 #define PCIE_PORT_STAT 0x0804
67 #define PCIE_PORT_STAT_READY (1 << 0)
68 #define PCIE_PORT_REFCLK 0x0810
69 #define PCIE_PORT_REFCLK_EN (1 << 0)
70 #define PCIE_PORT_REFCLK_CGDIS (1 << 8)
71 #define PCIE_PORT_PERST 0x0814
72 #define PCIE_PORT_PERST_DIS (1 << 0)
73 #define PCIE_PORT_RID2SID(idx) (0x0828 + (idx) * 4)
74 #define PCIE_PORT_RID2SID_VALID (1U << 31)
75 #define PCIE_PORT_RID2SID_SID_SHIFT 16
76 #define PCIE_PORT_RID2SID_RID_MASK 0x0000ffff
77 #define PCIE_PORT_MAX_RID2SID 64
78
79 #define PCIE_T6020_PORT_MSI_DOORBELL_LO 0x016c
80 #define PCIE_T6020_PORT_MSI_DOORBELL_HI 0x0170
81 #define PCIE_T6020_PORT_PERST 0x082c
82 #define PCIE_T6020_PORT_RID2SID(idx) (0x3000 + (idx) * 4)
83 #define PCIE_T6020_PORT_MAX_RID2SID 512
84 #define PCIE_T6020_PORT_MSI_MAP(idx) (0x3800 + (idx) * 4)
85 #define PCIE_T6020_PORT_MSI_MAP_ENABLE (1U << 31)
86
87 #define HREAD4(sc, reg) \
88 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
89 #define HWRITE4(sc, reg, val) \
90 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
91
92 #define RREAD4(sc, reg) \
93 (bus_space_read_4((sc)->sc_iot, (sc)->sc_rc_ioh, (reg)))
94 #define RWRITE4(sc, reg, val) \
95 bus_space_write_4((sc)->sc_iot, (sc)->sc_rc_ioh, (reg), (val))
96 #define RSET4(sc, reg, bits) \
97 RWRITE4((sc), (reg), RREAD4((sc), (reg)) | (bits))
98 #define RCLR4(sc, reg, bits) \
99 RWRITE4((sc), (reg), RREAD4((sc), (reg)) & ~(bits))
100
101 #define LREAD4(sc, port, reg) \
102 (bus_space_read_4((sc)->sc_iot, (sc)->sc_phy_ioh[port], (reg)))
103 #define LWRITE4(sc, port, reg, val) \
104 bus_space_write_4((sc)->sc_iot, (sc)->sc_phy_ioh[port], (reg), (val))
105 #define LSET4(sc, port, reg, bits) \
106 LWRITE4((sc), (port), (reg), LREAD4((sc), (port), (reg)) | (bits))
107 #define LCLR4(sc, port, reg, bits) \
108 LWRITE4((sc), (port), (reg), LREAD4((sc), (port), (reg)) & ~(bits))
109
110 #define PREAD4(sc, port, reg) \
111 (bus_space_read_4((sc)->sc_iot, (sc)->sc_port_ioh[(port)], (reg)))
112 #define PWRITE4(sc, port, reg, val) \
113 bus_space_write_4((sc)->sc_iot, (sc)->sc_port_ioh[(port)], (reg), (val))
114 #define PSET4(sc, port, reg, bits) \
115 PWRITE4((sc), (port), (reg), PREAD4((sc), (port), (reg)) | (bits))
116 #define PCLR4(sc, port, reg, bits) \
117 PWRITE4((sc), (port), (reg), PREAD4((sc), (port), (reg)) & ~(bits))
118
119 struct aplpcie_range {
120 uint32_t flags;
121 uint64_t pci_base;
122 uint64_t phys_base;
123 uint64_t size;
124 };
125
126 #define APLPCIE_MAX_PORTS 4
127
128 struct aplpcie_softc {
129 struct device sc_dev;
130 bus_space_tag_t sc_iot;
131 bus_space_handle_t sc_ioh;
132 bus_space_handle_t sc_rc_ioh;
133 bus_space_handle_t sc_phy_ioh[APLPCIE_MAX_PORTS];
134 bus_size_t sc_phy_ios[APLPCIE_MAX_PORTS];
135 bus_space_handle_t sc_port_ioh[APLPCIE_MAX_PORTS];
136 bus_size_t sc_port_ios[APLPCIE_MAX_PORTS];
137 bus_dma_tag_t sc_dmat;
138
139 int sc_node;
140 int sc_acells;
141 int sc_scells;
142 int sc_pacells;
143 int sc_pscells;
144 struct aplpcie_range *sc_ranges;
145 int sc_nranges;
146
147 struct bus_space sc_bus_iot;
148 struct bus_space sc_bus_memt;
149
150 struct machine_pci_chipset sc_pc;
151 struct extent *sc_busex;
152 struct extent *sc_memex;
153 struct extent *sc_pmemex;
154 struct extent *sc_ioex;
155 int sc_bus;
156
157 int sc_msi;
158 bus_addr_t sc_msi_doorbell;
159 uint32_t sc_msi_range[6];
160 int sc_msi_rangelen;
161 struct interrupt_controller sc_msi_ic;
162 };
163
164 int aplpcie_match(struct device *, void *, void *);
165 void aplpcie_attach(struct device *, struct device *, void *);
166
167 const struct cfattach aplpcie_ca = {
168 sizeof (struct aplpcie_softc), aplpcie_match, aplpcie_attach
169 };
170
171 struct cfdriver aplpcie_cd = {
172 NULL, "aplpcie", DV_DULL
173 };
174
175 int
aplpcie_match(struct device * parent,void * match,void * aux)176 aplpcie_match(struct device *parent, void *match, void *aux)
177 {
178 struct fdt_attach_args *faa = aux;
179
180 return OF_is_compatible(faa->fa_node, "apple,pcie") ||
181 OF_is_compatible(faa->fa_node, "apple,t6020-pcie");
182 }
183
184 void aplpcie_init_port(struct aplpcie_softc *, int);
185 void aplpcie_t6020_init_port(struct aplpcie_softc *, int);
186
187 void aplpcie_attach_hook(struct device *, struct device *,
188 struct pcibus_attach_args *);
189 int aplpcie_bus_maxdevs(void *, int);
190 pcitag_t aplpcie_make_tag(void *, int, int, int);
191 void aplpcie_decompose_tag(void *, pcitag_t, int *, int *, int *);
192 int aplpcie_conf_size(void *, pcitag_t);
193 pcireg_t aplpcie_conf_read(void *, pcitag_t, int);
194 void aplpcie_conf_write(void *, pcitag_t, int, pcireg_t);
195 int aplpcie_probe_device_hook(void *, struct pci_attach_args *);
196
197 int aplpcie_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
198 const char *aplpcie_intr_string(void *, pci_intr_handle_t);
199 void *aplpcie_intr_establish(void *, pci_intr_handle_t, int,
200 struct cpu_info *, int (*)(void *), void *, char *);
201 void aplpcie_intr_disestablish(void *, void *);
202
203 int aplpcie_bs_iomap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
204 bus_space_handle_t *);
205 int aplpcie_bs_memmap(bus_space_tag_t, bus_addr_t, bus_size_t, int,
206 bus_space_handle_t *);
207
208 void *aplpcie_intr_establish_msi(void *, uint64_t *, uint64_t *,
209 int, struct cpu_info *, int (*)(void *), void *, char *);
210 void aplpcie_intr_disestablish_msi(void *);
211
212 void
aplpcie_attach(struct device * parent,struct device * self,void * aux)213 aplpcie_attach(struct device *parent, struct device *self, void *aux)
214 {
215 struct aplpcie_softc *sc = (struct aplpcie_softc *)self;
216 struct fdt_attach_args *faa = aux;
217 struct pcibus_attach_args pba;
218 uint32_t *ranges;
219 int i, j, nranges, rangeslen;
220 uint32_t bus_range[2];
221 char name[32];
222 int idx, node, port;
223
224 sc->sc_iot = faa->fa_iot;
225
226 idx = OF_getindex(faa->fa_node, "config", "reg-names");
227 if (idx < 0 || idx >= faa->fa_nreg ||
228 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr,
229 faa->fa_reg[idx].size, 0, &sc->sc_ioh)) {
230 printf(": can't map registers\n");
231 return;
232 }
233
234 idx = OF_getindex(faa->fa_node, "rc", "reg-names");
235 if (idx < 0 || idx >= faa->fa_nreg ||
236 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr,
237 faa->fa_reg[idx].size, 0, &sc->sc_rc_ioh)) {
238 printf(": can't map registers\n");
239 return;
240 }
241
242 for (port = 0; port < APLPCIE_MAX_PORTS; port++) {
243 snprintf(name, sizeof(name), "port%d", port);
244 idx = OF_getindex(faa->fa_node, name, "reg-names");
245 if (idx < 0)
246 continue;
247 if (idx > faa->fa_nreg ||
248 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr,
249 faa->fa_reg[idx].size, 0, &sc->sc_port_ioh[port])) {
250 printf(": can't map registers\n");
251 return;
252 }
253 sc->sc_port_ios[port] = faa->fa_reg[idx].size;
254
255 snprintf(name, sizeof(name), "phy%d", port);
256 idx = OF_getindex(faa->fa_node, name, "reg-names");
257 if (idx < 0) {
258 bus_space_subregion(sc->sc_iot, sc->sc_rc_ioh,
259 PCIE_RC_PHY_BASE(port), PCIE_RC_PHY_SIZE,
260 &sc->sc_phy_ioh[port]);
261 continue;
262 }
263 if (idx > faa->fa_nreg ||
264 bus_space_map(sc->sc_iot, faa->fa_reg[idx].addr,
265 faa->fa_reg[idx].size, 0, &sc->sc_phy_ioh[port])) {
266 printf(": can't map registers\n");
267 return;
268 }
269 sc->sc_phy_ios[port] = faa->fa_reg[idx].size;
270 }
271
272 sc->sc_dmat = faa->fa_dmat;
273 sc->sc_node = faa->fa_node;
274
275 power_domain_enable(sc->sc_node);
276 pinctrl_byname(sc->sc_node, "default");
277
278 sc->sc_msi_doorbell =
279 OF_getpropint64(sc->sc_node, "msi-doorbell", 0xffff000ULL);
280 sc->sc_msi_rangelen = OF_getpropintarray(sc->sc_node, "msi-ranges",
281 sc->sc_msi_range, sizeof(sc->sc_msi_range));
282 if (sc->sc_msi_rangelen <= 0 ||
283 (sc->sc_msi_rangelen % sizeof(uint32_t)) ||
284 (sc->sc_msi_rangelen / sizeof(uint32_t)) < 5 ||
285 (sc->sc_msi_rangelen / sizeof(uint32_t) > 6)) {
286 printf(": invalid msi-ranges property\n");
287 return;
288 }
289
290 if (OF_is_compatible(sc->sc_node, "apple,t6020-pcie")) {
291 for (node = OF_child(sc->sc_node); node; node = OF_peer(node))
292 aplpcie_t6020_init_port(sc, node);
293 } else {
294 for (node = OF_child(sc->sc_node); node; node = OF_peer(node))
295 aplpcie_init_port(sc, node);
296 }
297
298 /*
299 * Must wait at least 100ms after link training completes
300 * before sending a configuration request to a device
301 * immediately below a port.
302 */
303 delay(100000);
304
305 sc->sc_acells = OF_getpropint(sc->sc_node, "#address-cells",
306 faa->fa_acells);
307 sc->sc_scells = OF_getpropint(sc->sc_node, "#size-cells",
308 faa->fa_scells);
309 sc->sc_pacells = faa->fa_acells;
310 sc->sc_pscells = faa->fa_scells;
311
312 rangeslen = OF_getproplen(sc->sc_node, "ranges");
313 if (rangeslen <= 0 || (rangeslen % sizeof(uint32_t)) ||
314 (rangeslen / sizeof(uint32_t)) % (sc->sc_acells +
315 sc->sc_pacells + sc->sc_scells)) {
316 printf(": invalid ranges property\n");
317 return;
318 }
319
320 ranges = malloc(rangeslen, M_TEMP, M_WAITOK);
321 OF_getpropintarray(sc->sc_node, "ranges", ranges,
322 rangeslen);
323
324 nranges = (rangeslen / sizeof(uint32_t)) /
325 (sc->sc_acells + sc->sc_pacells + sc->sc_scells);
326 sc->sc_ranges = mallocarray(nranges,
327 sizeof(struct aplpcie_range), M_TEMP, M_WAITOK);
328 sc->sc_nranges = nranges;
329
330 for (i = 0, j = 0; i < sc->sc_nranges; i++) {
331 sc->sc_ranges[i].flags = ranges[j++];
332 sc->sc_ranges[i].pci_base = ranges[j++];
333 if (sc->sc_acells - 1 == 2) {
334 sc->sc_ranges[i].pci_base <<= 32;
335 sc->sc_ranges[i].pci_base |= ranges[j++];
336 }
337 sc->sc_ranges[i].phys_base = ranges[j++];
338 if (sc->sc_pacells == 2) {
339 sc->sc_ranges[i].phys_base <<= 32;
340 sc->sc_ranges[i].phys_base |= ranges[j++];
341 }
342 sc->sc_ranges[i].size = ranges[j++];
343 if (sc->sc_scells == 2) {
344 sc->sc_ranges[i].size <<= 32;
345 sc->sc_ranges[i].size |= ranges[j++];
346 }
347 }
348
349 free(ranges, M_TEMP, rangeslen);
350
351 printf("\n");
352
353 /* Create extents for our address spaces. */
354 sc->sc_busex = extent_create("pcibus", 0, 255,
355 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
356 sc->sc_memex = extent_create("pcimem", 0, (u_long)-1,
357 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
358 sc->sc_pmemex = extent_create("pcipmem", 0, (u_long)-1,
359 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
360 sc->sc_ioex = extent_create("pciio", 0, 0xffffffff,
361 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED);
362 for (i = 0; i < sc->sc_nranges; i++) {
363 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000) {
364 extent_free(sc->sc_ioex, sc->sc_ranges[i].pci_base,
365 sc->sc_ranges[i].size, EX_WAITOK);
366 }
367 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x02000000) {
368 extent_free(sc->sc_memex, sc->sc_ranges[i].pci_base,
369 sc->sc_ranges[i].size, EX_WAITOK);
370 }
371 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x03000000) {
372 extent_free(sc->sc_pmemex, sc->sc_ranges[i].pci_base,
373 sc->sc_ranges[i].size, EX_WAITOK);
374 }
375 }
376
377 /* Set up bus range. */
378 if (OF_getpropintarray(sc->sc_node, "bus-range", bus_range,
379 sizeof(bus_range)) != sizeof(bus_range) ||
380 bus_range[0] >= 32 || bus_range[1] >= 32) {
381 bus_range[0] = 0;
382 bus_range[1] = 31;
383 }
384 sc->sc_bus = bus_range[0];
385 extent_free(sc->sc_busex, bus_range[0],
386 bus_range[1] - bus_range[0] + 1, EX_WAITOK);
387
388 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot));
389 sc->sc_bus_iot.bus_private = sc;
390 sc->sc_bus_iot._space_map = aplpcie_bs_iomap;
391 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt));
392 sc->sc_bus_memt.bus_private = sc;
393 sc->sc_bus_memt._space_map = aplpcie_bs_memmap;
394
395 sc->sc_pc.pc_conf_v = sc;
396 sc->sc_pc.pc_attach_hook = aplpcie_attach_hook;
397 sc->sc_pc.pc_bus_maxdevs = aplpcie_bus_maxdevs;
398 sc->sc_pc.pc_make_tag = aplpcie_make_tag;
399 sc->sc_pc.pc_decompose_tag = aplpcie_decompose_tag;
400 sc->sc_pc.pc_conf_size = aplpcie_conf_size;
401 sc->sc_pc.pc_conf_read = aplpcie_conf_read;
402 sc->sc_pc.pc_conf_write = aplpcie_conf_write;
403 sc->sc_pc.pc_probe_device_hook = aplpcie_probe_device_hook;
404
405 sc->sc_pc.pc_intr_v = sc;
406 sc->sc_pc.pc_intr_map = aplpcie_intr_map;
407 sc->sc_pc.pc_intr_map_msi = _pci_intr_map_msi;
408 sc->sc_pc.pc_intr_map_msivec = _pci_intr_map_msivec;
409 sc->sc_pc.pc_intr_map_msix = _pci_intr_map_msix;
410 sc->sc_pc.pc_intr_string = aplpcie_intr_string;
411 sc->sc_pc.pc_intr_establish = aplpcie_intr_establish;
412 sc->sc_pc.pc_intr_disestablish = aplpcie_intr_disestablish;
413
414 memset(&pba, 0, sizeof(pba));
415 pba.pba_busname = "pci";
416 pba.pba_iot = &sc->sc_bus_iot;
417 pba.pba_memt = &sc->sc_bus_memt;
418 pba.pba_dmat = sc->sc_dmat;
419 pba.pba_pc = &sc->sc_pc;
420 pba.pba_busex = sc->sc_busex;
421 pba.pba_memex = sc->sc_memex;
422 pba.pba_pmemex = sc->sc_pmemex;
423 pba.pba_ioex = sc->sc_ioex;
424 pba.pba_domain = pci_ndomains++;
425 pba.pba_bus = sc->sc_bus;
426 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED;
427
428 sc->sc_msi_ic.ic_node = sc->sc_node;
429 sc->sc_msi_ic.ic_cookie = sc;
430 sc->sc_msi_ic.ic_establish_msi = aplpcie_intr_establish_msi;
431 sc->sc_msi_ic.ic_disestablish = aplpcie_intr_disestablish_msi;
432 sc->sc_msi_ic.ic_barrier = intr_barrier;
433 fdt_intr_register(&sc->sc_msi_ic);
434
435 pci_dopm = 1;
436
437 config_found(self, &pba, NULL);
438 }
439
440 void
aplpcie_init_port(struct aplpcie_softc * sc,int node)441 aplpcie_init_port(struct aplpcie_softc *sc, int node)
442 {
443 char status[32];
444 uint32_t reg[5];
445 uint32_t *pwren_gpio;
446 uint32_t *reset_gpio;
447 int pwren_gpiolen, reset_gpiolen;
448 uint32_t stat;
449 int idx, port, timo;
450
451 if (OF_getprop(node, "status", status, sizeof(status)) > 0 &&
452 strcmp(status, "disabled") == 0)
453 return;
454
455 if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg))
456 return;
457
458 port = reg[0] >> 11;
459 if (port >= APLPCIE_MAX_PORTS || sc->sc_port_ios[port] == 0)
460 return;
461
462 pwren_gpiolen = OF_getproplen(node, "pwren-gpios");
463 reset_gpiolen = OF_getproplen(node, "reset-gpios");
464 if (reset_gpiolen <= 0)
465 return;
466
467 /*
468 * Set things up such that we can share the 32 available MSIs
469 * across all ports.
470 */
471 PWRITE4(sc, port, PCIE_PORT_MSI_CTRL,
472 PCIE_PORT_MSI_CTRL_32 | PCIE_PORT_MSI_CTRL_ENABLE);
473 PWRITE4(sc, port, PCIE_PORT_MSI_REMAP, 0);
474 PWRITE4(sc, port, PCIE_PORT_MSI_DOORBELL, sc->sc_msi_doorbell);
475
476 /*
477 * Clear stream ID mappings.
478 */
479 for (idx = 0; idx < PCIE_PORT_MAX_RID2SID; idx++)
480 PWRITE4(sc, port, PCIE_PORT_RID2SID(idx), 0);
481
482 /* Check if the link is already up. */
483 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT);
484 if (stat & PCIE_PORT_LINK_STAT_UP)
485 return;
486
487 PSET4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_EN);
488
489 /* Assert PERST#. */
490 reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK);
491 OF_getpropintarray(node, "reset-gpios", reset_gpio, reset_gpiolen);
492 gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT);
493 gpio_controller_set_pin(reset_gpio, 1);
494
495 /* Power up the device if necessary. */
496 if (pwren_gpiolen > 0) {
497 pwren_gpio = malloc(pwren_gpiolen, M_TEMP, M_WAITOK);
498 OF_getpropintarray(node, "pwren-gpios",
499 pwren_gpio, pwren_gpiolen);
500 gpio_controller_config_pin(pwren_gpio, GPIO_CONFIG_OUTPUT);
501 gpio_controller_set_pin(pwren_gpio, 1);
502 free(pwren_gpio, M_TEMP, pwren_gpiolen);
503 }
504
505 /* Setup Refclk. */
506 LSET4(sc, port, PCIE_PHY_LANE_CTRL, PCIE_PHY_LANE_CTRL_CFGACC);
507 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK0REQ);
508 for (timo = 500; timo > 0; timo--) {
509 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF);
510 if (stat & PCIE_PHY_LANE_CONF_REFCLK0ACK)
511 break;
512 delay(100);
513 }
514 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK1REQ);
515 for (timo = 500; timo > 0; timo--) {
516 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF);
517 if (stat & PCIE_PHY_LANE_CONF_REFCLK1ACK)
518 break;
519 delay(100);
520 }
521 LCLR4(sc, port, PCIE_PHY_LANE_CTRL, PCIE_PHY_LANE_CTRL_CFGACC);
522 LSET4(sc, port, PCIE_PHY_LANE_CONF,
523 PCIE_PHY_LANE_CONF_REFCLK0EN | PCIE_PHY_LANE_CONF_REFCLK1EN);
524 PSET4(sc, port, PCIE_PORT_REFCLK, PCIE_PORT_REFCLK_EN);
525
526 /*
527 * PERST# must remain asserted for at least 100us after the
528 * reference clock becomes stable. But also has to remain
529 * active at least 100ms after power up.
530 */
531 if (pwren_gpiolen > 0)
532 delay(100000);
533 else
534 delay(100);
535
536 /* Deassert PERST#. */
537 PSET4(sc, port, PCIE_PORT_PERST, PCIE_PORT_PERST_DIS);
538 gpio_controller_set_pin(reset_gpio, 0);
539 free(reset_gpio, M_TEMP, reset_gpiolen);
540
541 for (timo = 2500; timo > 0; timo--) {
542 stat = PREAD4(sc, port, PCIE_PORT_STAT);
543 if (stat & PCIE_PORT_STAT_READY)
544 break;
545 delay(100);
546 }
547 if ((stat & PCIE_PORT_STAT_READY) == 0)
548 return;
549
550 PCLR4(sc, port, PCIE_PORT_REFCLK, PCIE_PORT_REFCLK_CGDIS);
551 PCLR4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_CGDIS);
552
553 /* Bring up the link. */
554 PWRITE4(sc, port, PCIE_PORT_LTSSM_CTRL, PCIE_PORT_LTSSM_CTRL_START);
555 for (timo = 1000; timo > 0; timo--) {
556 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT);
557 if (stat & PCIE_PORT_LINK_STAT_UP)
558 break;
559 delay(100);
560 }
561 }
562
563 void
aplpcie_t6020_init_port(struct aplpcie_softc * sc,int node)564 aplpcie_t6020_init_port(struct aplpcie_softc *sc, int node)
565 {
566 char status[32];
567 uint32_t reg[5];
568 uint32_t *pwren_gpio;
569 uint32_t *reset_gpio;
570 int pwren_gpiolen, reset_gpiolen;
571 uint32_t stat;
572 int idx, msi, port, timo;
573
574 if (OF_getprop(node, "status", status, sizeof(status)) > 0 &&
575 strcmp(status, "disabled") == 0)
576 return;
577
578 if (OF_getpropintarray(node, "reg", reg, sizeof(reg)) != sizeof(reg))
579 return;
580
581 port = reg[0] >> 11;
582 if (port >= APLPCIE_MAX_PORTS || sc->sc_port_ios[port] == 0)
583 return;
584
585 pwren_gpiolen = OF_getproplen(node, "pwren-gpios");
586 reset_gpiolen = OF_getproplen(node, "reset-gpios");
587 if (reset_gpiolen <= 0)
588 return;
589
590 /*
591 * Set things up such that we can share the 32 available MSIs
592 * across all ports.
593 */
594 PWRITE4(sc, port, PCIE_PORT_MSI_CTRL, PCIE_PORT_MSI_CTRL_ENABLE);
595 for (msi = 0; msi < 32; msi++)
596 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_MAP(msi),
597 msi | PCIE_T6020_PORT_MSI_MAP_ENABLE);
598 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_DOORBELL_LO,
599 sc->sc_msi_doorbell);
600 PWRITE4(sc, port, PCIE_T6020_PORT_MSI_DOORBELL_HI,
601 sc->sc_msi_doorbell >> 32);
602
603 /*
604 * Clear stream ID mappings.
605 */
606 for (idx = 0; idx < PCIE_T6020_PORT_MAX_RID2SID; idx++)
607 PWRITE4(sc, port, PCIE_T6020_PORT_RID2SID(idx), 0);
608
609 /* Check if the link is already up. */
610 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT);
611 if (stat & PCIE_PORT_LINK_STAT_UP)
612 return;
613
614 PSET4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_EN);
615
616 /* Assert PERST#. */
617 reset_gpio = malloc(reset_gpiolen, M_TEMP, M_WAITOK);
618 OF_getpropintarray(node, "reset-gpios", reset_gpio, reset_gpiolen);
619 gpio_controller_config_pin(reset_gpio, GPIO_CONFIG_OUTPUT);
620 gpio_controller_set_pin(reset_gpio, 1);
621
622 /* Power up the device if necessary. */
623 if (pwren_gpiolen > 0) {
624 pwren_gpio = malloc(pwren_gpiolen, M_TEMP, M_WAITOK);
625 OF_getpropintarray(node, "pwren-gpios",
626 pwren_gpio, pwren_gpiolen);
627 gpio_controller_config_pin(pwren_gpio, GPIO_CONFIG_OUTPUT);
628 gpio_controller_set_pin(pwren_gpio, 1);
629 free(pwren_gpio, M_TEMP, pwren_gpiolen);
630 }
631
632 /* Setup Refclk. */
633 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK0REQ);
634 for (timo = 500; timo > 0; timo--) {
635 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF);
636 if (stat & PCIE_PHY_LANE_CONF_REFCLK0ACK)
637 break;
638 delay(100);
639 }
640 LSET4(sc, port, PCIE_PHY_LANE_CONF, PCIE_PHY_LANE_CONF_REFCLK1REQ);
641 for (timo = 500; timo > 0; timo--) {
642 stat = LREAD4(sc, port, PCIE_PHY_LANE_CONF);
643 if (stat & PCIE_PHY_LANE_CONF_REFCLK1ACK)
644 break;
645 delay(100);
646 }
647 LSET4(sc, port, PCIE_PHY_LANE_CONF,
648 PCIE_PHY_LANE_CONF_REFCLK0EN | PCIE_PHY_LANE_CONF_REFCLK1EN);
649
650 /*
651 * PERST# must remain asserted for at least 100us after the
652 * reference clock becomes stable. But also has to remain
653 * active at least 100ms after power up.
654 */
655 if (pwren_gpiolen > 0)
656 delay(100000);
657 else
658 delay(100);
659
660 /* Deassert PERST#. */
661 PSET4(sc, port, PCIE_T6020_PORT_PERST, PCIE_PORT_PERST_DIS);
662 gpio_controller_set_pin(reset_gpio, 0);
663 free(reset_gpio, M_TEMP, reset_gpiolen);
664
665 for (timo = 2500; timo > 0; timo--) {
666 stat = PREAD4(sc, port, PCIE_PORT_STAT);
667 if (stat & PCIE_PORT_STAT_READY)
668 break;
669 delay(100);
670 }
671 if ((stat & PCIE_PORT_STAT_READY) == 0)
672 return;
673
674 LSET4(sc, port, PCIE_PHY_LANE_CONF,
675 PCIE_PHY_LANE_CONF_REFCLK0CGEN | PCIE_PHY_LANE_CONF_REFCLK1CGEN);
676 PCLR4(sc, port, PCIE_PORT_APPCLK, PCIE_PORT_APPCLK_CGDIS);
677
678 /* Bring up the link. */
679 PWRITE4(sc, port, PCIE_PORT_LTSSM_CTRL, PCIE_PORT_LTSSM_CTRL_START);
680 for (timo = 1000; timo > 0; timo--) {
681 stat = PREAD4(sc, port, PCIE_PORT_LINK_STAT);
682 if (stat & PCIE_PORT_LINK_STAT_UP)
683 break;
684 delay(100);
685 }
686 }
687
688 void
aplpcie_attach_hook(struct device * parent,struct device * self,struct pcibus_attach_args * pba)689 aplpcie_attach_hook(struct device *parent, struct device *self,
690 struct pcibus_attach_args *pba)
691 {
692 }
693
694 int
aplpcie_bus_maxdevs(void * v,int bus)695 aplpcie_bus_maxdevs(void *v, int bus)
696 {
697 return 32;
698 }
699
700 int
aplpcie_find_node(int node,int bus,int device,int function)701 aplpcie_find_node(int node, int bus, int device, int function)
702 {
703 uint32_t reg[5];
704 uint32_t phys_hi;
705 int child;
706
707 phys_hi = ((bus << 16) | (device << 11) | (function << 8));
708
709 for (child = OF_child(node); child; child = OF_peer(child)) {
710 if (OF_getpropintarray(child, "reg",
711 reg, sizeof(reg)) != sizeof(reg))
712 continue;
713
714 if (reg[0] == phys_hi)
715 return child;
716
717 node = aplpcie_find_node(child, bus, device, function);
718 if (node)
719 return node;
720 }
721
722 return 0;
723 }
724
725 pcitag_t
aplpcie_make_tag(void * v,int bus,int device,int function)726 aplpcie_make_tag(void *v, int bus, int device, int function)
727 {
728 struct aplpcie_softc *sc = v;
729 int node;
730
731 node = aplpcie_find_node(sc->sc_node, bus, device, function);
732 return (((pcitag_t)node << 32) |
733 (bus << 20) | (device << 15) | (function << 12));
734 }
735
736 void
aplpcie_decompose_tag(void * v,pcitag_t tag,int * bp,int * dp,int * fp)737 aplpcie_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp)
738 {
739 if (bp != NULL)
740 *bp = (tag >> 20) & 0xff;
741 if (dp != NULL)
742 *dp = (tag >> 15) & 0x1f;
743 if (fp != NULL)
744 *fp = (tag >> 12) & 0x7;
745 }
746
747 int
aplpcie_conf_size(void * v,pcitag_t tag)748 aplpcie_conf_size(void *v, pcitag_t tag)
749 {
750 return PCIE_CONFIG_SPACE_SIZE;
751 }
752
753 pcireg_t
aplpcie_conf_read(void * v,pcitag_t tag,int reg)754 aplpcie_conf_read(void *v, pcitag_t tag, int reg)
755 {
756 struct aplpcie_softc *sc = v;
757
758 tag = PCITAG_OFFSET(tag);
759 return HREAD4(sc, tag | reg);
760 }
761
762 void
aplpcie_conf_write(void * v,pcitag_t tag,int reg,pcireg_t data)763 aplpcie_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
764 {
765 struct aplpcie_softc *sc = v;
766
767 tag = PCITAG_OFFSET(tag);
768 HWRITE4(sc, tag | reg, data);
769 }
770
771 int
aplpcie_find_port(struct aplpcie_softc * sc,int bus)772 aplpcie_find_port(struct aplpcie_softc *sc, int bus)
773 {
774 uint32_t bus_range[2];
775 uint32_t reg[5];
776 int node;
777
778 for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
779 /* Check if bus is in the range for this node. */
780 if (OF_getpropintarray(node, "bus-range", bus_range,
781 sizeof(bus_range)) != sizeof(bus_range))
782 continue;
783 if (bus < bus_range[0] || bus > bus_range[1])
784 continue;
785
786 if (OF_getpropintarray(node, "reg", reg,
787 sizeof(reg)) != sizeof(reg))
788 continue;
789 return reg[0] >> 11;
790 }
791
792 return -1;
793 }
794
795 int
aplpcie_map_rid(struct aplpcie_softc * sc,int port,uint16_t rid,uint32_t sid)796 aplpcie_map_rid(struct aplpcie_softc *sc, int port, uint16_t rid, uint32_t sid)
797 {
798 uint32_t reg;
799 int idx;
800
801 for (idx = 0; idx < PCIE_PORT_MAX_RID2SID; idx++) {
802 reg = PREAD4(sc, port, PCIE_PORT_RID2SID(idx));
803
804 /* If already mapped, we're done. */
805 if ((reg & PCIE_PORT_RID2SID_RID_MASK) == rid)
806 return 0;
807
808 /* Is this an empty slot? */
809 if (reg & PCIE_PORT_RID2SID_VALID)
810 continue;
811
812 /* Map using this slot. */
813 reg = (sid << PCIE_PORT_RID2SID_SID_SHIFT) | rid |
814 PCIE_PORT_RID2SID_VALID;
815 PWRITE4(sc, port, PCIE_PORT_RID2SID(idx), reg);
816
817 /* Read back to check the slot is implemented. */
818 if (PREAD4(sc, port, PCIE_PORT_RID2SID(idx)) != reg)
819 return ENODEV;
820 return 0;
821 }
822
823 return ENODEV;
824 }
825
826 int
aplpcie_t6020_map_rid(struct aplpcie_softc * sc,int port,uint16_t rid,uint32_t sid)827 aplpcie_t6020_map_rid(struct aplpcie_softc *sc, int port, uint16_t rid,
828 uint32_t sid)
829 {
830 uint32_t reg;
831 int idx;
832
833 for (idx = 0; idx < PCIE_T6020_PORT_MAX_RID2SID; idx++) {
834 reg = PREAD4(sc, port, PCIE_T6020_PORT_RID2SID(idx));
835
836 /* If already mapped, we're done. */
837 if ((reg & PCIE_PORT_RID2SID_RID_MASK) == rid)
838 return 0;
839
840 /* Is this an empty slot? */
841 if (reg & PCIE_PORT_RID2SID_VALID)
842 continue;
843
844 /* Map using this slot. */
845 reg = (sid << PCIE_PORT_RID2SID_SID_SHIFT) | rid |
846 PCIE_PORT_RID2SID_VALID;
847 PWRITE4(sc, port, PCIE_T6020_PORT_RID2SID(idx), reg);
848
849 /* Read back to check the slot is implemented. */
850 if (PREAD4(sc, port, PCIE_T6020_PORT_RID2SID(idx)) != reg)
851 return ENODEV;
852 return 0;
853 }
854
855 return ENODEV;
856 }
857
858 int
aplpcie_probe_device_hook(void * v,struct pci_attach_args * pa)859 aplpcie_probe_device_hook(void *v, struct pci_attach_args *pa)
860 {
861 struct aplpcie_softc *sc = v;
862 uint32_t phandle, sid;
863 uint16_t rid;
864 int error, port;
865
866 rid = pci_requester_id(pa->pa_pc, pa->pa_tag);
867 pa->pa_dmat = iommu_device_map_pci(sc->sc_node, rid, pa->pa_dmat);
868 if (iommu_device_lookup_pci(sc->sc_node, rid, &phandle, &sid))
869 return 0;
870
871 /*
872 * Create a stream ID mapping for this device. The mappings
873 * are per-port so we first need to find the port for this
874 * device. Then we find a free mapping slot to enter the
875 * mapping. If we run out of mappings, we print a warning; as
876 * long as the device doesn't do DMA, it will still work.
877 */
878
879 port = aplpcie_find_port(sc, pa->pa_bus);
880 if (port == -1)
881 return EINVAL;
882
883 if (OF_is_compatible(sc->sc_node, "apple,t6020-pcie"))
884 error = aplpcie_t6020_map_rid(sc, port, rid, sid);
885 else
886 error = aplpcie_map_rid(sc, port, rid, sid);
887 if (error) {
888 printf("%s: out of stream ID mapping slots\n",
889 sc->sc_dev.dv_xname);
890 }
891
892 /*
893 * Not all PCI devices do DMA, so don't return an error if we
894 * ran out of stream ID mapping slots.
895 */
896 return 0;
897 }
898
899 int
aplpcie_intr_map(struct pci_attach_args * pa,pci_intr_handle_t * ihp)900 aplpcie_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
901 {
902 int pin = pa->pa_rawintrpin;
903
904 if (pin == 0 || pin > PCI_INTERRUPT_PIN_MAX)
905 return -1;
906
907 if (pa->pa_tag == 0)
908 return -1;
909
910 ihp->ih_pc = pa->pa_pc;
911 ihp->ih_tag = pa->pa_intrtag;
912 ihp->ih_intrpin = pa->pa_intrpin;
913 ihp->ih_type = PCI_INTX;
914
915 return 0;
916 }
917
918 const char *
aplpcie_intr_string(void * v,pci_intr_handle_t ih)919 aplpcie_intr_string(void *v, pci_intr_handle_t ih)
920 {
921 switch (ih.ih_type) {
922 case PCI_MSI:
923 return "msi";
924 case PCI_MSIX:
925 return "msix";
926 }
927
928 return "intx";
929 }
930
931 void *
aplpcie_intr_establish(void * v,pci_intr_handle_t ih,int level,struct cpu_info * ci,int (* func)(void *),void * arg,char * name)932 aplpcie_intr_establish(void *v, pci_intr_handle_t ih, int level,
933 struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
934 {
935 struct aplpcie_softc *sc = v;
936 void *cookie;
937
938 KASSERT(ih.ih_type != PCI_NONE);
939
940 if (ih.ih_type != PCI_INTX) {
941 uint64_t addr, data;
942
943 addr = data = 0;
944 cookie = fdt_intr_establish_msi_cpu(sc->sc_node, &addr,
945 &data, level, ci, func, arg, name);
946 if (cookie == NULL)
947 return NULL;
948
949 if (ih.ih_type == PCI_MSIX) {
950 pci_msix_enable(ih.ih_pc, ih.ih_tag,
951 &sc->sc_bus_memt, ih.ih_intrpin, addr, data);
952 } else
953 pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data);
954 } else {
955 int bus, dev, fn;
956 uint32_t reg[4];
957
958 aplpcie_decompose_tag(sc, ih.ih_tag, &bus, &dev, &fn);
959
960 reg[0] = bus << 16 | dev << 11 | fn << 8;
961 reg[1] = reg[2] = 0;
962 reg[3] = ih.ih_intrpin;
963
964 cookie = fdt_intr_establish_imap_cpu(sc->sc_node, reg,
965 sizeof(reg), level, ci, func, arg, name);
966 }
967
968 return cookie;
969 }
970
971 void
aplpcie_intr_disestablish(void * v,void * cookie)972 aplpcie_intr_disestablish(void *v, void *cookie)
973 {
974 }
975
976 void *
aplpcie_intr_establish_msi(void * cookie,uint64_t * addr,uint64_t * data,int level,struct cpu_info * ci,int (* func)(void *),void * arg,char * name)977 aplpcie_intr_establish_msi(void *cookie, uint64_t *addr, uint64_t *data,
978 int level, struct cpu_info *ci, int (*func)(void *), void *arg, char *name)
979 {
980 struct aplpcie_softc *sc = cookie;
981 uint32_t cells[4];
982 int ncells;
983
984 ncells = sc->sc_msi_rangelen / sizeof(uint32_t);
985 if (sc->sc_msi >= sc->sc_msi_range[ncells - 1])
986 return NULL;
987
988 *addr = sc->sc_msi_doorbell;
989 *data = sc->sc_msi++;
990
991 memcpy(cells, &sc->sc_msi_range[1], sizeof(cells));
992 cells[ncells - 4] += *data;
993
994 return fdt_intr_parent_establish(&sc->sc_msi_ic, cells,
995 level, ci, func, arg, name);
996 }
997
998 void
aplpcie_intr_disestablish_msi(void * cookie)999 aplpcie_intr_disestablish_msi(void *cookie)
1000 {
1001 fdt_intr_parent_disestablish(cookie);
1002 }
1003
1004 int
aplpcie_bs_iomap(bus_space_tag_t t,bus_addr_t addr,bus_size_t size,int flags,bus_space_handle_t * bshp)1005 aplpcie_bs_iomap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1006 int flags, bus_space_handle_t *bshp)
1007 {
1008 struct aplpcie_softc *sc = t->bus_private;
1009 int i;
1010
1011 for (i = 0; i < sc->sc_nranges; i++) {
1012 uint64_t pci_start = sc->sc_ranges[i].pci_base;
1013 uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1014 uint64_t phys_start = sc->sc_ranges[i].phys_base;
1015
1016 if ((sc->sc_ranges[i].flags & 0x03000000) == 0x01000000 &&
1017 addr >= pci_start && addr + size <= pci_end) {
1018 return bus_space_map(sc->sc_iot,
1019 addr - pci_start + phys_start, size, flags, bshp);
1020 }
1021 }
1022
1023 return ENXIO;
1024 }
1025
1026 int
aplpcie_bs_memmap(bus_space_tag_t t,bus_addr_t addr,bus_size_t size,int flags,bus_space_handle_t * bshp)1027 aplpcie_bs_memmap(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
1028 int flags, bus_space_handle_t *bshp)
1029 {
1030 struct aplpcie_softc *sc = t->bus_private;
1031 int i;
1032
1033 flags |= BUS_SPACE_MAP_POSTED;
1034
1035 for (i = 0; i < sc->sc_nranges; i++) {
1036 uint64_t pci_start = sc->sc_ranges[i].pci_base;
1037 uint64_t pci_end = pci_start + sc->sc_ranges[i].size;
1038 uint64_t phys_start = sc->sc_ranges[i].phys_base;
1039
1040 if ((sc->sc_ranges[i].flags & 0x02000000) == 0x02000000 &&
1041 addr >= pci_start && addr + size <= pci_end) {
1042 return bus_space_map(sc->sc_iot,
1043 addr - pci_start + phys_start, size, flags, bshp);
1044 }
1045 }
1046
1047 return ENXIO;
1048 }
1049