1 /*-
2 * Copyright (c) 2015-2016 Landon Fuller <[email protected]>
3 * Copyright (c) 2017 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * Portions of this software were developed by Landon Fuller
7 * under sponsorship from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer,
14 * without modification.
15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
17 * redistribution must be conditioned upon including a substantially
18 * similar Disclaimer requirement for further binary redistribution.
19 *
20 * NO WARRANTY
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGES.
32 */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 /*
38 * PCI-specific implementation for the BHNDB bridge driver.
39 *
40 * Provides support for bridging from a PCI parent bus to a BHND-compatible
41 * bus (e.g. bcma or siba) via a Broadcom PCI core configured in end-point
42 * mode.
43 *
44 * This driver handles all initial generic host-level PCI interactions with a
45 * PCI/PCIe bridge core operating in endpoint mode. Once the bridged bhnd(4)
46 * bus has been enumerated, this driver works in tandem with a core-specific
47 * bhnd_pci_hostb driver to manage the PCI core.
48 */
49
50 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/bus.h>
53 #include <sys/limits.h>
54 #include <sys/malloc.h>
55 #include <sys/module.h>
56 #include <sys/systm.h>
57
58 #include <dev/pci/pcireg.h>
59 #include <dev/pci/pcivar.h>
60
61 #include <dev/bhnd/bhnd.h>
62 #include <dev/bhnd/bhndreg.h>
63
64 #include <dev/bhnd/bhnd_erom.h>
65 #include <dev/bhnd/bhnd_eromvar.h>
66
67 #include <dev/bhnd/siba/sibareg.h>
68
69 #include <dev/bhnd/cores/pci/bhnd_pcireg.h>
70
71 #include "bhnd_pwrctl_hostb_if.h"
72
73 #include "bhndb_pcireg.h"
74 #include "bhndb_pcivar.h"
75 #include "bhndb_private.h"
76
77 struct bhndb_pci_eio;
78 struct bhndb_pci_probe;
79
80 static int bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc,
81 int *msi_count);
82
83 static int bhndb_pci_add_children(struct bhndb_pci_softc *sc);
84
85 static bhnd_devclass_t bhndb_expected_pci_devclass(device_t dev);
86 static bool bhndb_is_pcie_attached(device_t dev);
87
88 static int bhndb_enable_pci_clocks(device_t dev);
89 static int bhndb_disable_pci_clocks(device_t dev);
90
91 static int bhndb_pci_compat_setregwin(device_t dev,
92 device_t pci_dev, const struct bhndb_regwin *,
93 bhnd_addr_t);
94 static int bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
95 const struct bhndb_regwin *, bhnd_addr_t);
96
97 static void bhndb_pci_write_core(struct bhndb_pci_softc *sc,
98 bus_size_t offset, uint32_t value, u_int width);
99 static uint32_t bhndb_pci_read_core(struct bhndb_pci_softc *sc,
100 bus_size_t offset, u_int width);
101
102 static int bhndb_pci_srsh_pi_war(struct bhndb_pci_softc *sc,
103 struct bhndb_pci_probe *probe);
104
105 static bus_addr_t bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
106 static bus_size_t bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
107
108 static int bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe,
109 device_t dev, bhnd_devclass_t pci_devclass);
110 static void bhndb_pci_probe_free(struct bhndb_pci_probe *probe);
111
112 static int bhndb_pci_probe_copy_core_table(
113 struct bhndb_pci_probe *probe,
114 struct bhnd_core_info **cores, u_int *ncores);
115 static void bhndb_pci_probe_free_core_table(
116 struct bhnd_core_info *cores);
117
118 static void bhndb_pci_probe_write(struct bhndb_pci_probe *sc,
119 bhnd_addr_t addr, bhnd_size_t offset,
120 uint32_t value, u_int width);
121 static uint32_t bhndb_pci_probe_read(struct bhndb_pci_probe *sc,
122 bhnd_addr_t addr, bhnd_size_t offset, u_int width);
123
124 static void bhndb_pci_eio_init(struct bhndb_pci_eio *eio,
125 struct bhndb_pci_probe *probe);
126 static int bhndb_pci_eio_map(struct bhnd_erom_io *eio,
127 bhnd_addr_t addr, bhnd_size_t size);
128 static int bhndb_pci_eio_tell(struct bhnd_erom_io *eio,
129 bhnd_addr_t *addr, bhnd_size_t *size);
130 static uint32_t bhndb_pci_eio_read(struct bhnd_erom_io *eio,
131 bhnd_size_t offset, u_int width);
132
133 #define BHNDB_PCI_MSI_COUNT 1
134
135 static struct bhndb_pci_quirk bhndb_pci_quirks[];
136 static struct bhndb_pci_quirk bhndb_pcie_quirks[];
137 static struct bhndb_pci_quirk bhndb_pcie2_quirks[];
138
139 static struct bhndb_pci_core bhndb_pci_cores[] = {
140 BHNDB_PCI_CORE(PCI, bhndb_pci_quirks),
141 BHNDB_PCI_CORE(PCIE, bhndb_pcie_quirks),
142 BHNDB_PCI_CORE(PCIE2, bhndb_pcie2_quirks),
143 BHNDB_PCI_CORE_END
144 };
145
146 /* bhndb_pci erom I/O instance state */
147 struct bhndb_pci_eio {
148 struct bhnd_erom_io eio;
149 bool mapped; /**< true if a valid mapping exists */
150 bhnd_addr_t addr; /**< mapped address */
151 bhnd_size_t size; /**< mapped size */
152 struct bhndb_pci_probe *probe; /**< borrowed probe reference */
153 };
154
155 /**
156 * Provides early bus access to the bridged device's cores and core enumeration
157 * table.
158 *
159 * May be safely used during probe or early device attach, prior to calling
160 * bhndb_attach().
161 */
162 struct bhndb_pci_probe {
163 device_t dev; /**< bridge device */
164 device_t pci_dev; /**< parent PCI device */
165 struct bhnd_chipid cid; /**< chip identification */
166 struct bhnd_core_info hostb_core; /**< PCI bridge core info */
167
168 struct bhndb_pci_eio erom_io; /**< erom I/O instance */
169 bhnd_erom_class_t *erom_class; /**< probed erom class */
170 bhnd_erom_t *erom; /**< erom parser */
171 struct bhnd_core_info *cores; /**< erom-owned core table */
172 u_int ncores; /**< number of cores */
173
174 const struct bhndb_regwin *m_win; /**< mapped register window, or NULL if no mapping */
175 struct resource *m_res; /**< resource containing the register window, or NULL if no window mapped */
176 bhnd_addr_t m_target; /**< base address mapped by m_win */
177 bhnd_addr_t m_addr; /**< mapped address */
178 bhnd_size_t m_size; /**< mapped size */
179 bool m_valid; /**< true if a valid mapping exists, false otherwise */
180
181 struct bhndb_host_resources *hr; /**< backing host resources */
182 };
183
184
185 static struct bhndb_pci_quirk bhndb_pci_quirks[] = {
186 /* Backplane interrupt flags must be routed via siba-specific
187 * SIBA_CFG0_INTVEC configuration register; the BHNDB_PCI_INT_MASK
188 * PCI configuration register is unsupported. */
189 {{ BHND_MATCH_CHIP_TYPE (SIBA) },
190 { BHND_MATCH_CORE_REV (HWREV_LTE(5)) },
191 BHNDB_PCI_QUIRK_SIBA_INTVEC },
192
193 /* All PCI core revisions require the SRSH work-around */
194 BHNDB_PCI_QUIRK(HWREV_ANY, BHNDB_PCI_QUIRK_SRSH_WAR),
195 BHNDB_PCI_QUIRK_END
196 };
197
198 static struct bhndb_pci_quirk bhndb_pcie_quirks[] = {
199 /* All PCIe-G1 core revisions require the SRSH work-around */
200 BHNDB_PCI_QUIRK(HWREV_ANY, BHNDB_PCI_QUIRK_SRSH_WAR),
201 BHNDB_PCI_QUIRK_END
202 };
203
204 static struct bhndb_pci_quirk bhndb_pcie2_quirks[] = {
205 BHNDB_PCI_QUIRK_END
206 };
207
208 /**
209 * Return the device table entry for @p ci, or NULL if none.
210 */
211 static struct bhndb_pci_core *
bhndb_pci_find_core(struct bhnd_core_info * ci)212 bhndb_pci_find_core(struct bhnd_core_info *ci)
213 {
214 for (size_t i = 0; !BHNDB_PCI_IS_CORE_END(&bhndb_pci_cores[i]); i++) {
215 struct bhndb_pci_core *entry = &bhndb_pci_cores[i];
216
217 if (bhnd_core_matches(ci, &entry->match))
218 return (entry);
219 }
220
221 return (NULL);
222 }
223
224 /**
225 * Return all quirk flags for the given @p cid and @p ci.
226 */
227 static uint32_t
bhndb_pci_get_core_quirks(struct bhnd_chipid * cid,struct bhnd_core_info * ci)228 bhndb_pci_get_core_quirks(struct bhnd_chipid *cid, struct bhnd_core_info *ci)
229 {
230 struct bhndb_pci_core *entry;
231 struct bhndb_pci_quirk *qtable;
232 uint32_t quirks;
233
234 quirks = 0;
235
236 /* No core entry? */
237 if ((entry = bhndb_pci_find_core(ci)) == NULL)
238 return (quirks);
239
240 /* No quirks? */
241 if ((qtable = entry->quirks) == NULL)
242 return (quirks);
243
244 for (size_t i = 0; !BHNDB_PCI_IS_QUIRK_END(&qtable[i]); i++) {
245 struct bhndb_pci_quirk *q = &qtable[i];
246
247 if (!bhnd_chip_matches(cid, &q->chip_desc))
248 continue;
249
250 if (!bhnd_core_matches(ci, &q->core_desc))
251 continue;
252
253 quirks |= q->quirks;
254 }
255
256 return (quirks);
257 }
258
259 /**
260 * Default bhndb_pci implementation of device_probe().
261 *
262 * Verifies that the parent is a PCI/PCIe device.
263 */
264 static int
bhndb_pci_probe(device_t dev)265 bhndb_pci_probe(device_t dev)
266 {
267 struct bhndb_pci_probe *probe;
268 struct bhndb_pci_core *entry;
269 bhnd_devclass_t hostb_devclass;
270 device_t parent, parent_bus;
271 devclass_t pci, bus_devclass;
272 int error;
273
274 probe = NULL;
275
276 /* Our parent must be a PCI/PCIe device. */
277 pci = devclass_find("pci");
278 parent = device_get_parent(dev);
279 parent_bus = device_get_parent(parent);
280 if (parent_bus == NULL)
281 return (ENXIO);
282
283 /* The bus device class may inherit from 'pci' */
284 for (bus_devclass = device_get_devclass(parent_bus);
285 bus_devclass != NULL;
286 bus_devclass = devclass_get_parent(bus_devclass))
287 {
288 if (bus_devclass == pci)
289 break;
290 }
291
292 if (bus_devclass != pci)
293 return (ENXIO);
294
295 /* Enable clocks */
296 if ((error = bhndb_enable_pci_clocks(dev)))
297 return (error);
298
299 /* Identify the chip and enumerate the bridged cores */
300 hostb_devclass = bhndb_expected_pci_devclass(dev);
301 if ((error = bhndb_pci_probe_alloc(&probe, dev, hostb_devclass)))
302 goto cleanup;
303
304 /* Look for a matching core table entry */
305 if ((entry = bhndb_pci_find_core(&probe->hostb_core)) == NULL) {
306 error = ENXIO;
307 goto cleanup;
308 }
309
310 device_set_desc(dev, "PCI-BHND bridge");
311
312 /* fall-through */
313 error = BUS_PROBE_DEFAULT;
314
315 cleanup:
316 if (probe != NULL)
317 bhndb_pci_probe_free(probe);
318
319 bhndb_disable_pci_clocks(dev);
320
321 return (error);
322 }
323
324 /**
325 * Attempt to allocate MSI interrupts, returning the count in @p msi_count
326 * on success.
327 */
328 static int
bhndb_pci_alloc_msi(struct bhndb_pci_softc * sc,int * msi_count)329 bhndb_pci_alloc_msi(struct bhndb_pci_softc *sc, int *msi_count)
330 {
331 int error, count;
332
333 /* Is MSI available? */
334 if (pci_msi_count(sc->parent) < BHNDB_PCI_MSI_COUNT)
335 return (ENXIO);
336
337 /* Allocate expected message count */
338 count = BHNDB_PCI_MSI_COUNT;
339 if ((error = pci_alloc_msi(sc->parent, &count))) {
340 device_printf(sc->dev, "failed to allocate MSI interrupts: "
341 "%d\n", error);
342
343 return (error);
344 }
345
346 if (count < BHNDB_PCI_MSI_COUNT) {
347 pci_release_msi(sc->parent);
348 return (ENXIO);
349 }
350
351 *msi_count = count;
352 return (0);
353 }
354
355 static int
bhndb_pci_attach(device_t dev)356 bhndb_pci_attach(device_t dev)
357 {
358 struct bhndb_pci_softc *sc;
359 struct bhnd_chipid cid;
360 struct bhnd_core_info *cores, hostb_core;
361 bhnd_erom_class_t *erom_class;
362 struct bhndb_pci_probe *probe;
363 u_int ncores;
364 int irq_rid;
365 int error;
366
367 sc = device_get_softc(dev);
368 sc->dev = dev;
369 sc->parent = device_get_parent(dev);
370 sc->pci_devclass = bhndb_expected_pci_devclass(dev);
371 sc->pci_quirks = 0;
372 sc->set_regwin = NULL;
373
374 BHNDB_PCI_LOCK_INIT(sc);
375
376 probe = NULL;
377 cores = NULL;
378
379 /* Enable PCI bus mastering */
380 pci_enable_busmaster(sc->parent);
381
382 /* Enable clocks (if required by this hardware) */
383 if ((error = bhndb_enable_pci_clocks(sc->dev)))
384 goto cleanup;
385
386 /* Identify the chip and enumerate the bridged cores */
387 error = bhndb_pci_probe_alloc(&probe, dev, sc->pci_devclass);
388 if (error)
389 goto cleanup;
390
391 sc->pci_quirks = bhndb_pci_get_core_quirks(&probe->cid,
392 &probe->hostb_core);
393
394 /* Select the appropriate register window handler */
395 if (probe->cid.chip_type == BHND_CHIPTYPE_SIBA) {
396 sc->set_regwin = bhndb_pci_compat_setregwin;
397 } else {
398 sc->set_regwin = bhndb_pci_fast_setregwin;
399 }
400
401 /*
402 * Fix up our PCI base address in the SPROM shadow, if necessary.
403 *
404 * This must be done prior to accessing any static register windows
405 * that map the PCI core.
406 */
407 if ((error = bhndb_pci_srsh_pi_war(sc, probe)))
408 goto cleanup;
409
410 /* Set up PCI interrupt handling */
411 if (bhndb_pci_alloc_msi(sc, &sc->msi_count) == 0) {
412 /* MSI uses resource IDs starting at 1 */
413 irq_rid = 1;
414
415 device_printf(dev, "Using MSI interrupts on %s\n",
416 device_get_nameunit(sc->parent));
417 } else {
418 sc->msi_count = 0;
419 irq_rid = 0;
420
421 device_printf(dev, "Using INTx interrupts on %s\n",
422 device_get_nameunit(sc->parent));
423 }
424
425 sc->isrc = bhndb_alloc_intr_isrc(sc->parent, irq_rid, 0, RM_MAX_END, 1,
426 RF_SHAREABLE | RF_ACTIVE);
427 if (sc->isrc == NULL) {
428 device_printf(sc->dev, "failed to allocate interrupt "
429 "resource\n");
430 error = ENXIO;
431 goto cleanup;
432 }
433
434 /*
435 * Copy out the probe results and then free our probe state, releasing
436 * its exclusive ownership of host bridge resources.
437 *
438 * This must be done prior to full configuration of the bridge via
439 * bhndb_attach().
440 */
441 cid = probe->cid;
442 erom_class = probe->erom_class;
443 hostb_core = probe->hostb_core;
444
445 error = bhndb_pci_probe_copy_core_table(probe, &cores, &ncores);
446 if (error) {
447 cores = NULL;
448 goto cleanup;
449 }
450
451 bhndb_pci_probe_free(probe);
452 probe = NULL;
453
454 /* Perform bridge attach */
455 error = bhndb_attach(dev, &cid, cores, ncores, &hostb_core, erom_class);
456 if (error)
457 goto cleanup;
458
459 /* Add any additional child devices */
460 if ((error = bhndb_pci_add_children(sc)))
461 goto cleanup;
462
463 /* Probe and attach our children */
464 if ((error = bus_generic_attach(dev)))
465 goto cleanup;
466
467 bhndb_pci_probe_free_core_table(cores);
468
469 return (0);
470
471 cleanup:
472 device_delete_children(dev);
473
474 if (sc->isrc != NULL)
475 bhndb_free_intr_isrc(sc->isrc);
476
477 if (sc->msi_count > 0)
478 pci_release_msi(sc->parent);
479
480 if (cores != NULL)
481 bhndb_pci_probe_free_core_table(cores);
482
483 if (probe != NULL)
484 bhndb_pci_probe_free(probe);
485
486 bhndb_disable_pci_clocks(sc->dev);
487
488 pci_disable_busmaster(sc->parent);
489
490 BHNDB_PCI_LOCK_DESTROY(sc);
491
492 return (error);
493 }
494
495 static int
bhndb_pci_detach(device_t dev)496 bhndb_pci_detach(device_t dev)
497 {
498 struct bhndb_pci_softc *sc;
499 int error;
500
501 sc = device_get_softc(dev);
502
503 /* Attempt to detach our children */
504 if ((error = bus_generic_detach(dev)))
505 return (error);
506
507 /* Perform generic bridge detach */
508 if ((error = bhndb_generic_detach(dev)))
509 return (error);
510
511 /* Disable clocks (if required by this hardware) */
512 if ((error = bhndb_disable_pci_clocks(sc->dev)))
513 return (error);
514
515 /* Free our interrupt resources */
516 bhndb_free_intr_isrc(sc->isrc);
517
518 /* Release MSI interrupts */
519 if (sc->msi_count > 0)
520 pci_release_msi(sc->parent);
521
522 /* Disable PCI bus mastering */
523 pci_disable_busmaster(sc->parent);
524
525 BHNDB_PCI_LOCK_DESTROY(sc);
526
527 return (0);
528 }
529
530 static int
bhndb_pci_add_children(struct bhndb_pci_softc * sc)531 bhndb_pci_add_children(struct bhndb_pci_softc *sc)
532 {
533 bus_size_t nv_sz;
534 int error;
535
536 /**
537 * If SPROM is mapped directly into BAR0, add child NVRAM
538 * device.
539 */
540 nv_sz = bhndb_pci_sprom_size(sc);
541 if (nv_sz > 0) {
542 struct bhndb_devinfo *dinfo;
543 device_t child;
544
545 if (bootverbose) {
546 device_printf(sc->dev, "found SPROM (%ju bytes)\n",
547 (uintmax_t)nv_sz);
548 }
549
550 /* Add sprom device, ordered early enough to be available
551 * before the bridged bhnd(4) bus is attached. */
552 child = BUS_ADD_CHILD(sc->dev,
553 BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY, "bhnd_nvram", -1);
554 if (child == NULL) {
555 device_printf(sc->dev, "failed to add sprom device\n");
556 return (ENXIO);
557 }
558
559 /* Initialize device address space and resource covering the
560 * BAR0 SPROM shadow. */
561 dinfo = device_get_ivars(child);
562 dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
563
564 error = bus_set_resource(child, SYS_RES_MEMORY, 0,
565 bhndb_pci_sprom_addr(sc), nv_sz);
566 if (error) {
567 device_printf(sc->dev,
568 "failed to register sprom resources\n");
569 return (error);
570 }
571 }
572
573 return (0);
574 }
575
576 static const struct bhndb_regwin *
bhndb_pci_sprom_regwin(struct bhndb_pci_softc * sc)577 bhndb_pci_sprom_regwin(struct bhndb_pci_softc *sc)
578 {
579 struct bhndb_resources *bres;
580 const struct bhndb_hwcfg *cfg;
581 const struct bhndb_regwin *sprom_win;
582
583 bres = sc->bhndb.bus_res;
584 cfg = bres->cfg;
585
586 sprom_win = bhndb_regwin_find_type(cfg->register_windows,
587 BHNDB_REGWIN_T_SPROM, BHNDB_PCI_V0_BAR0_SPROM_SIZE);
588
589 return (sprom_win);
590 }
591
592 static bus_addr_t
bhndb_pci_sprom_addr(struct bhndb_pci_softc * sc)593 bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc)
594 {
595 const struct bhndb_regwin *sprom_win;
596 struct resource *r;
597
598 /* Fetch the SPROM register window */
599 sprom_win = bhndb_pci_sprom_regwin(sc);
600 KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+"));
601
602 /* Fetch the associated resource */
603 r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, sprom_win);
604 KASSERT(r != NULL, ("missing resource for sprom window\n"));
605
606 return (rman_get_start(r) + sprom_win->win_offset);
607 }
608
609 static bus_size_t
bhndb_pci_sprom_size(struct bhndb_pci_softc * sc)610 bhndb_pci_sprom_size(struct bhndb_pci_softc *sc)
611 {
612 const struct bhndb_regwin *sprom_win;
613 uint32_t sctl;
614 bus_size_t sprom_sz;
615
616 sprom_win = bhndb_pci_sprom_regwin(sc);
617
618 /* PCI_V2 and later devices map SPROM/OTP via ChipCommon */
619 if (sprom_win == NULL)
620 return (0);
621
622 /* Determine SPROM size */
623 sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4);
624 if (sctl & BHNDB_PCI_SPROM_BLANK)
625 return (0);
626
627 switch (sctl & BHNDB_PCI_SPROM_SZ_MASK) {
628 case BHNDB_PCI_SPROM_SZ_1KB:
629 sprom_sz = (1 * 1024);
630 break;
631
632 case BHNDB_PCI_SPROM_SZ_4KB:
633 sprom_sz = (4 * 1024);
634 break;
635
636 case BHNDB_PCI_SPROM_SZ_16KB:
637 sprom_sz = (16 * 1024);
638 break;
639
640 case BHNDB_PCI_SPROM_SZ_RESERVED:
641 default:
642 device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl);
643 return (0);
644 }
645
646 /* If the device has a larger SPROM than can be addressed via our SPROM
647 * register window, the SPROM image data will still be located within
648 * the window's addressable range */
649 sprom_sz = MIN(sprom_sz, sprom_win->win_size);
650
651 return (sprom_sz);
652 }
653
654 /**
655 * Return the host resource providing a static mapping of the PCI core's
656 * registers.
657 *
658 * @param sc bhndb PCI driver state.
659 * @param offset The required readable offset within the PCI core
660 * register block.
661 * @param size The required readable size at @p offset.
662 * @param[out] res On success, the host resource containing our PCI
663 * core's register window.
664 * @param[out] res_offset On success, the @p offset relative to @p res.
665 *
666 * @retval 0 success
667 * @retval ENXIO if a valid static register window mapping the PCI core
668 * registers is not available.
669 */
670 static int
bhndb_pci_get_core_regs(struct bhndb_pci_softc * sc,bus_size_t offset,bus_size_t size,struct resource ** res,bus_size_t * res_offset)671 bhndb_pci_get_core_regs(struct bhndb_pci_softc *sc, bus_size_t offset,
672 bus_size_t size, struct resource **res, bus_size_t *res_offset)
673 {
674 const struct bhndb_regwin *win;
675 struct resource *r;
676
677 /* Locate the static register window mapping the requested offset */
678 win = bhndb_regwin_find_core(sc->bhndb.bus_res->cfg->register_windows,
679 sc->pci_devclass, 0, BHND_PORT_DEVICE, 0, 0, offset, size);
680 if (win == NULL) {
681 device_printf(sc->dev, "missing PCI core register window\n");
682 return (ENXIO);
683 }
684
685 /* Fetch the resource containing the register window */
686 r = bhndb_host_resource_for_regwin(sc->bhndb.bus_res->res, win);
687 if (r == NULL) {
688 device_printf(sc->dev, "missing PCI core register resource\n");
689 return (ENXIO);
690 }
691
692 KASSERT(offset >= win->d.core.offset, ("offset %#jx outside of "
693 "register window", (uintmax_t)offset));
694
695 *res = r;
696 *res_offset = win->win_offset + (offset - win->d.core.offset);
697
698 return (0);
699 }
700
701 /**
702 * Write a 1, 2, or 4 byte data item to the PCI core's registers at @p offset.
703 *
704 * @param sc bhndb PCI driver state.
705 * @param offset register write offset.
706 * @param value value to be written.
707 * @param width item width (1, 2, or 4 bytes).
708 */
709 static void
bhndb_pci_write_core(struct bhndb_pci_softc * sc,bus_size_t offset,uint32_t value,u_int width)710 bhndb_pci_write_core(struct bhndb_pci_softc *sc, bus_size_t offset,
711 uint32_t value, u_int width)
712 {
713 struct resource *r;
714 bus_size_t r_offset;
715 int error;
716
717 error = bhndb_pci_get_core_regs(sc, offset, width, &r, &r_offset);
718 if (error) {
719 panic("no PCI register window mapping %#jx+%#x: %d",
720 (uintmax_t)offset, width, error);
721 }
722
723 switch (width) {
724 case 1:
725 bus_write_1(r, r_offset, value);
726 break;
727 case 2:
728 bus_write_2(r, r_offset, value);
729 break;
730 case 4:
731 bus_write_4(r, r_offset, value);
732 break;
733 default:
734 panic("invalid width: %u", width);
735 }
736 }
737
738 /**
739 * Read a 1, 2, or 4 byte data item from the PCI core's registers
740 * at @p offset.
741 *
742 * @param sc bhndb PCI driver state.
743 * @param offset register read offset.
744 * @param width item width (1, 2, or 4 bytes).
745 */
746 static uint32_t
bhndb_pci_read_core(struct bhndb_pci_softc * sc,bus_size_t offset,u_int width)747 bhndb_pci_read_core(struct bhndb_pci_softc *sc, bus_size_t offset, u_int width)
748 {
749 struct resource *r;
750 bus_size_t r_offset;
751 int error;
752
753 error = bhndb_pci_get_core_regs(sc, offset, width, &r, &r_offset);
754 if (error) {
755 panic("no PCI register window mapping %#jx+%#x: %d",
756 (uintmax_t)offset, width, error);
757 }
758
759 switch (width) {
760 case 1:
761 return (bus_read_1(r, r_offset));
762 case 2:
763 return (bus_read_2(r, r_offset));
764 case 4:
765 return (bus_read_4(r, r_offset));
766 default:
767 panic("invalid width: %u", width);
768 }
769 }
770
771 /**
772 * Fix-up power on defaults for SPROM-less devices.
773 *
774 * On SPROM-less devices, the PCI(e) cores will be initialized with their their
775 * Power-on-Reset defaults; this can leave the BHND_PCI_SRSH_PI value pointing
776 * to the wrong backplane address. This value is used by the PCI core when
777 * performing address translation between static register windows in BAR0 that
778 * map the PCI core's register block, and backplane address space.
779 *
780 * When translating accesses via these BAR0 regions, the PCI bridge determines
781 * the base address of the PCI core by concatenating:
782 *
783 * [bits] [source]
784 * 31:16 bits [31:16] of the enumeration space address (e.g. 0x18000000)
785 * 15:12 value of BHND_PCI_SRSH_PI from the PCI core's SPROM shadow
786 * 11:0 bits [11:0] of the PCI bus address
787 *
788 * For example, on a PCI_V0 device, the following PCI core register offsets are
789 * mapped into BAR0:
790 *
791 * [BAR0 offset] [description] [PCI core offset]
792 * 0x1000-0x17FF sprom shadow 0x800-0xFFF
793 * 0x1800-0x1DFF device registers 0x000-0x5FF
794 * 0x1E00+0x1FFF siba config registers 0xE00-0xFFF
795 *
796 * This function checks -- and if necessary, corrects -- the BHND_PCI_SRSH_PI
797 * value in the SPROM shadow.
798 *
799 * This workaround must applied prior to accessing any static register windows
800 * that map the PCI core.
801 *
802 * Applies to all PCI and PCIe-G1 core revisions.
803 */
804 static int
bhndb_pci_srsh_pi_war(struct bhndb_pci_softc * sc,struct bhndb_pci_probe * probe)805 bhndb_pci_srsh_pi_war(struct bhndb_pci_softc *sc,
806 struct bhndb_pci_probe *probe)
807 {
808 struct bhnd_core_match md;
809 bhnd_addr_t pci_addr;
810 bhnd_size_t pci_size;
811 bus_size_t srsh_offset;
812 uint16_t srsh_val, pci_val;
813 uint16_t val;
814 int error;
815
816 if ((sc->pci_quirks & BHNDB_PCI_QUIRK_SRSH_WAR) == 0)
817 return (0);
818
819 /* Use an equality match descriptor to look up our PCI core's base
820 * address in the EROM */
821 md = bhnd_core_get_match_desc(&probe->hostb_core);
822 error = bhnd_erom_lookup_core_addr(probe->erom, &md, BHND_PORT_DEVICE,
823 0, 0, NULL, &pci_addr, &pci_size);
824 if (error) {
825 device_printf(sc->dev, "no base address found for the PCI host "
826 "bridge core: %d\n", error);
827 return (error);
828 }
829
830 /* Fetch the SPROM SRSH_PI value */
831 srsh_offset = BHND_PCI_SPROM_SHADOW + BHND_PCI_SRSH_PI_OFFSET;
832 val = bhndb_pci_probe_read(probe, pci_addr, srsh_offset, sizeof(val));
833 srsh_val = (val & BHND_PCI_SRSH_PI_MASK) >> BHND_PCI_SRSH_PI_SHIFT;
834
835 /* If it doesn't match PCI core's base address, update the SPROM
836 * shadow */
837 pci_val = (pci_addr & BHND_PCI_SRSH_PI_ADDR_MASK) >>
838 BHND_PCI_SRSH_PI_ADDR_SHIFT;
839 if (srsh_val != pci_val) {
840 val &= ~BHND_PCI_SRSH_PI_MASK;
841 val |= (pci_val << BHND_PCI_SRSH_PI_SHIFT);
842 bhndb_pci_probe_write(probe, pci_addr, srsh_offset, val,
843 sizeof(val));
844 }
845
846 return (0);
847 }
848
849 static int
bhndb_pci_resume(device_t dev)850 bhndb_pci_resume(device_t dev)
851 {
852 struct bhndb_pci_softc *sc;
853 int error;
854
855 sc = device_get_softc(dev);
856
857 /* Enable clocks (if supported by this hardware) */
858 if ((error = bhndb_enable_pci_clocks(sc->dev)))
859 return (error);
860
861 /* Perform resume */
862 return (bhndb_generic_resume(dev));
863 }
864
865 static int
bhndb_pci_suspend(device_t dev)866 bhndb_pci_suspend(device_t dev)
867 {
868 struct bhndb_pci_softc *sc;
869 int error;
870
871 sc = device_get_softc(dev);
872
873 /* Disable clocks (if supported by this hardware) */
874 if ((error = bhndb_disable_pci_clocks(sc->dev)))
875 return (error);
876
877 /* Perform suspend */
878 return (bhndb_generic_suspend(dev));
879 }
880
881 static int
bhndb_pci_set_window_addr(device_t dev,const struct bhndb_regwin * rw,bhnd_addr_t addr)882 bhndb_pci_set_window_addr(device_t dev, const struct bhndb_regwin *rw,
883 bhnd_addr_t addr)
884 {
885 struct bhndb_pci_softc *sc = device_get_softc(dev);
886 return (sc->set_regwin(sc->dev, sc->parent, rw, addr));
887 }
888
889 /**
890 * A siba(4) and bcma(4)-compatible bhndb_set_window_addr implementation.
891 *
892 * On siba(4) devices, it's possible that writing a PCI window register may
893 * not succeed; it's necessary to immediately read the configuration register
894 * and retry if not set to the desired value.
895 *
896 * This is not necessary on bcma(4) devices, but other than the overhead of
897 * validating the register, there's no harm in performing the verification.
898 */
899 static int
bhndb_pci_compat_setregwin(device_t dev,device_t pci_dev,const struct bhndb_regwin * rw,bhnd_addr_t addr)900 bhndb_pci_compat_setregwin(device_t dev, device_t pci_dev,
901 const struct bhndb_regwin *rw, bhnd_addr_t addr)
902 {
903 int error;
904 int reg;
905
906 if (rw->win_type != BHNDB_REGWIN_T_DYN)
907 return (ENODEV);
908
909 reg = rw->d.dyn.cfg_offset;
910 for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) {
911 if ((error = bhndb_pci_fast_setregwin(dev, pci_dev, rw, addr)))
912 return (error);
913
914 if (pci_read_config(pci_dev, reg, 4) == addr)
915 return (0);
916
917 DELAY(10);
918 }
919
920 /* Unable to set window */
921 return (ENODEV);
922 }
923
924 /**
925 * A bcma(4)-only bhndb_set_window_addr implementation.
926 */
927 static int
bhndb_pci_fast_setregwin(device_t dev,device_t pci_dev,const struct bhndb_regwin * rw,bhnd_addr_t addr)928 bhndb_pci_fast_setregwin(device_t dev, device_t pci_dev,
929 const struct bhndb_regwin *rw, bhnd_addr_t addr)
930 {
931 /* The PCI bridge core only supports 32-bit addressing, regardless
932 * of the bus' support for 64-bit addressing */
933 if (addr > UINT32_MAX)
934 return (ERANGE);
935
936 switch (rw->win_type) {
937 case BHNDB_REGWIN_T_DYN:
938 /* Addresses must be page aligned */
939 if (addr % rw->win_size != 0)
940 return (EINVAL);
941
942 pci_write_config(pci_dev, rw->d.dyn.cfg_offset, addr, 4);
943 break;
944 default:
945 return (ENODEV);
946 }
947
948 return (0);
949 }
950
951 static int
bhndb_pci_populate_board_info(device_t dev,device_t child,struct bhnd_board_info * info)952 bhndb_pci_populate_board_info(device_t dev, device_t child,
953 struct bhnd_board_info *info)
954 {
955 struct bhndb_pci_softc *sc;
956
957 sc = device_get_softc(dev);
958
959 /*
960 * On a subset of Apple BCM4360 modules, always prefer the
961 * PCI subdevice to the SPROM-supplied boardtype.
962 *
963 * TODO:
964 *
965 * Broadcom's own drivers implement this override, and then later use
966 * the remapped BCM4360 board type to determine the required
967 * board-specific workarounds.
968 *
969 * Without access to this hardware, it's unclear why this mapping
970 * is done, and we must do the same. If we can survey the hardware
971 * in question, it may be possible to replace this behavior with
972 * explicit references to the SPROM-supplied boardtype(s) in our
973 * quirk definitions.
974 */
975 if (pci_get_subvendor(sc->parent) == PCI_VENDOR_APPLE) {
976 switch (info->board_type) {
977 case BHND_BOARD_BCM94360X29C:
978 case BHND_BOARD_BCM94360X29CP2:
979 case BHND_BOARD_BCM94360X51:
980 case BHND_BOARD_BCM94360X51P2:
981 info->board_type = 0; /* allow override below */
982 break;
983 default:
984 break;
985 }
986 }
987
988 /* If NVRAM did not supply vendor/type/devid info, provide the PCI
989 * subvendor/subdevice/device values. */
990 if (info->board_vendor == 0)
991 info->board_vendor = pci_get_subvendor(sc->parent);
992
993 if (info->board_type == 0)
994 info->board_type = pci_get_subdevice(sc->parent);
995
996 if (info->board_devid == 0)
997 info->board_devid = pci_get_device(sc->parent);
998
999 return (0);
1000 }
1001
1002 /**
1003 * Examine the bridge device @p dev and return the expected host bridge
1004 * device class.
1005 *
1006 * @param dev The bhndb bridge device
1007 */
1008 static bhnd_devclass_t
bhndb_expected_pci_devclass(device_t dev)1009 bhndb_expected_pci_devclass(device_t dev)
1010 {
1011 if (bhndb_is_pcie_attached(dev))
1012 return (BHND_DEVCLASS_PCIE);
1013 else
1014 return (BHND_DEVCLASS_PCI);
1015 }
1016
1017 /**
1018 * Return true if the bridge device @p dev is attached via PCIe,
1019 * false otherwise.
1020 *
1021 * @param dev The bhndb bridge device
1022 */
1023 static bool
bhndb_is_pcie_attached(device_t dev)1024 bhndb_is_pcie_attached(device_t dev)
1025 {
1026 int reg;
1027
1028 if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, ®) == 0)
1029 return (true);
1030
1031 return (false);
1032 }
1033
1034 /**
1035 * Enable externally managed clocks, if required.
1036 *
1037 * Some PCI chipsets (BCM4306, possibly others) chips do not support
1038 * the idle low-power clock. Clocking must be bootstrapped at
1039 * attach/resume by directly adjusting GPIO registers exposed in the
1040 * PCI config space, and correspondingly, explicitly shutdown at
1041 * detach/suspend.
1042 *
1043 * @note This function may be safely called prior to device attach, (e.g.
1044 * from DEVICE_PROBE).
1045 *
1046 * @param dev The bhndb bridge device
1047 */
1048 static int
bhndb_enable_pci_clocks(device_t dev)1049 bhndb_enable_pci_clocks(device_t dev)
1050 {
1051 device_t pci_dev;
1052 uint32_t gpio_in, gpio_out, gpio_en;
1053 uint32_t gpio_flags;
1054 uint16_t pci_status;
1055
1056 pci_dev = device_get_parent(dev);
1057
1058 /* Only supported and required on PCI devices */
1059 if (bhndb_is_pcie_attached(dev))
1060 return (0);
1061
1062 /* Read state of XTAL pin */
1063 gpio_in = pci_read_config(pci_dev, BHNDB_PCI_GPIO_IN, 4);
1064 if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
1065 return (0); /* already enabled */
1066
1067 /* Fetch current config */
1068 gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4);
1069 gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4);
1070
1071 /* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */
1072 gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
1073 gpio_out |= gpio_flags;
1074 gpio_en |= gpio_flags;
1075
1076 pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1077 pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
1078 DELAY(1000);
1079
1080 /* Reset PLL_OFF */
1081 gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
1082 pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1083 DELAY(5000);
1084
1085 /* Clear any PCI 'sent target-abort' flag. */
1086 pci_status = pci_read_config(pci_dev, PCIR_STATUS, 2);
1087 pci_status &= ~PCIM_STATUS_STABORT;
1088 pci_write_config(pci_dev, PCIR_STATUS, pci_status, 2);
1089
1090 return (0);
1091 }
1092
1093 /**
1094 * Disable externally managed clocks, if required.
1095 *
1096 * This function may be safely called prior to device attach, (e.g.
1097 * from DEVICE_PROBE).
1098 *
1099 * @param dev The bhndb bridge device
1100 */
1101 static int
bhndb_disable_pci_clocks(device_t dev)1102 bhndb_disable_pci_clocks(device_t dev)
1103 {
1104 device_t pci_dev;
1105 uint32_t gpio_out, gpio_en;
1106
1107 pci_dev = device_get_parent(dev);
1108
1109 /* Only supported and required on PCI devices */
1110 if (bhndb_is_pcie_attached(dev))
1111 return (0);
1112
1113 /* Fetch current config */
1114 gpio_out = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUT, 4);
1115 gpio_en = pci_read_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, 4);
1116
1117 /* Set PLL_OFF to HIGH, XTAL_ON to LOW. */
1118 gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON;
1119 gpio_out |= BHNDB_PCI_GPIO_PLL_OFF;
1120 pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
1121
1122 /* Enable both output pins */
1123 gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
1124 pci_write_config(pci_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
1125
1126 return (0);
1127 }
1128
1129 static bhnd_clksrc
bhndb_pci_pwrctl_get_clksrc(device_t dev,device_t child,bhnd_clock clock)1130 bhndb_pci_pwrctl_get_clksrc(device_t dev, device_t child,
1131 bhnd_clock clock)
1132 {
1133 struct bhndb_pci_softc *sc;
1134 uint32_t gpio_out;
1135
1136 sc = device_get_softc(dev);
1137
1138 /* Only supported on PCI devices */
1139 if (bhndb_is_pcie_attached(sc->dev))
1140 return (BHND_CLKSRC_UNKNOWN);
1141
1142 /* Only ILP is supported */
1143 if (clock != BHND_CLOCK_ILP)
1144 return (BHND_CLKSRC_UNKNOWN);
1145
1146 gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
1147 if (gpio_out & BHNDB_PCI_GPIO_SCS)
1148 return (BHND_CLKSRC_PCI);
1149 else
1150 return (BHND_CLKSRC_XTAL);
1151 }
1152
1153 static int
bhndb_pci_pwrctl_gate_clock(device_t dev,device_t child,bhnd_clock clock)1154 bhndb_pci_pwrctl_gate_clock(device_t dev, device_t child,
1155 bhnd_clock clock)
1156 {
1157 struct bhndb_pci_softc *sc = device_get_softc(dev);
1158
1159 /* Only supported on PCI devices */
1160 if (bhndb_is_pcie_attached(sc->dev))
1161 return (ENODEV);
1162
1163 /* Only HT is supported */
1164 if (clock != BHND_CLOCK_HT)
1165 return (ENXIO);
1166
1167 return (bhndb_disable_pci_clocks(sc->dev));
1168 }
1169
1170 static int
bhndb_pci_pwrctl_ungate_clock(device_t dev,device_t child,bhnd_clock clock)1171 bhndb_pci_pwrctl_ungate_clock(device_t dev, device_t child,
1172 bhnd_clock clock)
1173 {
1174 struct bhndb_pci_softc *sc = device_get_softc(dev);
1175
1176 /* Only supported on PCI devices */
1177 if (bhndb_is_pcie_attached(sc->dev))
1178 return (ENODEV);
1179
1180 /* Only HT is supported */
1181 if (clock != BHND_CLOCK_HT)
1182 return (ENXIO);
1183
1184 return (bhndb_enable_pci_clocks(sc->dev));
1185 }
1186
1187 /**
1188 * BHNDB_MAP_INTR_ISRC()
1189 */
1190 static int
bhndb_pci_map_intr_isrc(device_t dev,struct resource * irq,struct bhndb_intr_isrc ** isrc)1191 bhndb_pci_map_intr_isrc(device_t dev, struct resource *irq,
1192 struct bhndb_intr_isrc **isrc)
1193 {
1194 struct bhndb_pci_softc *sc = device_get_softc(dev);
1195
1196 /* There's only one bridged interrupt to choose from */
1197 *isrc = sc->isrc;
1198 return (0);
1199 }
1200
1201 /* siba-specific implementation of BHNDB_ROUTE_INTERRUPTS() */
1202 static int
bhndb_pci_route_siba_interrupts(struct bhndb_pci_softc * sc,device_t child)1203 bhndb_pci_route_siba_interrupts(struct bhndb_pci_softc *sc, device_t child)
1204 {
1205 uint32_t sbintvec;
1206 u_int ivec;
1207 int error;
1208
1209 KASSERT(sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC,
1210 ("route_siba_interrupts not supported by this hardware"));
1211
1212 /* Fetch the sbflag# for the child */
1213 if ((error = bhnd_get_intr_ivec(child, 0, &ivec)))
1214 return (error);
1215
1216 if (ivec > (sizeof(sbintvec)*8) - 1 /* aka '31' */) {
1217 /* This should never be an issue in practice */
1218 device_printf(sc->dev, "cannot route interrupts to high "
1219 "sbflag# %u\n", ivec);
1220 return (ENXIO);
1221 }
1222
1223 BHNDB_PCI_LOCK(sc);
1224
1225 sbintvec = bhndb_pci_read_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), 4);
1226 sbintvec |= (1 << ivec);
1227 bhndb_pci_write_core(sc, SB0_REG_ABS(SIBA_CFG0_INTVEC), sbintvec, 4);
1228
1229 BHNDB_PCI_UNLOCK(sc);
1230
1231 return (0);
1232 }
1233
1234 /* BHNDB_ROUTE_INTERRUPTS() */
1235 static int
bhndb_pci_route_interrupts(device_t dev,device_t child)1236 bhndb_pci_route_interrupts(device_t dev, device_t child)
1237 {
1238 struct bhndb_pci_softc *sc;
1239 struct bhnd_core_info core;
1240 uint32_t core_bit;
1241 uint32_t intmask;
1242
1243 sc = device_get_softc(dev);
1244
1245 if (sc->pci_quirks & BHNDB_PCI_QUIRK_SIBA_INTVEC)
1246 return (bhndb_pci_route_siba_interrupts(sc, child));
1247
1248 core = bhnd_get_core_info(child);
1249 if (core.core_idx > BHNDB_PCI_SBIM_COREIDX_MAX) {
1250 /* This should never be an issue in practice */
1251 device_printf(dev, "cannot route interrupts to high core "
1252 "index %u\n", core.core_idx);
1253 return (ENXIO);
1254 }
1255
1256 BHNDB_PCI_LOCK(sc);
1257
1258 core_bit = (1<<core.core_idx) << BHNDB_PCI_SBIM_SHIFT;
1259 intmask = pci_read_config(sc->parent, BHNDB_PCI_INT_MASK, 4);
1260 intmask |= core_bit;
1261 pci_write_config(sc->parent, BHNDB_PCI_INT_MASK, intmask, 4);
1262
1263 BHNDB_PCI_UNLOCK(sc);
1264
1265 return (0);
1266 }
1267
1268 /**
1269 * Using the generic PCI bridge hardware configuration, allocate, initialize
1270 * and return a new bhndb_pci probe state instance.
1271 *
1272 * On success, the caller assumes ownership of the returned probe instance, and
1273 * is responsible for releasing this reference using bhndb_pci_probe_free().
1274 *
1275 * @param[out] probe On success, the newly allocated probe instance.
1276 * @param dev The bhndb_pci bridge device.
1277 * @param hostb_devclass The expected device class of the bridge core.
1278 *
1279 * @retval 0 success
1280 * @retval non-zero if allocating the probe state fails, a regular
1281 * unix error code will be returned.
1282 *
1283 * @note This function requires exclusive ownership over allocating and
1284 * configuring host bridge resources, and should only be called prior to
1285 * completion of device attach and full configuration of the bridge.
1286 */
1287 static int
bhndb_pci_probe_alloc(struct bhndb_pci_probe ** probe,device_t dev,bhnd_devclass_t hostb_devclass)1288 bhndb_pci_probe_alloc(struct bhndb_pci_probe **probe, device_t dev,
1289 bhnd_devclass_t hostb_devclass)
1290 {
1291 struct bhndb_pci_probe *p;
1292 struct bhnd_erom_io *eio;
1293 const struct bhndb_hwcfg *hwcfg;
1294 const struct bhnd_chipid *hint;
1295 device_t parent_dev;
1296 int error;
1297
1298 parent_dev = device_get_parent(dev);
1299 eio = NULL;
1300
1301 p = malloc(sizeof(*p), M_BHND, M_ZERO|M_WAITOK);
1302 p->dev = dev;
1303 p->pci_dev = parent_dev;
1304
1305 /* Our register window mapping state must be initialized at this point,
1306 * as bhndb_pci_eio will begin making calls into
1307 * bhndb_pci_probe_(read|write|get_mapping) */
1308 p->m_win = NULL;
1309 p->m_res = NULL;
1310 p->m_valid = false;
1311
1312 bhndb_pci_eio_init(&p->erom_io, p);
1313 eio = &p->erom_io.eio;
1314
1315 /* Fetch our chipid hint (if any) and generic hardware configuration */
1316 hwcfg = BHNDB_BUS_GET_GENERIC_HWCFG(parent_dev, dev);
1317 hint = BHNDB_BUS_GET_CHIPID(parent_dev, dev);
1318
1319 /* Allocate our host resources */
1320 error = bhndb_alloc_host_resources(&p->hr, dev, parent_dev, hwcfg);
1321 if (error) {
1322 p->hr = NULL;
1323 goto failed;
1324 }
1325
1326 /* Map the first bus core from our bridged bhnd(4) bus */
1327 error = bhnd_erom_io_map(eio, BHND_DEFAULT_CHIPC_ADDR,
1328 BHND_DEFAULT_CORE_SIZE);
1329 if (error)
1330 goto failed;
1331
1332 /* Probe for a usable EROM class, and read the chip identifier */
1333 p->erom_class = bhnd_erom_probe_driver_classes(
1334 device_get_devclass(dev), eio, hint, &p->cid);
1335 if (p->erom_class == NULL) {
1336 device_printf(dev, "device enumeration unsupported; no "
1337 "compatible driver found\n");
1338
1339 error = ENXIO;
1340 goto failed;
1341 }
1342
1343 /* Allocate EROM parser */
1344 p->erom = bhnd_erom_alloc(p->erom_class, &p->cid, eio);
1345 if (p->erom == NULL) {
1346 device_printf(dev, "failed to allocate device enumeration "
1347 "table parser\n");
1348 error = ENXIO;
1349 goto failed;
1350 }
1351
1352 /* The EROM I/O instance is now owned by our EROM parser */
1353 eio = NULL;
1354
1355 /* Read the full core table */
1356 error = bhnd_erom_get_core_table(p->erom, &p->cores, &p->ncores);
1357 if (error) {
1358 device_printf(p->dev, "error fetching core table: %d\n",
1359 error);
1360
1361 p->cores = NULL;
1362 goto failed;
1363 }
1364
1365 /* Identify the host bridge core */
1366 error = bhndb_find_hostb_core(p->cores, p->ncores, hostb_devclass,
1367 &p->hostb_core);
1368 if (error) {
1369 device_printf(dev, "failed to identify the host bridge "
1370 "core: %d\n", error);
1371
1372 goto failed;
1373 }
1374
1375 *probe = p;
1376 return (0);
1377
1378 failed:
1379 if (eio != NULL) {
1380 KASSERT(p->erom == NULL, ("I/O instance will be freed by "
1381 "its owning parser"));
1382
1383 bhnd_erom_io_fini(eio);
1384 }
1385
1386 if (p->erom != NULL) {
1387 if (p->cores != NULL)
1388 bhnd_erom_free_core_table(p->erom, p->cores);
1389
1390 bhnd_erom_free(p->erom);
1391 } else {
1392 KASSERT(p->cores == NULL, ("cannot free erom-owned core table "
1393 "without erom reference"));
1394 }
1395
1396 if (p->hr != NULL)
1397 bhndb_release_host_resources(p->hr);
1398
1399 free(p, M_BHND);
1400
1401 return (error);
1402 }
1403
1404 /**
1405 * Free the given @p probe instance and any associated host bridge resources.
1406 */
1407 static void
bhndb_pci_probe_free(struct bhndb_pci_probe * probe)1408 bhndb_pci_probe_free(struct bhndb_pci_probe *probe)
1409 {
1410 bhnd_erom_free_core_table(probe->erom, probe->cores);
1411 bhnd_erom_free(probe->erom);
1412 bhndb_release_host_resources(probe->hr);
1413 free(probe, M_BHND);
1414 }
1415
1416 /**
1417 * Return a copy of probed core table from @p probe.
1418 *
1419 * @param probe The probe instance.
1420 * @param[out] cores On success, a copy of the probed core table. The
1421 * caller is responsible for freeing this table
1422 * bhndb_pci_probe_free_core_table().
1423 * @param[out] ncores On success, the number of cores found in
1424 * @p cores.
1425 *
1426 * @retval 0 success
1427 * @retval non-zero if enumerating the bridged bhnd(4) bus fails, a regular
1428 * unix error code will be returned.
1429 */
1430 static int
bhndb_pci_probe_copy_core_table(struct bhndb_pci_probe * probe,struct bhnd_core_info ** cores,u_int * ncores)1431 bhndb_pci_probe_copy_core_table(struct bhndb_pci_probe *probe,
1432 struct bhnd_core_info **cores, u_int *ncores)
1433 {
1434 size_t len = sizeof(**cores) * probe->ncores;
1435
1436 *cores = malloc(len, M_BHND, M_WAITOK);
1437 memcpy(*cores, probe->cores, len);
1438
1439 *ncores = probe->ncores;
1440
1441 return (0);
1442 }
1443
1444 /**
1445 * Free a core table previously returned by bhndb_pci_probe_copy_core_table().
1446 *
1447 * @param cores The core table to be freed.
1448 */
1449 static void
bhndb_pci_probe_free_core_table(struct bhnd_core_info * cores)1450 bhndb_pci_probe_free_core_table(struct bhnd_core_info *cores)
1451 {
1452 free(cores, M_BHND);
1453 }
1454
1455 /**
1456 * Return true if @p addr and @p size are mapped by the dynamic register window
1457 * backing @p probe.
1458 */
1459 static bool
bhndb_pci_probe_has_mapping(struct bhndb_pci_probe * probe,bhnd_addr_t addr,bhnd_size_t size)1460 bhndb_pci_probe_has_mapping(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1461 bhnd_size_t size)
1462 {
1463 if (!probe->m_valid)
1464 return (false);
1465
1466 KASSERT(probe->m_win != NULL, ("missing register window"));
1467 KASSERT(probe->m_res != NULL, ("missing regwin resource"));
1468 KASSERT(probe->m_win->win_type == BHNDB_REGWIN_T_DYN,
1469 ("unexpected window type %d", probe->m_win->win_type));
1470
1471 if (addr < probe->m_target)
1472 return (false);
1473
1474 if (addr >= probe->m_target + probe->m_win->win_size)
1475 return (false);
1476
1477 if ((probe->m_target + probe->m_win->win_size) - addr < size)
1478 return (false);
1479
1480 return (true);
1481 }
1482
1483 /**
1484 * Attempt to adjust the dynamic register window backing @p probe to permit
1485 * accessing @p size bytes at @p addr.
1486 *
1487 * @param probe The bhndb_pci probe state to be modified.
1488 * @param addr The address at which @p size bytes will mapped.
1489 * @param size The number of bytes to be mapped.
1490 * @param[out] res On success, will be set to the host resource
1491 * mapping @p size bytes at @p addr.
1492 * @param[out] res_offset On success, will be set to the offset of @addr
1493 * within @p res.
1494 *
1495 * @retval 0 success
1496 * @retval non-zero if an error occurs adjusting the backing dynamic
1497 * register window.
1498 */
1499 static int
bhndb_pci_probe_map(struct bhndb_pci_probe * probe,bhnd_addr_t addr,bhnd_size_t offset,bhnd_size_t size,struct resource ** res,bus_size_t * res_offset)1500 bhndb_pci_probe_map(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1501 bhnd_size_t offset, bhnd_size_t size, struct resource **res,
1502 bus_size_t *res_offset)
1503 {
1504 const struct bhndb_regwin *regwin, *regwin_table;
1505 struct resource *regwin_res;
1506 bhnd_addr_t target;
1507 int error;
1508
1509 /* Determine the absolute address */
1510 if (BHND_SIZE_MAX - offset < addr) {
1511 device_printf(probe->dev, "invalid offset %#jx+%#jx\n", addr,
1512 offset);
1513 return (ENXIO);
1514 }
1515
1516 addr += offset;
1517
1518 /* Can we use the existing mapping? */
1519 if (bhndb_pci_probe_has_mapping(probe, addr, size)) {
1520 *res = probe->m_res;
1521 *res_offset = (addr - probe->m_target) +
1522 probe->m_win->win_offset;
1523
1524 return (0);
1525 }
1526
1527 /* Locate a useable dynamic register window */
1528 regwin_table = probe->hr->cfg->register_windows;
1529 regwin = bhndb_regwin_find_type(regwin_table,
1530 BHNDB_REGWIN_T_DYN, size);
1531 if (regwin == NULL) {
1532 device_printf(probe->dev, "unable to map %#jx+%#jx; no "
1533 "usable dynamic register window found\n", addr,
1534 size);
1535 return (ENXIO);
1536 }
1537
1538 /* Locate the host resource mapping our register window */
1539 regwin_res = bhndb_host_resource_for_regwin(probe->hr, regwin);
1540 if (regwin_res == NULL) {
1541 device_printf(probe->dev, "unable to map %#jx+%#jx; no "
1542 "usable register resource found\n", addr, size);
1543 return (ENXIO);
1544 }
1545
1546 /* Page-align the target address */
1547 target = addr - (addr % regwin->win_size);
1548
1549 /* Configure the register window */
1550 error = bhndb_pci_compat_setregwin(probe->dev, probe->pci_dev,
1551 regwin, target);
1552 if (error) {
1553 device_printf(probe->dev, "failed to configure dynamic "
1554 "register window: %d\n", error);
1555 return (error);
1556 }
1557
1558 /* Update our mapping state */
1559 probe->m_win = regwin;
1560 probe->m_res = regwin_res;
1561 probe->m_addr = addr;
1562 probe->m_size = size;
1563 probe->m_target = target;
1564 probe->m_valid = true;
1565
1566 *res = regwin_res;
1567 *res_offset = (addr - target) + regwin->win_offset;
1568
1569 return (0);
1570 }
1571
1572 /**
1573 * Write a data item to the bridged address space at the given @p offset from
1574 * @p addr.
1575 *
1576 * A dynamic register window will be used to map @p addr.
1577 *
1578 * @param probe The bhndb_pci probe state to be used to perform the
1579 * write.
1580 * @param addr The base address.
1581 * @param offset The offset from @p addr at which @p value will be
1582 * written.
1583 * @param value The data item to be written.
1584 * @param width The data item width (1, 2, or 4 bytes).
1585 */
1586 static void
bhndb_pci_probe_write(struct bhndb_pci_probe * probe,bhnd_addr_t addr,bhnd_size_t offset,uint32_t value,u_int width)1587 bhndb_pci_probe_write(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1588 bhnd_size_t offset, uint32_t value, u_int width)
1589 {
1590 struct resource *r;
1591 bus_size_t res_offset;
1592 int error;
1593
1594 /* Map the target address */
1595 error = bhndb_pci_probe_map(probe, addr, offset, width, &r,
1596 &res_offset);
1597 if (error) {
1598 device_printf(probe->dev, "error mapping %#jx+%#jx for "
1599 "writing: %d\n", addr, offset, error);
1600 return;
1601 }
1602
1603 /* Perform write */
1604 switch (width) {
1605 case 1:
1606 return (bus_write_1(r, res_offset, value));
1607 case 2:
1608 return (bus_write_2(r, res_offset, value));
1609 case 4:
1610 return (bus_write_4(r, res_offset, value));
1611 default:
1612 panic("unsupported width: %u", width);
1613 }
1614 }
1615
1616 /**
1617 * Read a data item from the bridged address space at the given @p offset
1618 * from @p addr.
1619 *
1620 * A dynamic register window will be used to map @p addr.
1621 *
1622 * @param probe The bhndb_pci probe state to be used to perform the
1623 * read.
1624 * @param addr The base address.
1625 * @param offset The offset from @p addr at which to read a data item of
1626 * @p width bytes.
1627 * @param width Item width (1, 2, or 4 bytes).
1628 */
1629 static uint32_t
bhndb_pci_probe_read(struct bhndb_pci_probe * probe,bhnd_addr_t addr,bhnd_size_t offset,u_int width)1630 bhndb_pci_probe_read(struct bhndb_pci_probe *probe, bhnd_addr_t addr,
1631 bhnd_size_t offset, u_int width)
1632 {
1633 struct resource *r;
1634 bus_size_t res_offset;
1635 int error;
1636
1637 /* Map the target address */
1638 error = bhndb_pci_probe_map(probe, addr, offset, width, &r,
1639 &res_offset);
1640 if (error) {
1641 device_printf(probe->dev, "error mapping %#jx+%#jx for "
1642 "reading: %d\n", addr, offset, error);
1643 return (UINT32_MAX);
1644 }
1645
1646 /* Perform read */
1647 switch (width) {
1648 case 1:
1649 return (bus_read_1(r, res_offset));
1650 case 2:
1651 return (bus_read_2(r, res_offset));
1652 case 4:
1653 return (bus_read_4(r, res_offset));
1654 default:
1655 panic("unsupported width: %u", width);
1656 }
1657 }
1658
1659 /**
1660 * Initialize a new bhndb PCI bridge EROM I/O instance. All I/O will be
1661 * performed using @p probe.
1662 *
1663 * @param pio The instance to be initialized.
1664 * @param probe The bhndb_pci probe state to be used to perform all
1665 * I/O.
1666 */
1667 static void
bhndb_pci_eio_init(struct bhndb_pci_eio * pio,struct bhndb_pci_probe * probe)1668 bhndb_pci_eio_init(struct bhndb_pci_eio *pio, struct bhndb_pci_probe *probe)
1669 {
1670 memset(pio, 0, sizeof(*pio));
1671
1672 pio->eio.map = bhndb_pci_eio_map;
1673 pio->eio.tell = bhndb_pci_eio_tell;
1674 pio->eio.read = bhndb_pci_eio_read;
1675 pio->eio.fini = NULL;
1676
1677 pio->mapped = false;
1678 pio->addr = 0;
1679 pio->size = 0;
1680 pio->probe = probe;
1681 }
1682
1683 /* bhnd_erom_io_map() implementation */
1684 static int
bhndb_pci_eio_map(struct bhnd_erom_io * eio,bhnd_addr_t addr,bhnd_size_t size)1685 bhndb_pci_eio_map(struct bhnd_erom_io *eio, bhnd_addr_t addr,
1686 bhnd_size_t size)
1687 {
1688 struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1689
1690 if (BHND_ADDR_MAX - addr < size)
1691 return (EINVAL); /* addr+size would overflow */
1692
1693 pio->addr = addr;
1694 pio->size = size;
1695 pio->mapped = true;
1696
1697 return (0);
1698 }
1699
1700 /* bhnd_erom_io_tell() implementation */
1701 static int
bhndb_pci_eio_tell(struct bhnd_erom_io * eio,bhnd_addr_t * addr,bhnd_size_t * size)1702 bhndb_pci_eio_tell(struct bhnd_erom_io *eio, bhnd_addr_t *addr,
1703 bhnd_size_t *size)
1704 {
1705 struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1706
1707 if (!pio->mapped)
1708 return (ENXIO);
1709
1710 *addr = pio->addr;
1711 *size = pio->size;
1712
1713 return (0);
1714 }
1715
1716 /* bhnd_erom_io_read() implementation */
1717 static uint32_t
bhndb_pci_eio_read(struct bhnd_erom_io * eio,bhnd_size_t offset,u_int width)1718 bhndb_pci_eio_read(struct bhnd_erom_io *eio, bhnd_size_t offset, u_int width)
1719 {
1720 struct bhndb_pci_eio *pio = (struct bhndb_pci_eio *)eio;
1721
1722 /* Must have a valid mapping */
1723 if (!pio->mapped)
1724 panic("no active mapping");
1725
1726 /* The requested subrange must fall within the existing mapped range */
1727 if (offset > pio->size ||
1728 width > pio->size ||
1729 pio->size - offset < width)
1730 {
1731 panic("invalid offset %#jx", offset);
1732 }
1733
1734 return (bhndb_pci_probe_read(pio->probe, pio->addr, offset, width));
1735 }
1736
1737 static device_method_t bhndb_pci_methods[] = {
1738 /* Device interface */
1739 DEVMETHOD(device_probe, bhndb_pci_probe),
1740 DEVMETHOD(device_attach, bhndb_pci_attach),
1741 DEVMETHOD(device_resume, bhndb_pci_resume),
1742 DEVMETHOD(device_suspend, bhndb_pci_suspend),
1743 DEVMETHOD(device_detach, bhndb_pci_detach),
1744
1745 /* BHNDB interface */
1746 DEVMETHOD(bhndb_set_window_addr, bhndb_pci_set_window_addr),
1747 DEVMETHOD(bhndb_populate_board_info, bhndb_pci_populate_board_info),
1748 DEVMETHOD(bhndb_map_intr_isrc, bhndb_pci_map_intr_isrc),
1749 DEVMETHOD(bhndb_route_interrupts, bhndb_pci_route_interrupts),
1750
1751 /* BHND PWRCTL hostb interface */
1752 DEVMETHOD(bhnd_pwrctl_hostb_get_clksrc, bhndb_pci_pwrctl_get_clksrc),
1753 DEVMETHOD(bhnd_pwrctl_hostb_gate_clock, bhndb_pci_pwrctl_gate_clock),
1754 DEVMETHOD(bhnd_pwrctl_hostb_ungate_clock, bhndb_pci_pwrctl_ungate_clock),
1755
1756 DEVMETHOD_END
1757 };
1758
1759 DEFINE_CLASS_1(bhndb, bhndb_pci_driver, bhndb_pci_methods,
1760 sizeof(struct bhndb_pci_softc), bhndb_driver);
1761
1762 MODULE_VERSION(bhndb_pci, 1);
1763 MODULE_DEPEND(bhndb_pci, bhnd_pci_hostb, 1, 1, 1);
1764 MODULE_DEPEND(bhndb_pci, pci, 1, 1, 1);
1765 MODULE_DEPEND(bhndb_pci, bhndb, 1, 1, 1);
1766 MODULE_DEPEND(bhndb_pci, bhnd, 1, 1, 1);
1767