1 /* $NetBSD: i80321_pci.c,v 1.4 2003/07/15 00:24:54 lukem Exp $ */
2
3 /*-
4 * Copyright (c) 2001, 2002 Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior
23 * written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * PCI configuration support for i80321 I/O Processor chip.
40 */
41
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD: releng/6.4/sys/arm/xscale/i80321/i80321_pci.c 172427 2007-10-03 20:41:35Z jhb $");
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/malloc.h>
48 #include <sys/bus.h>
49 #include <sys/kernel.h>
50 #include <sys/module.h>
51 #define __RMAN_RESOURCE_VISIBLE
52 #include <sys/rman.h>
53
54 #include <machine/bus.h>
55 #include <machine/cpu.h>
56 #include <machine/pcb.h>
57 #include <vm/vm.h>
58 #include <vm/pmap.h>
59 #include <vm/vm_extern.h>
60 #include <machine/pmap.h>
61
62 #include <arm/xscale/i80321/i80321reg.h>
63 #include <arm/xscale/i80321/i80321var.h>
64 #include <arm/xscale/i80321/i80321_intr.h>
65
66 #include <dev/pci/pcib_private.h>
67 #include "pcib_if.h"
68
69 #include <dev/pci/pcireg.h>
70 extern struct i80321_softc *i80321_softc;
71
72 struct i80321_pci_softc {
73 device_t sc_dev;
74 bus_space_tag_t sc_st;
75 bus_space_handle_t sc_atu_sh;
76 bus_space_tag_t sc_pciio;
77 bus_space_tag_t sc_pcimem;
78 int sc_busno;
79 struct rman sc_mem_rman;
80 struct rman sc_io_rman;
81 struct rman sc_irq_rman;
82 uint32_t sc_mem;
83 uint32_t sc_io;
84 };
85
86 static int
87 i80321_pci_probe(device_t dev)
88 {
89 device_set_desc(dev, "i80321 PCI bus");
90 return (0);
91 }
92
93 static int
94 i80321_pci_attach(device_t dev)
95 {
96
97 uint32_t busno;
98 struct i80321_pci_softc *sc = device_get_softc(dev);
99
100 sc->sc_st = i80321_softc->sc_st;
101 sc->sc_atu_sh = i80321_softc->sc_atu_sh;
102 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
103 busno = PCIXSR_BUSNO(busno);
104 if (busno == 0xff)
105 busno = 0;
106 sc->sc_dev = dev;
107 sc->sc_busno = busno;
108 sc->sc_pciio = &i80321_softc->sc_pci_iot;
109 sc->sc_pcimem = &i80321_softc->sc_pci_memt;
110 sc->sc_mem = i80321_softc->sc_owin[0].owin_xlate_lo +
111 VERDE_OUT_XLATE_MEM_WIN_SIZE;
112
113 sc->sc_io = i80321_softc->sc_iow_vaddr;
114 /* Initialize memory and i/o rmans. */
115 sc->sc_io_rman.rm_type = RMAN_ARRAY;
116 sc->sc_io_rman.rm_descr = "I80321 PCI I/O Ports";
117 if (rman_init(&sc->sc_io_rman) != 0 ||
118 rman_manage_region(&sc->sc_io_rman,
119 sc->sc_io,
120 sc->sc_io +
121 VERDE_OUT_XLATE_IO_WIN_SIZE) != 0) {
122 panic("i80321_pci_probe: failed to set up I/O rman");
123 }
124 sc->sc_mem_rman.rm_type = RMAN_ARRAY;
125 sc->sc_mem_rman.rm_descr = "I80321 PCI Memory";
126 if (rman_init(&sc->sc_mem_rman) != 0 ||
127 rman_manage_region(&sc->sc_mem_rman,
128 0, VERDE_OUT_XLATE_MEM_WIN_SIZE) != 0) {
129 panic("i80321_pci_probe: failed to set up memory rman");
130 }
131 sc->sc_irq_rman.rm_type = RMAN_ARRAY;
132 sc->sc_irq_rman.rm_descr = "i80321 PCI IRQs";
133 if (rman_init(&sc->sc_irq_rman) != 0 ||
134 rman_manage_region(&sc->sc_irq_rman, 26, 32) != 0)
135 panic("i80321_pci_probe: failed to set up IRQ rman");
136 device_add_child(dev, "pci",busno);
137 return (bus_generic_attach(dev));
138 }
139
140 static int
141 i80321_pci_maxslots(device_t dev)
142 {
143 return (PCI_SLOTMAX);
144 }
145
146
147
148 static int
149 i80321_pci_conf_setup(struct i80321_pci_softc *sc, int bus, int slot, int func,
150 int reg, uint32_t *addr)
151 {
152 uint32_t busno;
153
154 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
155 busno = PCIXSR_BUSNO(busno);
156 if (busno == 0xff)
157 busno = 0;
158
159 /*
160 * If the bus # is the same as our own, then use Type 0 cycles,
161 * else use Type 1.
162 *
163 * XXX We should filter out all non-private devices here!
164 * XXX How does private space interact with PCI-PCI bridges?
165 */
166 if (bus == busno) {
167 if (slot > (31 - 16))
168 return (1);
169 /*
170 * NOTE: PCI-X requires that that devices updated their
171 * PCIXSR on every config write with the device number
172 * specified in AD[15:11]. If we don't set this field,
173 * each device could end of thinking it is at device 0,
174 * which can cause a number of problems. Doing this
175 * unconditionally should be OK when only PCI devices
176 * are present.
177 */
178 bus &= 0xff;
179 slot &= 0x1f;
180 func &= 0x07;
181
182 *addr = (1U << (slot + 16)) |
183 (slot << 11) | (func << 8) | reg;
184 } else {
185 *addr = (bus << 16) | (slot << 11) | (func << 8) | reg | 1;
186 }
187
188 return (0);
189 }
190
191 static u_int32_t
192 i80321_pci_read_config(device_t dev, int bus, int slot, int func, int reg,
193 int bytes)
194 {
195 struct i80321_pci_softc *sc = device_get_softc(dev);
196 uint32_t isr;
197 uint32_t addr;
198 u_int32_t ret = 0;
199 vm_offset_t va;
200 int err = 0;
201 if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
202 return (-1);
203 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
204 addr/* & ~3*/);
205
206 va = sc->sc_atu_sh;
207 switch (bytes) {
208 case 1:
209 err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 1, &ret);
210 break;
211 case 2:
212 err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 2, &ret);
213 break;
214 case 4:
215 err = badaddr_read((void *)(va + ATU_OCCDR), 4, &ret);
216 break;
217 default:
218 printf("i803218_read_config: invalid size %d\n", bytes);
219 ret = -1;
220 }
221 if (err) {
222
223 isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR);
224 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR,
225 isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM|
226 ATUISR_PTAT|ATUISR_PMPE));
227 return (-1);
228 }
229 return (ret);
230 }
231
232 static void
233 i80321_pci_write_config(device_t dev, int bus, int slot, int func, int reg,
234 u_int32_t data, int bytes)
235 {
236 struct i80321_pci_softc *sc = device_get_softc(dev);
237 uint32_t addr;
238
239 if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr))
240 return;
241
242
243 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR,
244 addr);
245 switch (bytes) {
246 case 1:
247 bus_space_write_1(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
248 (reg & 3), data);
249 break;
250 case 2:
251 bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR +
252 (reg & 3), data);
253 break;
254 case 4:
255 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCDR, data);
256 break;
257 default:
258 printf("i80321_pci_write_config: Invalid size : %d\n", bytes);
259 }
260
261 }
262
263 static int
264 i80321_pci_route_interrupt(device_t pcib, device_t dev, int pin)
265 {
266 int bus;
267 int device;
268 int func;
269 uint32_t busno;
270 struct i80321_pci_softc *sc = device_get_softc(pcib);
271 bus = pci_get_bus(dev);
272 device = pci_get_slot(dev);
273 func = pci_get_function(dev);
274 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR);
275 busno = PCIXSR_BUSNO(busno);
276 if (busno == 0xff)
277 busno = 0;
278 if (bus != busno)
279 goto no_mapping;
280 switch (device) {
281 /* IQ31244 PCI */
282 case 1: /* PCIX-PCIX bridge */
283 /*
284 * The S-ATA chips are behind the bridge, and all of
285 * the S-ATA interrupts are wired together.
286 */
287 return (ICU_INT_XINT(2));
288 case 2: /* PCI slot */
289 /* All pins are wired together. */
290 return (ICU_INT_XINT(3));
291 case 3: /* i82546 dual Gig-E */
292 if (pin == 1 || pin == 2)
293 return (ICU_INT_XINT(0));
294 goto no_mapping;
295 /* IQ80321 PCI */
296 case 4: /* i82544 Gig-E */
297 case 8: /*
298 * Apparently you can set the device for the ethernet adapter
299 * to 8 with a jumper, so handle that as well
300 */
301 if (pin == 1)
302 return (ICU_INT_XINT(0));
303 goto no_mapping;
304 case 6: /* S-PCI-X slot */
305 if (pin == 1)
306 return (ICU_INT_XINT(2));
307 if (pin == 2)
308 return (ICU_INT_XINT(3));
309 goto no_mapping;
310 default:
311 no_mapping:
312 printf("No mapping for %d/%d/%d/%c\n", bus, device, func, pin);
313
314 }
315 return (0);
316
317 }
318
319 static int
320 i80321_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
321 {
322 struct i80321_pci_softc *sc = device_get_softc(dev);
323 switch (which) {
324 case PCIB_IVAR_BUS:
325
326 *result = sc->sc_busno;
327 return (0);
328
329 }
330 return (ENOENT);
331 }
332
333 static int
334 i80321_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
335 {
336 struct i80321_pci_softc * sc = device_get_softc(dev);
337
338 switch (which) {
339 case PCIB_IVAR_BUS:
340 sc->sc_busno = result;
341 return (0);
342 }
343 return (ENOENT);
344 }
345
346 static struct resource *
347 i80321_pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
348 u_long start, u_long end, u_long count, u_int flags)
349 {
350 struct i80321_pci_softc *sc = device_get_softc(bus);
351 struct resource *rv;
352 struct rman *rm;
353 bus_space_tag_t bt = NULL;
354 bus_space_handle_t bh = 0;
355
356 if (type == SYS_RES_IRQ) {
357 rv = malloc(sizeof(*rv), M_DEVBUF, M_WAITOK);
358 rv->r_start = start;
359 rv->r_end = end;
360 rv->r_rid = *rid;
361 return (rv);
362 }
363 switch (type) {
364 case SYS_RES_IRQ:
365 rm = &sc->sc_mem_rman;
366 break;
367 case SYS_RES_MEMORY:
368 rm = &sc->sc_mem_rman;
369 bt = sc->sc_pcimem;
370 bh = (start >= 0x80000000 && start < 0x84000000) ? 0x80000000 :
371 sc->sc_mem;
372 start &= (0x1000000 - 1);
373 end &= (0x1000000 - 1);
374 break;
375 case SYS_RES_IOPORT:
376 rm = &sc->sc_io_rman;
377 bt = sc->sc_pciio;
378 bh = sc->sc_io;
379 if (start < sc->sc_io) {
380 start = start - 0x90000000 + sc->sc_io;
381 end = end - 0x90000000 + sc->sc_io;
382 }
383 break;
384 default:
385 return (NULL);
386 }
387
388 rv = rman_reserve_resource(rm, start, end, count, flags, child);
389 if (rv == NULL)
390 return (NULL);
391 rman_set_rid(rv, *rid);
392 if (type != SYS_RES_IRQ) {
393 if (type == SYS_RES_MEMORY)
394 bh += (rman_get_start(rv));
395 rman_set_bustag(rv, bt);
396 rman_set_bushandle(rv, bh);
397 if (flags & RF_ACTIVE) {
398 if (bus_activate_resource(child, type, *rid, rv)) {
399 rman_release_resource(rv);
400 return (NULL);
401 }
402 }
403 }
404 return (rv);
405 }
406
407 static int
408 i80321_pci_activate_resource(device_t bus, device_t child, int type, int rid,
409 struct resource *r)
410 {
411 u_long p;
412 int error;
413
414 if (type == SYS_RES_MEMORY) {
415 error = bus_space_map(rman_get_bustag(r),
416 rman_get_bushandle(r), rman_get_size(r), 0, &p);
417 if (error)
418 return (error);
419 rman_set_bushandle(r, p);
420
421 }
422 return (rman_activate_resource(r));
423 }
424
425 static int
426 i80321_pci_setup_intr(device_t dev, device_t child,
427 struct resource *ires, int flags, driver_intr_t *intr, void *arg,
428 void **cookiep)
429 {
430 return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
431 intr, arg, cookiep));
432 }
433
434 static int
435 i80321_pci_teardown_intr(device_t dev, device_t child, struct resource *res,
436 void *cookie)
437 {
438 return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
439 }
440
441 static device_method_t i80321_pci_methods[] = {
442 /* Device interface */
443 DEVMETHOD(device_probe, i80321_pci_probe),
444 DEVMETHOD(device_attach, i80321_pci_attach),
445 DEVMETHOD(device_shutdown, bus_generic_shutdown),
446 DEVMETHOD(device_suspend, bus_generic_suspend),
447 DEVMETHOD(device_resume, bus_generic_resume),
448
449 /* Bus interface */
450 DEVMETHOD(bus_print_child, bus_generic_print_child),
451 DEVMETHOD(bus_read_ivar, i80321_read_ivar),
452 DEVMETHOD(bus_write_ivar, i80321_write_ivar),
453 DEVMETHOD(bus_alloc_resource, i80321_pci_alloc_resource),
454 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
455 DEVMETHOD(bus_activate_resource, i80321_pci_activate_resource),
456 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
457 DEVMETHOD(bus_setup_intr, i80321_pci_setup_intr),
458 DEVMETHOD(bus_teardown_intr, i80321_pci_teardown_intr),
459
460 /* pcib interface */
461 DEVMETHOD(pcib_maxslots, i80321_pci_maxslots),
462 DEVMETHOD(pcib_read_config, i80321_pci_read_config),
463 DEVMETHOD(pcib_write_config, i80321_pci_write_config),
464 DEVMETHOD(pcib_route_interrupt, i80321_pci_route_interrupt),
465
466 {0, 0}
467 };
468
469 static driver_t i80321_pci_driver = {
470 "pcib",
471 i80321_pci_methods,
472 sizeof(struct i80321_pci_softc),
473 };
474
475 static devclass_t i80321_pci_devclass;
476
477 DRIVER_MODULE(ipci, iq, i80321_pci_driver, i80321_pci_devclass, 0, 0);
Cache object: eafa7b0359a6609fc1aa84932e8f4401
|