1/*-
2 * Copyright (c) 2010 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Semihalf under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
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.
16 *
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
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD$");
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/ktr.h>
36#include <sys/kernel.h>
37#include <sys/bus.h>
38#include <sys/rman.h>
39#include <sys/malloc.h>
40
41#include <dev/fdt/fdt_common.h>
42#include <dev/pci/pcireg.h>
43
44#include <machine/fdt.h>
45
46#include "ofw_bus_if.h"
47#include "pcib_if.h"
48
49#ifdef DEBUG
50#define debugf(fmt, args...) do { printf("%s(): ", __func__);	\
51    printf(fmt,##args); } while (0)
52#else
53#define debugf(fmt, args...)
54#endif
55
56#define FDT_RANGES_CELLS	((3 + 3 + 2) * 2)
57
58static void
59fdt_pci_range_dump(struct fdt_pci_range *range)
60{
61#ifdef DEBUG
62	printf("\n");
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);
66#endif
67}
68
69int
70fdt_pci_ranges_decode(phandle_t node, struct fdt_pci_range *io_space,
71    struct fdt_pci_range *mem_space)
72{
73	pcell_t ranges[FDT_RANGES_CELLS];
74	struct fdt_pci_range *pci_space;
75	pcell_t addr_cells, size_cells, par_addr_cells;
76	pcell_t *rangesptr;
77	pcell_t cell0, cell1, cell2;
78	int tuple_size, tuples, i, rv, offset_cells, len;
79
80	/*
81	 * Retrieve 'ranges' property.
82	 */
83	if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
84		return (EINVAL);
85	if (addr_cells != 3 || size_cells != 2)
86		return (ERANGE);
87
88	par_addr_cells = fdt_parent_addr_cells(node);
89	if (par_addr_cells > 3)
90		return (ERANGE);
91
92	len = OF_getproplen(node, "ranges");
93	if (len > sizeof(ranges))
94		return (ENOMEM);
95
96	if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
97		return (EINVAL);
98
99	tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells +
100	    size_cells);
101	tuples = len / tuple_size;
102
103	/*
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.
107	 */
108	bzero(io_space, sizeof(*io_space));
109	bzero(mem_space, sizeof(*mem_space));
110
111	rangesptr = &ranges[0];
112	offset_cells = 0;
113	for (i = 0; i < tuples; i++) {
114		cell0 = fdt_data_get((void *)rangesptr, 1);
115		rangesptr++;
116		cell1 = fdt_data_get((void *)rangesptr, 1);
117		rangesptr++;
118		cell2 = fdt_data_get((void *)rangesptr, 1);
119		rangesptr++;
120
121		if (cell0 & 0x02000000) {
122			pci_space = mem_space;
123		} else if (cell0 & 0x01000000) {
124			pci_space = io_space;
125		} else {
126			rv = ERANGE;
127			goto out;
128		}
129
130		if (par_addr_cells == 3) {
131			/*
132			 * This is a PCI subnode 'ranges'. Skip cell0 and
133			 * cell1 of this entry and only use cell2.
134			 */
135			offset_cells = 2;
136			rangesptr += offset_cells;
137		}
138
139		if (fdt_data_verify((void *)rangesptr, par_addr_cells -
140		    offset_cells)) {
141			rv = ERANGE;
142			goto out;
143		}
144		pci_space->base_parent = fdt_data_get((void *)rangesptr,
145		    par_addr_cells - offset_cells);
146		rangesptr += par_addr_cells - offset_cells;
147
148		if (fdt_data_verify((void *)rangesptr, size_cells)) {
149			rv = ERANGE;
150			goto out;
151		}
152		pci_space->len = fdt_data_get((void *)rangesptr, size_cells);
153		rangesptr += size_cells;
154
155		pci_space->base_pci = cell2;
156	}
157	rv = 0;
158out:
159	return (rv);
160}
161
162int
163fdt_pci_ranges(phandle_t node, struct fdt_pci_range *io_space,
164    struct fdt_pci_range *mem_space)
165{
166	int err;
167
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");
171		return (err);
172	}
173
174	debugf("Post fixup dump:\n");
175	fdt_pci_range_dump(io_space);
176	fdt_pci_range_dump(mem_space);
177	return (0);
178}
179
180static int
181fdt_addr_cells(phandle_t node, int *addr_cells)
182{
183	pcell_t cell;
184	int cell_size;
185
186	cell_size = sizeof(cell);
187	if (OF_getprop(node, "#address-cells", &cell, cell_size) < cell_size)
188		return (EINVAL);
189	*addr_cells = fdt32_to_cpu((int)cell);
190
191	if (*addr_cells > 3)
192		return (ERANGE);
193	return (0);
194}
195
196static int
197fdt_interrupt_cells(phandle_t node)
198{
199	pcell_t intr_cells;
200
201	if (OF_getprop(node, "#interrupt-cells", &intr_cells,
202	    sizeof(intr_cells)) <= 0) {
203		debugf("no intr-cells defined, defaulting to 1\n");
204		intr_cells = 1;
205	}
206	intr_cells = fdt32_to_cpu(intr_cells);
207
208	return ((int)intr_cells);
209}
210
211int
212fdt_pci_intr_info(phandle_t node, struct fdt_pci_intr *intr_info)
213{
214	void *map, *mask;
215	int acells, icells;
216	int error, len;
217
218	error = fdt_addr_cells(node, &acells);
219	if (error)
220		return (error);
221
222	icells = fdt_interrupt_cells(node);
223
224	/*
225	 * Retrieve the interrupt map and mask properties.
226	 */
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);
230		goto err;
231	}
232
233	len = OF_getprop_alloc(node, "interrupt-map", 1, &map);
234	if (len <= 0) {
235		debugf("bad map len = %d\n", len);
236		goto err;
237	}
238
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;
244
245	debugf("acells=%u, icells=%u, map_len=%u\n", acells, icells, len);
246	return (0);
247
248err:
249	free(mask, M_OFWPROP);
250	return (ENXIO);
251}
252
253int
254fdt_pci_route_intr(int bus, int slot, int func, int pin,
255    struct fdt_pci_intr *intr_info, int *interrupt)
256{
257	pcell_t child_spec[4], masked[4];
258	ihandle_t iph;
259	pcell_t intr_par;
260	pcell_t *map_ptr;
261	uint32_t addr;
262	int i, j, map_len;
263	int par_intr_cells, par_addr_cells, child_spec_cells, row_cells;
264	int par_idx, spec_idx, err, trig, pol;
265
266	child_spec_cells = intr_info->addr_cells + intr_info->intr_cells;
267	if (child_spec_cells > sizeof(child_spec) / sizeof(pcell_t))
268		return (ENOMEM);
269
270	addr = (bus << 16) | (slot << 11) | (func << 8);
271	child_spec[0] = addr;
272	child_spec[1] = 0;
273	child_spec[2] = 0;
274	child_spec[3] = pin;
275
276	map_len = intr_info->map_len;
277	map_ptr = intr_info->map;
278
279	par_idx = child_spec_cells;
280	i = 0;
281	while (i < map_len) {
282		iph = fdt32_to_cpu(map_ptr[par_idx]);
283		intr_par = OF_instance_to_package(iph);
284
285		err = fdt_addr_cells(intr_par, &par_addr_cells);
286		if (err != 0) {
287			debugf("could not retrieve intr parent #addr-cells\n");
288			return (err);
289		}
290		par_intr_cells = fdt_interrupt_cells(intr_par);
291
292		row_cells = child_spec_cells + 1 + par_addr_cells +
293		    par_intr_cells;
294
295		/*
296		 * Apply mask and look up the entry in interrupt map.
297		 */
298		for (j = 0; j < child_spec_cells; j++) {
299			masked[j] = child_spec[j] &
300			    fdt32_to_cpu(intr_info->mask[j]);
301
302			if (masked[j] != fdt32_to_cpu(map_ptr[j]))
303				goto next;
304		}
305
306		/*
307		 * Decode interrupt of the parent intr controller.
308		 */
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);
312		if (err != 0) {
313			debugf("could not decode interrupt\n");
314			return (err);
315		}
316		debugf("decoded intr = %d, trig = %d, pol = %d\n", *interrupt,
317		    trig, pol);
318
319#if defined(__powerpc__)
320		powerpc_config_intr(FDT_MAP_IRQ(intr_par, *interrupt), trig,
321		    pol);
322#endif
323		return (0);
324
325next:
326		map_ptr += row_cells;
327		i += (row_cells * sizeof(pcell_t));
328	}
329
330	return (ENXIO);
331}
332
333#if defined(__arm__)
334int
335fdt_pci_devmap(phandle_t node, struct pmap_devmap *devmap, vm_offset_t io_va,
336    vm_offset_t mem_va)
337{
338	struct fdt_pci_range io_space, mem_space;
339	int error;
340
341	if ((error = fdt_pci_ranges_decode(node, &io_space, &mem_space)) != 0)
342		return (error);
343
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;
349	devmap++;
350
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;
356	return (0);
357}
358#endif
359
360#if 0
361static int
362fdt_pci_config_bar(device_t dev, int bus, int slot, int func, int bar)
363{
364}
365
366static int
367fdt_pci_config_normal(device_t dev, int bus, int slot, int func)
368{
369	int bar;
370	uint8_t command, intline, intpin;
371
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);
375
376	/* Program the base address registers. */
377	bar = 0;
378	while (bar <= PCIR_MAX_BAR_0)
379		bar += fdt_pci_config_bar(dev, bus, slot, func, bar);
380
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);
385
386	command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
387	PCIB_WRITE_CONFIG(dev, bus, slot, func, PCIR_COMMAND, command, 1);
388}
389
390static int
391fdt_pci_config_bridge(device_t dev, int bus, int secbus, int slot, int func)
392{
393	int maxbar;
394	uint8_t command;
395
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);
399
400	/* Program the base address registers. */
401                        maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6;
402                        bar = 0;
403                        while (bar < maxbar)
404                                bar += fsl_pcib_init_bar(sc, bus, slot, func,
405                                    bar);
406
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,
411                            intpin);
412                        fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
413                            PCIR_INTLINE, intline, 1);
414
415                        command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN;
416                        fsl_pcib_write_config(sc->sc_dev, bus, slot, func,
417                            PCIR_COMMAND, command, 1);
418
419                        /*
420                         * Handle PCI-PCI bridges
421                         */
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);
426
427                        /* Allow only proper PCI-PCI briges */
428                        if (class != PCIC_BRIDGE)
429                                continue;
430                        if (subclass != PCIS_BRIDGE_PCI)
431                                continue;
432
433                        secbus++;
434
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);
444
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);
450
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);
460
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);
468
469                        if (bootverbose)
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);
473
474                        new_pribus = bus;
475                        new_secbus = secbus;
476
477                        secbus = fsl_pcib_init(sc, secbus,
478                            (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0);
479
480                        new_subbus = secbus;
481
482                        if (bootverbose)
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);
487
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);
494
495}
496
497static int
498fdt_pci_config_slot(device_t dev, int bus, int secbus, int slot)
499{
500	int func, maxfunc;
501	uint16_t vendor;
502	uint8_t hdrtype;
503
504	maxfunc = 0;
505	for (func = 0; func <= maxfunc; func++) {
506		hdrtype = PCIB_READ_CONFIG(dev, bus, slot, func,
507		    PCIR_HDRTYPE, 1);
508		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
509			continue;
510		if (func == 0 && (hdrtype & PCIM_MFDEV))
511			maxfunc = PCI_FUNCMAX;
512
513		vendor = PCIB_READ_CONFIG(dev, bus, slot, func,
514		    PCIR_VENDOR, 2);
515		if (vendor == 0xffff)
516			continue;
517
518		if ((hdrtype & PCIM_HDRTYPE) == PCIM_HDRTYPE_NORMAL)
519			fdt_pci_config_normal(dev, bus, slot, func);
520		else
521			secbus = fdt_pci_config_bridge(dev, bus, secbus,
522			    slot, func);
523	}
524
525	return (secbus);
526}
527
528static int
529fdt_pci_config_bus(device_t dev, int bus, int maxslot)
530{
531	int func, maxfunc, secbus, slot;
532
533	secbus = bus;
534	for (slot = 0; slot <= maxslot; slot++)
535		secbus = fdt_pci_config_slot(dev, bus, secbus, slot);
536
537	return (secbus);
538}
539
540int
541fdt_pci_config_domain(device_t dev)
542{
543	pcell_t bus_range[2];
544	phandle_t root;
545	int bus, error, maxslot;
546
547	root = ofw_bus_get_node(dev);
548	if (root == 0)
549		return (EINVAL);
550	if (!fdt_is_type(root, "pci"))
551		return (EINVAL);
552
553	/*
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.
557	 */
558	if ((OF_getprop(root, "bus-range", bus_range, sizeof(bus_range)) <= 0)
559		bus = 0;
560	else
561		bus = fdt32_to_cpu(bus_range[0]);
562
563	error = BUS_WRITE_IVAR(dev, NULL, PCIB_IVAR_BUS, bus);
564	if (error)
565		return (error);
566
567	/* Get the maximum slot number for bus-enumeration. */
568	maxslot = PCIB_MAXSLOTS(dev);
569
570	bus = fdt_pci_config_bus(dev, bus, maxslot);
571	return (0);
572}
573#endif
574