static void slugiic_set_dir(void *arg, uint32_t bits) { struct slugiic_softc *sc = arg; uint32_t reg; int s; if (sc->sc_dirout == bits) return; s = splhigh(); sc->sc_dirout = bits; if (sc->sc_dirout) { /* SDA is output; enable SDA output if SDA OUTR is low */ reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); if ((reg & GPIO_I2C_SDA_BIT) == 0) { reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER); reg &= ~GPIO_I2C_SDA_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg); } } else { /* SDA is input; disable SDA output */ reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER); reg |= GPIO_I2C_SDA_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg); } splx(s); }
static void slugled_defer(device_t self) { struct slugled_softc *sc = device_private(self); struct ixp425_softc *ixsc = ixp425_softc; uint32_t reg; int s; s = splhigh(); /* Configure LED GPIO pins as output */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOER); reg &= ~(LEDBITS_USB0 | LEDBITS_USB1); reg &= ~(LEDBITS_READY | LEDBITS_STATUS); GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOER, reg); /* All LEDs off */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOUTR); reg |= LEDBITS_USB0 | LEDBITS_USB1; reg &= ~(LEDBITS_STATUS | LEDBITS_READY); GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOUTR, reg); splx(s); if (shutdownhook_establish(slugled_shutdown, sc) == NULL) aprint_error_dev(self, "WARNING - Failed to register shutdown hook\n"); callout_init(&sc->sc_usb0, 0); callout_setfunc(&sc->sc_usb0, slugled_callout, (void *)(uintptr_t)LEDBITS_USB0); callout_init(&sc->sc_usb1, 0); callout_setfunc(&sc->sc_usb1, slugled_callout, (void *)(uintptr_t)LEDBITS_USB1); callout_init(&sc->sc_usb2, 0); callout_setfunc(&sc->sc_usb2, slugled_callout, (void *)(uintptr_t)(LEDBITS_USB0 | LEDBITS_USB1)); sc->sc_usb0_ih = ixp425_intr_establish(PCI_INT_A, IPL_USB, slugled_intr0, sc); KDASSERT(sc->sc_usb0_ih != NULL); sc->sc_usb1_ih = ixp425_intr_establish(PCI_INT_B, IPL_USB, slugled_intr1, sc); KDASSERT(sc->sc_usb1_ih != NULL); sc->sc_usb2_ih = ixp425_intr_establish(PCI_INT_C, IPL_USB, slugled_intr2, sc); KDASSERT(sc->sc_usb2_ih != NULL); sc->sc_tmr_ih = ixp425_intr_establish(IXP425_INT_TMR0, IPL_CLOCK, slugled_tmr, NULL); KDASSERT(sc->sc_tmr_ih != NULL); }
static void slugbutt_deferred(device_t self) { struct slugbutt_softc *sc = device_private(self); struct ixp425_softc *ixsc = ixp425_softc; uint32_t reg; sc->sc_dev = self; /* Configure the GPIO pins as inputs */ reg = GPIO_CONF_READ_4(ixsc, IXP425_GPIO_GPOER); reg |= SLUGBUTT_PWR_BIT | SLUGBUTT_RST_BIT; GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPOER, reg); /* Configure the input type: Falling edge */ reg = GPIO_CONF_READ_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_PWR)); reg &= ~GPIO_TYPE(GPIO_BUTTON_PWR, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_BUTTON_PWR, GPIO_TYPE_EDG_FALLING); GPIO_CONF_WRITE_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_PWR), reg); reg = GPIO_CONF_READ_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_RST)); reg &= ~GPIO_TYPE(GPIO_BUTTON_RST, GPIO_TYPE_MASK); reg |= GPIO_TYPE(GPIO_BUTTON_RST, GPIO_TYPE_EDG_FALLING); GPIO_CONF_WRITE_4(ixsc, GPIO_TYPE_REG(GPIO_BUTTON_RST), reg); /* Clear any existing interrupt */ GPIO_CONF_WRITE_4(ixsc, IXP425_GPIO_GPISR, SLUGBUTT_PWR_BIT | SLUGBUTT_RST_BIT); sysmon_task_queue_init(); sc->sc_smpwr.smpsw_name = device_xname(sc->sc_dev); sc->sc_smpwr.smpsw_type = PSWITCH_TYPE_POWER; if (sysmon_pswitch_register(&sc->sc_smpwr) != 0) { printf("%s: unable to register power button with sysmon\n", device_xname(sc->sc_dev)); return; } sc->sc_smrst.smpsw_name = device_xname(sc->sc_dev); sc->sc_smrst.smpsw_type = PSWITCH_TYPE_RESET; if (sysmon_pswitch_register(&sc->sc_smrst) != 0) { printf("%s: unable to register reset button with sysmon\n", device_xname(sc->sc_dev)); return; } /* Hook the interrupts */ ixp425_intr_establish(BUTTON_PWR_INT, IPL_TTY, power_intr, sc); ixp425_intr_establish(BUTTON_RST_INT, IPL_TTY, reset_intr, sc); }
static uint32_t slugiic_read_bits(void *arg) { uint32_t reg; reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPINR); return (reg & (GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT)); }
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"); }
static int avila_gpio_pin_flags(struct avila_gpio_softc *sc, uint32_t pin) { uint32_t v; v = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin); return (v ? GPIO_PIN_INPUT : GPIO_PIN_OUTPUT); }
static void slugiic_deferred_attach(struct device *device) { struct slugiic_softc *sc = (struct slugiic_softc *)device; struct i2cbus_attach_args iba; uint32_t reg; reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); reg |= GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, reg); reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER); reg &= ~GPIO_I2C_SCL_BIT; reg |= GPIO_I2C_SDA_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, reg); iba.iba_tag = &sc->sc_ic; (void) config_found_ia(&sc->sc_dev, "i2cbus", &iba, iicbus_print); }
static int i2c_getsda(struct cambria_gpio_softc *sc) { uint32_t reg; IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); }
static void led_func(void *arg, int onoff) { struct led_avila_softc *sc = arg; uint32_t reg; reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOUTR); if (onoff) reg &= ~GPIO_LED_STATUS_BIT; else reg |= GPIO_LED_STATUS_BIT; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOUTR, reg); }
static int ixpiic_getsda(device_t dev) { struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; IXP4XX_GPIO_LOCK(); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); IXP4XX_GPIO_UNLOCK(); return (reg & GPIO_I2C_SDA_BIT); }
static void slugled_callout(void *arg) { uint32_t reg, bit; int is; bit = (uint32_t)(uintptr_t)arg; is = disable_interrupts(I32_bit); reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, reg | bit); restore_interrupts(is); }
static int ixpiic_getsda(device_t dev) { struct ixpiic_softc *sc = ixpiic_sc; uint32_t reg; mtx_lock(&Giant); GPIO_CONF_SET(sc, IXP425_GPIO_GPOER, GPIO_I2C_SDA_BIT); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR); mtx_unlock(&Giant); return (reg & GPIO_I2C_SDA_BIT); }
static void slugiic_set_bits(void *arg, uint32_t bits) { struct slugiic_softc *sc = arg; uint32_t oer, outr; int s; s = splhigh(); /* * Enable SCL output if the SCL line is to be driven low. * Enable SDA output if the SDA line is to be driven low and * SDA direction is output. * Otherwise switch them to input even if directions are output * so that we can emulate open collector output with the pullup * resistors. * If lines are to be set to high, disable OER first then set OUTR. * If lines are to be set to low, set OUTR first then enable OER. */ oer = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOER); if ((bits & GPIO_I2C_SCL_BIT) != 0) oer |= GPIO_I2C_SCL_BIT; if ((bits & GPIO_I2C_SDA_BIT) != 0) oer |= GPIO_I2C_SDA_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, oer); outr = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); outr &= ~(GPIO_I2C_SDA_BIT | GPIO_I2C_SCL_BIT); GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, outr | bits); if ((bits & GPIO_I2C_SCL_BIT) == 0) oer &= ~GPIO_I2C_SCL_BIT; if ((bits & GPIO_I2C_SDA_BIT) == 0 && sc->sc_dirout) oer &= ~GPIO_I2C_SDA_BIT; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOER, oer); splx(s); }
static int avila_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) { struct avila_gpio_softc *sc = device_get_softc(dev); if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & (1 << pin))) return (EINVAL); IXP4XX_GPIO_LOCK(); *val = (GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & (1 << pin)) ? 1 : 0; IXP4XX_GPIO_UNLOCK(); return (0); }
static int slugled_intr0(void *arg) { struct slugled_softc *sc = arg; uint32_t reg; int is; is = disable_interrupts(I32_bit); reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); reg &= ~LEDBITS_USB0; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, reg); restore_interrupts(is); callout_schedule(&sc->sc_usb0, SLUGLED_FLASH_LEN); return (1); }
static int avila_gpio_pin_toggle(device_t dev, uint32_t pin) { struct avila_gpio_softc *sc = device_get_softc(dev); uint32_t mask = 1 << pin; int res; if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); IXP4XX_GPIO_LOCK(); res = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPINR) & mask; if (res) GPIO_CLEAR_BITS(sc, IXP425_GPIO_GPOUTR, mask); else GPIO_SET_BITS(sc, IXP425_GPIO_GPOUTR, mask); IXP4XX_GPIO_UNLOCK(); return (0); }
static int led_avila_attach(device_t dev) { struct led_avila_softc *sc = device_get_softc(dev); struct ixp425_softc *sa = device_get_softc(device_get_parent(dev)); sc->sc_dev = dev; sc->sc_iot = sa->sc_iot; sc->sc_gpio_ioh = sa->sc_gpio_ioh; /* Configure LED GPIO pin as output */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER) &~ GPIO_LED_STATUS_BIT); sc->sc_led = led_create(led_func, sc, "gpioled"); led_func(sc, 1); /* Turn on LED */ return (0); }
static int slugled_tmr(void *arg) { struct clockframe *cf = arg; uint32_t reg, bit; int is; if (CLKF_INTR(cf) || sched_curcpu_runnable_p() || (curlwp != NULL && curlwp != curcpu()->ci_data.cpu_idlelwp)) bit = LEDBITS_STATUS; else bit = 0; is = disable_interrupts(I32_bit); reg = GPIO_CONF_READ_4(ixp425_softc, IXP425_GPIO_GPOUTR); reg &= ~LEDBITS_STATUS; GPIO_CONF_WRITE_4(ixp425_softc, IXP425_GPIO_GPOUTR, reg | bit); restore_interrupts(is); return (1); }
static void slugled_shutdown(void *arg) { struct slugled_softc *sc = arg; uint32_t reg; int s; ixp425_intr_disestablish(sc->sc_usb0_ih); ixp425_intr_disestablish(sc->sc_usb1_ih); ixp425_intr_disestablish(sc->sc_tmr_ih); /* Cancel the callouts */ s = splsoftclock(); callout_stop(&sc->sc_usb0); callout_stop(&sc->sc_usb1); splx(s); /* Turn off the disk LEDs, and set Ready/Status to amber */ s = splhigh(); reg = GPIO_CONF_READ_4(ixp425_softc,IXP425_GPIO_GPOUTR); reg |= LEDBITS_USB0 | LEDBITS_USB1 | LEDBITS_STATUS | LEDBITS_READY; GPIO_CONF_WRITE_4(ixp425_softc,IXP425_GPIO_GPOUTR, reg); splx(s); }
void ixp425_md_pci_init(struct ixp425_softc *sc) { pci_chipset_tag_t pc = &sc->ia_pci_chipset; u_int32_t reg; pc->pc_intr_v = sc; pc->pc_intr_map = nslu2_pci_intr_map; pc->pc_intr_string = nslu2_pci_intr_string; pc->pc_intr_evcnt = nslu2_pci_intr_evcnt; pc->pc_intr_establish = nslu2_pci_intr_establish; pc->pc_intr_disestablish = nslu2_pci_intr_disestablish; /* 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 */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPOER); reg &= ~((1u << GPIO_PCI_CLK) | (1u << GPIO_PCI_RESET)); reg |= (1u << GPIO_PCI_INTA) | (1u << GPIO_PCI_INTB) | (1u << GPIO_PCI_INTC); GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPOER, reg); /* * Set GPIO interrupt type * PCI_INT_A, PCI_INTB, PCI_INT_C: 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); /* Clear ISR */ GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPISR, (1u << GPIO_PCI_INTA) | (1u << GPIO_PCI_INTB) | (1u << GPIO_PCI_INTC)); /* Wait 1ms to satisfy "minimum reset assertion time" of the PCI spec */ DELAY(1000); reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); reg |= (0xf << GPCLKR_CLK0DC_SHIFT) | (0xf << GPCLKR_CLK0TC_SHIFT); GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg); /* PCI Clock Enable */ reg = GPIO_CONF_READ_4(sc, IXP425_GPIO_GPCLKR); reg |= GPCLKR_MUX14; GPIO_CONF_WRITE_4(sc, IXP425_GPIO_GPCLKR, reg); /* * 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); /* * AHB->PCI address translation * PCI Memory Map allocation in 0x48000000 (64MB) * see. IXP425_PCI_MEM_HWBASE */ PCI_CSR_WRITE_4(sc, PCI_PCIMEMBASE, 0x48494a4b); /* * PCI->AHB address translation * begin at the physical memory start + OFFSET */ #define AHB_OFFSET 0x10000000UL reg = (AHB_OFFSET + 0x00000000) >> 0; reg |= (AHB_OFFSET + 0x01000000) >> 8; reg |= (AHB_OFFSET + 0x02000000) >> 16; reg |= (AHB_OFFSET + 0x03000000) >> 24; PCI_CSR_WRITE_4(sc, PCI_AHBMEMBASE, reg); /* Write Mapping registers PCI Configuration Registers */ /* Base Address 0 - 3 */ ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR0, AHB_OFFSET + 0x00000000); ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR1, AHB_OFFSET + 0x01000000); ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR2, AHB_OFFSET + 0x02000000); ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR3, AHB_OFFSET + 0x03000000); /* Base Address 4 */ ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR4, 0xffffffff); /* Base Address 5 */ ixp425_pci_conf_reg_write(sc, PCI_MAPREG_BAR5, 0x00000000); /* Assert some PCI errors */ PCI_CSR_WRITE_4(sc, PCI_ISR, ISR_AHBE | ISR_PPE | ISR_PFE | ISR_PSE); /* * 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); /* * Enable bus mastering and I/O,memory access */ ixp425_pci_conf_reg_write(sc, PCI_COMMAND_STATUS_REG, PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE); /* * Wait some more to ensure PCI devices have stabilised. */ DELAY(50000); }
static int ata_avila_attach(device_t dev) { struct ata_avila_softc *sc = device_get_softc(dev); struct ixp425_softc *sa = device_get_softc(device_get_parent(dev)); u_int32_t alt_t_off, ide_gpin, ide_irq; sc->sc_dev = dev; /* NB: borrow from parent */ sc->sc_iot = sa->sc_iot; sc->sc_exp_ioh = sa->sc_exp_ioh; if (EXP_BUS_READ_4(sc, EXP_TIMING_CS2_OFFSET) != 0) { /* Avila board */ if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS1_HWBASE, IXP425_EXP_BUS_CS1_SIZE, 0, &sc->sc_ioh)) panic("%s: unable to map Expansion Bus CS1 window", __func__); if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS2_HWBASE, IXP425_EXP_BUS_CS2_SIZE, 0, &sc->sc_alt_ioh)) panic("%s: unable to map Expansion Bus CS2 window", __func__); ide_gpin = AVILA_IDE_GPIN; ide_irq = AVILA_IDE_IRQ; sc->sc_16bit_off = EXP_TIMING_CS1_OFFSET; alt_t_off = EXP_TIMING_CS2_OFFSET; } else { /* Pronghorn */ if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS3_HWBASE, IXP425_EXP_BUS_CS3_SIZE, 0, &sc->sc_ioh)) panic("%s: unable to map Expansion Bus CS3 window", __func__); if (bus_space_map(sc->sc_iot, IXP425_EXP_BUS_CS4_HWBASE, IXP425_EXP_BUS_CS4_SIZE, 0, &sc->sc_alt_ioh)) panic("%s: unable to map Expansion Bus CS4 window", __func__); ide_gpin = PRONGHORN_IDE_GPIN; ide_irq = PRONGHORN_IDE_IRQ; sc->sc_16bit_off = EXP_TIMING_CS3_OFFSET; alt_t_off = EXP_TIMING_CS4_OFFSET; } /* * Craft special resource for ATA bus space ops * that go through the expansion bus and require * special hackery to ena/dis 16-bit operations. * * XXX probably should just make this generic for * accessing the expansion bus. */ sc->sc_expbus_tag.bs_cookie = sc; /* NB: backpointer */ /* read single */ sc->sc_expbus_tag.bs_r_1 = ata_bs_r_1, sc->sc_expbus_tag.bs_r_2 = ata_bs_r_2, /* read multiple */ sc->sc_expbus_tag.bs_rm_2 = ata_bs_rm_2, sc->sc_expbus_tag.bs_rm_2_s = ata_bs_rm_2_s, /* write (single) */ sc->sc_expbus_tag.bs_w_1 = ata_bs_w_1, sc->sc_expbus_tag.bs_w_2 = ata_bs_w_2, /* write multiple */ sc->sc_expbus_tag.bs_wm_2 = ata_bs_wm_2, sc->sc_expbus_tag.bs_wm_2_s = ata_bs_wm_2_s, rman_set_bustag(&sc->sc_ata, &sc->sc_expbus_tag); rman_set_bushandle(&sc->sc_ata, sc->sc_ioh); rman_set_bustag(&sc->sc_alt_ata, &sc->sc_expbus_tag); rman_set_bushandle(&sc->sc_alt_ata, sc->sc_alt_ioh); GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPOER, GPIO_CONF_READ_4(sa, IXP425_GPIO_GPOER) | (1<<ide_gpin)); /* set interrupt type */ GPIO_CONF_WRITE_4(sa, GPIO_TYPE_REG(ide_gpin), (GPIO_CONF_READ_4(sa, GPIO_TYPE_REG(ide_gpin)) &~ GPIO_TYPE(ide_gpin, GPIO_TYPE_MASK)) | GPIO_TYPE(ide_gpin, GPIO_TYPE_EDG_RISING)); /* clear ISR */ GPIO_CONF_WRITE_4(sa, IXP425_GPIO_GPISR, (1<<ide_gpin)); /* configure CS1/3 window, leaving timing unchanged */ EXP_BUS_WRITE_4(sc, sc->sc_16bit_off, EXP_BUS_READ_4(sc, sc->sc_16bit_off) | EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); /* configure CS2/4 window, leaving timing unchanged */ EXP_BUS_WRITE_4(sc, alt_t_off, EXP_BUS_READ_4(sc, alt_t_off) | EXP_BYTE_EN | EXP_WR_EN | EXP_BYTE_RD16 | EXP_CS_EN); /* setup interrupt */ sc->sc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->sc_rid, ide_irq, ide_irq, 1, RF_ACTIVE); if (!sc->sc_irq) panic("Unable to allocate irq %u.\n", ide_irq); bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_BIO | INTR_MPSAFE | INTR_ENTROPY, NULL, ata_avila_intr, sc, &sc->sc_ih); /* attach channel on this controller */ device_add_child(dev, "ata", devclass_find_free_unit(ata_devclass, 0)); bus_generic_attach(dev); return 0; }
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"); }