xlp_pci.c revision 279341
1/*-
2 * Copyright (c) 2003-2012 Broadcom Corporation
3 * All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in
13 *    the documentation and/or other materials provided with the
14 *    distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/mips/nlm/xlp_pci.c 279341 2015-02-27 00:57:09Z jchandra $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/types.h>
35#include <sys/kernel.h>
36#include <sys/module.h>
37#include <sys/malloc.h>
38#include <sys/bus.h>
39#include <sys/endian.h>
40#include <sys/rman.h>
41#include <sys/pciio.h>
42
43#include <vm/vm.h>
44#include <vm/vm_param.h>
45#include <vm/pmap.h>
46
47#include <dev/pci/pcivar.h>
48#include <dev/pci/pcireg.h>
49#include <dev/pci/pci_private.h>
50
51#include <dev/uart/uart.h>
52#include <dev/uart/uart_bus.h>
53#include <dev/uart/uart_cpu.h>
54
55#include <machine/bus.h>
56#include <machine/md_var.h>
57#include <machine/intr_machdep.h>
58#include <machine/cpuregs.h>
59
60#include <mips/nlm/hal/haldefs.h>
61#include <mips/nlm/interrupt.h>
62#include <mips/nlm/hal/iomap.h>
63#include <mips/nlm/hal/mips-extns.h>
64#include <mips/nlm/hal/pic.h>
65#include <mips/nlm/hal/bridge.h>
66#include <mips/nlm/hal/gbu.h>
67#include <mips/nlm/hal/pcibus.h>
68#include <mips/nlm/hal/uart.h>
69#include <mips/nlm/xlp.h>
70
71#include "pcib_if.h"
72#include "pci_if.h"
73
74#define	EMUL_MEM_START	0x16000000UL
75#define	EMUL_MEM_END	0x18ffffffUL
76
77/* Override PCI a bit for SoC devices */
78
79enum {
80	INTERNAL_DEV	= 0x1,	/* internal device, skip on enumeration */
81	MEM_RES_EMUL	= 0x2,	/* no MEM or IO bar, custom res alloc */
82	SHARED_IRQ	= 0x4,
83	DEV_MMIO32	= 0x8,	/* byte access not allowed to mmio */
84};
85
86struct  xlp_devinfo {
87	struct pci_devinfo pcidev;
88	int	irq;
89	int	flags;
90	u_long	mem_res_start;
91};
92
93static struct resource *
94xlp_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
95    u_long start, u_long end, u_long count, u_int flags)
96{
97	struct resource *r;
98	struct xlp_devinfo *xlp_devinfo;
99	int busno;
100
101	/*
102	 * Do custom allocation for MEMORY resource for SoC device if
103	 * MEM_RES_EMUL flag is set
104	 */
105	busno = pci_get_bus(child);
106	if ((type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) && busno == 0) {
107		xlp_devinfo = (struct xlp_devinfo *)device_get_ivars(child);
108		if ((xlp_devinfo->flags & MEM_RES_EMUL) != 0) {
109			/* no emulation for IO ports */
110			if (type == SYS_RES_IOPORT)
111				return (NULL);
112
113			start = xlp_devinfo->mem_res_start;
114			count = XLP_PCIE_CFG_SIZE - XLP_IO_PCI_HDRSZ;
115
116			/* MMC needs to 2 slots with rids 16 and 20 and a
117			 * fixup for size */
118			if (pci_get_device(child) == PCI_DEVICE_ID_NLM_MMC) {
119				count = 0x100;
120				if (*rid == 16)
121					; /* first slot already setup */
122				else if (*rid == 20)
123					start += 0x100; /* second slot */
124				else
125					return (NULL);
126			}
127
128			end = start + count - 1;
129			r = BUS_ALLOC_RESOURCE(device_get_parent(bus), child,
130			    type, rid, start, end, count, flags);
131			if (r == NULL)
132				return (NULL);
133			if ((xlp_devinfo->flags & DEV_MMIO32) != 0)
134				rman_set_bustag(r, rmi_uart_bus_space);
135			return (r);
136		}
137	}
138
139	/* Not custom alloc, use PCI code */
140	return (pci_alloc_resource(bus, child, type, rid, start, end, count,
141	    flags));
142}
143
144static int
145xlp_pci_release_resource(device_t bus, device_t child, int type, int rid,
146    struct resource *r)
147{
148	u_long start;
149
150	/* If custom alloc, handle that */
151	start = rman_get_start(r);
152	if (type == SYS_RES_MEMORY && pci_get_bus(child) == 0 &&
153	    start >= EMUL_MEM_START && start <= EMUL_MEM_END)
154		return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child,
155		    type, rid, r));
156
157	/* use default PCI function */
158	return (bus_generic_rl_release_resource(bus, child, type, rid, r));
159}
160
161static void
162xlp_add_soc_child(device_t pcib, device_t dev, int b, int s, int f)
163{
164	struct pci_devinfo *dinfo;
165	struct xlp_devinfo *xlp_dinfo;
166	int domain, node, irq, devoffset, flags;
167	uint16_t devid;
168
169	domain = pcib_get_domain(dev);
170	node = s / 8;
171	devoffset = XLP_HDR_OFFSET(node, 0, s % 8, f);
172	if (!nlm_dev_exists(devoffset))
173		return;
174
175	/* Find if there is a desc for the SoC device */
176	devid = PCIB_READ_CONFIG(pcib, b, s, f, PCIR_DEVICE, 2);
177	flags = 0;
178	irq = 0;
179	switch (devid) {
180	case PCI_DEVICE_ID_NLM_UART:
181		irq = PIC_UART_0_IRQ + f;
182		flags = MEM_RES_EMUL | DEV_MMIO32;
183		break;
184	case PCI_DEVICE_ID_NLM_I2C:
185		flags = MEM_RES_EMUL | DEV_MMIO32;
186		break;
187	case PCI_DEVICE_ID_NLM_NOR:
188		flags = MEM_RES_EMUL;
189		break;
190	case PCI_DEVICE_ID_NLM_MMC:
191		irq = PIC_MMC_IRQ;
192		flags = MEM_RES_EMUL;
193		break;
194	case PCI_DEVICE_ID_NLM_EHCI:
195		irq = PIC_USB_0_IRQ + f;
196		break;
197	case PCI_DEVICE_ID_NLM_PCIE:
198		break;
199	case PCI_DEVICE_ID_NLM_ICI:
200	case PCI_DEVICE_ID_NLM_PIC:
201	case PCI_DEVICE_ID_NLM_FMN:
202	default:
203		return;
204	}
205
206	dinfo = pci_read_device(pcib, domain, b, s, f, sizeof(*xlp_dinfo));
207	if (dinfo == NULL)
208		return;
209	xlp_dinfo = (struct xlp_devinfo *)dinfo;
210	xlp_dinfo->irq = irq;
211	xlp_dinfo->flags = flags;
212
213	/* SoC device with interrupts need fixup (except PCIe controllers) */
214	if (irq != 0 && devid != PCI_DEVICE_ID_NLM_PCIE)
215		PCIB_WRITE_CONFIG(pcib, b, s, f, XLP_PCI_DEVSCRATCH_REG0 << 2,
216		    (1 << 8) | irq, 4);
217
218	/* memory resource from ecfg space, if MEM_RES_EMUL is set */
219	if ((flags & MEM_RES_EMUL) != 0)
220		xlp_dinfo->mem_res_start = XLP_DEFAULT_IO_BASE + devoffset +
221		    XLP_IO_PCI_HDRSZ;
222	pci_add_child(dev, dinfo);
223}
224
225static int
226xlp_pci_attach(device_t dev)
227{
228	device_t pcib = device_get_parent(dev);
229	int maxslots, s, f, pcifunchigh;
230	int busno;
231	uint8_t hdrtype;
232
233	/*
234	 * The on-chip devices are on a bus that is almost, but not
235	 * quite, completely like PCI. Add those things by hand.
236	 */
237	busno = pcib_get_bus(dev);
238	maxslots = PCIB_MAXSLOTS(pcib);
239	for (s = 0; s <= maxslots; s++) {
240		pcifunchigh = 0;
241		f = 0;
242		hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
243		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
244			continue;
245		if (hdrtype & PCIM_MFDEV)
246			pcifunchigh = PCI_FUNCMAX;
247		for (f = 0; f <= pcifunchigh; f++)
248			xlp_add_soc_child(pcib, dev, busno, s, f);
249	}
250	return (bus_generic_attach(dev));
251}
252
253static int
254xlp_pci_probe(device_t dev)
255{
256	device_t pcib;
257
258	pcib = device_get_parent(dev);
259	/*
260	 * Only the top level bus has SoC devices, leave the rest to
261	 * Generic PCI code
262	 */
263	if (strcmp(device_get_nameunit(pcib), "pcib0") != 0)
264		return (ENXIO);
265	device_set_desc(dev, "XLP SoCbus");
266	return (BUS_PROBE_DEFAULT);
267}
268
269static devclass_t pci_devclass;
270static device_method_t xlp_pci_methods[] = {
271	/* Device interface */
272	DEVMETHOD(device_probe,		xlp_pci_probe),
273	DEVMETHOD(device_attach,	xlp_pci_attach),
274	DEVMETHOD(bus_alloc_resource,	xlp_pci_alloc_resource),
275	DEVMETHOD(bus_release_resource, xlp_pci_release_resource),
276
277	DEVMETHOD_END
278};
279
280DEFINE_CLASS_1(pci, xlp_pci_driver, xlp_pci_methods, sizeof(struct pci_softc),
281    pci_driver);
282DRIVER_MODULE(xlp_pci, pcib, xlp_pci_driver, pci_devclass, 0, 0);
283
284static devclass_t pcib_devclass;
285static struct rman irq_rman, port_rman, mem_rman, emul_rman;
286
287static void
288xlp_pcib_init_resources(void)
289{
290	irq_rman.rm_start = 0;
291	irq_rman.rm_end = 255;
292	irq_rman.rm_type = RMAN_ARRAY;
293	irq_rman.rm_descr = "PCI Mapped Interrupts";
294	if (rman_init(&irq_rman)
295	    || rman_manage_region(&irq_rman, 0, 255))
296		panic("pci_init_resources irq_rman");
297
298	port_rman.rm_start = 0;
299	port_rman.rm_end = ~0ul;
300	port_rman.rm_type = RMAN_ARRAY;
301	port_rman.rm_descr = "I/O ports";
302	if (rman_init(&port_rman)
303	    || rman_manage_region(&port_rman, PCIE_IO_BASE, PCIE_IO_LIMIT))
304		panic("pci_init_resources port_rman");
305
306	mem_rman.rm_start = 0;
307	mem_rman.rm_end = ~0ul;
308	mem_rman.rm_type = RMAN_ARRAY;
309	mem_rman.rm_descr = "I/O memory";
310	if (rman_init(&mem_rman)
311	    || rman_manage_region(&mem_rman, PCIE_MEM_BASE, PCIE_MEM_LIMIT))
312		panic("pci_init_resources mem_rman");
313
314	/*
315	 * This includes the GBU (nor flash) memory range and the PCIe
316	 * memory area.
317	 */
318	emul_rman.rm_start = 0;
319	emul_rman.rm_end = ~0ul;
320	emul_rman.rm_type = RMAN_ARRAY;
321	emul_rman.rm_descr = "Emulated MEMIO";
322	if (rman_init(&emul_rman)
323	    || rman_manage_region(&emul_rman, EMUL_MEM_START, EMUL_MEM_END))
324		panic("pci_init_resources emul_rman");
325}
326
327static int
328xlp_pcib_probe(device_t dev)
329{
330
331	device_set_desc(dev, "XLP PCI bus");
332	return (BUS_PROBE_NOWILDCARD);
333}
334
335static int
336xlp_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
337{
338
339	switch (which) {
340	case PCIB_IVAR_DOMAIN:
341		*result = 0;
342		return (0);
343	case PCIB_IVAR_BUS:
344		*result = 0;
345		return (0);
346	}
347	return (ENOENT);
348}
349
350static int
351xlp_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
352{
353	switch (which) {
354	case PCIB_IVAR_DOMAIN:
355		return (EINVAL);
356	case PCIB_IVAR_BUS:
357		return (EINVAL);
358	}
359	return (ENOENT);
360}
361
362static int
363xlp_pcib_maxslots(device_t dev)
364{
365
366	return (PCI_SLOTMAX);
367}
368
369static u_int32_t
370xlp_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
371    u_int reg, int width)
372{
373	uint32_t data = 0;
374	uint64_t cfgaddr;
375	int	regindex = reg/sizeof(uint32_t);
376
377	cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f));
378	if ((width == 2) && (reg & 1))
379		return 0xFFFFFFFF;
380	else if ((width == 4) && (reg & 3))
381		return 0xFFFFFFFF;
382
383	/*
384	 * The intline and int pin of SoC devices are DOA, except
385	 * for bridges (slot %8 == 1).
386	 * use the values we stashed in a writable PCI scratch reg.
387	 */
388	if (b == 0 && regindex == 0xf && s % 8 > 1)
389		regindex = XLP_PCI_DEVSCRATCH_REG0;
390
391	data = nlm_read_pci_reg(cfgaddr, regindex);
392	if (width == 1)
393		return ((data >> ((reg & 3) << 3)) & 0xff);
394	else if (width == 2)
395		return ((data >> ((reg & 3) << 3)) & 0xffff);
396	else
397		return (data);
398}
399
400static void
401xlp_pcib_write_config(device_t dev, u_int b, u_int s, u_int f,
402    u_int reg, u_int32_t val, int width)
403{
404	uint64_t cfgaddr;
405	uint32_t data = 0;
406	int	regindex = reg / sizeof(uint32_t);
407
408	cfgaddr = nlm_pcicfg_base(XLP_HDR_OFFSET(0, b, s, f));
409	if ((width == 2) && (reg & 1))
410		return;
411	else if ((width == 4) && (reg & 3))
412		return;
413
414	if (width == 1) {
415		data = nlm_read_pci_reg(cfgaddr, regindex);
416		data = (data & ~(0xff << ((reg & 3) << 3))) |
417		    (val << ((reg & 3) << 3));
418	} else if (width == 2) {
419		data = nlm_read_pci_reg(cfgaddr, regindex);
420		data = (data & ~(0xffff << ((reg & 3) << 3))) |
421		    (val << ((reg & 3) << 3));
422	} else {
423		data = val;
424	}
425
426	/*
427	 * use shadow reg for intpin/intline which are dead
428	 */
429	if (b == 0 && regindex == 0xf && s % 8 > 1)
430		regindex = XLP_PCI_DEVSCRATCH_REG0;
431	nlm_write_pci_reg(cfgaddr, regindex, data);
432}
433
434/*
435 * Enable byte swap in hardware when compiled big-endian.
436 * Programs a link's PCIe SWAP regions from the link's IO and MEM address
437 * ranges.
438 */
439static void
440xlp_pcib_hardware_swap_enable(int node, int link)
441{
442#if BYTE_ORDER == BIG_ENDIAN
443	uint64_t bbase, linkpcibase;
444	uint32_t bar;
445	int pcieoffset;
446
447	pcieoffset = XLP_IO_PCIE_OFFSET(node, link);
448	if (!nlm_dev_exists(pcieoffset))
449		return;
450
451	bbase = nlm_get_bridge_regbase(node);
452	linkpcibase = nlm_pcicfg_base(pcieoffset);
453	bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_BASE0 + link);
454	nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_BASE, bar);
455
456	bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEMEM_LIMIT0 + link);
457	nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_MEM_LIM, bar | 0xFFF);
458
459	bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_BASE0 + link);
460	nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_BASE, bar);
461
462	bar = nlm_read_bridge_reg(bbase, BRIDGE_PCIEIO_LIMIT0 + link);
463	nlm_write_pci_reg(linkpcibase, PCIE_BYTE_SWAP_IO_LIM, bar | 0xFFF);
464#endif
465}
466
467static int
468xlp_pcib_attach(device_t dev)
469{
470	int node, link;
471
472	xlp_pcib_init_resources();
473
474	/* enable hardware swap on all nodes/links */
475	for (node = 0; node < XLP_MAX_NODES; node++)
476		for (link = 0; link < 4; link++)
477			xlp_pcib_hardware_swap_enable(node, link);
478
479	device_add_child(dev, "pci", 0);
480	bus_generic_attach(dev);
481	return (0);
482}
483
484static void
485xlp_pcib_identify(driver_t * driver, device_t parent)
486{
487
488	BUS_ADD_CHILD(parent, 0, "pcib", 0);
489}
490
491/*
492 * XLS PCIe can have upto 4 links, and each link has its on IRQ
493 * Find the link on which the device is on
494 */
495static int
496xlp_pcie_link(device_t pcib, device_t dev)
497{
498	device_t parent, tmp;
499
500	/* find the lane on which the slot is connected to */
501	tmp = dev;
502	while (1) {
503		parent = device_get_parent(tmp);
504		if (parent == NULL || parent == pcib) {
505			device_printf(dev, "Cannot find parent bus\n");
506			return (-1);
507		}
508		if (strcmp(device_get_nameunit(parent), "pci0") == 0)
509			break;
510		tmp = parent;
511	}
512	return (pci_get_function(tmp));
513}
514
515static int
516xlp_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
517{
518	int i, link;
519
520	/*
521	 * Each link has 32 MSIs that can be allocated, but for now
522	 * we only support one device per link.
523	 * msi_alloc() equivalent is needed when we start supporting
524	 * bridges on the PCIe link.
525	 */
526	link = xlp_pcie_link(pcib, dev);
527	if (link == -1)
528		return (ENXIO);
529
530	/*
531	 * encode the irq so that we know it is a MSI interrupt when we
532	 * setup interrupts
533	 */
534	for (i = 0; i < count; i++)
535		irqs[i] = 64 + link * 32 + i;
536
537	return (0);
538}
539
540static int
541xlp_release_msi(device_t pcib, device_t dev, int count, int *irqs)
542{
543	return (0);
544}
545
546static int
547xlp_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
548    uint32_t *data)
549{
550	int link;
551
552	if (irq < 64) {
553		device_printf(dev, "%s: map_msi for irq %d  - ignored",
554		    device_get_nameunit(pcib), irq);
555		return (ENXIO);
556	}
557	link = (irq - 64) / 32;
558	*addr = MIPS_MSI_ADDR(0);
559	*data = MIPS_MSI_DATA(PIC_PCIE_IRQ(link));
560	return (0);
561}
562
563static void
564bridge_pcie_ack(int irq, void *arg)
565{
566	uint32_t node,reg;
567	uint64_t base;
568
569	node = nlm_nodeid();
570	reg = PCIE_MSI_STATUS;
571
572	switch (irq) {
573		case PIC_PCIE_0_IRQ:
574			base = nlm_pcicfg_base(XLP_IO_PCIE0_OFFSET(node));
575			break;
576		case PIC_PCIE_1_IRQ:
577			base = nlm_pcicfg_base(XLP_IO_PCIE1_OFFSET(node));
578			break;
579		case PIC_PCIE_2_IRQ:
580			base = nlm_pcicfg_base(XLP_IO_PCIE2_OFFSET(node));
581			break;
582		case PIC_PCIE_3_IRQ:
583			base = nlm_pcicfg_base(XLP_IO_PCIE3_OFFSET(node));
584			break;
585		default:
586			return;
587	}
588
589	nlm_write_pci_reg(base, reg, 0xFFFFFFFF);
590	return;
591}
592
593static int
594mips_platform_pcib_setup_intr(device_t dev, device_t child,
595    struct resource *irq, int flags, driver_filter_t *filt,
596    driver_intr_t *intr, void *arg, void **cookiep)
597{
598	int error = 0;
599	int xlpirq;
600
601	error = rman_activate_resource(irq);
602	if (error)
603		return error;
604	if (rman_get_start(irq) != rman_get_end(irq)) {
605		device_printf(dev, "Interrupt allocation %lu != %lu\n",
606		    rman_get_start(irq), rman_get_end(irq));
607		return (EINVAL);
608	}
609	xlpirq = rman_get_start(irq);
610	if (xlpirq == 0)
611		return (0);
612
613	if (strcmp(device_get_name(dev), "pcib") != 0)
614		return (0);
615
616	/*
617	 * temporary hack for MSI, we support just one device per
618	 * link, and assign the link interrupt to the device interrupt
619	 */
620	if (xlpirq >= 64) {
621		int node, val, link;
622		uint64_t base;
623
624		xlpirq -= 64;
625		if (xlpirq % 32 != 0)
626			return (0);
627
628		node = nlm_nodeid();
629		link = xlpirq / 32;
630		base = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node,link));
631
632		/* MSI Interrupt Vector enable at bridge's configuration */
633		nlm_write_pci_reg(base, PCIE_MSI_EN, PCIE_MSI_VECTOR_INT_EN);
634
635		val = nlm_read_pci_reg(base, PCIE_INT_EN0);
636		/* MSI Interrupt enable at bridge's configuration */
637		nlm_write_pci_reg(base, PCIE_INT_EN0,
638		    (val | PCIE_MSI_INT_EN));
639
640		/* legacy interrupt disable at bridge */
641		val = nlm_read_pci_reg(base, PCIE_BRIDGE_CMD);
642		nlm_write_pci_reg(base, PCIE_BRIDGE_CMD,
643		    (val | PCIM_CMD_INTxDIS));
644
645		/* MSI address update at bridge */
646		nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRL,
647		    MSI_MIPS_ADDR_BASE);
648		nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_ADDRH, 0);
649
650		val = nlm_read_pci_reg(base, PCIE_BRIDGE_MSI_CAP);
651		/* MSI capability enable at bridge */
652		nlm_write_pci_reg(base, PCIE_BRIDGE_MSI_CAP,
653		    (val | (PCIM_MSICTRL_MSI_ENABLE << 16) |
654		        (PCIM_MSICTRL_MMC_32 << 16)));
655		xlpirq = PIC_PCIE_IRQ(link);
656	}
657
658	/* if it is for real PCIe, we need to ack at bridge too */
659	if (xlpirq >= PIC_PCIE_IRQ(0) && xlpirq <= PIC_PCIE_IRQ(3))
660		xlp_set_bus_ack(xlpirq, bridge_pcie_ack, NULL);
661	cpu_establish_hardintr(device_get_name(child), filt, intr, arg,
662	    xlpirq, flags, cookiep);
663
664	return (0);
665}
666
667static int
668mips_platform_pcib_teardown_intr(device_t dev, device_t child,
669    struct resource *irq, void *cookie)
670{
671	if (strcmp(device_get_name(child), "pci") == 0) {
672		/* if needed reprogram the pic to clear pcix related entry */
673		device_printf(dev, "teardown intr\n");
674	}
675	return (bus_generic_teardown_intr(dev, child, irq, cookie));
676}
677
678static struct resource *
679xlp_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid,
680    u_long start, u_long end, u_long count, u_int flags)
681{
682	struct rman *rm = NULL;
683	struct resource *rv;
684	void *va;
685	int needactivate = flags & RF_ACTIVE;
686
687	switch (type) {
688	case SYS_RES_IRQ:
689		rm = &irq_rman;
690		break;
691
692	case SYS_RES_IOPORT:
693		rm = &port_rman;
694		break;
695
696	case SYS_RES_MEMORY:
697		if (start >= EMUL_MEM_START && start <= EMUL_MEM_END)
698			rm = &emul_rman;
699		else
700			rm = &mem_rman;
701			break;
702
703	default:
704		return (0);
705	}
706
707	rv = rman_reserve_resource(rm, start, end, count, flags, child);
708	if (rv == NULL)
709		return (NULL);
710
711	rman_set_rid(rv, *rid);
712
713	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
714		va = pmap_mapdev(start, count);
715		rman_set_bushandle(rv, (bus_space_handle_t)va);
716		rman_set_bustag(rv, rmi_bus_space);
717	}
718	if (needactivate) {
719		if (bus_activate_resource(child, type, *rid, rv)) {
720			rman_release_resource(rv);
721			return (NULL);
722		}
723	}
724	return (rv);
725}
726
727static int
728xlp_pcib_release_resource(device_t bus, device_t child, int type, int rid,
729    struct resource *r)
730{
731
732	return (rman_release_resource(r));
733}
734
735static int
736xlp_pcib_activate_resource(device_t bus, device_t child, int type, int rid,
737    struct resource *r)
738{
739
740	return (rman_activate_resource(r));
741}
742
743static int
744xlp_pcib_deactivate_resource(device_t bus, device_t child, int type, int rid,
745    struct resource *r)
746{
747
748	return (rman_deactivate_resource(r));
749}
750
751static int
752mips_pcib_route_interrupt(device_t bus, device_t dev, int pin)
753{
754	int f, d;
755
756	/*
757	 * Validate requested pin number.
758	 */
759	if ((pin < 1) || (pin > 4))
760		return (255);
761
762	if (pci_get_bus(dev) == 0 &&
763	    pci_get_vendor(dev) == PCI_VENDOR_NETLOGIC) {
764		f = pci_get_function(dev);
765		d = pci_get_slot(dev) % 8;
766
767		/*
768		 * For PCIe links, return link IRT, for other SoC devices
769		 * get the IRT from its PCIe header
770		 */
771		if (d == 1)
772			return (PIC_PCIE_IRQ(f));
773		else
774			return (255);	/* use intline, don't reroute */
775	} else {
776		/* Regular PCI devices */
777		return (PIC_PCIE_IRQ(xlp_pcie_link(bus, dev)));
778	}
779}
780
781static device_method_t xlp_pcib_methods[] = {
782	/* Device interface */
783	DEVMETHOD(device_identify, xlp_pcib_identify),
784	DEVMETHOD(device_probe, xlp_pcib_probe),
785	DEVMETHOD(device_attach, xlp_pcib_attach),
786
787	/* Bus interface */
788	DEVMETHOD(bus_read_ivar, xlp_pcib_read_ivar),
789	DEVMETHOD(bus_write_ivar, xlp_pcib_write_ivar),
790	DEVMETHOD(bus_alloc_resource, xlp_pcib_alloc_resource),
791	DEVMETHOD(bus_release_resource, xlp_pcib_release_resource),
792	DEVMETHOD(bus_activate_resource, xlp_pcib_activate_resource),
793	DEVMETHOD(bus_deactivate_resource, xlp_pcib_deactivate_resource),
794	DEVMETHOD(bus_setup_intr, mips_platform_pcib_setup_intr),
795	DEVMETHOD(bus_teardown_intr, mips_platform_pcib_teardown_intr),
796
797	/* pcib interface */
798	DEVMETHOD(pcib_maxslots, xlp_pcib_maxslots),
799	DEVMETHOD(pcib_read_config, xlp_pcib_read_config),
800	DEVMETHOD(pcib_write_config, xlp_pcib_write_config),
801	DEVMETHOD(pcib_route_interrupt, mips_pcib_route_interrupt),
802
803	DEVMETHOD(pcib_alloc_msi, xlp_alloc_msi),
804	DEVMETHOD(pcib_release_msi, xlp_release_msi),
805	DEVMETHOD(pcib_map_msi, xlp_map_msi),
806
807	DEVMETHOD_END
808};
809
810static driver_t xlp_pcib_driver = {
811	"pcib",
812	xlp_pcib_methods,
813	1, /* no softc */
814};
815
816DRIVER_MODULE(pcib, nexus, xlp_pcib_driver, pcib_devclass, 0, 0);
817