cxgbe/t4_tom: Read the chip's DDP page sizes and save them in a
[freebsd-src.git] / sys / mips / idt / idtpci.c
blob98d199697c71c99d4b360a802aadc45fa1f7d668
1 /* $NetBSD: idtpci.c,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */
3 /*-
4 * Copyright (c) 2007 David Young.
5 * Copyright (c) 2007 Oleskandr Tymoshenko. All rights reserved.
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
9 * conditions are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * 3. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 * OF SUCH DAMAGE.
33 /*-
34 * Copyright (c) 2006 Itronix Inc.
35 * All rights reserved.
37 * Written by Garrett D'Amore for Itronix Inc.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions
41 * are met:
42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 * 3. The name of Itronix Inc. may not be used to endorse
48 * or promote products derived from this software without specific
49 * prior written permission.
51 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
55 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 * ON ANY THEORY OF LIABILITY, WHETHER IN
59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61 * POSSIBILITY OF SUCH DAMAGE.
62 */
64 #include <sys/cdefs.h>
65 __FBSDID("$FreeBSD$");
67 #include <sys/param.h>
68 #include <sys/systm.h>
70 #include <sys/bus.h>
71 #include <sys/interrupt.h>
72 #include <sys/malloc.h>
73 #include <sys/kernel.h>
74 #include <sys/module.h>
75 #include <sys/rman.h>
77 #include <vm/vm.h>
78 #include <vm/pmap.h>
79 #include <vm/vm_extern.h>
81 #include <machine/bus.h>
82 #include <machine/cpu.h>
84 #include <dev/pci/pcivar.h>
85 #include <dev/pci/pcireg.h>
87 #include <dev/pci/pcib_private.h>
88 #include "pcib_if.h"
90 #include <mips/idt/idtreg.h>
92 #ifdef IDTPCI_DEBUG
93 int idtpci_debug = 1;
94 #define IDTPCI_DPRINTF(__fmt, ...) \
95 do { \
96 if (idtpci_debug) \
97 printf((__fmt), __VA_ARGS__); \
98 } while (/*CONSTCOND*/0)
99 #else /* !IDTPCI_DEBUG */
100 #define IDTPCI_DPRINTF(__fmt, ...) do { } while (/*CONSTCOND*/0)
101 #endif /* IDTPCI_DEBUG */
103 #define IDTPCI_TAG_BUS_MASK 0x007f0000
104 #define IDTPCI_TAG_DEVICE_MASK 0x00007800
105 #define IDTPCI_TAG_FUNCTION_MASK 0x00000300
106 #define IDTPCI_TAG_REGISTER_MASK 0x0000007c
108 #define IDTPCI_MAX_DEVICE
110 #define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(IDT_BASE_PCI + (o)))
111 #define REG_WRITE(o,v) (REG_READ(o)) = (v)
113 unsigned int korina_fixup[24] = {
114 0x00000157, 0x00000000, 0x00003c04, 0x00000008, 0x18800001, 0x18000001,
115 0x48000008, 0x00000000, 0x00000000, 0x00000000, 0x011d0214, 0x00000000,
116 0x00000000, 0x00000000, 0x38080101, 0x00008080, 0x00000d6e, 0x00000000,
117 0x00000051, 0x00000000, 0x00000055, 0x18000000, 0x00000000, 0x00000000
120 struct idtpci_softc {
121 device_t sc_dev;
123 int sc_busno;
124 struct rman sc_mem_rman[2];
125 struct rman sc_io_rman[2];
126 struct rman sc_irq_rman;
129 static uint32_t
130 idtpci_make_addr(int bus, int slot, int func, int reg)
133 return 0x80000000 | (bus << 16) | (slot << 11) | (func << 8) | reg;
136 static int
137 idtpci_probe(device_t dev)
140 return (0);
143 static int
144 idtpci_attach(device_t dev)
146 int busno = 0;
147 struct idtpci_softc *sc = device_get_softc(dev);
148 unsigned int pci_data, force_endianess = 0;
149 int i;
150 bus_addr_t addr;
152 sc->sc_dev = dev;
153 sc->sc_busno = busno;
155 /* TODO: Check for host mode */
157 /* Enabled PCI, IG mode, EAP mode */
158 REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP |
159 IDT_PCI_CNTL_EN);
160 /* Wait while "Reset in progress bit" set */
161 while(1) {
162 pci_data = REG_READ(IDT_PCI_STATUS);
163 if((pci_data & IDT_PCI_STATUS_RIP) == 0)
164 break;
167 /* Reset status register */
168 REG_WRITE(IDT_PCI_STATUS, 0);
169 /* Mask interrupts related to status register */
170 REG_WRITE(IDT_PCI_STATUS_MASK, 0xffffffff);
172 /* Disable PCI decoupled access */
173 REG_WRITE(IDT_PCI_DAC, 0);
174 /* Zero status and mask DA interrupts */
175 REG_WRITE(IDT_PCI_DAS, 0);
176 REG_WRITE(IDT_PCI_DASM, 0x7f);
178 /* Init PCI messaging unit */
179 /* Disable messaging interrupts */
180 REG_WRITE(IDT_PCI_IIC, 0);
181 REG_WRITE(IDT_PCI_IIM, 0xffffffff);
182 REG_WRITE(IDT_PCI_OIC, 0);
183 REG_WRITE(IDT_PCI_OIM, 0);
185 #ifdef __MIPSEB__
186 force_endianess = IDT_PCI_LBA_FE;
187 #endif
189 /* LBA0 -- memory window */
190 REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE);
191 REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE);
192 REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess);
193 pci_data = REG_READ(IDT_PCI_LBA0_CNTL);
195 /* LBA1 -- memory window */
196 REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE);
197 REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE);
198 REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess);
199 pci_data = REG_READ(IDT_PCI_LBA1_CNTL);
201 /* LBA2 -- IO window */
202 REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE);
203 REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE);
204 REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI |
205 force_endianess);
206 pci_data = REG_READ(IDT_PCI_LBA2_CNTL);
208 /* LBA3 -- IO window */
209 REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE);
210 REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE);
211 REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI |
212 force_endianess);
213 pci_data = REG_READ(IDT_PCI_LBA3_CNTL);
216 pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR;
217 REG_WRITE(IDT_PCI_CNTL, pci_data);
218 pci_data = REG_READ(IDT_PCI_CNTL);
220 /* Rewrite Target Control register with default values */
221 REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER);
223 /* Perform Korina fixup */
224 addr = idtpci_make_addr(0, 0, 0, 4);
225 for (i = 0; i < 24; i++) {
227 REG_WRITE(IDT_PCI_CFG_ADDR, addr);
228 REG_WRITE(IDT_PCI_CFG_DATA, korina_fixup[i]);
229 __asm__ volatile ("sync");
231 REG_WRITE(IDT_PCI_CFG_ADDR, 0);
232 REG_WRITE(IDT_PCI_CFG_DATA, 0);
233 addr += 4;
236 /* Use KSEG1 to access IO ports for it is uncached */
237 sc->sc_io_rman[0].rm_type = RMAN_ARRAY;
238 sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1";
239 if (rman_init(&sc->sc_io_rman[0]) != 0 ||
240 rman_manage_region(&sc->sc_io_rman[0],
241 IDT_PCIMEM2_BASE, IDT_PCIMEM2_BASE + IDT_PCIMEM2_SIZE - 1) != 0) {
242 panic("idtpci_attach: failed to set up I/O rman");
245 sc->sc_io_rman[1].rm_type = RMAN_ARRAY;
246 sc->sc_io_rman[1].rm_descr = "IDTPCI I/O Ports window 2";
247 if (rman_init(&sc->sc_io_rman[1]) != 0 ||
248 rman_manage_region(&sc->sc_io_rman[1],
249 IDT_PCIMEM3_BASE, IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1) != 0) {
250 panic("idtpci_attach: failed to set up I/O rman");
253 /* Use KSEG1 to access PCI memory for it is uncached */
254 sc->sc_mem_rman[0].rm_type = RMAN_ARRAY;
255 sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1";
256 if (rman_init(&sc->sc_mem_rman[0]) != 0 ||
257 rman_manage_region(&sc->sc_mem_rman[0],
258 IDT_PCIMEM0_BASE, IDT_PCIMEM0_BASE + IDT_PCIMEM0_SIZE) != 0) {
259 panic("idtpci_attach: failed to set up memory rman");
262 sc->sc_mem_rman[1].rm_type = RMAN_ARRAY;
263 sc->sc_mem_rman[1].rm_descr = "IDTPCI PCI Memory window 2";
264 if (rman_init(&sc->sc_mem_rman[1]) != 0 ||
265 rman_manage_region(&sc->sc_mem_rman[1],
266 IDT_PCIMEM1_BASE, IDT_PCIMEM1_BASE + IDT_PCIMEM1_SIZE) != 0) {
267 panic("idtpci_attach: failed to set up memory rman");
270 sc->sc_irq_rman.rm_type = RMAN_ARRAY;
271 sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs";
272 if (rman_init(&sc->sc_irq_rman) != 0 ||
273 rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE,
274 PCI_IRQ_END) != 0)
275 panic("idtpci_attach: failed to set up IRQ rman");
277 device_add_child(dev, "pci", -1);
278 return (bus_generic_attach(dev));
281 static int
282 idtpci_maxslots(device_t dev)
285 return (PCI_SLOTMAX);
288 static uint32_t
289 idtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
290 int bytes)
292 uint32_t data;
293 uint32_t shift, mask;
294 bus_addr_t addr;
296 IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__,
297 bus, slot, func, reg, bytes);
299 addr = idtpci_make_addr(bus, slot, func, reg);
301 REG_WRITE(IDT_PCI_CFG_ADDR, addr);
302 data = REG_READ(IDT_PCI_CFG_DATA);
304 switch (reg % 4) {
305 case 3:
306 shift = 24;
307 break;
308 case 2:
309 shift = 16;
310 break;
311 case 1:
312 shift = 8;
313 break;
314 default:
315 shift = 0;
316 break;
319 switch (bytes) {
320 case 1:
321 mask = 0xff;
322 data = (data >> shift) & mask;
323 break;
324 case 2:
325 mask = 0xffff;
326 if (reg % 4 == 0)
327 data = data & mask;
328 else
329 data = (data >> 16) & mask;
330 break;
331 case 4:
332 break;
333 default:
334 panic("%s: wrong bytes count", __func__);
335 break;
338 __asm__ volatile ("sync");
339 IDTPCI_DPRINTF("%s: read 0x%x\n", __func__, data);
341 return (data);
344 static void
345 idtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
346 uint32_t data, int bytes)
348 bus_addr_t addr;
349 uint32_t reg_data;
350 uint32_t shift, mask;
352 IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__,
353 bus, slot, func, reg, bytes, data);
355 if (bytes != 4) {
356 reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4);
358 switch (reg % 4) {
359 case 3:
360 shift = 24;
361 break;
362 case 2:
363 shift = 16;
364 break;
365 case 1:
366 shift = 8;
367 break;
368 default:
369 shift = 0;
370 break;
373 switch (bytes) {
374 case 1:
375 mask = 0xff;
376 data = (reg_data & ~ (mask << shift)) | (data << shift);
377 break;
378 case 2:
379 mask = 0xffff;
380 if (reg % 4 == 0)
381 data = (reg_data & ~mask) | data;
382 else
383 data = (reg_data & ~ (mask << shift)) |
384 (data << shift);
385 break;
386 case 4:
387 break;
388 default:
389 panic("%s: wrong bytes count", __func__);
390 break;
394 addr = idtpci_make_addr(bus, slot, func, reg);
397 REG_WRITE(IDT_PCI_CFG_ADDR, addr);
398 REG_WRITE(IDT_PCI_CFG_DATA, data);
399 __asm__ volatile ("sync");
401 REG_WRITE(IDT_PCI_CFG_ADDR, 0);
402 REG_WRITE(IDT_PCI_CFG_DATA, 0);
405 static int
406 idtpci_route_interrupt(device_t pcib, device_t device, int pin)
408 static int idt_pci_table[2][12] =
410 { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 },
411 { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 }
413 int dev, bus, irq;
415 dev = pci_get_slot(device);
416 bus = pci_get_bus(device);
417 if (bootverbose)
418 device_printf(pcib, "routing pin %d for %s\n", pin,
419 device_get_nameunit(device));
420 if (bus >= 0 && bus <= 1 &&
421 dev >= 0 && dev <= 11) {
422 irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4);
423 if (bootverbose)
424 printf("idtpci: %d/%d/%d -> IRQ%d\n",
425 pci_get_bus(device), dev, pci_get_function(device),
426 irq);
427 return (irq);
428 } else
429 printf("idtpci: no mapping for %d/%d/%d\n",
430 pci_get_bus(device), dev, pci_get_function(device));
432 return (-1);
435 static int
436 idtpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
438 struct idtpci_softc *sc = device_get_softc(dev);
440 switch (which) {
441 case PCIB_IVAR_DOMAIN:
442 *result = 0;
443 return (0);
444 case PCIB_IVAR_BUS:
445 *result = sc->sc_busno;
446 return (0);
449 return (ENOENT);
452 static int
453 idtpci_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
455 struct idtpci_softc * sc = device_get_softc(dev);
457 switch (which) {
458 case PCIB_IVAR_BUS:
459 sc->sc_busno = result;
460 return (0);
462 return (ENOENT);
465 static struct resource *
466 idtpci_alloc_resource(device_t bus, device_t child, int type, int *rid,
467 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
470 struct idtpci_softc *sc = device_get_softc(bus);
471 struct resource *rv = NULL;
472 struct rman *rm1, *rm2;
474 switch (type) {
475 case SYS_RES_IRQ:
476 rm1 = &sc->sc_irq_rman;
477 rm2 = NULL;
478 break;
479 case SYS_RES_MEMORY:
480 rm1 = &sc->sc_mem_rman[0];
481 rm2 = &sc->sc_mem_rman[1];
482 break;
483 case SYS_RES_IOPORT:
484 rm1 = &sc->sc_io_rman[0];
485 rm2 = &sc->sc_io_rman[1];
486 break;
487 default:
488 return (NULL);
491 rv = rman_reserve_resource(rm1, start, end, count, flags, child);
493 /* Try second window if it exists */
494 if ((rv == NULL) && (rm2 != NULL))
495 rv = rman_reserve_resource(rm2, start, end, count, flags,
496 child);
498 if (rv == NULL)
499 return (NULL);
501 rman_set_rid(rv, *rid);
503 if (flags & RF_ACTIVE) {
504 if (bus_activate_resource(child, type, *rid, rv)) {
505 rman_release_resource(rv);
506 return (NULL);
510 return (rv);
513 static int
514 idtpci_teardown_intr(device_t dev, device_t child, struct resource *res,
515 void *cookie)
518 return (intr_event_remove_handler(cookie));
521 static device_method_t idtpci_methods[] = {
522 /* Device interface */
523 DEVMETHOD(device_probe, idtpci_probe),
524 DEVMETHOD(device_attach, idtpci_attach),
525 DEVMETHOD(device_shutdown, bus_generic_shutdown),
526 DEVMETHOD(device_suspend, bus_generic_suspend),
527 DEVMETHOD(device_resume, bus_generic_resume),
529 /* Bus interface */
530 DEVMETHOD(bus_read_ivar, idtpci_read_ivar),
531 DEVMETHOD(bus_write_ivar, idtpci_write_ivar),
532 DEVMETHOD(bus_alloc_resource, idtpci_alloc_resource),
533 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
534 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
535 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
536 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
537 DEVMETHOD(bus_teardown_intr, idtpci_teardown_intr),
539 /* pcib interface */
540 DEVMETHOD(pcib_maxslots, idtpci_maxslots),
541 DEVMETHOD(pcib_read_config, idtpci_read_config),
542 DEVMETHOD(pcib_write_config, idtpci_write_config),
543 DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt),
545 DEVMETHOD_END
548 static driver_t idtpci_driver = {
549 "pcib",
550 idtpci_methods,
551 sizeof(struct idtpci_softc),
554 static devclass_t idtpci_devclass;
556 DRIVER_MODULE(idtpci, obio, idtpci_driver, idtpci_devclass, 0, 0);