Index: head/sys/arm/xscale/ixp425/ixdp425_pci.c =================================================================== --- head/sys/arm/xscale/ixp425/ixdp425_pci.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixdp425_pci.c (revision 327256) @@ -1,175 +1,169 @@ -/* $NetBSD: ixdp425_pci.c,v 1.5 2005/12/11 12:17:09 christos Exp $ */ +/* $NetBSD: ixdp425_pci.c,v 1.6 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #define _ARM32_BUS_DMA_PRIVATE #include #include #include #include #include #include #include #include #include #include #include #include #include #include void ixp425_md_attach(device_t dev) { struct ixp425_softc *sc = device_get_softc(device_get_parent(dev)); struct ixppcib_softc *pci_sc = device_get_softc(dev); uint32_t reg; /* PCI Reset Assert */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); reg &= ~(1U << GPIO_PCI_RESET); GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg); /* PCI Clock Disable */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); reg &= ~GPCLKR_MUX14; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg); /* * set GPIO Direction * Output: PCI_CLK, PCI_RESET * Input: PCI_INTA, PCI_INTB, PCI_INTC, PCI_INTD */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER); reg &= ~(1U << GPIO_PCI_CLK); reg &= ~(1U << GPIO_PCI_RESET); reg |= ((1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg); /* * Set GPIO interrupt type * PCI_INT_A, PCI_INTB, PCI_INT_C, PCI_INT_D: Active Low */ reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA)); reg &= ~GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_PCI_INTA, GPIO_TYPE_ACT_LOW); GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTA), reg); reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB)); reg &= ~GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_PCI_INTB, GPIO_TYPE_ACT_LOW); GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTB), reg); reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC)); reg &= ~GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_PCI_INTC, GPIO_TYPE_ACT_LOW); GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTC), reg); reg = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD)); reg &= ~GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_PCI_INTD, GPIO_TYPE_ACT_LOW); GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(GPIO_PCI_INTD), reg); /* clear ISR */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, (1U << GPIO_PCI_INTA) | (1U << GPIO_PCI_INTB) | (1U << GPIO_PCI_INTC) | (1U << GPIO_PCI_INTD)); /* wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */ DELAY(1000); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | (0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT)); /* PCI Clock Enable */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); reg |= GPCLKR_MUX14; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg | GPCLKR_MUX14); /* * wait 100us to satisfy "minimum reset assertion time from clock stable * requirement of the PCI spec */ DELAY(100); /* PCI Reset deassert */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); reg |= 1U << GPIO_PCI_RESET; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg | (1U << GPIO_PCI_RESET)); pci_sc->sc_irq_rman.rm_type = RMAN_ARRAY; pci_sc->sc_irq_rman.rm_descr = "IXP425 PCI IRQs"; CTASSERT(PCI_INT_D < PCI_INT_A); /* XXX this overlaps the irq's setup in ixp425_attach */ if (rman_init(&pci_sc->sc_irq_rman) != 0 || rman_manage_region(&pci_sc->sc_irq_rman, PCI_INT_D, PCI_INT_A) != 0) panic("ixp425_md_attach: failed to set up IRQ rman"); } #define IXP425_MAX_DEV 5 #define IXP425_MAX_LINE 4 int ixp425_md_route_interrupt(device_t bridge, device_t device, int pin) { static int ixp425_pci_table[IXP425_MAX_DEV][IXP425_MAX_LINE] = { {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, {PCI_INT_B, PCI_INT_C, PCI_INT_D, PCI_INT_A}, {PCI_INT_C, PCI_INT_D, PCI_INT_A, PCI_INT_B}, {PCI_INT_D, PCI_INT_A, PCI_INT_B, PCI_INT_C}, /* NB: for optional USB controller on Gateworks Avila */ {PCI_INT_A, PCI_INT_B, PCI_INT_C, PCI_INT_D}, }; int dev; dev = pci_get_slot(device); if (bootverbose) device_printf(bridge, "routing pin %d for %s\n", pin, device_get_nameunit(device)); if (pin >= 1 && pin <= IXP425_MAX_LINE && dev >= 1 && dev <= IXP425_MAX_DEV) { return (ixp425_pci_table[dev - 1][pin - 1]); } else printf("ixppcib: no mapping for %d/%d/%d\n", pci_get_bus(device), dev, pci_get_function(device)); return (-1); } Index: head/sys/arm/xscale/ixp425/ixdp425reg.h =================================================================== --- head/sys/arm/xscale/ixp425/ixdp425reg.h (revision 327255) +++ head/sys/arm/xscale/ixp425/ixdp425reg.h (revision 327256) @@ -1,56 +1,50 @@ -/* $NetBSD: ixdp425reg.h,v 1.6 2005/12/11 12:17:09 christos Exp $ */ +/* $NetBSD: ixdp425reg.h,v 1.7 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* $FreeBSD$ */ #ifndef _IXDP425REG_H_ #define _IXDP425REG_H_ /* GPIOs */ #define GPIO_PCI_CLK 14 #define GPIO_PCI_RESET 13 #define GPIO_PCI_INTA 11 #define GPIO_PCI_INTB 10 #define GPIO_PCI_INTC 9 #define GPIO_PCI_INTD 8 #define GPIO_I2C_SDA 7 #define GPIO_I2C_SDA_BIT (1U << GPIO_I2C_SDA) #define GPIO_I2C_SCL 6 #define GPIO_I2C_SCL_BIT (1U << GPIO_I2C_SCL) /* Interrupt */ #define PCI_INT_A IXP425_INT_GPIO_11 #define PCI_INT_B IXP425_INT_GPIO_10 #define PCI_INT_C IXP425_INT_GPIO_9 #define PCI_INT_D IXP425_INT_GPIO_8 #endif /* _IXDP425REG_H_ */ Index: head/sys/arm/xscale/ixp425/ixp425.c =================================================================== --- head/sys/arm/xscale/ixp425/ixp425.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425.c (revision 327256) @@ -1,698 +1,692 @@ -/* $NetBSD: ixp425.c,v 1.10 2005/12/11 12:16:51 christos Exp $ */ +/* $NetBSD: ixp425.c,v 1.13 2009/10/21 14:15:50 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #define _ARM32_BUS_DMA_PRIVATE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include volatile uint32_t intr_enabled; uint32_t intr_steer = 0; /* ixp43x et. al have +32 IRQ's */ volatile uint32_t intr_enabled2; uint32_t intr_steer2 = 0; struct ixp425_softc *ixp425_softc = NULL; struct mtx ixp425_gpio_mtx; static int ixp425_probe(device_t); static void ixp425_identify(driver_t *, device_t); static int ixp425_attach(device_t); /* * Return a mask of the "fuse" bits that identify * which h/w features are present. * NB: assumes the expansion bus is mapped. */ uint32_t ixp4xx_read_feature_bits(void) { uint32_t bits = ~IXPREG(IXP425_EXP_VBASE + EXP_FCTRL_OFFSET); bits &= ~EXP_FCTRL_RESVD; if (!cpu_is_ixp46x()) bits &= ~EXP_FCTRL_IXP46X_ONLY; return bits; } void ixp4xx_write_feature_bits(uint32_t v) { IXPREG(IXP425_EXP_VBASE + EXP_FCTRL_OFFSET) = ~v; } struct arm32_dma_range * bus_dma_get_range(void) { return (NULL); } int bus_dma_get_range_nb(void) { return (0); } static const uint8_t int2gpio[32] __attribute__ ((aligned(32))) = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* INT#0 -> INT#5 */ 0x00, 0x01, /* GPIO#0 -> GPIO#1 */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* INT#8 -> INT#13 */ 0xff, 0xff, 0xff, 0xff, 0xff, /* INT#14 -> INT#18 */ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* GPIO#2 -> GPIO#7 */ 0x08, 0x09, 0x0a, 0x0b, 0x0c, /* GPIO#8 -> GPIO#12 */ 0xff, 0xff /* INT#30 -> INT#31 */ }; static __inline uint32_t ixp425_irq2gpio_bit(int irq) { return (1U << int2gpio[irq]); } #ifdef DDB #include DB_SHOW_COMMAND(gpio, db_show_gpio) { static const char *itype[8] = { [GPIO_TYPE_ACT_HIGH] = "act-high", [GPIO_TYPE_ACT_LOW] = "act-low", [GPIO_TYPE_EDG_RISING] = "edge-rising", [GPIO_TYPE_EDG_FALLING] = "edge-falling", [GPIO_TYPE_TRANSITIONAL]= "transitional", [5] = "type-5", [6] = "type-6", [7] = "type-7" }; uint32_t gpoutr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); uint32_t gpoer = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER); uint32_t gpinr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPINR); uint32_t gpit1r = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPIT1R); uint32_t gpit2r = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPIT2R); int i, j; db_printf("GPOUTR %08x GPINR %08x GPOER %08x GPISR %08x\n", gpoutr, gpinr, gpoer, GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPISR)); db_printf("GPIT1R %08x GPIT2R %08x GPCLKR %08x\n", gpit1r, gpit2r, GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPCLKR)); for (i = 0; i < 16; i++) { db_printf("[%2d] out %u in %u %-3s", i, (gpoutr>>i)&1, (gpinr>>i)&1, (gpoer>>i)&1 ? "in" : "out"); for (j = 0; j < 32; j++) if (int2gpio[j] == i) { db_printf(" irq %2u %s", j, itype[ (((i & 8) ? gpit2r : gpit1r) >> (3*(i&7))) & 7]); break; } db_printf("\n"); } } #endif void ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type) { uint32_t gpiotr = GPIO_CONF_READ_4(sc, GPIO_TYPE_REG(pin)); IXP4XX_GPIO_LOCK(); /* clear interrupt type */ GPIO_CONF_WRITE_4(sc, GPIO_TYPE_REG(pin), gpiotr &~ GPIO_TYPE(pin, GPIO_TYPE_MASK)); /* clear any pending interrupt */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, (1<> last; for (; mask != 0; mask >>= 1, last++) { if (mask & 1) return last; } last = 32; } if (cpu_is_ixp43x()) { mask = ixp435_irq_read() >> (32-last); for (; mask != 0; mask >>= 1, last++) { if (mask & 1) return last; } } return -1; } void cpu_reset(void) { bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, IXP425_OST_WDOG_KEY, OST_WDOG_KEY_MAJICK); bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, IXP425_OST_WDOG, 0); bus_space_write_4(&ixp425_bs_tag, IXP425_TIMER_VBASE, IXP425_OST_WDOG_ENAB, OST_WDOG_ENAB_RST_ENA | OST_WDOG_ENAB_CNT_ENA); printf("Reset failed!\n"); for(;;); } static void ixp425_identify(driver_t *driver, device_t parent) { BUS_ADD_CHILD(parent, 0, "ixp", 0); } static int ixp425_probe(device_t dev) { device_set_desc(dev, "Intel IXP4XX"); return (0); } static int ixp425_attach(device_t dev) { struct ixp425_softc *sc; device_printf(dev, "%b\n", ixp4xx_read_feature_bits(), EXP_FCTRL_BITS); sc = device_get_softc(dev); sc->sc_iot = &ixp425_bs_tag; KASSERT(ixp425_softc == NULL, ("%s called twice?", __func__)); ixp425_softc = sc; intr_enabled = 0; ixp425_set_intrmask(); ixp425_set_intrsteer(); if (cpu_is_ixp43x()) { intr_enabled2 = 0; ixp435_set_intrmask(); ixp435_set_intrsteer(); } arm_post_filter = ixp425_post_filter; mtx_init(&ixp425_gpio_mtx, "gpio", NULL, MTX_DEF); if (bus_space_map(sc->sc_iot, IXP425_GPIO_HWBASE, IXP425_GPIO_SIZE, 0, &sc->sc_gpio_ioh)) panic("%s: unable to map GPIO registers", __func__); if (bus_space_map(sc->sc_iot, IXP425_EXP_HWBASE, IXP425_EXP_SIZE, 0, &sc->sc_exp_ioh)) panic("%s: unable to map Expansion Bus registers", __func__); /* XXX belongs in platform init */ if (cpu_is_ixp43x()) cambria_exp_bus_init(sc); if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, 0xffffffff, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_dmat)) panic("%s: failed to create dma tag", __func__); sc->sc_irq_rman.rm_type = RMAN_ARRAY; sc->sc_irq_rman.rm_descr = "IXP4XX IRQs"; if (rman_init(&sc->sc_irq_rman) != 0 || rman_manage_region(&sc->sc_irq_rman, 0, cpu_is_ixp43x() ? 63 : 31) != 0) panic("%s: failed to set up IRQ rman", __func__); sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "IXP4XX Memory"; if (rman_init(&sc->sc_mem_rman) != 0 || rman_manage_region(&sc->sc_mem_rman, 0, ~0) != 0) panic("%s: failed to set up memory rman", __func__); BUS_ADD_CHILD(dev, 0, "pcib", 0); BUS_ADD_CHILD(dev, 0, "ixpclk", 0); BUS_ADD_CHILD(dev, 0, "ixpiic", 0); /* XXX move to hints? */ BUS_ADD_CHILD(dev, 0, "ixpwdog", 0); /* attach wired devices via hints */ bus_enumerate_hinted_children(dev); bus_generic_probe(dev); bus_generic_attach(dev); return (0); } static void ixp425_hinted_child(device_t bus, const char *dname, int dunit) { device_t child; struct ixp425_ivar *ivar; child = BUS_ADD_CHILD(bus, 0, dname, dunit); ivar = IXP425_IVAR(child); resource_int_value(dname, dunit, "addr", &ivar->addr); resource_int_value(dname, dunit, "irq", &ivar->irq); } static device_t ixp425_add_child(device_t dev, u_int order, const char *name, int unit) { device_t child; struct ixp425_ivar *ivar; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return NULL; ivar = malloc(sizeof(struct ixp425_ivar), M_DEVBUF, M_NOWAIT); if (ivar == NULL) { device_delete_child(dev, child); return NULL; } ivar->addr = 0; ivar->irq = -1; device_set_ivars(child, ivar); return child; } static int ixp425_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) { struct ixp425_ivar *ivar = IXP425_IVAR(child); switch (which) { case IXP425_IVAR_ADDR: if (ivar->addr != 0) { *(uint32_t *)result = ivar->addr; return 0; } break; case IXP425_IVAR_IRQ: if (ivar->irq != -1) { *(int *)result = ivar->irq; return 0; } break; } return EINVAL; } /* * NB: This table handles P->V translations for regions setup with * static mappings in initarm. This is used solely for calls to * bus_alloc_resource_any; anything done with bus_space_map is * handled elsewhere and does not require an entry here. * * XXX this table is also used by uart_cpu_getdev via getvbase * (hence the public api) */ struct hwvtrans { uint32_t hwbase; uint32_t size; uint32_t vbase; int isa4x; /* XXX needs special bus space tag */ int isslow; /* XXX needs special bus space tag */ }; static const struct hwvtrans * gethwvtrans(uint32_t hwbase, uint32_t size) { static const struct hwvtrans hwvtrans[] = { /* NB: needed only for uart_cpu_getdev */ { .hwbase = IXP425_UART0_HWBASE, .size = IXP425_REG_SIZE, .vbase = IXP425_UART0_VBASE, .isa4x = 1 }, { .hwbase = IXP425_UART1_HWBASE, .size = IXP425_REG_SIZE, .vbase = IXP425_UART1_VBASE, .isa4x = 1 }, { .hwbase = IXP425_PCI_HWBASE, .size = IXP425_PCI_SIZE, .vbase = IXP425_PCI_VBASE }, { .hwbase = IXP425_PCI_MEM_HWBASE, .size = IXP425_PCI_MEM_SIZE, .vbase = IXP425_PCI_MEM_VBASE }, { .hwbase = IXP425_EXP_BUS_CS0_HWBASE, .size = IXP425_EXP_BUS_CS0_SIZE, .vbase = IXP425_EXP_BUS_CS0_VBASE }, /* NB: needed for ixp435 ehci controllers */ { .hwbase = IXP435_USB1_HWBASE, .size = IXP435_USB1_SIZE, .vbase = IXP435_USB1_VBASE }, { .hwbase = IXP435_USB2_HWBASE, .size = IXP435_USB2_SIZE, .vbase = IXP435_USB2_VBASE }, { .hwbase = CAMBRIA_GPS_HWBASE, .size = CAMBRIA_GPS_SIZE, .vbase = CAMBRIA_GPS_VBASE, .isslow = 1 }, { .hwbase = CAMBRIA_RS485_HWBASE, .size = CAMBRIA_RS485_SIZE, .vbase = CAMBRIA_RS485_VBASE, .isslow = 1 }, }; int i; for (i = 0; i < nitems(hwvtrans); i++) { if (hwbase >= hwvtrans[i].hwbase && hwbase + size <= hwvtrans[i].hwbase + hwvtrans[i].size) return &hwvtrans[i]; } return NULL; } /* XXX for uart_cpu_getdev */ int getvbase(uint32_t hwbase, uint32_t size, uint32_t *vbase) { const struct hwvtrans *hw; hw = gethwvtrans(hwbase, size); if (hw == NULL) return (ENOENT); *vbase = hwbase - hw->hwbase + hw->vbase; return (0); } static struct resource * ixp425_alloc_resource(device_t dev, device_t child, int type, int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) { struct ixp425_softc *sc = device_get_softc(dev); const struct hwvtrans *vtrans; struct resource *rv; uint32_t addr; int needactivate = flags & RF_ACTIVE; int irq; flags &= ~RF_ACTIVE; switch (type) { case SYS_RES_IRQ: /* override per hints */ if (BUS_READ_IVAR(dev, child, IXP425_IVAR_IRQ, &irq) == 0) start = end = irq; rv = rman_reserve_resource(&sc->sc_irq_rman, start, end, count, flags, child); if (rv != NULL) rman_set_rid(rv, *rid); break; case SYS_RES_MEMORY: /* override per hints */ if (BUS_READ_IVAR(dev, child, IXP425_IVAR_ADDR, &addr) == 0) { start = addr; /* XXX use nominal window to check for mapping */ vtrans = gethwvtrans(start, 0x1000); if (vtrans != NULL) { /* * Assign the entire mapped region; this may * not be correct but without more info from * the caller we cannot tell. */ end = start + vtrans->size - (start - vtrans->hwbase); if (bootverbose) device_printf(child, "%s: assign 0x%jx:0x%jx%s\n", __func__, start, end - start, vtrans->isa4x ? " A4X" : vtrans->isslow ? " SLOW" : ""); } } else vtrans = gethwvtrans(start, end - start); if (vtrans == NULL) { /* likely means above table needs to be updated */ device_printf(child, "%s: no mapping for 0x%jx:0x%jx\n", __func__, start, end - start); return NULL; } rv = rman_reserve_resource(&sc->sc_mem_rman, start, end, end - start, flags, child); if (rv == NULL) { device_printf(child, "%s: cannot reserve 0x%jx:0x%jx\n", __func__, start, end - start); return NULL; } rman_set_rid(rv, *rid); break; default: rv = NULL; break; } if (rv != NULL && needactivate) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } return (rv); } static int ixp425_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* NB: no private resources, just release */ return rman_release_resource(r); } static int ixp425_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { struct ixp425_softc *sc = device_get_softc(dev); const struct hwvtrans *vtrans; if (type == SYS_RES_MEMORY) { vtrans = gethwvtrans(rman_get_start(r), rman_get_size(r)); if (vtrans == NULL) { /* NB: should not happen */ device_printf(child, "%s: no mapping for 0x%jx:0x%jx\n", __func__, rman_get_start(r), rman_get_size(r)); return (ENOENT); } if (vtrans->isa4x) rman_set_bustag(r, &ixp425_a4x_bs_tag); else if (vtrans->isslow) rman_set_bustag(r, &cambria_exp_bs_tag); else rman_set_bustag(r, sc->sc_iot); rman_set_bushandle(r, vtrans->vbase); } return (rman_activate_resource(r)); } static int ixp425_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { /* NB: no private resources, just deactive */ return (rman_deactivate_resource(r)); } static __inline void get_masks(struct resource *res, uint32_t *mask, uint32_t *mask2) { int i; *mask = 0; for (i = rman_get_start(res); i < 32 && i <= rman_get_end(res); i++) *mask |= 1 << i; *mask2 = 0; for (; i <= rman_get_end(res); i++) *mask2 |= 1 << (i - 32); } static __inline void update_masks(uint32_t mask, uint32_t mask2) { intr_enabled = mask; ixp425_set_intrmask(); if (cpu_is_ixp43x()) { intr_enabled2 = mask2; ixp435_set_intrmask(); } } static int ixp425_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { uint32_t mask, mask2; int error; error = BUS_SETUP_INTR(device_get_parent(dev), child, res, flags, filt, intr, arg, cookiep); if (error) return (error); get_masks(res, &mask, &mask2); update_masks(intr_enabled | mask, intr_enabled2 | mask2); return (0); } static int ixp425_teardown_intr(device_t dev, device_t child, struct resource *res, void *cookie) { uint32_t mask, mask2; get_masks(res, &mask, &mask2); update_masks(intr_enabled &~ mask, intr_enabled2 &~ mask2); return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie)); } static device_method_t ixp425_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ixp425_probe), DEVMETHOD(device_attach, ixp425_attach), DEVMETHOD(device_identify, ixp425_identify), /* Bus interface */ DEVMETHOD(bus_add_child, ixp425_add_child), DEVMETHOD(bus_hinted_child, ixp425_hinted_child), DEVMETHOD(bus_read_ivar, ixp425_read_ivar), DEVMETHOD(bus_alloc_resource, ixp425_alloc_resource), DEVMETHOD(bus_release_resource, ixp425_release_resource), DEVMETHOD(bus_activate_resource, ixp425_activate_resource), DEVMETHOD(bus_deactivate_resource, ixp425_deactivate_resource), DEVMETHOD(bus_setup_intr, ixp425_setup_intr), DEVMETHOD(bus_teardown_intr, ixp425_teardown_intr), {0, 0}, }; static driver_t ixp425_driver = { "ixp", ixp425_methods, sizeof(struct ixp425_softc), }; static devclass_t ixp425_devclass; DRIVER_MODULE(ixp, nexus, ixp425_driver, ixp425_devclass, 0, 0); Index: head/sys/arm/xscale/ixp425/ixp425_pci.c =================================================================== --- head/sys/arm/xscale/ixp425/ixp425_pci.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425_pci.c (revision 327256) @@ -1,483 +1,477 @@ -/* $NetBSD: ixp425_pci.c,v 1.5 2006/04/10 03:36:03 simonb Exp $ */ +/* $NetBSD: ixp425_pci.c,v 1.6 2009/10/21 14:15:50 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #define _ARM32_BUS_DMA_PRIVATE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pcib_if.h" #include extern struct ixp425_softc *ixp425_softc; #define PCI_CSR_WRITE_4(sc, reg, data) \ bus_write_4(sc->sc_csr, reg, data) #define PCI_CSR_READ_4(sc, reg) \ bus_read_4(sc->sc_csr, reg) #define PCI_CONF_LOCK(s) (s) = disable_interrupts(PSR_I) #define PCI_CONF_UNLOCK(s) restore_interrupts((s)) static device_probe_t ixppcib_probe; static device_attach_t ixppcib_attach; static bus_read_ivar_t ixppcib_read_ivar; static bus_write_ivar_t ixppcib_write_ivar; static bus_setup_intr_t ixppcib_setup_intr; static bus_teardown_intr_t ixppcib_teardown_intr; static bus_alloc_resource_t ixppcib_alloc_resource; static bus_activate_resource_t ixppcib_activate_resource; static bus_deactivate_resource_t ixppcib_deactivate_resource; static bus_release_resource_t ixppcib_release_resource; static pcib_maxslots_t ixppcib_maxslots; static pcib_read_config_t ixppcib_read_config; static pcib_write_config_t ixppcib_write_config; static pcib_route_interrupt_t ixppcib_route_interrupt; static int ixppcib_probe(device_t dev) { device_set_desc(dev, "IXP4XX PCI Bus"); return (0); } static void ixp425_pci_conf_reg_write(struct ixppcib_softc *sc, uint32_t reg, uint32_t data) { PCI_CSR_WRITE_4(sc, PCI_CRP_AD_CBE, ((reg & ~3) | COMMAND_CRP_WRITE)); PCI_CSR_WRITE_4(sc, PCI_CRP_AD_WDATA, data); } static int ixppcib_attach(device_t dev) { int rid; struct ixppcib_softc *sc; sc = device_get_softc(dev); rid = 0; sc->sc_csr = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, IXP425_PCI_HWBASE, IXP425_PCI_HWBASE + IXP425_PCI_SIZE, IXP425_PCI_SIZE, RF_ACTIVE); if (sc->sc_csr == NULL) panic("cannot allocate PCI CSR registers"); ixp425_md_attach(dev); /* always setup the base, incase another OS messes w/ it */ PCI_CSR_WRITE_4(sc, PCI_PCIMEMBASE, 0x48494a4b); rid = 0; sc->sc_mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE, IXP425_PCI_MEM_SIZE, RF_ACTIVE); if (sc->sc_mem == NULL) panic("cannot allocate PCI MEM space"); /* NB: PCI dma window is 64M so anything above must be bounced */ if (bus_dma_tag_create(NULL, 1, 0, IXP425_AHB_OFFSET + 64 * 1024 * 1024, BUS_SPACE_MAXADDR, NULL, NULL, 0xffffffff, 0xff, 0xffffffff, 0, NULL, NULL, &sc->sc_dmat)) panic("couldn't create the PCI dma tag !"); /* * Initialize the bus space tags. */ ixp425_io_bs_init(&sc->sc_pci_iot, sc); ixp425_mem_bs_init(&sc->sc_pci_memt, sc); sc->sc_dev = dev; /* Initialize memory and i/o rmans. */ sc->sc_io_rman.rm_type = RMAN_ARRAY; sc->sc_io_rman.rm_descr = "IXP4XX PCI I/O Ports"; if (rman_init(&sc->sc_io_rman) != 0 || rman_manage_region(&sc->sc_io_rman, 0, IXP425_PCI_IO_SIZE) != 0) { panic("ixppcib_probe: failed to set up I/O rman"); } sc->sc_mem_rman.rm_type = RMAN_ARRAY; sc->sc_mem_rman.rm_descr = "IXP4XX PCI Memory"; if (rman_init(&sc->sc_mem_rman) != 0 || rman_manage_region(&sc->sc_mem_rman, IXP425_PCI_MEM_HWBASE, IXP425_PCI_MEM_HWBASE + IXP425_PCI_MEM_SIZE) != 0) { panic("ixppcib_probe: failed to set up memory rman"); } /* * PCI->AHB address translation * begin at the physical memory start + OFFSET */ PCI_CSR_WRITE_4(sc, PCI_AHBMEMBASE, (IXP425_AHB_OFFSET & 0xFF000000) + ((IXP425_AHB_OFFSET & 0xFF000000) >> 8) + ((IXP425_AHB_OFFSET & 0xFF000000) >> 16) + ((IXP425_AHB_OFFSET & 0xFF000000) >> 24) + 0x00010203); #define IXPPCIB_WRITE_CONF(sc, reg, val) \ ixp425_pci_conf_reg_write(sc, reg, val) /* Write Mapping registers PCI Configuration Registers */ /* Base Address 0 - 3 */ IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR0, IXP425_AHB_OFFSET + 0x00000000); IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR1, IXP425_AHB_OFFSET + 0x01000000); IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR2, IXP425_AHB_OFFSET + 0x02000000); IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR3, IXP425_AHB_OFFSET + 0x03000000); /* Base Address 4 */ IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR4, 0xffffffff); /* Base Address 5 */ IXPPCIB_WRITE_CONF(sc, PCI_MAPREG_BAR5, 0x00000000); /* Assert some PCI errors */ PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_AHBE | ISR_PPE | ISR_PFE | ISR_PSE); #ifdef __ARMEB__ /* * Set up byte lane swapping between little-endian PCI * and the big-endian AHB bus */ PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE | CSR_PDS); #else PCI_CSR_WRITE_4(sc, PCI_CSR, CSR_IC | CSR_ABE); #endif /* * Enable bus mastering and I/O,memory access */ IXPPCIB_WRITE_CONF(sc, PCIR_COMMAND, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); /* * Wait some more to ensure PCI devices have stabilised. */ DELAY(50000); device_add_child(dev, "pci", -1); return (bus_generic_attach(dev)); } static int ixppcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) { struct ixppcib_softc *sc; sc = device_get_softc(dev); switch (which) { case PCIB_IVAR_DOMAIN: *result = 0; return (0); case PCIB_IVAR_BUS: *result = sc->sc_bus; return (0); } return (ENOENT); } static int ixppcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) { struct ixppcib_softc *sc; sc = device_get_softc(dev); switch (which) { case PCIB_IVAR_DOMAIN: return (EINVAL); case PCIB_IVAR_BUS: sc->sc_bus = value; return (0); } return (ENOENT); } static int ixppcib_setup_intr(device_t dev, device_t child, struct resource *ires, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, filt, intr, arg, cookiep)); } static int ixppcib_teardown_intr(device_t dev, device_t child, struct resource *vec, void *cookie) { return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, vec, cookie)); } static struct resource * ixppcib_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) { struct ixppcib_softc *sc = device_get_softc(bus); struct rman *rmanp; struct resource *rv; rv = NULL; switch (type) { case SYS_RES_IRQ: rmanp = &sc->sc_irq_rman; break; case SYS_RES_IOPORT: rmanp = &sc->sc_io_rman; break; case SYS_RES_MEMORY: rmanp = &sc->sc_mem_rman; break; default: return (rv); } rv = rman_reserve_resource(rmanp, start, end, count, flags & ~RF_ACTIVE, child); if (rv == NULL) return (NULL); rman_set_rid(rv, *rid); if (flags & RF_ACTIVE) { if (bus_activate_resource(child, type, *rid, rv)) { rman_release_resource(rv); return (NULL); } } return (rv); } static int ixppcib_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { struct ixppcib_softc *sc = device_get_softc(bus); int error; error = rman_activate_resource(r); if (error) return (error); switch (type) { case SYS_RES_IOPORT: rman_set_bustag(r, &sc->sc_pci_iot); rman_set_bushandle(r, rman_get_start(r)); break; case SYS_RES_MEMORY: rman_set_bustag(r, &sc->sc_pci_memt); rman_set_bushandle(r, rman_get_bushandle(sc->sc_mem) + (rman_get_start(r) - IXP425_PCI_MEM_HWBASE)); break; } return (0); } static int ixppcib_deactivate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { device_printf(bus, "%s called deactivate_resource (unexpected)\n", device_get_nameunit(child)); return (ENXIO); } static int ixppcib_release_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { device_printf(bus, "%s called release_resource (unexpected)\n", device_get_nameunit(child)); return (ENXIO); } static bus_dma_tag_t ixppcib_get_dma_tag(device_t bus, device_t child) { struct ixppcib_softc *sc = device_get_softc(bus); return (sc->sc_dmat); } static void ixppcib_conf_setup(struct ixppcib_softc *sc, int bus, int slot, int func, int reg) { if (bus == 0) { /* configuration type 0 */ PCI_CSR_WRITE_4(sc, PCI_NP_AD, (1U << (32 - (slot & 0x1f))) | ((func & 0x7) << 8) | (reg & ~3)); } else { /* configuration type 1 */ PCI_CSR_WRITE_4(sc, PCI_NP_AD, (bus << 16) | (slot << 11) | (func << 8) | (reg & ~3) | 1); } } static int ixppcib_maxslots(device_t dev) { return (PCI_SLOTMAX); } static u_int32_t ixppcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, int bytes) { struct ixppcib_softc *sc = device_get_softc(dev); u_int32_t data, ret; ixppcib_conf_setup(sc, bus, slot, func, reg & ~3); PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_READ); ret = PCI_CSR_READ_4(sc, PCI_NP_RDATA); ret >>= (reg & 3) * 8; ret &= 0xffffffff >> ((4 - bytes) * 8); #if 0 device_printf(dev, "%s: %u:%u:%u %#x(%d) = %#x\n", __func__, bus, slot, func, reg, bytes, ret); #endif /* check & clear PCI abort */ data = PCI_CSR_READ_4(sc, PCI_ISR); if (data & ISR_PFE) { PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE); return (-1); } return (ret); } static const int byteenables[] = { 0, 0x10, 0x30, 0x70, 0xf0 }; static void ixppcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, u_int32_t val, int bytes) { struct ixppcib_softc *sc = device_get_softc(dev); u_int32_t data; #if 0 device_printf(dev, "%s: %u:%u:%u %#x(%d) = %#x\n", __func__, bus, slot, func, reg, bytes, val); #endif ixppcib_conf_setup(sc, bus, slot, func, reg & ~3); /* Byte enables are active low, so not them first */ PCI_CSR_WRITE_4(sc, PCI_NP_CBE, COMMAND_NP_CONF_WRITE | (~(byteenables[bytes] << (reg & 3)) & 0xf0)); PCI_CSR_WRITE_4(sc, PCI_NP_WDATA, val << ((reg & 3) * 8)); /* check & clear PCI abort */ data = PCI_CSR_READ_4(sc, PCI_ISR); if (data & ISR_PFE) PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_PFE); } static int ixppcib_route_interrupt(device_t bridge, device_t device, int pin) { return (ixp425_md_route_interrupt(bridge, device, pin)); } static device_method_t ixppcib_methods[] = { /* Device interface */ DEVMETHOD(device_probe, ixppcib_probe), DEVMETHOD(device_attach, ixppcib_attach), /* Bus interface */ DEVMETHOD(bus_read_ivar, ixppcib_read_ivar), DEVMETHOD(bus_write_ivar, ixppcib_write_ivar), DEVMETHOD(bus_setup_intr, ixppcib_setup_intr), DEVMETHOD(bus_teardown_intr, ixppcib_teardown_intr), DEVMETHOD(bus_alloc_resource, ixppcib_alloc_resource), DEVMETHOD(bus_activate_resource, ixppcib_activate_resource), DEVMETHOD(bus_deactivate_resource, ixppcib_deactivate_resource), DEVMETHOD(bus_release_resource, ixppcib_release_resource), DEVMETHOD(bus_get_dma_tag, ixppcib_get_dma_tag), /* pcib interface */ DEVMETHOD(pcib_maxslots, ixppcib_maxslots), DEVMETHOD(pcib_read_config, ixppcib_read_config), DEVMETHOD(pcib_write_config, ixppcib_write_config), DEVMETHOD(pcib_route_interrupt, ixppcib_route_interrupt), DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), DEVMETHOD_END }; static driver_t ixppcib_driver = { "pcib", ixppcib_methods, sizeof(struct ixppcib_softc), }; static devclass_t ixppcib_devclass; DRIVER_MODULE(ixppcib, ixp, ixppcib_driver, ixppcib_devclass, 0, 0); Index: head/sys/arm/xscale/ixp425/ixp425_pci_space.c =================================================================== --- head/sys/arm/xscale/ixp425/ixp425_pci_space.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425_pci_space.c (revision 327256) @@ -1,487 +1,481 @@ -/* $NetBSD: ixp425_pci_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */ +/* $NetBSD: ixp425_pci_space.c,v 1.7 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * bus_space PCI functions for ixp425 */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* * Macros to read/write registers */ #define CSR_READ_4(x) *(volatile uint32_t *) \ (IXP425_PCI_CSR_BASE + (x)) #define CSR_WRITE_4(x, v) *(volatile uint32_t *) \ (IXP425_PCI_CSR_BASE + (x)) = (v) /* Proto types for all the bus_space structure functions */ bs_protos(ixp425_pci); bs_protos(ixp425_pci_io); bs_protos(ixp425_pci_mem); /* special I/O functions */ static u_int8_t _pci_io_bs_r_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int16_t _pci_io_bs_r_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int32_t _pci_io_bs_r_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static void _pci_io_bs_w_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t); static void _pci_io_bs_w_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t); static void _pci_io_bs_w_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t); #ifdef __ARMEB__ static u_int8_t _pci_io_bs_r_1_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int16_t _pci_io_bs_r_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int32_t _pci_io_bs_r_4_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static void _pci_io_bs_w_1_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t); static void _pci_io_bs_w_2_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t); static void _pci_io_bs_w_4_s(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t); static u_int8_t _pci_mem_bs_r_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int16_t _pci_mem_bs_r_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static u_int32_t _pci_mem_bs_r_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t); static void _pci_mem_bs_w_1(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int8_t); static void _pci_mem_bs_w_2(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int16_t); static void _pci_mem_bs_w_4(bus_space_tag_t tag, bus_space_handle_t, bus_size_t, u_int32_t); #endif struct bus_space ixp425_pci_io_bs_tag_template = { /* mapping/unmapping */ .bs_map = ixp425_pci_io_bs_map, .bs_unmap = ixp425_pci_io_bs_unmap, .bs_subregion = ixp425_pci_bs_subregion, .bs_alloc = ixp425_pci_io_bs_alloc, .bs_free = ixp425_pci_io_bs_free, /* barrier */ .bs_barrier = ixp425_pci_bs_barrier, /* * IXP425 processor does not have PCI I/O windows */ /* read (single) */ .bs_r_1 = _pci_io_bs_r_1, .bs_r_2 = _pci_io_bs_r_2, .bs_r_4 = _pci_io_bs_r_4, /* write (single) */ .bs_w_1 = _pci_io_bs_w_1, .bs_w_2 = _pci_io_bs_w_2, .bs_w_4 = _pci_io_bs_w_4, #ifdef __ARMEB__ .bs_r_1_s = _pci_io_bs_r_1_s, .bs_r_2_s = _pci_io_bs_r_2_s, .bs_r_4_s = _pci_io_bs_r_4_s, .bs_w_1_s = _pci_io_bs_w_1_s, .bs_w_2_s = _pci_io_bs_w_2_s, .bs_w_4_s = _pci_io_bs_w_4_s, #else .bs_r_1_s = _pci_io_bs_r_1, .bs_r_2_s = _pci_io_bs_r_2, .bs_r_4_s = _pci_io_bs_r_4, .bs_w_1_s = _pci_io_bs_w_1, .bs_w_2_s = _pci_io_bs_w_2, .bs_w_4_s = _pci_io_bs_w_4, #endif }; void ixp425_io_bs_init(bus_space_tag_t bs, void *cookie) { *bs = ixp425_pci_io_bs_tag_template; bs->bs_privdata = cookie; } struct bus_space ixp425_pci_mem_bs_tag_template = { /* mapping/unmapping */ .bs_map = ixp425_pci_mem_bs_map, .bs_unmap = ixp425_pci_mem_bs_unmap, .bs_subregion = ixp425_pci_bs_subregion, .bs_alloc = ixp425_pci_mem_bs_alloc, .bs_free = ixp425_pci_mem_bs_free, /* barrier */ .bs_barrier = ixp425_pci_bs_barrier, #ifdef __ARMEB__ /* read (single) */ .bs_r_1_s = _pci_mem_bs_r_1, .bs_r_2_s = _pci_mem_bs_r_2, .bs_r_4_s = _pci_mem_bs_r_4, .bs_r_1 = ixp425_pci_mem_bs_r_1, .bs_r_2 = ixp425_pci_mem_bs_r_2, .bs_r_4 = ixp425_pci_mem_bs_r_4, /* write (single) */ .bs_w_1_s = _pci_mem_bs_w_1, .bs_w_2_s = _pci_mem_bs_w_2, .bs_w_4_s = _pci_mem_bs_w_4, .bs_w_1 = ixp425_pci_mem_bs_w_1, .bs_w_2 = ixp425_pci_mem_bs_w_2, .bs_w_4 = ixp425_pci_mem_bs_w_4, #else /* read (single) */ .bs_r_1 = ixp425_pci_mem_bs_r_1, .bs_r_2 = ixp425_pci_mem_bs_r_2, .bs_r_4 = ixp425_pci_mem_bs_r_4, .bs_r_1_s = ixp425_pci_mem_bs_r_1, .bs_r_2_s = ixp425_pci_mem_bs_r_2, .bs_r_4_s = ixp425_pci_mem_bs_r_4, /* write (single) */ .bs_w_1 = ixp425_pci_mem_bs_w_1, .bs_w_2 = ixp425_pci_mem_bs_w_2, .bs_w_4 = ixp425_pci_mem_bs_w_4, .bs_w_1_s = ixp425_pci_mem_bs_w_1, .bs_w_2_s = ixp425_pci_mem_bs_w_2, .bs_w_4_s = ixp425_pci_mem_bs_w_4, #endif }; void ixp425_mem_bs_init(bus_space_tag_t bs, void *cookie) { *bs = ixp425_pci_mem_bs_tag_template; bs->bs_privdata = cookie; } /* common routine */ int ixp425_pci_bs_subregion(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) { *nbshp = bsh + offset; return (0); } void ixp425_pci_bs_barrier(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t offset, bus_size_t len, int flags) { /* NULL */ } /* io bs */ int ixp425_pci_io_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp) { *bshp = bpa; return (0); } void ixp425_pci_io_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size) { /* Nothing to do. */ } int ixp425_pci_io_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable, bus_addr_t *bpap, bus_space_handle_t *bshp) { panic("ixp425_pci_io_bs_alloc(): not implemented\n"); } void ixp425_pci_io_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size) { panic("ixp425_pci_io_bs_free(): not implemented\n"); } /* special I/O functions */ static __inline u_int32_t _bs_r(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t be) { u_int32_t data; CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3); CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_READ); data = CSR_READ_4(PCI_NP_RDATA); if (CSR_READ_4(PCI_ISR) & ISR_PFE) CSR_WRITE_4(PCI_ISR, ISR_PFE); return data; } static u_int8_t _pci_io_bs_r_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~(1U << n)) << NP_CBE_SHIFT; data = _bs_r(tag, ioh, off, be); return data >> (8 * n); } static u_int16_t _pci_io_bs_r_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT; data = _bs_r(tag, ioh, off, be); return data >> (8 * n); } static u_int32_t _pci_io_bs_r_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data; data = _bs_r(tag, ioh, off, 0); return data; } #ifdef __ARMEB__ static u_int8_t _pci_io_bs_r_1_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~(1U << n)) << NP_CBE_SHIFT; data = _bs_r(tag, ioh, off, be); return data >> (8 * n); } static u_int16_t _pci_io_bs_r_2_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT; data = _bs_r(tag, ioh, off, be); return data >> (8 * n); } static u_int32_t _pci_io_bs_r_4_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data; data = _bs_r(tag, ioh, off, 0); return le32toh(data); } #endif /* __ARMEB__ */ static __inline void _bs_w(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t be, u_int32_t data) { CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3); CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_WRITE); CSR_WRITE_4(PCI_NP_WDATA, data); if (CSR_READ_4(PCI_ISR) & ISR_PFE) CSR_WRITE_4(PCI_ISR, ISR_PFE); } static void _pci_io_bs_w_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int8_t val) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~(1U << n)) << NP_CBE_SHIFT; data = val << (8 * n); _bs_w(tag, ioh, off, be, data); } static void _pci_io_bs_w_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int16_t val) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT; data = val << (8 * n); _bs_w(tag, ioh, off, be, data); } static void _pci_io_bs_w_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t val) { _bs_w(tag, ioh, off, 0, val); } #ifdef __ARMEB__ static void _pci_io_bs_w_1_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int8_t val) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~(1U << n)) << NP_CBE_SHIFT; data = val << (8 * n); _bs_w(tag, ioh, off, be, data); } static void _pci_io_bs_w_2_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int16_t val) { u_int32_t data, n, be; n = (ioh + off) % 4; be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT; data = val << (8 * n); _bs_w(tag, ioh, off, be, data); } static void _pci_io_bs_w_4_s(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t val) { _bs_w(tag, ioh, off, 0, htole32(val)); } #endif /* __ARMEB__ */ /* mem bs */ int ixp425_pci_mem_bs_map(bus_space_tag_t tag, bus_addr_t bpa, bus_size_t size, int cacheable, bus_space_handle_t *bshp) { *bshp = (vm_offset_t)pmap_mapdev(bpa, size); return (0); } void ixp425_pci_mem_bs_unmap(bus_space_tag_t tag, bus_space_handle_t h, bus_size_t size) { pmap_unmapdev((vm_offset_t)h, size); } int ixp425_pci_mem_bs_alloc(bus_space_tag_t tag, bus_addr_t rstart, bus_addr_t rend, bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable, bus_addr_t *bpap, bus_space_handle_t *bshp) { panic("ixp425_mem_bs_alloc(): not implemented\n"); } void ixp425_pci_mem_bs_free(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size) { panic("ixp425_mem_bs_free(): not implemented\n"); } #ifdef __ARMEB__ static u_int8_t _pci_mem_bs_r_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { return ixp425_pci_mem_bs_r_1(tag, ioh, off); } static u_int16_t _pci_mem_bs_r_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { return (ixp425_pci_mem_bs_r_2(tag, ioh, off)); } static u_int32_t _pci_mem_bs_r_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off) { u_int32_t data; data = ixp425_pci_mem_bs_r_4(tag, ioh, off); return (le32toh(data)); } static void _pci_mem_bs_w_1(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int8_t val) { ixp425_pci_mem_bs_w_1(tag, ioh, off, val); } static void _pci_mem_bs_w_2(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int16_t val) { ixp425_pci_mem_bs_w_2(tag, ioh, off, val); } static void _pci_mem_bs_w_4(bus_space_tag_t tag, bus_space_handle_t ioh, bus_size_t off, u_int32_t val) { ixp425_pci_mem_bs_w_4(tag, ioh, off, htole32(val)); } #endif /* __ARMEB__ */ /* End of ixp425_pci_space.c */ Index: head/sys/arm/xscale/ixp425/ixp425_space.c =================================================================== --- head/sys/arm/xscale/ixp425/ixp425_space.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425_space.c (revision 327256) @@ -1,131 +1,125 @@ -/* $NetBSD: ixp425_space.c,v 1.6 2006/04/10 03:36:03 simonb Exp $ */ +/* $NetBSD: ixp425_space.c,v 1.7 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * bus_space I/O functions for ixp425 */ #include #include #include #include #include #include #include #include #include #include #include #include /* Proto types for all the bus_space structure functions */ bs_protos(generic); struct bus_space ixp425_bs_tag = { /* cookie */ .bs_privdata = (void *) 0, /* mapping/unmapping */ .bs_map = generic_bs_map, .bs_unmap = generic_bs_unmap, .bs_subregion = generic_bs_subregion, /* allocation/deallocation */ .bs_alloc = generic_bs_alloc, .bs_free = generic_bs_free, /* barrier */ .bs_barrier = generic_bs_barrier, /* read (single) */ .bs_r_1 = generic_bs_r_1, .bs_r_2 = generic_bs_r_2, .bs_r_4 = generic_bs_r_4, .bs_r_8 = NULL, /* read multiple */ .bs_rm_1 = generic_bs_rm_1, .bs_rm_2 = generic_bs_rm_2, .bs_rm_4 = generic_bs_rm_4, .bs_rm_8 = NULL, /* read region */ .bs_rr_1 = generic_bs_rr_1, .bs_rr_2 = generic_bs_rr_2, .bs_rr_4 = generic_bs_rr_4, .bs_rr_8 = NULL, /* write (single) */ .bs_w_1 = generic_bs_w_1, .bs_w_2 = generic_bs_w_2, .bs_w_4 = generic_bs_w_4, .bs_w_8 = NULL, /* write multiple */ .bs_wm_1 = generic_bs_wm_1, .bs_wm_2 = generic_bs_wm_2, .bs_wm_4 = generic_bs_wm_4, .bs_wm_8 = NULL, /* write region */ .bs_wr_1 = generic_bs_wr_1, .bs_wr_2 = generic_bs_wr_2, .bs_wr_4 = generic_bs_wr_4, .bs_wr_8 = NULL, /* set multiple */ /* XXX not implemented */ /* set region */ .bs_sr_1 = NULL, .bs_sr_2 = generic_bs_sr_2, .bs_sr_4 = generic_bs_sr_4, .bs_sr_8 = NULL, /* copy */ .bs_c_1 = NULL, .bs_c_2 = generic_bs_c_2, .bs_c_4 = NULL, .bs_c_8 = NULL, }; Index: head/sys/arm/xscale/ixp425/ixp425_timer.c =================================================================== --- head/sys/arm/xscale/ixp425/ixp425_timer.c (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425_timer.c (revision 327256) @@ -1,270 +1,264 @@ -/* $NetBSD: ixp425_timer.c,v 1.11 2006/04/10 03:36:03 simonb Exp $ */ +/* $NetBSD: ixp425_timer.c,v 1.15 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static uint32_t counts_per_hz; /* callback functions for intr_functions */ int ixpclk_intr(void *); struct ixpclk_softc { device_t sc_dev; bus_addr_t sc_baseaddr; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; }; static unsigned ixp425_timer_get_timecount(struct timecounter *tc); #ifndef IXP425_CLOCK_FREQ #define COUNTS_PER_SEC 66666600 /* 66MHz */ #else #define COUNTS_PER_SEC IXP425_CLOCK_FREQ #endif #define COUNTS_PER_USEC ((COUNTS_PER_SEC / 1000000) + 1) static struct ixpclk_softc *ixpclk_sc = NULL; #define GET_TS_VALUE(sc) (*(volatile u_int32_t *) \ (IXP425_TIMER_VBASE + IXP425_OST_TS)) static struct timecounter ixp425_timer_timecounter = { ixp425_timer_get_timecount, /* get_timecount */ NULL, /* no poll_pps */ ~0u, /* counter_mask */ COUNTS_PER_SEC, /* frequency */ "IXP4XX Timer", /* name */ 1000, /* quality */ }; static int ixpclk_probe(device_t dev) { device_set_desc(dev, "IXP4XX Timer"); return (0); } static int ixpclk_attach(device_t dev) { struct ixpclk_softc *sc = device_get_softc(dev); struct ixp425_softc *sa = device_get_softc(device_get_parent(dev)); ixpclk_sc = sc; sc->sc_dev = dev; sc->sc_iot = sa->sc_iot; sc->sc_baseaddr = IXP425_TIMER_HWBASE; if (bus_space_map(sc->sc_iot, sc->sc_baseaddr, 8, 0, &sc->sc_ioh)) panic("%s: Cannot map registers", device_get_name(dev)); return (0); } static device_method_t ixpclk_methods[] = { DEVMETHOD(device_probe, ixpclk_probe), DEVMETHOD(device_attach, ixpclk_attach), {0, 0}, }; static driver_t ixpclk_driver = { "ixpclk", ixpclk_methods, sizeof(struct ixpclk_softc), }; static devclass_t ixpclk_devclass; DRIVER_MODULE(ixpclk, ixp, ixpclk_driver, ixpclk_devclass, 0, 0); static unsigned ixp425_timer_get_timecount(struct timecounter *tc) { uint32_t ret; ret = GET_TS_VALUE(sc); return (ret); } /* * cpu_initclocks: * * Initialize the clock and get them going. */ void cpu_initclocks(void) { struct ixpclk_softc* sc = ixpclk_sc; struct resource *irq; device_t dev = sc->sc_dev; u_int oldirqstate; int rid = 0; void *ihl; if (hz < 50 || COUNTS_PER_SEC % hz) { printf("Cannot get %d Hz clock; using 100 Hz\n", hz); hz = 100; } tick = 1000000 / hz; /* number of microseconds between interrupts */ /* * We only have one timer available; stathz and profhz are * always left as 0 (the upper-layer clock code deals with * this situation). */ if (stathz != 0) printf("Cannot get %d Hz statclock\n", stathz); stathz = 0; if (profhz != 0) printf("Cannot get %d Hz profclock\n", profhz); profhz = 0; /* Report the clock frequency. */ oldirqstate = disable_interrupts(PSR_I); irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, IXP425_INT_TMR0, IXP425_INT_TMR0, 1, RF_ACTIVE); if (!irq) panic("Unable to setup the clock irq handler.\n"); else bus_setup_intr(dev, irq, INTR_TYPE_CLK, ixpclk_intr, NULL, NULL, &ihl); /* Set up the new clock parameters. */ /* clear interrupt */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS, OST_WARM_RESET | OST_WDOG_INT | OST_TS_INT | OST_TIM1_INT | OST_TIM0_INT); counts_per_hz = COUNTS_PER_SEC / hz; /* reload value & Timer enable */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_TIM0_RELOAD, (counts_per_hz & TIMERRELOAD_MASK) | OST_TIMER_EN); tc_init(&ixp425_timer_timecounter); restore_interrupts(oldirqstate); rid = 0; } /* * DELAY: * * Delay for at least N microseconds. */ void DELAY(int n) { u_int32_t first, last; int usecs; if (n == 0) return; /* * Clamp the timeout at a maximum value (about 32 seconds with * a 66MHz clock). *Nobody* should be delay()ing for anywhere * near that length of time and if they are, they should be hung * out to dry. */ if (n >= (0x80000000U / COUNTS_PER_USEC)) usecs = (0x80000000U / COUNTS_PER_USEC) - 1; else usecs = n * COUNTS_PER_USEC; /* Note: Timestamp timer counts *up*, unlike the other timers */ first = GET_TS_VALUE(); while (usecs > 0) { last = GET_TS_VALUE(); usecs -= (int)(last - first); first = last; } } /* * ixpclk_intr: * * Handle the hardclock interrupt. */ int ixpclk_intr(void *arg) { struct ixpclk_softc* sc = ixpclk_sc; struct trapframe *frame = arg; bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXP425_OST_STATUS, OST_TIM0_INT); hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); return (FILTER_HANDLED); } void cpu_startprofclock(void) { } void cpu_stopprofclock(void) { } Index: head/sys/arm/xscale/ixp425/ixp425reg.h =================================================================== --- head/sys/arm/xscale/ixp425/ixp425reg.h (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425reg.h (revision 327256) @@ -1,716 +1,710 @@ -/* $NetBSD: ixp425reg.h,v 1.19 2005/12/11 12:16:51 christos Exp $ */ +/* $NetBSD: ixp425reg.h,v 1.21 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ #ifndef _IXP425REG_H_ #define _IXP425REG_H_ /* * Physical memory map for the Intel IXP425 */ /* * CC00 00FF --------------------------- * SDRAM Configuration Registers * CC00 0000 --------------------------- * * C800 BFFF --------------------------- * System and Peripheral Registers * C800 0000 --------------------------- * Expansion Bus Configuration Registers * C400 0000 --------------------------- * PCI Configuration and Status Registers * C000 0000 --------------------------- * * 6400 0000 --------------------------- * Queue manager * 6000 0000 --------------------------- * Expansion Bus Data * 5000 0000 --------------------------- * PCI Data * 4800 0000 --------------------------- * * 4000 0000 --------------------------- * SDRAM * 0000 0000 --------------------------- */ /* * Virtual memory map for the Intel IXP425/IXP435 integrated devices */ /* * FFFF FFFF --------------------------- * * Global cache clean area * FF00 0000 --------------------------- * * FE00 0000 --------------------------- * 16M CFI Flash (on ext bus) * FD00 0000 --------------------------- * * FC00 0000 --------------------------- * PCI Data (memory space) * F800 0000 --------------------------- IXP425_PCI_MEM_VBASE * * F020 1000 --------------------------- * SDRAM/DDR Memory Controller * F020 0000 --------------------------- IXP425_MCU_VBASE * * F001 F000 RS485 (Cambria) CAMBRIA_RS485_VBASE * F001 E000 GPS (Cambria) CAMBRIA_GPS_VBASE * F001 D000 EHCI USB 2 (IXP435) IXP435_USB2_VBASE * F001 C000 EHCI USB 1 (IXP435) IXP435_USB1_VBASE * Queue manager * F001 8000 --------------------------- IXP425_QMGR_VBASE * PCI Configuration and Status * F001 7000 --------------------------- IXP425_PCI_VBASE * * (NB: gap for future addition of EXP CS5-7) * F001 4000 Expansion Bus Chip Select 4 * F001 3000 Expansion Bus Chip Select 3 * F001 2000 Expansion Bus Chip Select 2 * F001 1000 Expansion Bus Chip Select 1 * Expansion Bus Configuration * F001 0000 --------------------------- IXP425_EXP_VBASE * * F000 C000 MAC-A (IXP435) * F000 B000 USB (option on IXP425) * F000 A000 MAC-B (IXP425) | MAC-C (IXP435) * F000 9000 MAC-A (IXP425) * F000 8000 NPE-C * F000 7000 NPE-B (IXP425) * F000 6000 NPE-A * F000 5000 Timers * F000 4000 GPIO Controller * F000 3000 Interrupt Controller * F000 2000 Performance Monitor Controller (PMC) * F000 1000 UART 1 (IXP425) * F000 0000 UART 0 * F000 0000 --------------------------- IXP425_IO_VBASE * * 0000 0000 --------------------------- * */ /* Physical/Virtual address for I/O space */ #define IXP425_IO_VBASE 0xf0000000UL #define IXP425_IO_HWBASE 0xc8000000UL #define IXP425_IO_SIZE 0x00010000UL /* Physical/Virtual addresss offsets */ #define IXP425_UART0_OFFSET 0x00000000UL #define IXP425_UART1_OFFSET 0x00001000UL #define IXP425_PMC_OFFSET 0x00002000UL #define IXP425_INTR_OFFSET 0x00003000UL #define IXP425_GPIO_OFFSET 0x00004000UL #define IXP425_TIMER_OFFSET 0x00005000UL #define IXP425_NPE_A_OFFSET 0x00006000UL /* Not User Programmable */ #define IXP425_NPE_B_OFFSET 0x00007000UL /* Not User Programmable */ #define IXP425_NPE_C_OFFSET 0x00008000UL /* Not User Programmable */ #define IXP425_MAC_B_OFFSET 0x00009000UL /* Ethernet MAC on NPE-B */ #define IXP425_MAC_C_OFFSET 0x0000a000UL /* Ethernet MAC on NPE-C */ #define IXP425_USB_OFFSET 0x0000b000UL #define IXP435_MAC_A_OFFSET 0x0000c000UL /* Ethernet MAC on NPE-A */ #define IXP425_REG_SIZE 0x1000 /* * UART * UART0 0xc8000000 * UART1 0xc8001000 * */ /* I/O space */ #define IXP425_UART0_HWBASE (IXP425_IO_HWBASE + IXP425_UART0_OFFSET) #define IXP425_UART1_HWBASE (IXP425_IO_HWBASE + IXP425_UART1_OFFSET) #define IXP425_UART0_VBASE (IXP425_IO_VBASE + IXP425_UART0_OFFSET) /* 0xf0000000 */ #define IXP425_UART1_VBASE (IXP425_IO_VBASE + IXP425_UART1_OFFSET) /* 0xf0001000 */ #define IXP425_UART_FREQ 14745600 #define IXP425_UART_IER 0x01 /* interrupt enable register */ #define IXP425_UART_IER_RTOIE 0x10 /* receiver timeout interrupt enable */ #define IXP425_UART_IER_UUE 0x40 /* UART Unit enable */ /*#define IXP4XX_COM_NPORTS 8*/ /* * Timers */ #define IXP425_TIMER_HWBASE (IXP425_IO_HWBASE + IXP425_TIMER_OFFSET) #define IXP425_TIMER_VBASE (IXP425_IO_VBASE + IXP425_TIMER_OFFSET) #define IXP425_OST_TS 0x0000 #define IXP425_OST_TIM0 0x0004 #define IXP425_OST_TIM1 0x000C #define IXP425_OST_TIM0_RELOAD 0x0008 #define IXP425_OST_TIM1_RELOAD 0x0010 #define TIMERRELOAD_MASK 0xFFFFFFFC #define OST_ONESHOT_EN (1U << 1) #define OST_TIMER_EN (1U << 0) #define IXP425_OST_STATUS 0x0020 #define OST_WARM_RESET (1U << 4) #define OST_WDOG_INT (1U << 3) #define OST_TS_INT (1U << 2) #define OST_TIM1_INT (1U << 1) #define OST_TIM0_INT (1U << 0) #define IXP425_OST_WDOG 0x0014 #define IXP425_OST_WDOG_ENAB 0x0018 #define IXP425_OST_WDOG_KEY 0x001c #define OST_WDOG_KEY_MAJICK 0x482e #define OST_WDOG_ENAB_RST_ENA (1u << 0) #define OST_WDOG_ENAB_INT_ENA (1u << 1) #define OST_WDOG_ENAB_CNT_ENA (1u << 2) /* * Interrupt Controller Unit. * PA 0xc8003000 */ #define IXP425_IRQ_HWBASE IXP425_IO_HWBASE + IXP425_INTR_OFFSET #define IXP425_IRQ_VBASE IXP425_IO_VBASE + IXP425_INTR_OFFSET /* 0xf0003000 */ #define IXP425_IRQ_SIZE 0x00000020UL #define IXP425_INT_STATUS (IXP425_IRQ_VBASE + 0x00) #define IXP425_INT_ENABLE (IXP425_IRQ_VBASE + 0x04) #define IXP425_INT_SELECT (IXP425_IRQ_VBASE + 0x08) #define IXP425_IRQ_STATUS (IXP425_IRQ_VBASE + 0x0C) #define IXP425_FIQ_STATUS (IXP425_IRQ_VBASE + 0x10) #define IXP425_INT_PRTY (IXP425_IRQ_VBASE + 0x14) #define IXP425_IRQ_ENC (IXP425_IRQ_VBASE + 0x18) #define IXP425_FIQ_ENC (IXP425_IRQ_VBASE + 0x1C) #define IXP425_INT_SW1 31 /* SW Interrupt 1 */ #define IXP425_INT_SW0 30 /* SW Interrupt 0 */ #define IXP425_INT_GPIO_12 29 /* GPIO 12 */ #define IXP425_INT_GPIO_11 28 /* GPIO 11 */ #define IXP425_INT_GPIO_10 27 /* GPIO 11 */ #define IXP425_INT_GPIO_9 26 /* GPIO 9 */ #define IXP425_INT_GPIO_8 25 /* GPIO 8 */ #define IXP425_INT_GPIO_7 24 /* GPIO 7 */ #define IXP425_INT_GPIO_6 23 /* GPIO 6 */ #define IXP425_INT_GPIO_5 22 /* GPIO 5 */ #define IXP425_INT_GPIO_4 21 /* GPIO 4 */ #define IXP425_INT_GPIO_3 20 /* GPIO 3 */ #define IXP425_INT_GPIO_2 19 /* GPIO 2 */ #define IXP425_INT_XSCALE_PMU 18 /* XScale PMU */ #define IXP425_INT_AHB_PMU 17 /* AHB PMU */ #define IXP425_INT_WDOG 16 /* Watchdog Timer */ #define IXP425_INT_UART0 15 /* HighSpeed UART */ #define IXP425_INT_STAMP 14 /* Timestamp Timer */ #define IXP425_INT_UART1 13 /* Console UART */ #define IXP425_INT_USB 12 /* USB */ #define IXP425_INT_TMR1 11 /* General-Purpose Timer1 */ #define IXP425_INT_PCIDMA2 10 /* PCI DMA Channel 2 */ #define IXP425_INT_PCIDMA1 9 /* PCI DMA Channel 1 */ #define IXP425_INT_PCIINT 8 /* PCI Interrupt */ #define IXP425_INT_GPIO_1 7 /* GPIO 1 */ #define IXP425_INT_GPIO_0 6 /* GPIO 0 */ #define IXP425_INT_TMR0 5 /* General-Purpose Timer0 */ #define IXP425_INT_QUE33_64 4 /* Queue Manager 33-64 */ #define IXP425_INT_QUE1_32 3 /* Queue Manager 1-32 */ #define IXP425_INT_NPE_C 2 /* NPE C */ #define IXP425_INT_NPE_B 1 /* NPE B */ #define IXP425_INT_NPE_A 0 /* NPE A */ /* NB: IXP435 has an additional 32 IRQ's */ #define IXP435_INT_STATUS2 (IXP425_IRQ_VBASE + 0x20) #define IXP435_INT_ENABLE2 (IXP425_IRQ_VBASE + 0x24) #define IXP435_INT_SELECT2 (IXP425_IRQ_VBASE + 0x28) #define IXP435_IRQ_STATUS2 (IXP425_IRQ_VBASE + 0x2C) #define IXP435_FIQ_STATUS2 (IXP425_IRQ_VBASE + 0x30) #define IXP435_INT_USB0 32 /* USB Host 2.0 Host 0 */ #define IXP435_INT_USB1 33 /* USB Host 2.0 Host 1 */ #define IXP435_INT_QMGR_PER 60 /* Queue manager parity error */ #define IXP435_INT_ECC 61 /* Single or multi-bit ECC error */ /* * software interrupt */ #define IXP425_INT_bit31 31 #define IXP425_INT_bit30 30 #define IXP425_INT_bit14 14 #define IXP425_INT_bit11 11 #define IXP425_INT_HWMASK (0xffffffff & \ ~((1 << IXP425_INT_bit31) | \ (1 << IXP425_INT_bit30) | \ (1 << IXP425_INT_bit14) | \ (1 << IXP425_INT_bit11))) #define IXP425_INT_GPIOMASK (0x3ff800c0u) #define IXP435_INT_HWMASK ((1 << (IXP435_INT_USB0 - 32)) | \ (1 << (IXP435_INT_USB1 - 32)) | \ (1 << (IXP435_INT_QMGR_PER - 32)) | \ (1 << (IXP435_INT_ECC - 32))) /* * GPIO */ #define IXP425_GPIO_HWBASE IXP425_IO_HWBASE + IXP425_GPIO_OFFSET #define IXP425_GPIO_VBASE IXP425_IO_VBASE + IXP425_GPIO_OFFSET /* 0xf0004000 */ #define IXP425_GPIO_SIZE 0x00000020UL #define IXP425_GPIO_GPOUTR 0x00 #define IXP425_GPIO_GPOER 0x04 #define IXP425_GPIO_GPINR 0x08 #define IXP425_GPIO_GPISR 0x0c #define IXP425_GPIO_GPIT1R 0x10 #define IXP425_GPIO_GPIT2R 0x14 #define IXP425_GPIO_GPCLKR 0x18 # define GPCLKR_MUX14 (1U << 8) # define GPCLKR_CLK0TC_SHIFT 4 # define GPCLKR_CLK0DC_SHIFT 0 /* GPIO Output */ #define GPOUT_ON 0x1 #define GPOUT_OFF 0x0 /* GPIO direction */ #define GPOER_INPUT 0x1 #define GPOER_OUTPUT 0x0 /* GPIO Type bits */ #define GPIO_TYPE_ACT_HIGH 0x0 #define GPIO_TYPE_ACT_LOW 0x1 #define GPIO_TYPE_EDG_RISING 0x2 #define GPIO_TYPE_EDG_FALLING 0x3 #define GPIO_TYPE_TRANSITIONAL 0x4 #define GPIO_TYPE_MASK 0x7 #define GPIO_TYPE(b,v) ((v) << (((b) & 0x7) * 3)) #define GPIO_TYPE_REG(b) (((b)&8)?IXP425_GPIO_GPIT2R:IXP425_GPIO_GPIT1R) #define IXP4XX_GPIO_PINS 16 /* * Expansion Bus Configuration Space. */ #define IXP425_EXP_HWBASE 0xc4000000UL #define IXP425_EXP_VBASE 0xf0010000UL #define IXP425_EXP_SIZE 0x1000 /* offset */ #define EXP_TIMING_CS0_OFFSET 0x0000 #define EXP_TIMING_CS1_OFFSET 0x0004 #define EXP_TIMING_CS2_OFFSET 0x0008 #define EXP_TIMING_CS3_OFFSET 0x000c #define EXP_TIMING_CS4_OFFSET 0x0010 #define EXP_TIMING_CS5_OFFSET 0x0014 #define EXP_TIMING_CS6_OFFSET 0x0018 #define EXP_TIMING_CS7_OFFSET 0x001c #define EXP_CNFG0_OFFSET 0x0020 #define EXP_CNFG1_OFFSET 0x0024 #define EXP_FCTRL_OFFSET 0x0028 #define IXP425_EXP_RECOVERY_SHIFT 16 #define IXP425_EXP_HOLD_SHIFT 20 #define IXP425_EXP_STROBE_SHIFT 22 #define IXP425_EXP_SETUP_SHIFT 26 #define IXP425_EXP_ADDR_SHIFT 28 #define IXP425_EXP_CS_EN (1U << 31) #define IXP425_EXP_RECOVERY_T(x) (((x) & 15) << IXP425_EXP_RECOVERY_SHIFT) #define IXP425_EXP_HOLD_T(x) (((x) & 3) << IXP425_EXP_HOLD_SHIFT) #define IXP425_EXP_STROBE_T(x) (((x) & 15) << IXP425_EXP_STROBE_SHIFT) #define IXP425_EXP_SETUP_T(x) (((x) & 3) << IXP425_EXP_SETUP_SHIFT) #define IXP425_EXP_ADDR_T(x) (((x) & 3) << IXP425_EXP_ADDR_SHIFT) /* EXP_CSn bits */ #define EXP_BYTE_EN 0x00000001 /* bus uses only 8-bit data */ #define EXP_WR_EN 0x00000002 /* ena writes to CS region */ /* bit 2 is reserved */ #define EXP_SPLT_EN 0x00000008 /* ena AHB split transfers */ #define EXP_MUX_EN 0x00000010 /* multiplexed address/data */ #define EXP_HRDY_POL 0x00000020 /* HPI|HRDY polarity */ #define EXP_BYTE_RD16 0x00000040 /* byte rd access to word dev */ #define EXP_CNFG 0x00003c00 /* device config size */ #define EXP_SZ_512 (0 << 10) #define EXP_SZ_1K (1 << 10) #define EXP_SZ_2K (2 << 10) #define EXP_SZ_4K (3 << 10) #define EXP_SZ_8K (4 << 10) #define EXP_SZ_16K (5 << 10) #define EXP_SZ_32K (6 << 10) #define EXP_SZ_64K (7 << 10) #define EXP_SZ_128K (8 << 10) #define EXP_SZ_256K (9 << 10) #define EXP_SZ_512K (10 << 10) #define EXP_SZ_1M (11 << 10) #define EXP_SZ_2M (12 << 10) #define EXP_SZ_4M (13 << 10) #define EXP_SZ_8M (14 << 10) #define EXP_SZ_16M (15 << 10) #define EXP_CYC_TYPE 0x0000c000 /* bus cycle "type" */ #define EXP_CYC_INTEL (0 << 14) #define EXP_CYC_MOTO (1 << 14) #define EXP_CYC_HPI (2 << 14) #define EXP_T5 0x000f0000 /* recovery timing */ #define EXP_T4 0x00300000 /* hold timing */ #define EXP_T3 0x03c00000 /* strobe timing */ #define EXP_T2 0x0c000000 /* setup/chip select timing */ #define EXP_T1 0x30000000 /* address timing */ /* bit 30 is reserved */ #define EXP_CS_EN 0x80000000 /* chip select enabled */ /* EXP_CNFG0 bits */ #define EXP_CNFG0_8BIT (1 << 0) #define EXP_CNFG0_PCI_HOST (1 << 1) #define EXP_CNFG0_PCI_ARB (1 << 2) #define EXP_CNFG0_PCI_66MHZ (1 << 4) #define EXP_CNFG0_MEM_MAP (1U << 31) /* EXP_CNFG1 bits */ #define EXP_CNFG1_SW_INT0 (1 << 0) #define EXP_CNFG1_SW_INT1 (1 << 1) #define EXP_FCTRL_RCOMP (1<<0) #define EXP_FCTRL_USB_DEVICE (1<<1) #define EXP_FCTRL_HASH (1<<2) #define EXP_FCTRL_AES (1<<3) #define EXP_FCTRL_DES (1<<4) #define EXP_FCTRL_HDLC (1<<5) #define EXP_FCTRL_AAL (1<<6) #define EXP_FCTRL_HSS (1<<7) #define EXP_FCTRL_UTOPIA (1<<8) #define EXP_FCTRL_ETH0 (1<<9) #define EXP_FCTRL_ETH1 (1<<10) #define EXP_FCTRL_NPEA (1<<11) /* reset */ #define EXP_FCTRL_NPEB (1<<12) /* reset */ #define EXP_FCTRL_NPEC (1<<13) /* reset */ #define EXP_FCTRL_PCI (1<<14) #define EXP_FCTRL_ECC_TIMESYNC (1<<15) #define EXP_FCTRL_UTOPIA_PHY (3<<16) /* PHY limit */ #define EXP_FCTRL_USB_HOST (1<<18) #define EXP_FCTRL_NPEA_ETH (1<<19) #define EXP_FCTRL_NPEB_ETH (1<<20) #define EXP_FCTRL_RSA (1<<21) #define EXP_FCTRL_MAXFREQ (3<<22) /* XScale frequency */ #define EXP_FCTRL_RESVD (0xff<<24) #define EXP_FCTRL_IXP46X_ONLY \ (EXP_FCTRL_ECC_TIMESYNC | EXP_FCTRL_USB_HOST | EXP_FCTRL_NPEA_ETH | \ EXP_FCTRL_NPEB_ETH | EXP_FCTRL_RSA | EXP_FCTRL_MAXFREQ) #define EXP_FCTRL_BITS \ "\20\1RCOMP\2USB\3HASH\4AES\5DES\6HDLC\7AAL\10HSS\11UTOPIA\12ETH0" \ "\13ETH1\17PCI\20ECC\23USB_HOST\24NPEA_ETH\25NPEB_ETH\26RSA" /* * PCI */ #define IXP425_PCI_HWBASE 0xc0000000 #define IXP425_PCI_VBASE 0xf0017000UL #define IXP425_PCI_SIZE 0x1000 #define IXP425_AHB_OFFSET 0x00000000UL /* AHB bus */ /* * Mapping registers of IXP425 PCI Configuration */ /* PCI_ID_REG 0x00 */ /* PCI_COMMAND_STATUS_REG 0x04 */ /* PCI_CLASS_REG 0x08 */ /* PCI_BHLC_REG 0x0c */ #define PCI_MAPREG_BAR0 0x10 /* Base Address 0 */ #define PCI_MAPREG_BAR1 0x14 /* Base Address 1 */ #define PCI_MAPREG_BAR2 0x18 /* Base Address 2 */ #define PCI_MAPREG_BAR3 0x1c /* Base Address 3 */ #define PCI_MAPREG_BAR4 0x20 /* Base Address 4 */ #define PCI_MAPREG_BAR5 0x24 /* Base Address 5 */ /* PCI_SUBSYS_ID_REG 0x2c */ /* PCI_INTERRUPT_REG 0x3c */ #define PCI_RTOTTO 0x40 /* PCI Controller CSR Base Address */ #define IXP425_PCI_CSR_BASE IXP425_PCI_VBASE /* PCI Memory Space */ #define IXP425_PCI_MEM_HWBASE 0x48000000UL #define IXP425_PCI_MEM_VBASE 0xf8000000UL #define IXP425_PCI_MEM_SIZE 0x04000000UL /* 64MB */ /* PCI I/O Space */ #define IXP425_PCI_IO_HWBASE 0x00000000UL #define IXP425_PCI_IO_SIZE 0x00100000UL /* 1Mbyte */ /* PCI Controller Configuration Offset */ #define PCI_NP_AD 0x00 #define PCI_NP_CBE 0x04 # define NP_CBE_SHIFT 4 #define PCI_NP_WDATA 0x08 #define PCI_NP_RDATA 0x0c #define PCI_CRP_AD_CBE 0x10 #define PCI_CRP_AD_WDATA 0x14 #define PCI_CRP_AD_RDATA 0x18 #define PCI_CSR 0x1c # define CSR_PRST (1U << 16) # define CSR_IC (1U << 15) # define CSR_ABE (1U << 4) # define CSR_PDS (1U << 3) # define CSR_ADS (1U << 2) # define CSR_HOST (1U << 0) #define PCI_ISR 0x20 # define ISR_AHBE (1U << 3) # define ISR_PPE (1U << 2) # define ISR_PFE (1U << 1) # define ISR_PSE (1U << 0) #define PCI_INTEN 0x24 #define PCI_DMACTRL 0x28 #define PCI_AHBMEMBASE 0x2c #define PCI_AHBIOBASE 0x30 #define PCI_PCIMEMBASE 0x34 #define PCI_AHBDOORBELL 0x38 #define PCI_PCIDOORBELL 0x3c #define PCI_ATPDMA0_AHBADDR 0x40 #define PCI_ATPDMA0_PCIADDR 0x44 #define PCI_ATPDMA0_LENGTH 0x48 #define PCI_ATPDMA1_AHBADDR 0x4c #define PCI_ATPDMA1_PCIADDR 0x50 #define PCI_ATPDMA1_LENGTH 0x54 #define PCI_PTADMA0_AHBADDR 0x58 #define PCI_PTADMA0_PCIADDR 0x5c #define PCI_PTADMA0_LENGTH 0x60 #define PCI_PTADMA1_AHBADDR 0x64 #define PCI_PTADMA1_PCIADDR 0x68 #define PCI_PTADMA1_LENGTH 0x6c /* PCI target(T)/initiator(I) Interface Commands for PCI_NP_CBE register */ #define COMMAND_NP_IA 0x0 /* Interrupt Acknowledge (I)*/ #define COMMAND_NP_SC 0x1 /* Special Cycle (I)*/ #define COMMAND_NP_IO_READ 0x2 /* I/O Read (T)(I) */ #define COMMAND_NP_IO_WRITE 0x3 /* I/O Write (T)(I) */ #define COMMAND_NP_MEM_READ 0x6 /* Memory Read (T)(I) */ #define COMMAND_NP_MEM_WRITE 0x7 /* Memory Write (T)(I) */ #define COMMAND_NP_CONF_READ 0xa /* Configuration Read (T)(I) */ #define COMMAND_NP_CONF_WRITE 0xb /* Configuration Write (T)(I) */ /* PCI byte enables */ #define BE_8BIT(a) ((0x10u << ((a) & 0x03)) ^ 0xf0) #define BE_16BIT(a) ((0x30u << ((a) & 0x02)) ^ 0xf0) #define BE_32BIT(a) 0x00 /* PCI byte selects */ #define READ_8BIT(v,a) ((u_int8_t)((v) >> (((a) & 3) * 8))) #define READ_16BIT(v,a) ((u_int16_t)((v) >> (((a) & 2) * 8))) #define WRITE_8BIT(v,a) (((u_int32_t)(v)) << (((a) & 3) * 8)) #define WRITE_16BIT(v,a) (((u_int32_t)(v)) << (((a) & 2) * 8)) /* PCI Controller Configuration Commands for PCI_CRP_AD_CBE */ #define COMMAND_CRP_READ 0x00 #define COMMAND_CRP_WRITE (1U << 16) /* * SDRAM Configuration Register */ #define IXP425_MCU_HWBASE 0xcc000000UL #define IXP425_MCU_VBASE 0xf0200000UL #define IXP425_MCU_SIZE 0x1000 /* Actually only 256 bytes */ #define MCU_SDR_CONFIG 0x00 #define MCU_SDR_CONFIG_MCONF(x) ((x) & 0x7) #define MCU_SDR_CONFIG_64MBIT (1u << 5) #define MCU_SDR_REFRESH 0x04 #define MCU_SDR_IR 0x08 /* * IXP435 DDR MCU Registers */ #define IXP435_MCU_HWBASE 0xcc00e500UL #define MCU_DDR_SDIR 0x00 /* DDR SDAM Initialization Reg*/ #define MCU_DDR_SDCR0 0x04 /* DDR SDRAM Control Reg 0 */ #define MCU_DDR_SDCR1 0x08 /* DDR SDRAM Control Reg 1 */ #define MCU_DDR_SDBR 0x0c /* SDRAM Base Register */ #define MCU_DDR_SBR0 0x10 /* SDRAM Boundary Register 0 */ #define MCU_DDR_SBR1 0x14 /* SDRAM Boundary Register 1 */ #define MCU_DDR_ECCR 0x1c /* ECC Control Register */ #define MCU_DDR_ELOG0 0x20 /* ECC Log Register 0 */ #define MCU_DDR_ELOG1 0x24 /* ECC Log Register 1 */ #define MCU_DDR_ECAR0 0x28 /* ECC Address Register 0 */ #define MCU_DDR_ECAR1 0x2c /* ECC Address Register 1 */ #define MCU_DDR_ECTST 0x30 /* ECC Test Register */ #define MCU_DDR_MCISR 0x34 /* MC Interrupt Status Reg */ #define MCU_DDR_MPTCR 0x3c /* MC Port Transaction Cnt Reg*/ #define MCU_DDR_RFR 0x48 /* Refresh Frequency Register */ #define MCU_DDR_SDPR(n) (0x50+(n)*4) /* SDRAM Page Register 0-7 */ /* NB: RCVDLY at 0x1050 and LEGOVERIDE at 0x1074 */ /* * Performance Monitoring Unit (CP14) * * CP14.0.1 Performance Monitor Control Register(PMNC) * CP14.1.1 Clock Counter(CCNT) * CP14.4.1 Interrupt Enable Register(INTEN) * CP14.5.1 Overflow Flag Register(FLAG) * CP14.8.1 Event Selection Register(EVTSEL) * CP14.0.2 Performance Counter Register 0(PMN0) * CP14.1.2 Performance Counter Register 0(PMN1) * CP14.2.2 Performance Counter Register 0(PMN2) * CP14.3.2 Performance Counter Register 0(PMN3) */ #define PMNC_E 0x00000001 /* enable all counters */ #define PMNC_P 0x00000002 /* reset all PMNs to 0 */ #define PMNC_C 0x00000004 /* clock counter reset */ #define PMNC_D 0x00000008 /* clock counter / 64 */ #define INTEN_CC_IE 0x00000001 /* enable clock counter interrupt */ #define INTEN_PMN0_IE 0x00000002 /* enable PMN0 interrupt */ #define INTEN_PMN1_IE 0x00000004 /* enable PMN1 interrupt */ #define INTEN_PMN2_IE 0x00000008 /* enable PMN2 interrupt */ #define INTEN_PMN3_IE 0x00000010 /* enable PMN3 interrupt */ #define FLAG_CC_IF 0x00000001 /* clock counter overflow */ #define FLAG_PMN0_IF 0x00000002 /* PMN0 overflow */ #define FLAG_PMN1_IF 0x00000004 /* PMN1 overflow */ #define FLAG_PMN2_IF 0x00000008 /* PMN2 overflow */ #define FLAG_PMN3_IF 0x00000010 /* PMN3 overflow */ #define EVTSEL_EVCNT_MASK 0x0000000ff /* event to count for PMNs */ #define PMNC_EVCNT0_SHIFT 0 #define PMNC_EVCNT1_SHIFT 8 #define PMNC_EVCNT2_SHIFT 16 #define PMNC_EVCNT3_SHIFT 24 /* * Queue Manager */ #define IXP425_QMGR_HWBASE 0x60000000UL #define IXP425_QMGR_VBASE 0xf0018000UL #define IXP425_QMGR_SIZE 0x4000 /* * Network Processing Engines (NPE's) and associated Ethernet MAC's. */ #define IXP425_NPE_A_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_A_OFFSET) #define IXP425_NPE_A_VBASE (IXP425_IO_VBASE + IXP425_NPE_A_OFFSET) #define IXP425_NPE_A_SIZE 0x1000 /* Actually only 256 bytes */ #define IXP425_NPE_B_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_B_OFFSET) #define IXP425_NPE_B_VBASE (IXP425_IO_VBASE + IXP425_NPE_B_OFFSET) #define IXP425_NPE_B_SIZE 0x1000 /* Actually only 256 bytes */ #define IXP425_NPE_C_HWBASE (IXP425_IO_HWBASE + IXP425_NPE_C_OFFSET) #define IXP425_NPE_C_VBASE (IXP425_IO_VBASE + IXP425_NPE_C_OFFSET) #define IXP425_NPE_C_SIZE 0x1000 /* Actually only 256 bytes */ #define IXP425_MAC_B_HWBASE (IXP425_IO_HWBASE + IXP425_MAC_B_OFFSET) #define IXP425_MAC_B_VBASE (IXP425_IO_VBASE + IXP425_MAC_B_OFFSET) #define IXP425_MAC_B_SIZE 0x1000 /* Actually only 256 bytes */ #define IXP425_MAC_C_HWBASE (IXP425_IO_HWBASE + IXP425_MAC_C_OFFSET) #define IXP425_MAC_C_VBASE (IXP425_IO_VBASE + IXP425_MAC_C_OFFSET) #define IXP425_MAC_C_SIZE 0x1000 /* Actually only 256 bytes */ #define IXP435_MAC_A_HWBASE (IXP425_IO_HWBASE + IXP435_MAC_A_OFFSET) #define IXP435_MAC_A_VBASE (IXP425_IO_VBASE + IXP435_MAC_A_OFFSET) #define IXP435_MAC_A_SIZE 0x1000 /* Actually only 256 bytes */ /* * Expansion Bus Data Space. */ #define IXP425_EXP_BUS_HWBASE 0x50000000UL #define IXP425_EXP_BUS_SIZE 0x01000000 /* max, typically smaller */ #define IXP425_EXP_BUS_CSx_HWBASE(i) \ (IXP425_EXP_BUS_HWBASE + (i)*IXP425_EXP_BUS_SIZE) #define IXP425_EXP_BUS_CSx_SIZE 0x1000 #define IXP425_EXP_BUS_CSx_VBASE(i) \ (0xF0011000UL + (((i)-1)*IXP425_EXP_BUS_CSx_SIZE)) /* NB: CS0 is special; it maps flash */ #define IXP425_EXP_BUS_CS0_HWBASE IXP425_EXP_BUS_CSx_HWBASE(0) #define IXP425_EXP_BUS_CS0_VBASE 0xFD000000UL #ifndef IXP4XX_FLASH_SIZE #define IXP425_EXP_BUS_CS0_SIZE 0x01000000 /* NB: 16M */ #else #define IXP425_EXP_BUS_CS0_SIZE IXP4XX_FLASH_SIZE #endif #define IXP425_EXP_BUS_CS1_HWBASE IXP425_EXP_BUS_CSx_HWBASE(1) #define IXP425_EXP_BUS_CS1_VBASE IXP425_EXP_BUS_CSx_VBASE(1) #define IXP425_EXP_BUS_CS1_SIZE IXP425_EXP_BUS_CSx_SIZE #define IXP425_EXP_BUS_CS2_HWBASE IXP425_EXP_BUS_CSx_HWBASE(2) #define IXP425_EXP_BUS_CS2_VBASE IXP425_EXP_BUS_CSx_VBASE(2) #define IXP425_EXP_BUS_CS2_SIZE IXP425_EXP_BUS_CSx_SIZE #define IXP425_EXP_BUS_CS3_HWBASE IXP425_EXP_BUS_CSx_HWBASE(3) #define IXP425_EXP_BUS_CS3_VBASE IXP425_EXP_BUS_CSx_VBASE(3) #define IXP425_EXP_BUS_CS3_SIZE IXP425_EXP_BUS_CSx_SIZE #define IXP425_EXP_BUS_CS4_HWBASE IXP425_EXP_BUS_CSx_HWBASE(4) #define IXP425_EXP_BUS_CS4_VBASE IXP425_EXP_BUS_CSx_VBASE(4) #define IXP425_EXP_BUS_CS4_SIZE IXP425_EXP_BUS_CSx_SIZE /* NB: not mapped (yet) */ #define IXP425_EXP_BUS_CS5_HWBASE IXP425_EXP_BUS_CSx_HWBASE(5) #define IXP425_EXP_BUS_CS6_HWBASE IXP425_EXP_BUS_CSx_HWBASE(6) #define IXP425_EXP_BUS_CS7_HWBASE IXP425_EXP_BUS_CSx_HWBASE(7) /* * IXP435/Gateworks Cambria */ #define IXP435_USB1_HWBASE 0xCD000000UL /* USB host controller 1 */ #define IXP435_USB1_VBASE 0xF001C000UL #define IXP435_USB1_SIZE 0x1000 /* NB: only uses 0x300 */ #define IXP435_USB2_HWBASE 0xCE000000UL /* USB host controller 2 */ #define IXP435_USB2_VBASE 0xF001D000UL #define IXP435_USB2_SIZE 0x1000 /* NB: only uses 0x300 */ #define CAMBRIA_GPS_HWBASE 0x53FC0000UL /* optional GPS Serial Port */ #define CAMBRIA_GPS_VBASE 0xF001E000UL #define CAMBRIA_GPS_SIZE 0x1000 #define CAMBRIA_RS485_HWBASE 0x53F80000UL /* optional RS485 Serial Port */ #define CAMBRIA_RS485_VBASE 0xF001F000UL #define CAMBRIA_RS485_SIZE 0x1000 /* NB: these are mapped on the fly, so no fixed virtual addresses */ #define CAMBRIA_OCTAL_LED_HWBASE 0x53F40000UL /* Octal Status LED Latch */ #define CAMBRIA_OCTAL_LED_SIZE 0x1000 #define CAMBRIA_CFSEL1_HWBASE 0x53E40000UL /* Compact Flash Socket Sel 0 */ #define CAMBRIA_CFSEL1_SIZE 0x40000 #define CAMBRIA_CFSEL0_HWBASE 0x53E00000UL /* Compact Flash Socket Sel 1 */ #define CAMBRIA_CFSEL0_SIZE 0x40000 #endif /* _IXP425REG_H_ */ Index: head/sys/arm/xscale/ixp425/ixp425var.h =================================================================== --- head/sys/arm/xscale/ixp425/ixp425var.h (revision 327255) +++ head/sys/arm/xscale/ixp425/ixp425var.h (revision 327256) @@ -1,130 +1,124 @@ -/* $NetBSD: ixp425var.h,v 1.10 2006/04/10 03:36:03 simonb Exp $ */ +/* $NetBSD: ixp425var.h,v 1.12 2009/10/21 14:15:51 rmind Exp $ */ /*- - * SPDX-License-Identifier: BSD-4-Clause + * SPDX-License-Identifier: BSD-2-Clause-NetBSD * * Copyright (c) 2003 * Ichiro FUKUHARA . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Ichiro FUKUHARA. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. * * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ #ifndef _IXP425VAR_H_ #define _IXP425VAR_H_ #include #include #include #include /* NB: cputype is setup by set_cpufuncs */ #define cpu_is_ixp42x() (cputype == CPU_ID_IXP425) #define cpu_is_ixp43x() (cputype == CPU_ID_IXP435) #define cpu_is_ixp46x() (cputype == CPU_ID_IXP465) struct ixp425_softc { device_t sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_gpio_ioh; bus_space_handle_t sc_exp_ioh; u_int32_t sc_intrmask; struct rman sc_irq_rman; struct rman sc_mem_rman; bus_dma_tag_t sc_dmat; }; void ixp425_set_gpio(struct ixp425_softc *sc, int pin, int type); struct ixppcib_softc { device_t sc_dev; u_int sc_bus; struct resource *sc_csr; struct resource *sc_mem; struct rman sc_io_rman; struct rman sc_mem_rman; struct rman sc_irq_rman; struct bus_space sc_pci_memt; struct bus_space sc_pci_iot; bus_dma_tag_t sc_dmat; }; #define EXP_BUS_WRITE_4(sc, reg, data) \ bus_space_write_4(sc->sc_iot, sc->sc_exp_ioh, reg, data) #define EXP_BUS_READ_4(sc, reg) \ bus_space_read_4(sc->sc_iot, sc->sc_exp_ioh, reg) #define GPIO_CONF_WRITE_4(sc, reg, data) \ bus_space_write_4(sc->sc_iot, sc->sc_gpio_ioh, reg, data) #define GPIO_CONF_READ_4(sc, reg) \ bus_space_read_4(sc->sc_iot, sc->sc_gpio_ioh, reg) #define IXP4XX_GPIO_LOCK() mtx_lock(&ixp425_gpio_mtx) #define IXP4XX_GPIO_UNLOCK() mtx_unlock(&ixp425_gpio_mtx) extern struct mtx ixp425_gpio_mtx; extern struct bus_space ixp425_bs_tag; extern struct bus_space ixp425_a4x_bs_tag; extern struct bus_space cambria_exp_bs_tag; void cambria_exp_bus_init(struct ixp425_softc *); void ixp425_io_bs_init(bus_space_tag_t, void *); void ixp425_mem_bs_init(bus_space_tag_t, void *); uint32_t ixp425_sdram_size(void); uint32_t ixp435_ddram_size(void); uint32_t ixp4xx_read_feature_bits(void); void ixp4xx_write_feature_bits(uint32_t); int ixp425_md_route_interrupt(device_t, device_t, int); void ixp425_md_attach(device_t); int getvbase(uint32_t, uint32_t, uint32_t *); struct ixp425_ivar { uint32_t addr; int irq; }; #define IXP425_IVAR(d) ((struct ixp425_ivar *) device_get_ivars(d)) enum { IXP425_IVAR_ADDR, /* base physical address */ IXP425_IVAR_IRQ /* irq/gpio pin assignment */ }; #endif /* _IXP425VAR_H_ */