i81342_pci.c revision 331722
1/*-
2 * Copyright (c) 2006 Olivier Houchard
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 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: stable/11/sys/arm/xscale/i8134x/i81342_pci.c 331722 2018-03-29 02:50:57Z eadler $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/types.h>
36#include <sys/rman.h>
37
38#include <machine/bus.h>
39#include <machine/cpu.h>
40#include <machine/pcb.h>
41#include <vm/vm.h>
42#include <vm/pmap.h>
43#include <vm/vm_extern.h>
44
45#include <arm/xscale/i8134x/i81342reg.h>
46#include <arm/xscale/i8134x/i81342var.h>
47
48#include <dev/pci/pcivar.h>
49#include <dev/pci/pcib_private.h>
50#include "pcib_if.h"
51
52#include <dev/pci/pcireg.h>
53
54static pcib_read_config_t i81342_pci_read_config;
55static pcib_write_config_t i81342_pci_write_config;
56
57static int
58i81342_pci_probe(device_t dev)
59{
60	struct i81342_pci_softc *sc;
61
62	sc = device_get_softc(dev);
63	if (device_get_unit(dev) == 0) {
64		device_set_desc(dev, "i81342 PCI-X bus");
65		sc->sc_is_atux = 1;
66	} else {
67		device_set_desc(dev, "i81342 PCIe bus");
68		sc->sc_is_atux = 0;
69	}
70	return (0);
71}
72
73#define PCI_MAPREG_MEM_PREFETCHABLE_MASK	0x00000008
74#define PCI_MAPREG_MEM_TYPE_64BIT		0x00000004
75
76static int
77i81342_pci_attach(device_t dev)
78{
79	struct i81342_softc *parent_sc;
80	struct i81342_pci_softc *sc;
81	uint32_t memsize, memstart;
82	uint32_t reg;
83	int func;
84	uint32_t busno;
85
86	sc = device_get_softc(dev);
87	parent_sc = device_get_softc(device_get_parent(dev));
88	sc->sc_atu_sh = sc->sc_is_atux ? parent_sc->sc_atux_sh :
89	    parent_sc->sc_atue_sh;
90	sc->sc_st = parent_sc->sc_st;
91	if (bus_space_read_4(sc->sc_st, parent_sc->sc_sh, IOP34X_ESSTSR0)
92	    & IOP34X_INT_SEL_PCIX) {
93		if (sc->sc_is_atux)
94			func = 5;
95		else
96			func = 0;
97	} else {
98		if (sc->sc_is_atux)
99			func = 0;
100		else
101			func = 5;
102	}
103	i81342_io_bs_init(&sc->sc_pciio, sc);
104	i81342_mem_bs_init(&sc->sc_pcimem, sc);
105	i81342_sdram_bounds(sc->sc_st, IOP34X_VADDR, &memstart, &memsize);
106	if (sc->sc_is_atux) {
107		reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
108		if (reg & ATUX_P_RSTOUT) {
109			bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR,
110			    reg &~ ATUX_P_RSTOUT);
111			DELAY(200);
112		}
113	}
114	/* Setup the Inbound windows. */
115	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR0, 0);
116	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR0, 0);
117	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 0);
118
119	/* Set the mapping Physical address <=> PCI address */
120	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR1,
121	    memstart | PCI_MAPREG_MEM_PREFETCHABLE_MASK |
122	    PCI_MAPREG_MEM_TYPE_64BIT);
123	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR1, 0);
124	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1,
125	    rounddown2(~(0xfff), memsize));
126	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR1, memstart);
127	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUTVR1, 0);
128
129	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR2, 0);
130	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR2, 0);
131	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 0);
132
133	/* Setup the Outbound IO Bar */
134	if (sc->sc_is_atux)
135		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR,
136		    (IOP34X_PCIX_OIOBAR >> 4) | func);
137	else
138		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR,
139		    (IOP34X_PCIE_OIOBAR >> 4) | func);
140
141	/* Setup the Outbound windows */
142	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR0, 0);
143	if (sc->sc_is_atux)
144		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1,
145		    (IOP34X_PCIX_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) |
146		    ATU_OUMBAR_EN);
147	else
148		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1,
149		    (IOP34X_PCIE_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) |
150		    ATU_OUMBAR_EN);
151	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, 0);
152	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR2, 0);
153	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR3, 0);
154
155	/* Enable the outbound windows. */
156	reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_CR);
157	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_CR,
158	    reg | ATU_CR_OUT_EN);
159
160	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR,
161	    bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK);
162	/*
163	 * Enable bus mastering, memory access, SERR, and parity
164	 * checking on the ATU.
165	 */
166	if (sc->sc_is_atux) {
167		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
168		busno = PCIXSR_BUSNO(busno);
169	} else {
170		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
171		busno = PCIE_BUSNO(busno);
172	}
173	reg = bus_space_read_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD);
174	reg |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN |
175	    PCIM_CMD_SERRESPEN;
176	bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD, reg);
177	sc->sc_busno = busno;
178	/* Initialize memory and i/o rmans. */
179	sc->sc_io_rman.rm_type = RMAN_ARRAY;
180	sc->sc_io_rman.rm_descr = "I81342 PCI I/O Ports";
181	if (rman_init(&sc->sc_io_rman) != 0 ||
182		rman_manage_region(&sc->sc_io_rman,
183		sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
184		IOP34X_PCIE_OIOBAR_VADDR,
185		(sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
186		IOP34X_PCIE_OIOBAR_VADDR) + IOP34X_OIOBAR_SIZE) != 0) {
187		panic("i81342_pci_probe: failed to set up I/O rman");
188	}
189	sc->sc_mem_rman.rm_type = RMAN_ARRAY;
190	sc->sc_mem_rman.rm_descr = "I81342 PCI Memory";
191	if (rman_init(&sc->sc_mem_rman) != 0 ||
192	    rman_manage_region(&sc->sc_mem_rman,
193	    0, 0xffffffff) != 0) {
194		panic("i81342_pci_attach: failed to set up memory rman");
195	}
196	sc->sc_irq_rman.rm_type = RMAN_ARRAY;
197	sc->sc_irq_rman.rm_descr = "i81342 PCI IRQs";
198	if (sc->sc_is_atux) {
199		if (rman_init(&sc->sc_irq_rman) != 0 ||
200		    rman_manage_region(&sc->sc_irq_rman, ICU_INT_XINT0,
201		    ICU_INT_XINT3) != 0)
202			panic("i83142_pci_attach: failed to set up IRQ rman");
203	} else {
204		if (rman_init(&sc->sc_irq_rman) != 0 ||
205		    rman_manage_region(&sc->sc_irq_rman, ICU_INT_ATUE_MA,
206		    ICU_INT_ATUE_MD) != 0)
207			panic("i81342_pci_attach: failed to set up IRQ rman");
208
209	}
210	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR,
211	    bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK);
212	device_add_child(dev, "pci", -1);
213	return (bus_generic_attach(dev));
214}
215
216static int
217i81342_pci_maxslots(device_t dev)
218{
219
220	return (PCI_SLOTMAX);
221}
222
223static void
224i81342_pci_conf_setup(struct i81342_pci_softc *sc, int bus, int slot, int func,
225    int reg, uint32_t *addr)
226{
227	uint32_t busno;
228
229	if (sc->sc_is_atux) {
230		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
231		busno = PCIXSR_BUSNO(busno);
232	} else {
233		busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR);
234		busno = PCIE_BUSNO(busno);
235	}
236	bus &= 0xff;
237	slot &= 0x1f;
238	func &= 0x7;
239	if (sc->sc_is_atux) {
240		if (busno == bus)
241			*addr = (1 << (slot + 16)) | (slot << 11) |
242			    (func << 8) | reg;
243		else
244			*addr = (bus << 16) | (slot << 11) | (func << 11) |
245			    reg | 1;
246	} else {
247		*addr = (bus << 24) | (slot << 19) | (func << 16) | reg;
248		if (bus != busno)
249			*addr |= 1;
250	}
251}
252
253static u_int32_t
254i81342_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func,
255    u_int reg, int bytes)
256{
257	struct i81342_pci_softc *sc = device_get_softc(dev);
258	uint32_t addr;
259	uint32_t ret = 0;
260	uint32_t isr;
261	int err = 0;
262	vm_offset_t va;
263
264	i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr);
265	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ?
266	    ATUX_OCCAR : ATUE_OCCAR, addr);
267	if (sc->sc_is_atux)
268		va = sc->sc_atu_sh + ATUX_OCCDR;
269	else
270		va = sc->sc_atu_sh + ATUE_OCCDR;
271	switch (bytes) {
272	case 1:
273		err = badaddr_read((void*)(va + (reg & 3)), 1, &ret);
274		break;
275	case 2:
276		err = badaddr_read((void*)(va + (reg & 3)), 2, &ret);
277		break;
278	case 4:
279		err = badaddr_read((void *)(va) , 4, &ret);
280		break;
281	default:
282		printf("i81342_read_config: invalid size %d\n", bytes);
283		ret = -1;
284	}
285	if (err) {
286		isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR);
287		if (sc->sc_is_atux)
288			isr &= ATUX_ISR_ERRMSK;
289		else
290			isr &= ATUE_ISR_ERRMSK;
291		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, isr);
292		ret = -1;
293	}
294
295	return (ret);
296}
297
298static void
299i81342_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func,
300    u_int reg, u_int32_t data, int bytes)
301{
302	struct i81342_pci_softc *sc = device_get_softc(dev);
303	uint32_t addr;
304	vm_offset_t va;
305
306	i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr);
307	bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ?
308	    ATUX_OCCAR : ATUE_OCCAR, addr);
309	va = sc->sc_is_atux ? ATUX_OCCDR : ATUE_OCCDR;
310		switch (bytes) {
311	case 1:
312		bus_space_write_1(sc->sc_st, sc->sc_atu_sh, va + (reg & 3)
313		    , data);
314		break;
315	case 2:
316		bus_space_write_2(sc->sc_st, sc->sc_atu_sh, va + (reg & 3)
317		    , data);
318		break;
319	case 4:
320		bus_space_write_4(sc->sc_st, sc->sc_atu_sh, va, data);
321		break;
322	default:
323		printf("i81342_pci_write_config: Invalid size : %d\n", bytes);
324	}
325
326
327}
328
329static struct resource *
330i81342_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
331   rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
332{
333	struct i81342_pci_softc *sc = device_get_softc(bus);
334	struct resource *rv;
335	struct rman *rm;
336	bus_space_tag_t bt = NULL;
337	bus_space_handle_t bh = 0;
338
339	switch (type) {
340	case SYS_RES_IRQ:
341		rm = &sc->sc_irq_rman;
342		break;
343	case SYS_RES_MEMORY:
344		rm = &sc->sc_mem_rman;
345		bt = &sc->sc_pcimem;
346		bh = 0;
347		break;
348	case SYS_RES_IOPORT:
349		rm = &sc->sc_io_rman;
350		bt = &sc->sc_pciio;
351		bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR :
352		    IOP34X_PCIE_OIOBAR_VADDR;
353		start += bh;
354		end += bh;
355		break;
356	default:
357		return (NULL);
358	}
359
360	rv = rman_reserve_resource(rm, start, end, count, flags, child);
361	if (rv == NULL)
362		return (NULL);
363	rman_set_rid(rv, *rid);
364	if (type != SYS_RES_IRQ) {
365		if (type == SYS_RES_MEMORY)
366			bh += (rman_get_start(rv));
367		rman_set_bustag(rv, bt);
368		rman_set_bushandle(rv, bh);
369		if (flags & RF_ACTIVE) {
370			if (bus_activate_resource(child, type, *rid, rv)) {
371				rman_release_resource(rv);
372				return (NULL);
373			}
374		}
375	}
376	return (rv);
377
378
379	return (NULL);
380}
381
382static int
383i81342_pci_activate_resource(device_t bus, device_t child, int type, int rid,
384    struct resource *r)
385{
386	bus_space_handle_t p;
387	int error;
388
389	if (type == SYS_RES_MEMORY) {
390		error = bus_space_map(rman_get_bustag(r),
391		    rman_get_bushandle(r), rman_get_size(r), 0, &p);
392		if (error)
393			return (error);
394		rman_set_bushandle(r, p);
395
396	}
397	return (rman_activate_resource(r));
398}
399
400static int
401i81342_pci_setup_intr(device_t dev, device_t child, struct resource *ires,
402    int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
403    void **cookiep)
404{
405
406	return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
407	    filt, intr, arg, cookiep));
408}
409
410
411
412static int
413i81342_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
414    void *cookie)
415{
416	return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
417}
418
419static int
420i81342_pci_route_interrupt(device_t pcib, device_t dev, int pin)
421{
422	struct i81342_pci_softc *sc;
423	int device;
424
425	device = pci_get_slot(dev);
426	sc = device_get_softc(pcib);
427	/* XXX: Is board specific */
428	if (sc->sc_is_atux) {
429		/* PCI-X */
430		switch(device) {
431		case 1:
432			switch (pin) {
433			case 1:
434				return (ICU_INT_XINT1);
435			case 2:
436				return (ICU_INT_XINT2);
437			case 3:
438				return (ICU_INT_XINT3);
439			case 4:
440				return (ICU_INT_XINT0);
441			default:
442				break;
443			}
444		case 2:
445			switch (pin) {
446			case 1:
447				return (ICU_INT_XINT2);
448			case 2:
449				return (ICU_INT_XINT3);
450			case 3:
451				return (ICU_INT_XINT2);
452			case 4:
453				return (ICU_INT_XINT3);
454			default:
455				break;
456			}
457		}
458
459	} else {
460		switch (pin) {
461		case 1:
462			return (ICU_INT_ATUE_MA);
463		case 2:
464			return (ICU_INT_ATUE_MB);
465		case 3:
466			return (ICU_INT_ATUE_MC);
467		case 4:
468			return (ICU_INT_ATUE_MD);
469		default:
470			break;
471		}
472	}
473	printf("Warning: couldn't map %s IRQ for device %d pin %d\n",
474	    sc->sc_is_atux ? "PCI-X" : "PCIe", device, pin);
475	return (-1);
476}
477
478static int
479i81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
480{
481	struct i81342_pci_softc *sc = device_get_softc(dev);
482	switch (which) {
483	case PCIB_IVAR_DOMAIN:
484		*result = 0;
485		return (0);
486	case PCIB_IVAR_BUS:
487		*result = sc->sc_busno;
488		return (0);
489
490	}
491	return (ENOENT);
492}
493
494static int
495i81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
496{
497	struct i81342_pci_softc * sc = device_get_softc(dev);
498
499	switch (which) {
500	case PCIB_IVAR_DOMAIN:
501		return (EINVAL);
502	case PCIB_IVAR_BUS:
503		sc->sc_busno = result;
504		return (0);
505	}
506	return (ENOENT);
507}
508
509static device_method_t i81342_pci_methods[] = {
510	/* Device interface */
511	DEVMETHOD(device_probe,		i81342_pci_probe),
512	DEVMETHOD(device_attach,	i81342_pci_attach),
513	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
514	DEVMETHOD(device_suspend,	bus_generic_suspend),
515	DEVMETHOD(device_resume,	bus_generic_resume),
516
517	/* Bus interface */
518	DEVMETHOD(bus_read_ivar,	i81342_read_ivar),
519	DEVMETHOD(bus_write_ivar,	i81342_write_ivar),
520	DEVMETHOD(bus_alloc_resource,	i81342_pci_alloc_resource),
521	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
522	DEVMETHOD(bus_activate_resource, i81342_pci_activate_resource),
523	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
524	DEVMETHOD(bus_setup_intr,	i81342_pci_setup_intr),
525	DEVMETHOD(bus_teardown_intr,	i81342_pci_teardown_intr),
526
527	/* pcib interface */
528	DEVMETHOD(pcib_maxslots,	i81342_pci_maxslots),
529	DEVMETHOD(pcib_read_config,	i81342_pci_read_config),
530	DEVMETHOD(pcib_write_config,	i81342_pci_write_config),
531	DEVMETHOD(pcib_route_interrupt,	i81342_pci_route_interrupt),
532
533	DEVMETHOD_END
534};
535
536static driver_t i81342_pci_driver = {
537	"pcib",
538	i81342_pci_methods,
539	sizeof(struct i81342_pci_softc),
540};
541
542static devclass_t i81342_pci_devclass;
543
544DRIVER_MODULE(ipci, iq, i81342_pci_driver, i81342_pci_devclass, 0, 0);
545