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