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"
53 #define debugf(fmt, args...) do { printf("%s(): ", __func__); \
54 printf(fmt,##args); } while (0)
56 #define debugf(fmt, args...)
59 #define FDT_RANGES_CELLS ((3 + 3 + 2) * 2)
62 fdt_pci_range_dump(struct fdt_pci_range *range)
66 printf(" base_pci = 0x%08lx\n", range->base_pci);
67 printf(" base_par = 0x%08lx\n", range->base_parent);
68 printf(" len = 0x%08lx\n", range->len);
73 fdt_pci_ranges_decode(phandle_t node, struct fdt_pci_range *io_space,
74 struct fdt_pci_range *mem_space)
76 pcell_t ranges[FDT_RANGES_CELLS];
77 struct fdt_pci_range *pci_space;
78 pcell_t addr_cells, size_cells, par_addr_cells;
80 pcell_t cell0, cell1, cell2;
81 int tuple_size, tuples, i, rv, offset_cells, len;
84 * Retrieve 'ranges' property.
86 if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
88 if (addr_cells != 3 || size_cells != 2)
91 par_addr_cells = fdt_parent_addr_cells(node);
92 if (par_addr_cells > 3)
95 len = OF_getproplen(node, "ranges");
96 if (len > sizeof(ranges))
99 if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
102 tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
104 tuples = len / tuple_size;
106 rangesptr = &ranges[0];
108 for (i = 0; i < tuples; i++) {
109 cell0 = fdt_data_get((void *)rangesptr, 1);
111 cell1 = fdt_data_get((void *)rangesptr, 1);
113 cell2 = fdt_data_get((void *)rangesptr, 1);
116 if (cell0 & 0x02000000) {
117 pci_space = mem_space;
118 } else if (cell0 & 0x01000000) {
119 pci_space = io_space;
125 if (par_addr_cells == 3) {
127 * This is a PCI subnode 'ranges'. Skip cell0 and
128 * cell1 of this entry and only use cell2.
131 rangesptr += offset_cells;
134 if (fdt_data_verify((void *)rangesptr, par_addr_cells -
139 pci_space->base_parent = fdt_data_get((void *)rangesptr,
140 par_addr_cells - offset_cells);
141 rangesptr += par_addr_cells - offset_cells;
143 if (fdt_data_verify((void *)rangesptr, size_cells)) {
147 pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
148 rangesptr += size_cells;
150 pci_space->base_pci = cell2;
158 fdt_pci_ranges(phandle_t node, struct fdt_pci_range *io_space,
159 struct fdt_pci_range *mem_space)
163 debugf("Processing PCI node: %x\n", node);
164 if ((err = fdt_pci_ranges_decode(node, io_space, mem_space)) != 0) {
165 debugf("could not decode parent PCI node 'ranges'\n");
169 debugf("Post fixup dump:\n");
170 fdt_pci_range_dump(io_space);
171 fdt_pci_range_dump(mem_space);
176 fdt_addr_cells(phandle_t node, int *addr_cells)
181 cell_size = sizeof(cell);
182 if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
184 *addr_cells = fdt32_to_cpu((int)cell);
192 fdt_interrupt_cells(phandle_t node)
196 if (OF_getprop(node, "#interrupt-cells", &intr_cells,
197 sizeof(intr_cells)) <= 0) {
198 debugf("no intr-cells defined, defaulting to 1\n");
201 intr_cells = fdt32_to_cpu(intr_cells);
203 return ((int)intr_cells);
207 fdt_pci_intr_info(phandle_t node, struct fdt_pci_intr *intr_info)
213 error = fdt_addr_cells(node, &acells);
217 icells = fdt_interrupt_cells(node);
220 * Retrieve the interrupt map and mask properties.
222 len = OF_getprop_alloc(node, "interrupt-map-mask", 1, &mask);
223 if (len / sizeof(pcell_t) != (acells + icells)) {
224 debugf("bad mask len = %d\n", len);
228 len = OF_getprop_alloc(node, "interrupt-map", 1, &map);
230 debugf("bad map len = %d\n", len);
234 intr_info->map_len = len;
235 intr_info->map = map;
236 intr_info->mask = mask;
237 intr_info->addr_cells = acells;
238 intr_info->intr_cells = icells;
240 debugf("acells=%u, icells=%u, map_len=%u\n", acells, icells, len);
244 free(mask, M_OFWPROP);
249 fdt_pci_route_intr(int bus, int slot, int func, int pin,
250 struct fdt_pci_intr *intr_info, int *interrupt)
252 pcell_t child_spec[4], masked[4];
258 int par_intr_cells, par_addr_cells, child_spec_cells, row_cells;
259 int par_idx, spec_idx, err, trig, pol;
261 child_spec_cells = intr_info->addr_cells + intr_info->intr_cells;
262 if (child_spec_cells > sizeof(child_spec) / sizeof(pcell_t))
265 addr = (bus << 16) | (slot << 11) | (func << 8);
266 child_spec[0] = addr;
271 map_len = intr_info->map_len;
272 map_ptr = intr_info->map;
274 par_idx = child_spec_cells;
276 while (i < map_len) {
277 iph = fdt32_to_cpu(map_ptr[par_idx]);
278 intr_par = OF_instance_to_package(iph);
280 err = fdt_addr_cells(intr_par, &par_addr_cells);
282 debugf("could not retrieve intr parent #addr-cells\n");
285 par_intr_cells = fdt_interrupt_cells(intr_par);
287 row_cells = child_spec_cells + 1 + par_addr_cells +
291 * Apply mask and look up the entry in interrupt map.
293 for (j = 0; j < child_spec_cells; j++) {
294 masked[j] = child_spec[j] &
295 fdt32_to_cpu(intr_info->mask[j]);
297 if (masked[j] != fdt32_to_cpu(map_ptr[j]))
302 * Decode interrupt of the parent intr controller.
304 spec_idx = child_spec_cells + 1 + par_addr_cells;
305 err = fdt_intr_decode(intr_par, &map_ptr[spec_idx],
306 interrupt, &trig, &pol);
308 debugf("could not decode interrupt\n");
311 debugf("decoded intr = %d, trig = %d, pol = %d\n", *interrupt,
314 #if defined(__powerpc__)
315 powerpc_config_intr(FDT_MAP_IRQ(intr_par, *interrupt), trig,
321 map_ptr += row_cells;
322 i += (row_cells * sizeof(pcell_t));
330 fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va,
333 struct fdt_pci_range io_space, mem_space;
336 if ((error = fdt_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
339 devmap->pd_va = io_va;
340 devmap->pd_pa = io_space.base_parent;
341 devmap->pd_size = io_space.len;
342 devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
343 devmap->pd_cache = PTE_NOCACHE;
346 devmap->pd_va = mem_va;
347 devmap->pd_pa = mem_space.base_parent;
348 devmap->pd_size = mem_space.len;
349 devmap->pd_prot = VM_PROT_READ | VM_PROT_WRITE;
350 devmap->pd_cache = PTE_NOCACHE;
357 fdt_pci_config_bar(device_t dev, int bus, int slot, int func, int bar)
362 fdt_pci_config_normal(device_t dev, int bus, int slot, int func)
365 uint8_t command, intline, intpin;
367 command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
368 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
369 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
371 /* Program the base address registers. */
373 while (bar <= PCIR_MAX_BAR_0)
374 bar += fdt_pci_config_bar(dev, bus, slot, func, bar);
376 /* Perform interrupt routing. */
377 intpin = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_INTPIN, 1);
378 intline = fsl_pcib_route_int(dev, bus, slot, func, intpin);
379 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_INTLINE, intline, 1);
381 command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
382 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
386 fdt_pci_config_bridge(device_t dev, int bus, int secbus, int slot, int func)
391 command = PCIB_READ_CONFIG(dev, bus, slot, func, PCIR_COMMAND, 1);
392 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN);
393 PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
395 /* Program the base address registers. */
396 maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6;
399 bar += fsl_pcib_init_bar(sc, bus, slot, func,
402 /* Perform interrupt routing. */
403 intpin = fsl_pcib_read_config(sc->sc_dev, bus, slot,
404 func, PCIR_INTPIN, 1);
405 intline = fsl_pcib_route_int(sc, bus, slot, func,
407 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
408 PCIR_INTLINE, intline, 1);
410 command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
411 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
412 PCIR_COMMAND, command, 1);
415 * Handle PCI-PCI bridges
417 class = fsl_pcib_read_config(sc->sc_dev, bus, slot,
418 func, PCIR_CLASS, 1);
419 subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot,
420 func, PCIR_SUBCLASS, 1);
422 /* Allow only proper PCI-PCI briges */
423 if (class != PCIC_BRIDGE)
425 if (subclass != PCIS_BRIDGE_PCI)
430 /* Program I/O decoder. */
431 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
432 PCIR_IOBASEL_1, sc->sc_ioport.rm_start >> 8, 1);
433 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
434 PCIR_IOLIMITL_1, sc->sc_ioport.rm_end >> 8, 1);
435 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
436 PCIR_IOBASEH_1, sc->sc_ioport.rm_start >> 16, 2);
437 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
438 PCIR_IOLIMITH_1, sc->sc_ioport.rm_end >> 16, 2);
440 /* Program (non-prefetchable) memory decoder. */
441 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
442 PCIR_MEMBASE_1, sc->sc_iomem.rm_start >> 16, 2);
443 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
444 PCIR_MEMLIMIT_1, sc->sc_iomem.rm_end >> 16, 2);
446 /* Program prefetchable memory decoder. */
447 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
448 PCIR_PMBASEL_1, 0x0010, 2);
449 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
450 PCIR_PMLIMITL_1, 0x000f, 2);
451 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
452 PCIR_PMBASEH_1, 0x00000000, 4);
453 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
454 PCIR_PMLIMITH_1, 0x00000000, 4);
456 /* Read currect bus register configuration */
457 old_pribus = fsl_pcib_read_config(sc->sc_dev, bus,
458 slot, func, PCIR_PRIBUS_1, 1);
459 old_secbus = fsl_pcib_read_config(sc->sc_dev, bus,
460 slot, func, PCIR_SECBUS_1, 1);
461 old_subbus = fsl_pcib_read_config(sc->sc_dev, bus,
462 slot, func, PCIR_SUBBUS_1, 1);
465 printf("PCI: reading firmware bus numbers for "
466 "secbus = %d (bus/sec/sub) = (%d/%d/%d)\n",
467 secbus, old_pribus, old_secbus, old_subbus);
472 secbus = fsl_pcib_init(sc, secbus,
473 (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
478 printf("PCI: translate firmware bus numbers "
479 "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n",
480 secbus, old_pribus, old_secbus, old_subbus,
481 new_pribus, new_secbus, new_subbus);
483 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
484 PCIR_PRIBUS_1, new_pribus, 1);
485 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
486 PCIR_SECBUS_1, new_secbus, 1);
487 fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
488 PCIR_SUBBUS_1, new_subbus, 1);
493 fdt_pci_config_slot(device_t dev, int bus, int secbus, int slot)
500 for (func = 0; func <= maxfunc; func++) {
501 hdrtype = PCIB_READ_CONFIG(dev, bus, slot, func,
503 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
505 if (func == 0 && (hdrtype & PCIM_MFDEV))
506 maxfunc = PCI_FUNCMAX;
508 vendor = PCIB_READ_CONFIG(dev, bus, slot, func,
510 if (vendor == 0xffff)
513 if ((hdrtype & PCIM_HDRTYPE) == PCIM_HDRTYPE_NORMAL)
514 fdt_pci_config_normal(dev, bus, slot, func);
516 secbus = fdt_pci_config_bridge(dev, bus, secbus,
524 fdt_pci_config_bus(device_t dev, int bus, int maxslot)
526 int func, maxfunc, secbus, slot;
529 for (slot = 0; slot <= maxslot; slot++)
530 secbus = fdt_pci_config_slot(dev, bus, secbus, slot);
536 fdt_pci_config_domain(device_t dev)
538 pcell_t bus_range[2];
540 int bus, error, maxslot;
542 root = ofw_bus_get_node(dev);
545 if (!fdt_is_type(root, "pci"))
549 * Determine the bus number of the root in this domain.
550 * Lacking any information, this will be bus 0.
551 * Write the bus number to the bus device, using the IVAR.
553 if ((OF_getprop(root, "bus-range", bus_range, sizeof(bus_range)) <= 0)
556 bus = fdt32_to_cpu(bus_range[0]);
558 error = BUS_WRITE_IVAR(dev, NULL, PCIB_IVAR_BUS, bus);
562 /* Get the maximum slot number for bus-enumeration. */
563 maxslot = PCIB_MAXSLOTS(dev);
565 bus = fdt_pci_config_bus(dev, bus, maxslot);