xref: /freebsd-11-stable/sys/mips/rmi/xlr_pci.c (revision 4ab2e064d7950be84256d671a7ae93f87cc6aa36)
1 /*-
2  * Copyright (c) 2003-2009 RMI 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  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
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  * RMI_BSD */
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/types.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/malloc.h>
39 #include <sys/bus.h>
40 #include <sys/endian.h>
41 #include <sys/rman.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 
50 #include <machine/bus.h>
51 #include <machine/md_var.h>
52 #include <machine/intr_machdep.h>
53 #include <machine/cpuregs.h>
54 
55 #include <mips/rmi/rmi_mips_exts.h>
56 #include <mips/rmi/interrupt.h>
57 #include <mips/rmi/iomap.h>
58 #include <mips/rmi/pic.h>
59 #include <mips/rmi/board.h>
60 #include <mips/rmi/pcibus.h>
61 
62 #include "pcib_if.h"
63 
64 #define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where))
65 #define PCIE_LINK_STATE    0x4000
66 
67 #define LSU_CFG0_REGID       0
68 #define LSU_CERRLOG_REGID    9
69 #define LSU_CERROVF_REGID    10
70 #define LSU_CERRINT_REGID    11
71 
72 /* MSI support */
73 #define MSI_MIPS_ADDR_DEST		0x000ff000
74 #define MSI_MIPS_ADDR_RH		0x00000008
75 #define MSI_MIPS_ADDR_RH_OFF		0x00000000
76 #define MSI_MIPS_ADDR_RH_ON		0x00000008
77 #define MSI_MIPS_ADDR_DM		0x00000004
78 #define MSI_MIPS_ADDR_DM_PHYSICAL	0x00000000
79 #define MSI_MIPS_ADDR_DM_LOGICAL	0x00000004
80 
81 /* Fields in data for Intel MSI messages. */
82 #define MSI_MIPS_DATA_TRGRMOD		0x00008000	/* Trigger mode */
83 #define MSI_MIPS_DATA_TRGREDG		0x00000000	/* edge */
84 #define MSI_MIPS_DATA_TRGRLVL		0x00008000	/* level */
85 
86 #define MSI_MIPS_DATA_LEVEL		0x00004000	/* Polarity. */
87 #define MSI_MIPS_DATA_DEASSERT		0x00000000
88 #define MSI_MIPS_DATA_ASSERT		0x00004000
89 
90 #define MSI_MIPS_DATA_DELMOD		0x00000700	/* Delivery Mode */
91 #define MSI_MIPS_DATA_DELFIXED		0x00000000	/* fixed */
92 #define MSI_MIPS_DATA_DELLOPRI		0x00000100	/* lowest priority */
93 
94 #define MSI_MIPS_DATA_INTVEC		0x000000ff
95 
96 /*
97  * Build Intel MSI message and data values from a source.  AMD64 systems
98  * seem to be compatible, so we use the same function for both.
99  */
100 #define MIPS_MSI_ADDR(cpu)					       \
101         (MSI_MIPS_ADDR_BASE | (cpu) << 12 |			       \
102 	 MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL)
103 
104 #define MIPS_MSI_DATA(irq)					       \
105         (MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED |	       \
106 	 MSI_MIPS_DATA_ASSERT | (irq))
107 
108 struct xlr_pcib_softc {
109 	bus_dma_tag_t	sc_pci_dmat;	/* PCI DMA tag pointer */
110 };
111 
112 static devclass_t pcib_devclass;
113 static void *xlr_pci_config_base;
114 static struct rman irq_rman, port_rman, mem_rman;
115 
116 static void
xlr_pci_init_resources(void)117 xlr_pci_init_resources(void)
118 {
119 
120 	irq_rman.rm_start = 0;
121 	irq_rman.rm_end = 255;
122 	irq_rman.rm_type = RMAN_ARRAY;
123 	irq_rman.rm_descr = "PCI Mapped Interrupts";
124 	if (rman_init(&irq_rman)
125 	    || rman_manage_region(&irq_rman, 0, 255))
126 		panic("pci_init_resources irq_rman");
127 
128 	port_rman.rm_type = RMAN_ARRAY;
129 	port_rman.rm_descr = "I/O ports";
130 	if (rman_init(&port_rman)
131 	    || rman_manage_region(&port_rman, 0x10000000, 0x1fffffff))
132 		panic("pci_init_resources port_rman");
133 
134 	mem_rman.rm_type = RMAN_ARRAY;
135 	mem_rman.rm_descr = "I/O memory";
136 	if (rman_init(&mem_rman)
137 	    || rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff))
138 		panic("pci_init_resources mem_rman");
139 }
140 
141 static int
xlr_pcib_probe(device_t dev)142 xlr_pcib_probe(device_t dev)
143 {
144 
145 	if (xlr_board_info.is_xls)
146 		device_set_desc(dev, "XLS PCIe bus");
147 	else
148 		device_set_desc(dev, "XLR PCI bus");
149 
150 	xlr_pci_init_resources();
151 	xlr_pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE);
152 
153 	return (0);
154 }
155 
156 static int
xlr_pcib_read_ivar(device_t dev,device_t child,int which,uintptr_t * result)157 xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
158 {
159 
160 	switch (which) {
161 	case PCIB_IVAR_DOMAIN:
162 		*result = 0;
163 		return (0);
164 	case PCIB_IVAR_BUS:
165 		*result = 0;
166 		return (0);
167 	}
168 	return (ENOENT);
169 }
170 
171 static int
xlr_pcib_write_ivar(device_t dev,device_t child,int which,uintptr_t result)172 xlr_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
173 {
174 	switch (which) {
175 	case PCIB_IVAR_DOMAIN:
176 		return (EINVAL);
177 	case PCIB_IVAR_BUS:
178 		return (EINVAL);
179 	}
180 	return (ENOENT);
181 }
182 
183 static int
xlr_pcib_maxslots(device_t dev)184 xlr_pcib_maxslots(device_t dev)
185 {
186 
187 	return (PCI_SLOTMAX);
188 }
189 
190 static __inline__ void
disable_and_clear_cache_error(void)191 disable_and_clear_cache_error(void)
192 {
193 	uint64_t lsu_cfg0;
194 
195 	lsu_cfg0 = read_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
196 	lsu_cfg0 = lsu_cfg0 & ~0x2e;
197 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
198 	/* Clear cache error log */
199 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
200 }
201 
202 static __inline__ void
clear_and_enable_cache_error(void)203 clear_and_enable_cache_error(void)
204 {
205 	uint64_t lsu_cfg0 = 0;
206 
207 	/* first clear the cache error logging register */
208 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0);
209 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0);
210 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0);
211 
212 	lsu_cfg0 = read_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID);
213 	lsu_cfg0 = lsu_cfg0 | 0x2e;
214 	write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0);
215 }
216 
217 static uint32_t
pci_cfg_read_32bit(uint32_t addr)218 pci_cfg_read_32bit(uint32_t addr)
219 {
220 	uint32_t temp = 0;
221 	uint32_t *p = (uint32_t *)xlr_pci_config_base + addr / sizeof(uint32_t);
222 	uint64_t cerr_cpu_log = 0;
223 
224 	disable_and_clear_cache_error();
225 	temp = bswap32(*p);
226 
227 	/* Read cache err log */
228 	cerr_cpu_log = read_xlr_ctrl_register(CPU_BLOCKID_LSU,
229 	    LSU_CERRLOG_REGID);
230 	if (cerr_cpu_log) {
231 		/* Device don't exist. */
232 		temp = ~0x0;
233 	}
234 	clear_and_enable_cache_error();
235 	return (temp);
236 }
237 
238 static u_int32_t
xlr_pcib_read_config(device_t dev,u_int b,u_int s,u_int f,u_int reg,int width)239 xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f,
240 			u_int reg, int width)
241 {
242 	uint32_t data = 0;
243 
244 	if ((width == 2) && (reg & 1))
245 		return 0xFFFFFFFF;
246 	else if ((width == 4) && (reg & 3))
247 		return 0xFFFFFFFF;
248 
249 	data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg));
250 
251 	if (width == 1)
252 		return ((data >> ((reg & 3) << 3)) & 0xff);
253 	else if (width == 2)
254 		return ((data >> ((reg & 3) << 3)) & 0xffff);
255 	else
256 		return (data);
257 }
258 
259 static void
xlr_pcib_write_config(device_t dev,u_int b,u_int s,u_int f,u_int reg,u_int32_t val,int width)260 xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f,
261 		u_int reg, u_int32_t val, int width)
262 {
263 	uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg);
264 	uint32_t data = 0, *p;
265 
266 	if ((width == 2) && (reg & 1))
267 		return;
268 	else if ((width == 4) && (reg & 3))
269 		return;
270 
271 	if (width == 1) {
272 		data = pci_cfg_read_32bit(cfgaddr);
273 		data = (data & ~(0xff << ((reg & 3) << 3))) |
274 		    (val << ((reg & 3) << 3));
275 	} else if (width == 2) {
276 		data = pci_cfg_read_32bit(cfgaddr);
277 		data = (data & ~(0xffff << ((reg & 3) << 3))) |
278 		    (val << ((reg & 3) << 3));
279 	} else {
280 		data = val;
281 	}
282 
283 	p = (uint32_t *)xlr_pci_config_base + cfgaddr / sizeof(uint32_t);
284 	*p = bswap32(data);
285 
286 	return;
287 }
288 
289 static int
xlr_pcib_attach(device_t dev)290 xlr_pcib_attach(device_t dev)
291 {
292 	struct xlr_pcib_softc *sc;
293 	sc = device_get_softc(dev);
294 
295 	/*
296 	 * XLR C revision chips cannot do DMA above 2G physical address
297 	 * create a parent tag with this lowaddr
298 	 */
299 	if (xlr_is_c_revision()) {
300 		if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
301 		    0x7fffffff, ~0, NULL, NULL, 0x7fffffff,
302 		    0xff, 0x7fffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0)
303 			panic("%s: bus_dma_tag_create failed", __func__);
304 	}
305 	device_add_child(dev, "pci", -1);
306 	bus_generic_attach(dev);
307 	return (0);
308 }
309 
310 static void
xlr_pcib_identify(driver_t * driver,device_t parent)311 xlr_pcib_identify(driver_t * driver, device_t parent)
312 {
313 
314 	BUS_ADD_CHILD(parent, 0, "pcib", 0);
315 }
316 
317 /*
318  * XLS PCIe can have upto 4 links, and each link has its on IRQ
319  * Find the link on which the device is on
320  */
321 static int
xls_pcie_link(device_t pcib,device_t dev)322 xls_pcie_link(device_t pcib, device_t dev)
323 {
324 	device_t parent, tmp;
325 
326 	/* find the lane on which the slot is connected to */
327 	printf("xls_pcie_link : bus %s dev %s\n", device_get_nameunit(pcib),
328 		device_get_nameunit(dev));
329 	tmp = dev;
330 	while (1) {
331 		parent = device_get_parent(tmp);
332 		if (parent == NULL || parent == pcib) {
333 			device_printf(dev, "Cannot find parent bus\n");
334 			return (-1);
335 		}
336 		if (strcmp(device_get_nameunit(parent), "pci0") == 0)
337 			break;
338 		tmp = parent;
339 	}
340 	return (pci_get_slot(tmp));
341 }
342 
343 /*
344  * Find the IRQ for the link, each link has a different interrupt
345  * at the XLS pic
346  */
347 static int
xls_pcie_link_irq(int link)348 xls_pcie_link_irq(int link)
349 {
350 
351 	switch (link) {
352 	case 0:
353 		return (PIC_PCIE_LINK0_IRQ);
354 	case 1:
355 		return (PIC_PCIE_LINK1_IRQ);
356 	case 2:
357 		if (xlr_is_xls_b0())
358 			return (PIC_PCIE_B0_LINK2_IRQ);
359 		else
360 			return (PIC_PCIE_LINK2_IRQ);
361 	case 3:
362 		if (xlr_is_xls_b0())
363 			return (PIC_PCIE_B0_LINK3_IRQ);
364 		else
365 			return (PIC_PCIE_LINK3_IRQ);
366 	}
367 	return (-1);
368 }
369 
370 static int
xlr_alloc_msi(device_t pcib,device_t dev,int count,int maxcount,int * irqs)371 xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs)
372 {
373 	int i, link;
374 
375 	/*
376 	 * Each link has 32 MSIs that can be allocated, but for now
377 	 * we only support one device per link.
378 	 * msi_alloc() equivalent is needed when we start supporting
379 	 * bridges on the PCIe link.
380 	 */
381 	link = xls_pcie_link(pcib, dev);
382 	if (link == -1)
383 		return (ENXIO);
384 
385 	/*
386 	 * encode the irq so that we know it is a MSI interrupt when we
387 	 * setup interrupts
388 	 */
389 	for (i = 0; i < count; i++)
390 		irqs[i] = 64 + link * 32 + i;
391 
392 	return (0);
393 }
394 
395 static int
xlr_release_msi(device_t pcib,device_t dev,int count,int * irqs)396 xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs)
397 {
398 	device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib),
399 	    count);
400 	return (0);
401 }
402 
403 static int
xlr_map_msi(device_t pcib,device_t dev,int irq,uint64_t * addr,uint32_t * data)404 xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr,
405     uint32_t *data)
406 {
407 	int msi;
408 
409 	if (irq >= 64) {
410 		msi = irq - 64;
411 		*addr = MIPS_MSI_ADDR(0);
412 		*data = MIPS_MSI_DATA(msi);
413 		return (0);
414 	} else {
415 		device_printf(dev, "%s: map_msi for irq %d  - ignored",
416 		    device_get_nameunit(pcib), irq);
417 		return (ENXIO);
418 	}
419 }
420 
421 static void
bridge_pcix_ack(int irq)422 bridge_pcix_ack(int irq)
423 {
424 
425 	(void)xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2);
426 }
427 
428 static void
bridge_pcie_ack(int irq)429 bridge_pcie_ack(int irq)
430 {
431 	uint32_t reg;
432 	xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET);
433 
434 	switch (irq) {
435 	case PIC_PCIE_LINK0_IRQ:
436 		reg = PCIE_LINK0_MSI_STATUS;
437 		break;
438 	case PIC_PCIE_LINK1_IRQ:
439 		reg = PCIE_LINK1_MSI_STATUS;
440 		break;
441 	case PIC_PCIE_LINK2_IRQ:
442 	case PIC_PCIE_B0_LINK2_IRQ:
443 		reg = PCIE_LINK2_MSI_STATUS;
444 		break;
445 	case PIC_PCIE_LINK3_IRQ:
446 	case PIC_PCIE_B0_LINK3_IRQ:
447 		reg = PCIE_LINK3_MSI_STATUS;
448 		break;
449 	default:
450 		return;
451 	}
452 	xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff);
453 }
454 
455 static int
mips_platform_pci_setup_intr(device_t dev,device_t child,struct resource * irq,int flags,driver_filter_t * filt,driver_intr_t * intr,void * arg,void ** cookiep)456 mips_platform_pci_setup_intr(device_t dev, device_t child,
457     struct resource *irq, int flags, driver_filter_t *filt,
458     driver_intr_t *intr, void *arg, void **cookiep)
459 {
460 	int error = 0;
461 	int xlrirq;
462 
463 	error = rman_activate_resource(irq);
464 	if (error)
465 		return error;
466 	if (rman_get_start(irq) != rman_get_end(irq)) {
467 		device_printf(dev, "Interrupt allocation %ju != %ju\n",
468 		    rman_get_start(irq), rman_get_end(irq));
469 		return (EINVAL);
470 	}
471 	xlrirq = rman_get_start(irq);
472 
473 	if (strcmp(device_get_name(dev), "pcib") != 0)
474 		return (0);
475 
476 	if (xlr_board_info.is_xls == 0) {
477 		xlr_establish_intr(device_get_name(child), filt,
478 		    intr, arg, PIC_PCIX_IRQ, flags, cookiep, bridge_pcix_ack);
479 		pic_setup_intr(PIC_IRT_PCIX_INDEX, PIC_PCIX_IRQ, 0x1, 1);
480 	} else {
481 		/*
482 		 * temporary hack for MSI, we support just one device per
483 		 * link, and assign the link interrupt to the device interrupt
484 		 */
485 		if (xlrirq >= 64) {
486 			xlrirq -= 64;
487 			if (xlrirq % 32 != 0)
488 				return (0);
489 			xlrirq = xls_pcie_link_irq(xlrirq / 32);
490 			if (xlrirq == -1)
491 				return (EINVAL);
492 		}
493 		xlr_establish_intr(device_get_name(child), filt,
494 		    intr, arg, xlrirq, flags, cookiep, bridge_pcie_ack);
495 		pic_setup_intr(xlrirq - PIC_IRQ_BASE, xlrirq, 0x1, 1);
496 	}
497 
498 	return (bus_generic_setup_intr(dev, child, irq, flags, filt, intr,
499 	    arg, cookiep));
500 }
501 
502 static int
mips_platform_pci_teardown_intr(device_t dev,device_t child,struct resource * irq,void * cookie)503 mips_platform_pci_teardown_intr(device_t dev, device_t child,
504     struct resource *irq, void *cookie)
505 {
506 	if (strcmp(device_get_name(child), "pci") == 0) {
507 		/* if needed reprogram the pic to clear pcix related entry */
508 		device_printf(dev, "teardown intr\n");
509 	}
510 	return (bus_generic_teardown_intr(dev, child, irq, cookie));
511 }
512 
513 static struct resource *
xlr_pci_alloc_resource(device_t bus,device_t child,int type,int * rid,rman_res_t start,rman_res_t end,rman_res_t count,u_int flags)514 xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
515 	rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
516 {
517 	struct rman *rm;
518 	struct resource *rv;
519 	vm_offset_t va;
520 	int needactivate = flags & RF_ACTIVE;
521 
522 	switch (type) {
523 	case SYS_RES_IRQ:
524 		rm = &irq_rman;
525 		break;
526 
527 	case SYS_RES_IOPORT:
528 		rm = &port_rman;
529 		break;
530 
531 	case SYS_RES_MEMORY:
532 		rm = &mem_rman;
533 		break;
534 
535 	default:
536 		return (0);
537 	}
538 
539 	rv = rman_reserve_resource(rm, start, end, count, flags, child);
540 	if (rv == NULL)
541 		return (0);
542 
543 	rman_set_rid(rv, *rid);
544 
545 	if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
546 		va = (vm_offset_t)pmap_mapdev(start, count);
547 		rman_set_bushandle(rv, va);
548 		/* bushandle is same as virtual addr */
549 		rman_set_virtual(rv, (void *)va);
550 		rman_set_bustag(rv, rmi_pci_bus_space);
551 	}
552 
553 	if (needactivate) {
554 		if (bus_activate_resource(child, type, *rid, rv)) {
555 			rman_release_resource(rv);
556 			return (NULL);
557 		}
558 	}
559 	return (rv);
560 }
561 
562 static int
xlr_pci_release_resource(device_t bus,device_t child,int type,int rid,struct resource * r)563 xlr_pci_release_resource(device_t bus, device_t child, int type, int rid,
564 		       struct resource *r)
565 {
566 
567 	return (rman_release_resource(r));
568 }
569 
570 static bus_dma_tag_t
xlr_pci_get_dma_tag(device_t bus,device_t child)571 xlr_pci_get_dma_tag(device_t bus, device_t child)
572 {
573 	struct xlr_pcib_softc *sc;
574 
575 	sc = device_get_softc(bus);
576 	return (sc->sc_pci_dmat);
577 }
578 
579 static int
xlr_pci_activate_resource(device_t bus,device_t child,int type,int rid,struct resource * r)580 xlr_pci_activate_resource(device_t bus, device_t child, int type, int rid,
581                       struct resource *r)
582 {
583 
584 	return (rman_activate_resource(r));
585 }
586 
587 static int
xlr_pci_deactivate_resource(device_t bus,device_t child,int type,int rid,struct resource * r)588 xlr_pci_deactivate_resource(device_t bus, device_t child, int type, int rid,
589                           struct resource *r)
590 {
591 
592 	return (rman_deactivate_resource(r));
593 }
594 
595 static int
mips_pci_route_interrupt(device_t bus,device_t dev,int pin)596 mips_pci_route_interrupt(device_t bus, device_t dev, int pin)
597 {
598 	int irq, link;
599 
600 	/*
601 	 * Validate requested pin number.
602 	 */
603 	if ((pin < 1) || (pin > 4))
604 		return (255);
605 
606 	if (xlr_board_info.is_xls) {
607 		link = xls_pcie_link(bus, dev);
608 		irq = xls_pcie_link_irq(link);
609 		if (irq != -1)
610 			return (irq);
611 	} else {
612 		if (pin == 1)
613 			return (PIC_PCIX_IRQ);
614 	}
615 
616 	return (255);
617 }
618 
619 static device_method_t xlr_pcib_methods[] = {
620 	/* Device interface */
621 	DEVMETHOD(device_identify, xlr_pcib_identify),
622 	DEVMETHOD(device_probe, xlr_pcib_probe),
623 	DEVMETHOD(device_attach, xlr_pcib_attach),
624 
625 	/* Bus interface */
626 	DEVMETHOD(bus_read_ivar, xlr_pcib_read_ivar),
627 	DEVMETHOD(bus_write_ivar, xlr_pcib_write_ivar),
628 	DEVMETHOD(bus_alloc_resource, xlr_pci_alloc_resource),
629 	DEVMETHOD(bus_release_resource, xlr_pci_release_resource),
630 	DEVMETHOD(bus_get_dma_tag, xlr_pci_get_dma_tag),
631 	DEVMETHOD(bus_activate_resource, xlr_pci_activate_resource),
632 	DEVMETHOD(bus_deactivate_resource, xlr_pci_deactivate_resource),
633 	DEVMETHOD(bus_setup_intr, mips_platform_pci_setup_intr),
634 	DEVMETHOD(bus_teardown_intr, mips_platform_pci_teardown_intr),
635 
636 	/* pcib interface */
637 	DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots),
638 	DEVMETHOD(pcib_read_config, xlr_pcib_read_config),
639 	DEVMETHOD(pcib_write_config, xlr_pcib_write_config),
640 	DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt),
641 
642 	DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi),
643 	DEVMETHOD(pcib_release_msi, xlr_release_msi),
644 	DEVMETHOD(pcib_map_msi, xlr_map_msi),
645 
646 	DEVMETHOD_END
647 };
648 
649 static driver_t xlr_pcib_driver = {
650 	"pcib",
651 	xlr_pcib_methods,
652 	sizeof(struct xlr_pcib_softc),
653 };
654 
655 DRIVER_MODULE(pcib, iodi, xlr_pcib_driver, pcib_devclass, 0, 0);
656