2 * Copyright (c) 2010 The FreeBSD Foundation
5 * This software was developed by Semihalf under sponsorship from
6 * the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/kernel.h>
39 #include <sys/malloc.h>
41 #include <dev/fdt/fdt_common.h>
42 #include <dev/pci/pcireg.h>
44 #include <machine/fdt.h>
46 #include "ofw_bus_if.h"
50 #define debugf(fmt, args...) do { printf("%s(): ", __func__); \
51 printf(fmt,##args); } while (0)
53 #define debugf(fmt, args...)
56 #define FDT_RANGES_CELLS ((3 + 3 + 2) * 2)
59 fdt_pci_range_dump(struct fdt_pci_range *range)
63 printf(" base_pci = 0x%08lx\n", range->base_pci);
64 printf(" base_par = 0x%08lx\n", range->base_parent);
65 printf(" len = 0x%08lx\n", range->len);
70 fdt_pci_ranges_decode(phandle_t node, struct fdt_pci_range *io_space,
71 struct fdt_pci_range *mem_space)
73 pcell_t ranges[FDT_RANGES_CELLS];
74 struct fdt_pci_range *pci_space;
75 pcell_t addr_cells, size_cells, par_addr_cells;
77 pcell_t cell0, cell1, cell2;
78 int tuple_size, tuples, i, rv, offset_cells, len;
81 * Retrieve 'ranges' property.
83 if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
85 if (addr_cells != 3 || size_cells != 2)
88 par_addr_cells = fdt_parent_addr_cells(node);
89 if (par_addr_cells > 3)
92 len = OF_getproplen(node, "ranges");
93 if (len > sizeof(ranges))
96 if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
99 tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
101 tuples = len / tuple_size;
104 * Initialize the ranges so that we don't have to worry about
105 * having them all defined in the FDT. In particular, it is
106 * perfectly fine not to want I/O space on PCI busses.
108 bzero(io_space, sizeof(*io_space));
109 bzero(mem_space, sizeof(*mem_space));
111 rangesptr = &ranges[0];
113 for (i = 0; i < tuples; i++) {
114 cell0 = fdt_data_get((void *)rangesptr, 1);
116 cell1 = fdt_data_get((void *)rangesptr, 1);
118 cell2 = fdt_data_get((void *)rangesptr, 1);
121 if (cell0 & 0x02000000) {
122 pci_space = mem_space;
123 } else if (cell0 & 0x01000000) {
124 pci_space = io_space;
130 if (par_addr_cells == 3) {
132 * This is a PCI subnode 'ranges'. Skip cell0 and
133 * cell1 of this entry and only use cell2.
136 rangesptr += offset_cells;
139 if (fdt_data_verify((void *)rangesptr, par_addr_cells -
144 pci_space->base_parent = fdt_data_get((void *)rangesptr,
145 par_addr_cells - offset_cells);
146 rangesptr += par_addr_cells - offset_cells;
148 if (fdt_data_verify((void *)rangesptr, size_cells)) {
152 pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
153 rangesptr += size_cells;
155 pci_space->base_pci = cell2;
163 fdt_pci_ranges(phandle_t node, struct fdt_pci_range *io_space,
164 struct fdt_pci_range *mem_space)
168 debugf("Processing PCI node: %x\n", node);
169 if ((err = fdt_pci_ranges_decode(node, io_space, mem_space)) != 0) {
170 debugf("could not decode parent PCI node 'ranges'\n");
174 debugf("Post fixup dump:\n");
175 fdt_pci_range_dump(io_space);
176 fdt_pci_range_dump(mem_space);
181 fdt_addr_cells(phandle_t node, int *addr_cells)
186 cell_size = sizeof(cell);
187 if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
189 *addr_cells = fdt32_to_cpu((int)cell);
197 fdt_interrupt_cells(phandle_t node)
201 if (OF_getprop(node, "#interrupt-cells", &intr_cells,
202 sizeof(intr_cells)) <= 0) {
203 debugf("no intr-cells defined, defaulting to 1\n");
206 intr_cells = fdt32_to_cpu(intr_cells);
208 return ((int)intr_cells);
212 fdt_pci_intr_info(phandle_t node, struct fdt_pci_intr *intr_info)
218 error = fdt_addr_cells(node, &acells);
222 icells = fdt_interrupt_cells(node);
225 * Retrieve the interrupt map and mask properties.
227 len = OF_getprop_alloc(node, "interrupt-map-mask", 1, &mask);
228 if (len / sizeof(pcell_t) != (acells + icells)) {
229 debugf("bad mask len = %d\n", len);
233 len = OF_getprop_alloc(node, "interrupt-map", 1, &map);
235 debugf("bad map len = %d\n", len);
239 intr_info->map_len = len;
240 intr_info->map = map;
241 intr_info->mask = mask;
242 intr_info->addr_cells = acells;
243 intr_info->intr_cells = icells;
245 debugf("acells=%u, icells=%u, map_len=%u\n", acells, icells, len);
249 free(mask, M_OFWPROP);
254 fdt_pci_route_intr(int bus, int slot, int func, int pin,
255 struct fdt_pci_intr *intr_info, int *interrupt)
257 pcell_t child_spec[4], masked[4];
263 int par_intr_cells, par_addr_cells, child_spec_cells, row_cells;
264 int par_idx, spec_idx, err, trig, pol;
266 child_spec_cells = intr_info->addr_cells + intr_info->intr_cells;
267 if (child_spec_cells > sizeof(child_spec) / sizeof(pcell_t))
270 addr = (bus << 16) | (slot << 11) | (func << 8);
271 child_spec[0] = addr;
276 map_len = intr_info->map_len;
277 map_ptr = intr_info->map;
279 par_idx = child_spec_cells;
281 while (i < map_len) {
282 iph = fdt32_to_cpu(map_ptr[par_idx]);
283 intr_par = OF_instance_to_package(iph);
285 err = fdt_addr_cells(intr_par, &par_addr_cells);
287 debugf("could not retrieve intr parent #addr-cells\n");
290 par_intr_cells = fdt_interrupt_cells(intr_par);
292 row_cells = child_spec_cells + 1 + par_addr_cells +
296 * Apply mask and look up the entry in interrupt map.
298 for (j = 0; j < child_spec_cells; j++) {
299 masked[j] = child_spec[j] &
300 fdt32_to_cpu(intr_info->mask[j]);
302 if (masked[j] != fdt32_to_cpu(map_ptr[j]))
307 * Decode interrupt of the parent intr controller.
309 spec_idx = child_spec_cells + 1 + par_addr_cells;
310 err = fdt_intr_decode(intr_par, &map_ptr[spec_idx],
311 interrupt, &trig, &pol);
313 debugf("could not decode interrupt\n");
316 debugf("decoded intr = %d, trig = %d, pol = %d\n", *interrupt,
319 #if defined(__powerpc__)
320 powerpc_config_intr(FDT_MAP_IRQ(intr_par, *interrupt), trig,
326 map_ptr += row_cells;
327 i += (row_cells * sizeof(pcell_t));
335 fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va,
338 struct fdt_pci_range io_space, mem_space;
341 if ((error = fdt_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
344 devmap->pd_va = (io_va ? io_va : io_space.base_parent);
345 devmap->pd_pa = io_space.base_parent;
346 devmap->pd_size = io_space.len;
347 devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
348 devmap->pd_cache = PTE_NOCACHE;
351 devmap->pd_va = (mem_va ? mem_va : mem_space.base_parent);
352 devmap->pd_pa = mem_space.base_parent;
353 devmap->pd_size = mem_space.len;
354 devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
355 devmap->pd_cache = PTE_NOCACHE;
362 fdt_pci_config_bar(device_t dev, int bus, int slot, int func, int bar)
367 fdt_pci_config_normal(device_t dev, int bus, int slot, int func)
370 uint8_t command, intline, intpin;
372 command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
373 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
374 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
376 /* Program the base address registers. */
378 while (bar <= PCIR_MAX_BAR_0)
379 bar += fdt_pci_config_bar(dev, bus, slot, func, bar);
381 /* Perform interrupt routing. */
382 intpin = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_INTPIN, 1);
383 intline = fsl_pcib_route_int(dev, bus, slot, func, intpin);
384 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_INTLINE, intline, 1);
386 command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
387 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
391 fdt_pci_config_bridge(device_t dev, int bus, int secbus, int slot, int func)
396 command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
397 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
398 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
400 /* Program the base address registers. */
401 maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6;
404 bar += fsl_pcib_init_bar(sc, bus, slot, func,
407 /* Perform interrupt routing. */
408 intpin = fsl_pcib_read_config(sc->sc_dev, bus, slot,
409 func, PCIR_INTPIN, 1);
410 intline = fsl_pcib_route_int(sc, bus, slot, func,
412 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
413 PCIR_INTLINE, intline, 1);
415 command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
416 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
417 PCIR_COMMAND, command, 1);
420 * Handle PCI-PCI bridges
422 class = fsl_pcib_read_config(sc->sc_dev, bus, slot,
423 func, PCIR_CLASS, 1);
424 subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot,
425 func, PCIR_SUBCLASS, 1);
427 /* Allow only proper PCI-PCI briges */
428 if (class != PCIC_BRIDGE)
430 if (subclass != PCIS_BRIDGE_PCI)
435 /* Program I/O decoder. */
436 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
437 PCIR_IOBASEL_1, sc->sc_ioport.rm_start >> 8, 1);
438 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
439 PCIR_IOLIMITL_1, sc->sc_ioport.rm_end >> 8, 1);
440 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
441 PCIR_IOBASEH_1, sc->sc_ioport.rm_start >> 16, 2);
442 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
443 PCIR_IOLIMITH_1, sc->sc_ioport.rm_end >> 16, 2);
445 /* Program (non-prefetchable) memory decoder. */
446 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
447 PCIR_MEMBASE_1, sc->sc_iomem.rm_start >> 16, 2);
448 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
449 PCIR_MEMLIMIT_1, sc->sc_iomem.rm_end >> 16, 2);
451 /* Program prefetchable memory decoder. */
452 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
453 PCIR_PMBASEL_1, 0x0010, 2);
454 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
455 PCIR_PMLIMITL_1, 0x000f, 2);
456 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
457 PCIR_PMBASEH_1, 0x00000000, 4);
458 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
459 PCIR_PMLIMITH_1, 0x00000000, 4);
461 /* Read currect bus register configuration */
462 old_pribus = fsl_pcib_read_config(sc->sc_dev, bus,
463 slot, func, PCIR_PRIBUS_1, 1);
464 old_secbus = fsl_pcib_read_config(sc->sc_dev, bus,
465 slot, func, PCIR_SECBUS_1, 1);
466 old_subbus = fsl_pcib_read_config(sc->sc_dev, bus,
467 slot, func, PCIR_SUBBUS_1, 1);
470 printf("PCI: reading firmware bus numbers for "
471 "secbus = %d (bus/sec/sub) = (%d/%d/%d)\n",
472 secbus, old_pribus, old_secbus, old_subbus);
477 secbus = fsl_pcib_init(sc, secbus,
478 (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
483 printf("PCI: translate firmware bus numbers "
484 "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
485 secbus, old_pribus, old_secbus, old_subbus,
486 new_pribus, new_secbus, new_subbus);
488 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
489 PCIR_PRIBUS_1, new_pribus, 1);
490 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
491 PCIR_SECBUS_1, new_secbus, 1);
492 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
493 PCIR_SUBBUS_1, new_subbus, 1);
498 fdt_pci_config_slot(device_t dev, int bus, int secbus, int slot)
505 for (func = 0; func <= maxfunc; func++) {
506 hdrtype = PCIB_READ_CONFIG(dev, bus, slot, func,
508 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
510 if (func == 0 && (hdrtype & PCIM_MFDEV))
511 maxfunc = PCI_FUNCMAX;
513 vendor = PCIB_READ_CONFIG(dev, bus, slot, func,
515 if (vendor == 0xffff)
518 if ((hdrtype & PCIM_HDRTYPE) == PCIM_HDRTYPE_NORMAL)
519 fdt_pci_config_normal(dev, bus, slot, func);
521 secbus = fdt_pci_config_bridge(dev, bus, secbus,
529 fdt_pci_config_bus(device_t dev, int bus, int maxslot)
531 int func, maxfunc, secbus, slot;
534 for (slot = 0; slot <= maxslot; slot++)
535 secbus = fdt_pci_config_slot(dev, bus, secbus, slot);
541 fdt_pci_config_domain(device_t dev)
543 pcell_t bus_range[2];
545 int bus, error, maxslot;
547 root = ofw_bus_get_node(dev);
550 if (!fdt_is_type(root, "pci"))
554 * Determine the bus number of the root in this domain.
555 * Lacking any information, this will be bus 0.
556 * Write the bus number to the bus device, using the IVAR.
558 if ((OF_getprop(root, "bus-range", bus_range, sizeof(bus_range)) <= 0)
561 bus = fdt32_to_cpu(bus_range[0]);
563 error = BUS_WRITE_IVAR(dev, NULL, PCIB_IVAR_BUS, bus);
567 /* Get the maximum slot number for bus-enumeration. */
568 maxslot = PCIB_MAXSLOTS(dev);
570 bus = fdt_pci_config_bus(dev, bus, maxslot);