2 * Copyright (c) 2000 Matthew Jacob
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #define __RMAN_RESOURCE_VISIBLE
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/mutex.h>
40 #include <machine/bus.h>
41 #include <machine/md_var.h>
44 #include <sys/interrupt.h>
46 #include <machine/swiz.h>
47 #include <machine/intr.h>
48 #include <machine/intrcnt.h>
49 #include <machine/resource.h>
50 #include <machine/sgmap.h>
51 #include <machine/prom.h>
53 #include <vm/vm_page.h>
56 #include <alpha/mcbus/mcbusreg.h>
57 #include <alpha/mcbus/mcbusvar.h>
59 #include <alpha/mcbus/mcpciareg.h>
60 #include <alpha/mcbus/mcpciavar.h>
61 #include <alpha/pci/pcibus.h>
62 #include <dev/pci/pcireg.h>
63 #include <dev/pci/pcivar.h>
65 #include "alphapci_if.h"
68 static devclass_t mcpcia_devclass;
70 /* We're only allowing for one MCBUS right now */
71 static device_t mcpcias[MCPCIA_PER_MCBUS];
73 #define KV(pa) ((void *)ALPHA_PHYS_TO_K0SEG(pa))
76 struct mcpcia_softc *next;
77 device_t dev; /* backpointer */
78 u_int64_t sysbase; /* shorthand */
79 vm_offset_t dmem_base; /* dense memory */
80 vm_offset_t smem_base; /* sparse memory */
81 vm_offset_t io_base; /* sparse i/o */
82 int mcpcia_inst; /* our mcpcia instance # */
83 struct swiz_space io_space; /* accessor for ports */
84 struct swiz_space mem_space; /* accessor for memory */
85 struct rman io_rman; /* resource manager for ports */
86 struct rman mem_rman; /* resource manager for memory */
88 static struct mcpcia_softc *mcpcia_eisa = NULL;
89 extern void dec_kn300_cons_init(void);
91 static driver_intr_t mcpcia_intr;
92 static void mcpcia_enable_intr(struct mcpcia_softc *, int);
93 static void mcpcia_disable_intr(struct mcpcia_softc *, int);
96 * SGMAP window for ISA: 8M at 8M
98 #define MCPCIA_ISA_SG_MAPPED_BASE (8*1024*1024)
99 #define MCPCIA_ISA_SG_MAPPED_SIZE (8*1024*1024)
102 * Direct-mapped window: 2G at 2G
104 #define MCPCIA_DIRECT_MAPPED_BASE (2UL*1024UL*1024UL*1024UL)
105 #define MCPCIA_DIRECT_MAPPED_SIZE (2UL*1024UL*1024UL*1024UL)
108 * SGMAP window for PCI: 1G at 1G
110 #define MCPCIA_PCI_SG_MAPPED_BASE (1UL*1024UL*1024UL*1024UL)
111 #define MCPCIA_PCI_SG_MAPPED_SIZE (1UL*1024UL*1024UL*1024UL)
113 #define MCPCIA_SGTLB_INVALIDATE(sc) \
116 REGVAL(MCPCIA_SG_TBIA(sc)) = 0xdeadbeef; \
120 static void mcpcia_dma_init(struct mcpcia_softc *);
121 static void mcpcia_sgmap_map(void *, bus_addr_t, vm_offset_t);
123 #define MCPCIA_SOFTC(dev) (struct mcpcia_softc *) device_get_softc(dev)
125 static struct mcpcia_softc *mcpcia_root;
128 * Early console support requires us to partially probe the bus to
129 * find the ISA bus resources.
132 mcpcia_init(int gid, int mid)
134 static struct swiz_space io_space;
135 static struct swiz_space mem_space;
137 vm_offset_t regs, io_base, smem_base;
139 sysbase = MCBUS_IOSPACE |
140 (((u_int64_t) gid) << MCBUS_GID_SHIFT) |
141 (((u_int64_t) mid) << MCBUS_MID_SHIFT);
143 if (EISA_PRESENT(REGVAL(sysbase
145 | _MCPCIA_PCI_REV))) {
147 * Define temporary spaces for bootstrap i/o.
149 regs = (vm_offset_t) KV(sysbase);
150 io_base = regs + MCPCIA_PCI_IOSPACE;
151 smem_base = regs + MCPCIA_PCI_SPARSE;
153 swiz_init_space(&io_space, io_base);
154 swiz_init_space(&mem_space, smem_base);
156 busspace_isa_io = (struct alpha_busspace *) &io_space;
157 busspace_isa_mem = (struct alpha_busspace *) &mem_space;
162 mcpcia_probe(device_t dev)
166 struct mcpcia_softc *xc, *sc = MCPCIA_SOFTC(dev);
168 unit = device_get_unit(dev);
170 printf("%s: already attached\n", device_get_nameunit(dev));
173 sc->mcpcia_inst = unit;
174 if ((xc = mcpcia_root) == NULL) {
181 sc->dev = mcpcias[unit] = dev;
183 device_set_desc(dev, "MCPCIA PCI Adapter");
185 pci_init_resources();
187 child = device_add_child(dev, "pci", -1);
188 device_set_ivars(child, &sc->mcpcia_inst);
193 mcpcia_attach(device_t dev)
195 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
196 device_t p = device_get_parent(dev);
202 mid = mcbus_get_mid(dev);
203 gid = mcbus_get_gid(dev);
205 sc->sysbase = MCBUS_IOSPACE |
206 (((u_int64_t) gid) << MCBUS_GID_SHIFT) | \
207 (((u_int64_t) mid) << MCBUS_MID_SHIFT);
208 regs = (vm_offset_t) KV(sc->sysbase);
209 sc->dmem_base = regs + MCPCIA_PCI_DENSE;
210 sc->smem_base = regs + MCPCIA_PCI_SPARSE;
211 sc->io_base = regs + MCPCIA_PCI_IOSPACE;
213 swiz_init_space(&sc->io_space, sc->io_base);
214 swiz_init_space(&sc->mem_space, sc->smem_base);
216 sc->io_rman.rm_start = 0;
217 sc->io_rman.rm_end = ~0u;
218 sc->io_rman.rm_type = RMAN_ARRAY;
219 sc->io_rman.rm_descr = "I/O ports";
220 if (rman_init(&sc->io_rman)
221 || rman_manage_region(&sc->io_rman, 0x0, (1L << 32)))
222 panic("mcpcia_attach: io_rman");
224 sc->mem_rman.rm_start = 0;
225 sc->mem_rman.rm_end = ~0u;
226 sc->mem_rman.rm_type = RMAN_ARRAY;
227 sc->mem_rman.rm_descr = "I/O memory";
228 if (rman_init(&sc->mem_rman)
229 || rman_manage_region(&sc->mem_rman, 0x0, (1L << 32)))
230 panic("mcpcia_attach: mem_rman");
233 * Disable interrupts and clear errors prior to probing
235 REGVAL(MCPCIA_INT_MASK0(sc)) = 0;
236 REGVAL(MCPCIA_INT_MASK1(sc)) = 0;
237 REGVAL(MCPCIA_CAP_ERR(sc)) = 0xFFFFFFFF;
243 ctl = REGVAL(MCPCIA_PCI_REV(sc));
244 printf("%s: Horse Revision %d, %s Handed Saddle Revision %d,"
245 " CAP Revision %d\n", device_get_nameunit(dev), HORSE_REV(ctl),
246 (SADDLE_TYPE(ctl) & 1)? "Right": "Left", SADDLE_REV(ctl),
250 * See if we're the fella with the EISA bus...
253 if (EISA_PRESENT(REGVAL(MCPCIA_PCI_REV(sc)))) {
258 * Set up DMA stuff here.
264 * Register our interrupt service requirements with our parent.
267 BUS_SETUP_INTR(p, dev, NULL, INTR_TYPE_MISC, mcpcia_intr, 0, &intr);
269 if (sc == mcpcia_eisa) {
270 busspace_isa_io = (struct alpha_busspace *)
272 busspace_isa_mem = (struct alpha_busspace *)
275 * Enable EISA interrupts.
277 mcpcia_enable_intr(sc, 16);
279 bus_generic_attach(dev);
285 mcpcia_enable_intr(struct mcpcia_softc *sc, int irq)
288 REGVAL(MCPCIA_INT_MASK0(sc)) |= (1 << irq);
293 mcpcia_disable_intr(struct mcpcia_softc *sc, int irq)
297 * We need to write to INT_REQ as well as INT_MASK0 in case we
298 * are trying to mask an interrupt which is already
299 * asserted. Writing a 1 bit to INT_REQ clears the
300 * corresponding bit in the register.
302 REGVAL(MCPCIA_INT_MASK0(sc)) &= ~(1 << irq);
303 REGVAL(MCPCIA_INT_REQ(sc)) = (1 << irq);
308 mcpcia_disable_intr_vec(uintptr_t vector)
311 struct mcpcia_softc *sc = mcpcia_root;
313 if (vector < MCPCIA_VEC_PCI) {
314 printf("EISA disable (0x%lx)\n", vector);
318 if (vector == MCPCIA_VEC_NCR) {
323 tmp = vector - MCPCIA_VEC_PCI;
324 mid = (tmp / MCPCIA_VECWIDTH_PER_MCPCIA) + 4;
325 tmp &= (MCPCIA_VECWIDTH_PER_MCPCIA - 1);
326 slot = tmp / MCPCIA_VECWIDTH_PER_SLOT;
327 if (slot < 2 || slot > 5) {
328 printf("Bad slot (%d) for vector %lx\n", slot, vector);
331 tmp -= (2 * MCPCIA_VECWIDTH_PER_SLOT);
332 irq = (tmp >> MCPCIA_VECWIDTH_PER_INTPIN) & 0xf;
334 /* printf("D<%03x>=%d,%d\n", vector, mid, irq); */
336 if (mcbus_get_mid(sc->dev) == mid) {
342 panic("couldn't find MCPCIA softc for vector 0x%lx", vector);
344 mtx_lock_spin(&icu_lock);
345 mcpcia_disable_intr(sc, irq);
346 mtx_unlock_spin(&icu_lock);
350 mcpcia_enable_intr_vec(uintptr_t vector)
353 struct mcpcia_softc *sc = mcpcia_root;
355 if (vector < MCPCIA_VEC_PCI) {
356 printf("EISA ensable (0x%lx)\n", vector);
360 if (vector == MCPCIA_VEC_NCR) {
365 tmp = vector - MCPCIA_VEC_PCI;
366 mid = (tmp / MCPCIA_VECWIDTH_PER_MCPCIA) + 4;
367 tmp &= (MCPCIA_VECWIDTH_PER_MCPCIA - 1);
368 slot = tmp / MCPCIA_VECWIDTH_PER_SLOT;
369 if (slot < 2 || slot > 5) {
370 printf("Bad slot (%d) for vector %lx\n", slot, vector);
373 tmp -= (2 * MCPCIA_VECWIDTH_PER_SLOT);
374 irq = (tmp >> MCPCIA_VECWIDTH_PER_INTPIN) & 0xf;
376 /* printf("E<%03x>=%d,%d\n", vector, mid, irq); */
378 if (mcbus_get_mid(sc->dev) == mid) {
384 panic("couldn't find MCPCIA softc for vector 0x%lx", vector);
386 mtx_lock_spin(&icu_lock);
387 mcpcia_enable_intr(sc, irq);
388 mtx_unlock_spin(&icu_lock);
392 mcpcia_pci_route_interrupt(device_t bus, device_t dev, int pin)
397 * Validate requested pin number.
399 if ((pin < 1) || (pin > 4)) {
400 printf("mcpcia_pci_route_interrupt: bad interrupt pin %d\n",
405 slot = pci_get_slot(dev);
406 mid = mcbus_get_mid(bus);
409 printf("mcpcia_pci_route_interrupt: called for slot=%d, pin=%d, mid=%d\n", slot, pin, mid);
412 if (mid == 5 && slot == 1) {
413 irq = 16; /* MID 5, slot 1, is the internal NCR 53c810 */
414 } else if (slot >= 2 && slot <= 5) {
415 irq = ((slot - 2) * 4) + (pin - 1);
417 printf("mcpcia_pci_route_interrupt: weird device number %d\n",
426 mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags,
427 driver_intr_t *intr, void *arg, void **cp)
429 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
430 int mid, birq, irq, error, h;
433 mid = mcbus_get_mid(dev);
435 error = rman_activate_resource(ir);
440 * We now construct a vector as the hardware would, unless
441 * this is the internal NCR 53c810 interrupt.
447 ((mid - MCPCIA_PCI_MIDMIN) * MCPCIA_VECWIDTH_PER_MCPCIA) +
448 irq * MCPCIA_VECWIDTH_PER_INTPIN +
449 2 * MCPCIA_VECWIDTH_PER_SLOT;
451 birq = irq + INTRCNT_KN300_IRQ;
452 error = alpha_setup_intr(device_get_nameunit(child), h,
453 intr, arg, flags, cp, &intrcnt[birq],
454 mcpcia_disable_intr_vec, mcpcia_enable_intr_vec);
457 mtx_lock_spin(&icu_lock);
458 mcpcia_enable_intr(sc, irq);
459 mtx_unlock_spin(&icu_lock);
460 device_printf(child, "interrupting at IRQ 0x%x (vec 0x%x)\n",
466 mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c)
468 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
470 mtx_lock_spin(&icu_lock);
471 mcpcia_disable_intr(sc, i->r_start);
472 mtx_unlock_spin(&icu_lock);
473 alpha_teardown_intr(c);
474 return (rman_deactivate_resource(i));
478 mcpcia_read_ivar(device_t dev, device_t child, int which, u_long *result)
489 mcpcia_cvt_dense(device_t dev, vm_offset_t addr)
491 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
493 addr &= 0xffffffffUL;
494 return (void *) KV(addr | sc->dmem_base);
498 static struct alpha_busspace *
499 mcpcia_get_bustag(device_t dev, int type)
501 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
505 return (struct alpha_busspace *) &sc->io_space;
508 return (struct alpha_busspace *) &sc->mem_space;
515 mcpcia_get_rman(device_t dev, int type)
517 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
524 return &sc->mem_rman;
531 mcpcia_maxslots(device_t dev)
533 return (MCPCIA_MAXDEV);
537 mcpcia_read_config(device_t dev, int bus, int slot, int func,
540 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
541 u_int32_t *dp, data, rvp;
544 if ((off == PCIR_INTLINE) && (sz == 1)) {
545 /* SRM left bad value; let intr_route fill them in later */
552 * There's nothing in slot 0 on a primary bus.
554 if (bus == 0 && (slot < 1 || slot >= MCPCIA_MAXDEV))
560 paddr |= ((sz - 1) << 3);
561 paddr |= ((unsigned long) ((off >> 2) << 7));
562 paddr |= MCPCIA_PCI_CONF;
563 paddr |= sc->sysbase;
564 dp = (u_int32_t *)KV(paddr);
567 printf("CFGREAD MID %d %d.%d.%d sz %d off %d -> paddr 0x%x",
568 mcbus_get_mid(dev), bus , slot, func, sz, off, paddr);
570 if (badaddr(dp, sizeof (*dp)) == 0) {
575 rvp = SPARSE_BYTE_EXTRACT(off, data);
576 } else if (sz == 2) {
577 rvp = SPARSE_WORD_EXTRACT(off, data);
586 printf(" data 0x%x -> 0x%x\n", data, rvp);
592 mcpcia_write_config(device_t dev, int bus, int slot, int func,
593 int off, u_int32_t data, int sz)
595 struct mcpcia_softc *sc = MCPCIA_SOFTC(dev);
600 * There's nothing in slot 0 on a primary bus.
602 if (bus != 0 && (slot < 1 || slot >= MCPCIA_MAXDEV))
608 paddr |= ((sz - 1) << 3);
609 paddr |= ((unsigned long) ((off >> 2) << 7));
610 paddr |= MCPCIA_PCI_CONF;
611 paddr |= sc->sysbase;
612 dp = (u_int32_t *)KV(paddr);
614 if (badaddr(dp, sizeof (*dp)) == 0) {
617 new_data = SPARSE_BYTE_INSERT(off, data);
618 } else if (sz == 2) {
619 new_data = SPARSE_WORD_INSERT(off, data);
625 printf("CFGWRITE MID%d %d.%d.%d sz %d off %d paddr %lx, data %x new_data %x\n",
626 mcbus_get_mid(dev), bus , slot, func, sz, off, paddr, data, new_data);
634 mcpcia_sgmap_map(void *arg, bus_addr_t ba, vm_offset_t pa)
636 u_int64_t *sgtable = arg;
637 int index = alpha_btop(ba - MCPCIA_ISA_SG_MAPPED_BASE);
641 panic("mcpcia_sgmap_map: can't map address 0x%lx", pa);
642 sgtable[index] = ((pa >> 13) << 1) | 1;
647 MCPCIA_SGTLB_INVALIDATE(mcpcia_eisa);
651 mcpcia_dma_init(struct mcpcia_softc *sc)
655 * Disable all windows first.
658 REGVAL(MCPCIA_W0_BASE(sc)) = 0;
659 REGVAL(MCPCIA_W1_BASE(sc)) = 0;
660 REGVAL(MCPCIA_W2_BASE(sc)) = 0;
661 REGVAL(MCPCIA_W3_BASE(sc)) = 0;
662 REGVAL(MCPCIA_T0_BASE(sc)) = 0;
663 REGVAL(MCPCIA_T1_BASE(sc)) = 0;
664 REGVAL(MCPCIA_T2_BASE(sc)) = 0;
665 REGVAL(MCPCIA_T3_BASE(sc)) = 0;
669 * Set up window 0 as an 8MB SGMAP-mapped window starting at 8MB.
670 * Do this only for the EISA carrying MCPCIA. Partly because
671 * there's only one chipset sgmap thingie.
674 if (sc == mcpcia_eisa) {
676 REGVAL(MCPCIA_W0_MASK(sc)) = MCPCIA_WMASK_8M;
678 sgtable = contigmalloc(8192, M_DEVBUF,
679 M_NOWAIT, 0, 1L<<34, 32<<10, 1L<<34);
681 if (sgtable == NULL) {
682 panic("mcpcia_dma_init: cannot allocate sgmap");
685 REGVAL(MCPCIA_T0_BASE(sc)) =
686 pmap_kextract((vm_offset_t)sgtable) >> MCPCIA_TBASEX_SHIFT;
689 REGVAL(MCPCIA_W0_BASE(sc)) = MCPCIA_WBASE_EN |
690 MCPCIA_WBASE_SG | MCPCIA_ISA_SG_MAPPED_BASE;
692 MCPCIA_SGTLB_INVALIDATE(sc);
693 chipset.sgmap = sgmap_map_create(MCPCIA_ISA_SG_MAPPED_BASE,
694 MCPCIA_ISA_SG_MAPPED_BASE + MCPCIA_ISA_SG_MAPPED_SIZE - 1,
695 mcpcia_sgmap_map, sgtable);
699 * Set up window 1 as a 2 GB Direct-mapped window starting at 2GB.
702 REGVAL(MCPCIA_W1_MASK(sc)) = MCPCIA_WMASK_2G;
703 REGVAL(MCPCIA_T1_BASE(sc)) = 0;
705 REGVAL(MCPCIA_W1_BASE(sc)) =
706 MCPCIA_DIRECT_MAPPED_BASE | MCPCIA_WBASE_EN;
710 * When we get around to redoing the 'chipset' stuff to have more
711 * than one sgmap handler...
716 * Set up window 2 as a 1G SGMAP-mapped window starting at 1G.
719 REGVAL(MCPCIA_W2_MASK(sc)) = MCPCIA_WMASK_1G;
720 REGVAL(MCPCIA_T2_BASE(sc)) =
721 ccp->cc_pci_sgmap.aps_ptpa >> MCPCIA_TBASEX_SHIFT;
723 REGVAL(MCPCIA_W2_BASE(sc)) =
724 MCPCIA_WBASE_EN | MCPCIA_WBASE_SG | MCPCIA_PCI_SG_MAPPED_BASE;
728 /* XXX XXX BEGIN XXX XXX */
730 alpha_XXX_dmamap_or = MCPCIA_DIRECT_MAPPED_BASE;/* XXX */
732 /* XXX XXX END XXX XXX */
739 mcpcia_intr(void *arg)
741 unsigned long vec = (unsigned long) arg;
744 * Check for I2C interrupts. These are technically within
745 * the PCI vector range, but no PCI device should ever map
748 if (vec == MCPCIA_I2C_CVEC) {
749 printf("i2c: controller interrupt\n");
752 if (vec == MCPCIA_I2C_BVEC) {
753 printf("i2c: bus interrupt\n");
757 alpha_dispatch_intr(NULL, vec);
760 static device_method_t mcpcia_methods[] = {
761 /* Device interface */
762 DEVMETHOD(device_probe, mcpcia_probe),
763 DEVMETHOD(device_attach, mcpcia_attach),
766 DEVMETHOD(bus_print_child, bus_generic_print_child),
767 DEVMETHOD(bus_read_ivar, mcpcia_read_ivar),
768 DEVMETHOD(bus_setup_intr, mcpcia_setup_intr),
769 DEVMETHOD(bus_teardown_intr, mcpcia_teardown_intr),
770 DEVMETHOD(bus_alloc_resource, alpha_pci_alloc_resource),
771 DEVMETHOD(bus_release_resource, pci_release_resource),
772 DEVMETHOD(bus_activate_resource, pci_activate_resource),
773 DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
775 /* alphapci interface */
776 DEVMETHOD(alphapci_cvt_dense, mcpcia_cvt_dense),
777 DEVMETHOD(alphapci_get_bustag, mcpcia_get_bustag),
778 DEVMETHOD(alphapci_get_rman, mcpcia_get_rman),
781 DEVMETHOD(pcib_maxslots, mcpcia_maxslots),
782 DEVMETHOD(pcib_read_config, mcpcia_read_config),
783 DEVMETHOD(pcib_write_config, mcpcia_write_config),
784 DEVMETHOD(pcib_route_interrupt, mcpcia_pci_route_interrupt),
789 static driver_t mcpcia_driver = {
790 "pcib", mcpcia_methods, sizeof (struct mcpcia_softc)
793 DRIVER_MODULE(pcib, mcbus, mcpcia_driver, mcpcia_devclass, 0, 0);