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 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"); }
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); }