void omgpio_recalc_interrupts(struct omgpio_softc *sc) { struct intrhand *ih; int max = IPL_NONE; int min = IPL_HIGH; int i; for (i = 0; i < GPIO_NUM_PINS; i++) { ih = sc->sc_handlers[i]; if (ih != NULL) { if (ih->ih_ipl > max) max = ih->ih_ipl; if (ih->ih_ipl < min) min = ih->ih_ipl; } } if (max == IPL_NONE) min = IPL_NONE; #if 0 if ((max == IPL_NONE || max != sc->sc_max_il) && sc->sc_ih_h != NULL) arm_intr_disestablish(sc->sc_ih_h); if (max != IPL_NONE && max != sc->sc_max_il) { sc->sc_ih_h = arm_intr_establish(sc->sc_irq, max, omgpio_irq, sc, NULL); } #else if (sc->sc_ih_h != NULL) arm_intr_disestablish(sc->sc_ih_h); if (max != IPL_NONE) { sc->sc_ih_h = arm_intr_establish(sc->sc_irq, max, omgpio_irq, sc, NULL); } #endif sc->sc_max_il = max; if (sc->sc_ih_l != NULL) arm_intr_disestablish(sc->sc_ih_l); if (max != min) { sc->sc_ih_h = arm_intr_establish(sc->sc_irq, min, omgpio_irq_dummy, sc, NULL); } sc->sc_min_il = min; }
void imxuartattach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct imxuart_softc *sc = (struct imxuart_softc *) self; sc->sc_irq = arm_intr_establish(aa->aa_dev->irq[0], IPL_TTY, imxuart_intr, sc, sc->sc_dev.dv_xname); sc->sc_iot = aa->aa_iot; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxuartattach: bus_space_map failed!"); if (aa->aa_dev->mem[0].addr == imxuartconsaddr) printf(" console"); timeout_set(&sc->sc_diag_tmo, imxuart_diag, sc); timeout_set(&sc->sc_dtr_tmo, imxuart_raisedtr, sc); sc->sc_si = softintr_establish(IPL_TTY, imxuart_softint, sc); if(sc->sc_si == NULL) panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname); printf("\n"); }
void imxahci_attach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct imxahci_softc *imxsc = (struct imxahci_softc *) self; struct ahci_softc *sc = &imxsc->sc; uint32_t timeout = 0x100000; sc->sc_iot = aa->aa_iot; sc->sc_ios = aa->aa_dev->mem[0].size; sc->sc_dmat = aa->aa_dmat; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxahci_attach: bus_space_map failed!"); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, ahci_intr, sc, sc->sc_dev.dv_xname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); goto unmap; } /* power it up */ imxccm_enable_sata(); delay(100); /* power phy up */ imxiomuxc_enable_sata(); /* setup */ bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR, bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0PHYCR) & ~SATA_P0PHYCR_TEST_PDDQ); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_GHC, SATA_GHC_HR); while (!bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_VERSIONR)); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_CAP, bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_CAP) | SATA_CAP_SSS); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_PI, 1); bus_space_write_4(sc->sc_iot, sc->sc_ioh, SATA_TIMER1MS, imxccm_get_ahbclk()); while (!(bus_space_read_4(sc->sc_iot, sc->sc_ioh, SATA_P0SSTS) & 0xF) && timeout--); if (ahci_attach(sc) != 0) { /* error printed by ahci_attach */ goto irq; } return; irq: arm_intr_disestablish(sc->sc_ih); unmap: bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); }
void exehci_attach(struct device *parent, struct device *self, void *aux) { struct exehci_softc *sc = (struct exehci_softc *)self; struct armv7_attach_args *aa = aux; usbd_status r; char *devname = sc->sc.sc_bus.bdev.dv_xname; sc->sc.iot = aa->aa_iot; sc->sc.sc_bus.dmatag = aa->aa_dmat; sc->sc.sc_size = aa->aa_dev->mem[0].size; /* Map I/O space */ if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc.ioh)) { printf(": cannot map mem space\n"); goto out; } if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[1].addr, aa->aa_dev->mem[1].size, 0, &sc->ph_ioh)) { printf(": cannot map mem space\n"); goto mem0; } printf("\n"); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_USB, ehci_intr, &sc->sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); goto mem1; } exehci_setup(sc); strlcpy(sc->sc.sc_vendor, "Exynos 5", sizeof(sc->sc.sc_vendor)); r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); goto intr; } config_found((void *)sc, &sc->sc.sc_bus, usbctlprint); goto out; intr: arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; mem1: bus_space_unmap(sc->sc.iot, sc->ph_ioh, aa->aa_dev->mem[1].addr); mem0: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; out: return; }
void sxiuartattach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct sxiuart_softc *sc = (struct sxiuart_softc *) self; bus_space_tag_t iot; bus_space_handle_t ioh; int s; sc->sc_iot = iot = aa->aa_iot; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("sxiuartattach: bus_space_map failed!"); ioh = sc->sc_ioh; if (aa->aa_dev->mem[0].addr == sxiuartconsaddr) { cn_tab->cn_dev = makedev(12 /* XXX */, 0); cdevsw[12] = sxiuartdev; /* KLUDGE */ printf(": console"); /* XXX compare uses of COM_HW_CONSOLE against com.c */ SET(sc->sc_hwflags, COM_HW_CONSOLE); SET(sc->sc_swflags, COM_SW_SOFTCAR); sxiuartconsiot = iot; sxiuartconsioh = ioh; } timeout_set(&sc->sc_diag_tmo, sxiuart_diag, sc); timeout_set(&sc->sc_dtr_tmo, sxiuart_raisedtr, sc); sc->sc_si = softintr_establish(IPL_TTY, sxiuart_softint, sc); if(sc->sc_si == NULL) panic("%s: can't establish soft interrupt.", sc->sc_dev.dv_xname); sc->sc_frequency = 24000000; /* XXX */ if ((bus_space_read_1(sc->sc_iot, sc->sc_ioh, SXIUART_IIR) & IIR_BUSY) == IIR_BUSY) (void)bus_space_read_4(sc->sc_iot, sc->sc_ioh, SXIUART_USR); sc->sc_ier = 0; /* disable interrupts */ bus_space_write_1(iot, ioh, SXIUART_IER, sc->sc_ier); /* clear and disable fifo */ bus_space_write_1(iot, ioh, SXIUART_FCR, 0 | RFIFOR | XFIFOR); s = splhigh(); SET(sc->sc_mcr, MCR_DTR | MCR_RTS | MCR_IENABLE); bus_space_write_1(sc->sc_iot, sc->sc_ioh, SXIUART_MCR, sc->sc_mcr); splx(s); arm_intr_establish(aa->aa_dev->irq[0], IPL_TTY, sxiuart_intr, sc, sc->sc_dev.dv_xname); printf("\n"); }
void imxiic_attach(struct device *parent, struct device *self, void *args) { struct imxiic_softc *sc = (struct imxiic_softc *)self; struct armv7_attach_args *aa = args; sc->sc_iot = aa->aa_iot; sc->sc_ios = aa->aa_dev->mem[0].size; sc->unit = aa->aa_dev->unit; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxiic_attach: bus_space_map failed!"); #if 0 sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, imxiic_intr, sc, sc->sc_dev.dv_xname); #endif printf("\n"); /* set iomux pins */ imxiomuxc_enable_i2c(sc->unit); /* set speed to 100kHz */ imxiic_setspeed(sc, 100); /* reset */ HWRITE2(sc, I2C_I2CR, 0); HWRITE2(sc, I2C_I2SR, 0); sc->stopped = 1; rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); struct i2cbus_attach_args iba; sc->i2c_tag.ic_cookie = sc; sc->i2c_tag.ic_acquire_bus = imxiic_i2c_acquire_bus; sc->i2c_tag.ic_release_bus = imxiic_i2c_release_bus; sc->i2c_tag.ic_exec = imxiic_i2c_exec; bzero(&iba, sizeof iba); iba.iba_name = "iic"; iba.iba_tag = &sc->i2c_tag; config_found(&sc->sc_dev, &iba, NULL); }
void exiic_attach(struct device *parent, struct device *self, void *args) { struct exiic_softc *sc = (struct exiic_softc *)self; struct armv7_attach_args *aa = args; sc->sc_iot = aa->aa_iot; sc->sc_ios = aa->aa_dev->mem[0].size; sc->unit = aa->aa_dev->unit; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("exiic_attach: bus_space_map failed!"); #if 0 sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_BIO, exiic_intr, sc, sc->sc_dev.dv_xname); #endif printf("\n"); rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname); struct i2cbus_attach_args iba; sc->i2c_tag.ic_cookie = sc; sc->i2c_tag.ic_acquire_bus = exiic_i2c_acquire_bus; sc->i2c_tag.ic_release_bus = exiic_i2c_release_bus; sc->i2c_tag.ic_exec = exiic_i2c_exec; bzero(&iba, sizeof iba); iba.iba_name = "iic"; iba.iba_tag = &sc->i2c_tag; iba.iba_bus_scan = exiic_bus_scan; iba.iba_bus_scan_arg = sc; config_found(&sc->sc_dev, &iba, NULL); }
void imxehci_attach(struct device *parent, struct device *self, void *aux) { struct imxehci_softc *sc = (struct imxehci_softc *)self; struct armv7_attach_args *aa = aux; usbd_status r; char *devname = sc->sc.sc_bus.bdev.dv_xname; sc->sc.iot = aa->aa_iot; sc->sc.sc_bus.dmatag = aa->aa_dmat; sc->sc.sc_size = aa->aa_dev->mem[0].size; /* Map I/O space */ if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc.ioh)) { printf(": cannot map mem space\n"); goto out; } if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[1].addr, aa->aa_dev->mem[1].size, 0, &sc->uh_ioh)) { printf(": cannot map mem space\n"); goto mem0; } if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[2].addr, aa->aa_dev->mem[2].size, 0, &sc->ph_ioh)) { printf(": cannot map mem space\n"); goto mem1; } if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[3].addr, aa->aa_dev->mem[3].size, 0, &sc->nc_ioh)) { printf(": cannot map mem space\n"); goto mem2; } printf("\n"); imxccm_enable_usboh3(); delay(1000); if (aa->aa_dev->mem[0].addr == USBUH1_EHCI_ADDR) { /* enable usb port power */ switch (board_id) { case BOARD_ID_IMX6_PHYFLEX: imxgpio_set_dir(EHCI_PHYFLEX_USB_H1_PWR, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(EHCI_PHYFLEX_USB_H1_PWR); delay(10); break; case BOARD_ID_IMX6_CUBOXI: case BOARD_ID_IMX6_HUMMINGBOARD: imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_H1_PWR); imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_H1_PWR, IMXGPIO_DIR_OUT); delay(10); break; case BOARD_ID_IMX6_SABRELITE: imxgpio_clear_bit(EHCI_NITROGEN6X_USB_HUB_RST); imxgpio_set_dir(EHCI_NITROGEN6X_USB_HUB_RST, IMXGPIO_DIR_OUT); delay(1000 * 2); imxgpio_set_bit(EHCI_NITROGEN6X_USB_HUB_RST); delay(10); break; case BOARD_ID_IMX6_SABRESD: imxgpio_set_bit(EHCI_SABRESD_USB_PWR); imxgpio_set_dir(EHCI_SABRESD_USB_PWR, IMXGPIO_DIR_OUT); delay(10); break; case BOARD_ID_IMX6_UTILITE: imxgpio_clear_bit(EHCI_UTILITE_USB_HUB_RST); imxgpio_set_dir(EHCI_UTILITE_USB_HUB_RST, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(EHCI_UTILITE_USB_HUB_RST); delay(1000); break; } /* disable the carger detection, else signal on DP will be poor */ imxccm_disable_usb2_chrg_detect(); /* power host 1 */ imxccm_enable_pll_usb2(); /* over current and polarity setting */ bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL, bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL) | (USBNC_USB_UH1_CTRL_OVER_CUR_POL | USBNC_USB_UH1_CTRL_OVER_CUR_DIS)); } else if (aa->aa_dev->mem[0].addr == USBOTG_EHCI_ADDR) { /* enable usb port power */ switch (board_id) { case BOARD_ID_IMX6_CUBOXI: case BOARD_ID_IMX6_HUMMINGBOARD: imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_OTG_PWR, IMXGPIO_DIR_OUT); imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_OTG_PWR); delay(10); break; } /* disable the carger detection, else signal on DP will be poor */ imxccm_disable_usb1_chrg_detect(); /* power host 0 */ imxccm_enable_pll_usb1(); /* over current and polarity setting */ bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_OTG_CTRL, bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_OTG_CTRL) | (USBNC_USB_OTG_CTRL_OVER_CUR_POL | USBNC_USB_OTG_CTRL_OVER_CUR_DIS)); } bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_CTRL_CLR, USBPHY_CTRL_CLKGATE); /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); /* Stop then Reset */ uint32_t val = EOREAD4(&sc->sc, EHCI_USBCMD); val &= ~EHCI_CMD_RS; EOWRITE4(&sc->sc, EHCI_USBCMD, val); while (EOREAD4(&sc->sc, EHCI_USBCMD) & EHCI_CMD_RS) ; val = EOREAD4(&sc->sc, EHCI_USBCMD); val |= EHCI_CMD_HCRESET; EOWRITE4(&sc->sc, EHCI_USBCMD, val); while (EOREAD4(&sc->sc, EHCI_USBCMD) & EHCI_CMD_HCRESET) ; /* Reset USBPHY module */ bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_CTRL_SET, USBPHY_CTRL_SFTRST); delay(10); /* Remove CLKGATE and SFTRST */ bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_CTRL_CLR, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST); delay(10); /* Power up the PHY */ bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_PWD, 0); /* enable FS/LS device */ bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_CTRL_SET, USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3); /* set host mode */ EWRITE4(&sc->sc, EHCI_USBMODE, EREAD4(&sc->sc, EHCI_USBMODE) | EHCI_USBMODE_HOST); /* set to UTMI mode */ EOWRITE4(&sc->sc, EHCI_PORTSC(1), EOREAD4(&sc->sc, EHCI_PORTSC(1)) & ~EHCI_PS_PTS_UTMI_MASK); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_USB, ehci_intr, &sc->sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); goto mem3; } strlcpy(sc->sc.sc_vendor, "i.MX6", sizeof(sc->sc.sc_vendor)); r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); goto intr; } config_found(self, &sc->sc.sc_bus, usbctlprint); goto out; intr: arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; mem3: bus_space_unmap(sc->sc.iot, sc->nc_ioh, aa->aa_dev->mem[3].addr); mem2: bus_space_unmap(sc->sc.iot, sc->ph_ioh, aa->aa_dev->mem[2].addr); mem1: bus_space_unmap(sc->sc.iot, sc->uh_ioh, aa->aa_dev->mem[1].addr); mem0: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; out: return; }
void imxenet_attach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; struct imxenet_softc *sc = (struct imxenet_softc *) self; struct mii_data *mii; struct ifnet *ifp; int tsize, rsize, tbsize, rbsize, s; sc->sc_iot = aa->aa_iot; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("imxenet_attach: bus_space_map failed!"); sc->sc_dma_tag = aa->aa_dmat; /* power it up */ clk_enable(clk_get("enet_ref")); clk_enable(clk_get("enet")); switch (board_id) { case BOARD_ID_IMX6_HUMMINGBOARD: imxgpio_set_dir(ENET_HUMMINGBOARD_PHY_RST, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(ENET_HUMMINGBOARD_PHY_RST); delay(10); break; case BOARD_ID_IMX6_SABRELITE: /* SABRE Lite PHY reset */ imxgpio_set_dir(ENET_SABRELITE_PHY_RST, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(ENET_SABRELITE_PHY_RST); delay(10); break; case BOARD_ID_IMX6_UDOO: // UDOO PHY reset imxgpio_set_dir(ENET_UDOO_PHY_RST, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(ENET_UDOO_PHY_RST); delay(10); break; } /* reset the controller */ HWRITE4(sc, ENET_ECR, ENET_ECR_RESET); while(HREAD4(sc, ENET_ECR) & ENET_ECR_RESET); HWRITE4(sc, ENET_EIMR, 0); HWRITE4(sc, ENET_EIR, 0xffffffff); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_NET, imxenet_intr, sc, sc->sc_dev.dv_xname); tsize = ENET_MAX_TXD * sizeof(struct imxenet_buf_desc); tsize = ENET_ROUNDUP(tsize, PAGE_SIZE); if (imxenet_dma_malloc(sc, tsize, &sc->txdma)) { printf("%s: Unable to allocate tx_desc memory\n", sc->sc_dev.dv_xname); goto bad; } sc->tx_desc_base = (struct imxenet_buf_desc *)sc->txdma.dma_vaddr; rsize = ENET_MAX_RXD * sizeof(struct imxenet_buf_desc); rsize = ENET_ROUNDUP(rsize, PAGE_SIZE); if (imxenet_dma_malloc(sc, rsize, &sc->rxdma)) { printf("%s: Unable to allocate rx_desc memory\n", sc->sc_dev.dv_xname); goto txdma; } sc->rx_desc_base = (struct imxenet_buf_desc *)sc->rxdma.dma_vaddr; tbsize = ENET_MAX_TXD * ENET_MAX_PKT_SIZE; tbsize = ENET_ROUNDUP(tbsize, PAGE_SIZE); if (imxenet_dma_malloc(sc, tbsize, &sc->tbdma)) { printf("%s: Unable to allocate tx_buffer memory\n", sc->sc_dev.dv_xname); goto rxdma; } sc->tx_buffer_base = (struct imxenet_buffer *)sc->tbdma.dma_vaddr; rbsize = ENET_MAX_RXD * ENET_MAX_PKT_SIZE; rbsize = ENET_ROUNDUP(rbsize, PAGE_SIZE); if (imxenet_dma_malloc(sc, rbsize, &sc->rbdma)) { printf("%s: Unable to allocate rx_buffer memory\n", sc->sc_dev.dv_xname); goto tbdma; } sc->rx_buffer_base = (struct imxenet_buffer *)sc->rbdma.dma_vaddr; sc->cur_tx = 0; sc->cur_rx = 0; printf("\n"); s = splnet(); ifp = &sc->sc_ac.ac_if; ifp->if_softc = sc; strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = imxenet_ioctl; ifp->if_start = imxenet_start; ifp->if_capabilities = IFCAP_VLAN_MTU; memset(sc->sc_ac.ac_enaddr, 0xff, ETHER_ADDR_LEN); imxocotp_get_ethernet_address(sc->sc_ac.ac_enaddr); printf("%s: address %s\n", sc->sc_dev.dv_xname, ether_sprintf(sc->sc_ac.ac_enaddr)); /* initialize the chip */ imxenet_chip_init(sc); IFQ_SET_READY(&ifp->if_snd); /* Initialize MII/media info. */ mii = &sc->sc_mii; mii->mii_ifp = ifp; mii->mii_readreg = imxenet_miibus_readreg; mii->mii_writereg = imxenet_miibus_writereg; mii->mii_statchg = imxenet_miibus_statchg; mii->mii_flags = MIIF_AUTOTSLEEP; ifmedia_init(&mii->mii_media, 0, imxenet_ifmedia_upd, imxenet_ifmedia_sts); mii_attach(self, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&mii->mii_phys) == NULL) { ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); } else ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); if_attach(ifp); ether_ifattach(ifp); splx(s); imxenet_sc = sc; return; tbdma: imxenet_dma_free(sc, &sc->tbdma); rxdma: imxenet_dma_free(sc, &sc->rxdma); txdma: imxenet_dma_free(sc, &sc->txdma); bad: bus_space_unmap(sc->sc_iot, sc->sc_ioh, aa->aa_dev->mem[0].size); }
void imxehci_attach(struct device *parent, struct device *self, void *aux) { struct imxehci_softc *sc = (struct imxehci_softc *)self; struct ehci_softc *esc; struct armv7_attach_args *aa = aux; struct fdt_memory hmem, pmem, mmem; int irq, r; sc->iot = aa->aa_iot; sc->sc_dmat = aa->aa_dmat; if (aa->aa_node) { uint32_t ints[3]; void *node; if (fdt_get_memory_address(aa->aa_node, 0, &hmem)) panic("%s: could not extract memory data from FDT", __func__); node = fdt_find_node_by_phandle_prop(aa->aa_node, "fsl,usbphy"); if (node == NULL || fdt_get_memory_address(node, 0, &pmem)) panic("%s: could not extract phy data from FDT", __func__); node = fdt_find_node_by_phandle_prop(aa->aa_node, "fsl,usbmisc"); if (node == NULL || fdt_get_memory_address(node, 0, &mmem)) panic("%s: could not extract phy data from FDT", __func__); /* TODO: Add interrupt FDT API. */ if (fdt_node_property_ints(aa->aa_node, "interrupts", ints, 3) != 3) panic("%s: could not extract interrupt data from FDT", __func__); irq = ints[1]; } else { hmem.addr = aa->aa_dev->mem[0].addr; hmem.size = aa->aa_dev->mem[0].size; pmem.addr = aa->aa_dev->mem[1].addr; pmem.size = aa->aa_dev->mem[1].size; mmem.addr = aa->aa_dev->mem[2].addr; mmem.size = aa->aa_dev->mem[2].size; irq = aa->aa_dev->irq[0]; } /* Map I/O space */ if (bus_space_map(sc->iot, hmem.addr, hmem.size, 0, &sc->uh_ioh)) { printf(": cannot map mem space\n"); goto hmem; } sc->ioh = sc->uh_ioh + 0x100; sc->sc_size = hmem.size; if (bus_space_map(sc->iot, pmem.addr, pmem.size, 0, &sc->ph_ioh)) { printf(": cannot map mem space\n"); goto pmem; } if (bus_space_map(sc->iot, mmem.addr, mmem.size, 0, &sc->nc_ioh)) { printf(": cannot map mem space\n"); goto mmem; } clk_enable(clk_get("usboh3")); delay(1000); if (hmem.addr == USBUH1_ADDR) { /* enable usb port power */ switch (board_id) { case BOARD_ID_IMX6_CUBOXI: case BOARD_ID_IMX6_HUMMINGBOARD: imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_H1_PWR); imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_H1_PWR, IMXGPIO_DIR_OUT); delay(10); break; case BOARD_ID_IMX6_SABRELITE: imxgpio_clear_bit(EHCI_NITROGEN6X_USB_HUB_RST); imxgpio_set_dir(EHCI_NITROGEN6X_USB_HUB_RST, IMXGPIO_DIR_OUT); delay(1000 * 2); imxgpio_set_bit(EHCI_NITROGEN6X_USB_HUB_RST); delay(10); break; case BOARD_ID_IMX6_SABRESD: imxgpio_set_bit(EHCI_SABRESD_USB_PWR); imxgpio_set_dir(EHCI_SABRESD_USB_PWR, IMXGPIO_DIR_OUT); delay(10); break; case BOARD_ID_IMX6_UTILITE: imxgpio_clear_bit(EHCI_UTILITE_USB_HUB_RST); imxgpio_set_dir(EHCI_UTILITE_USB_HUB_RST, IMXGPIO_DIR_OUT); delay(10); imxgpio_set_bit(EHCI_UTILITE_USB_HUB_RST); delay(1000); break; } /* disable the carger detection, else signal on DP will be poor */ imxccm_disable_usb2_chrg_detect(); /* power host 1 */ clk_enable(clk_get("pll7_usb_host")); clk_enable(clk_get("usbphy2_gate")); /* over current and polarity setting */ bus_space_write_4(sc->iot, sc->nc_ioh, USBNC_USB_UH1_CTRL, bus_space_read_4(sc->iot, sc->nc_ioh, USBNC_USB_UH1_CTRL) | (USBNC_USB_UH1_CTRL_OVER_CUR_POL | USBNC_USB_UH1_CTRL_OVER_CUR_DIS)); } else if (hmem.addr == USBOTG_ADDR) { /* enable usb port power */ switch (board_id) { case BOARD_ID_IMX6_CUBOXI: case BOARD_ID_IMX6_HUMMINGBOARD: imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_OTG_PWR); imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_OTG_PWR, IMXGPIO_DIR_OUT); delay(10); break; } /* disable the carger detection, else signal on DP will be poor */ imxccm_disable_usb1_chrg_detect(); /* power host 0 */ clk_enable(clk_get("pll3_usb_otg")); clk_enable(clk_get("usbphy1_gate")); /* over current and polarity setting */ bus_space_write_4(sc->iot, sc->nc_ioh, USBNC_USB_OTG_CTRL, bus_space_read_4(sc->iot, sc->nc_ioh, USBNC_USB_OTG_CTRL) | (USBNC_USB_OTG_CTRL_OVER_CUR_POL | USBNC_USB_OTG_CTRL_OVER_CUR_DIS)); } bus_space_write_4(sc->iot, sc->ph_ioh, USBPHY_CTRL_CLR, USBPHY_CTRL_CLKGATE); /* Disable interrupts, so we don't get any spurious ones. */ sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); EOWRITE2(sc, EHCI_USBINTR, 0); /* Stop then Reset */ uint32_t val = EOREAD4(sc, EHCI_USBCMD); val &= ~EHCI_CMD_RS; EOWRITE4(sc, EHCI_USBCMD, val); while (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_RS) ; val = EOREAD4(sc, EHCI_USBCMD); val |= EHCI_CMD_HCRESET; EOWRITE4(sc, EHCI_USBCMD, val); while (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET) ; /* Reset USBPHY module */ bus_space_write_4(sc->iot, sc->ph_ioh, USBPHY_CTRL_SET, USBPHY_CTRL_SFTRST); delay(10); /* Remove CLKGATE and SFTRST */ bus_space_write_4(sc->iot, sc->ph_ioh, USBPHY_CTRL_CLR, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST); delay(10); /* Power up the PHY */ bus_space_write_4(sc->iot, sc->ph_ioh, USBPHY_PWD, 0); /* enable FS/LS device */ bus_space_write_4(sc->iot, sc->ph_ioh, USBPHY_CTRL_SET, USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3); /* set host mode */ EWRITE4(sc, EHCI_USBMODE, EREAD4(sc, EHCI_USBMODE) | EHCI_USBMODE_HOST); /* set to UTMI mode */ EOWRITE4(sc, EHCI_PORTSC(1), EOREAD4(sc, EHCI_PORTSC(1)) & ~EHCI_PS_PTS_UTMI_MASK); printf("\n"); if ((esc = (struct ehci_softc *)config_found(self, NULL, NULL)) == NULL) goto mmem; esc->iot = sc->iot; esc->ioh = sc->ioh; esc->sc_bus.dmatag = sc->sc_dmat; esc->sc_offs = sc->sc_offs; sc->sc_ih = arm_intr_establish(irq, IPL_USB, ehci_intr, esc, esc->sc_bus.bdev.dv_xname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); return; } strlcpy(esc->sc_vendor, "i.MX6", sizeof(esc->sc_vendor)); r = ehci_init(esc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", esc->sc_bus.bdev.dv_xname, r); goto intr; } printf("\n"); config_found((struct device *)esc, &esc->sc_bus, usbctlprint); goto out; intr: arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; mmem: bus_space_unmap(sc->iot, sc->nc_ioh, mmem.size); pmem: bus_space_unmap(sc->iot, sc->ph_ioh, pmem.size); hmem: bus_space_unmap(sc->iot, sc->uh_ioh, sc->sc_size); sc->sc_size = 0; out: return; }
static void ti_iic_attach(struct device *parent, struct device *self, void *args) { struct ti_iic_softc *sc = (struct ti_iic_softc *)self; struct armv7_attach_args *aa = args; struct i2cbus_attach_args iba; uint16_t rev; const char *mode; u_int state; char buf[20]; char *pin; /* BBB specific pin names */ char *pins[6] = {"I2C0_SDA", "I2C0_SCL", "SPIO_D1", "SPI0_CS0", "UART1_CTSn", "UART1_RTSn"}; sc->sc_iot = aa->aa_iot; rw_init(&sc->sc_buslock, "tiiilk"); sc->sc_rxthres = sc->sc_txthres = 4; if (bus_space_map(sc->sc_iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_ioh)) panic("%s: bus_space_map failed!"); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_NET, ti_iic_intr, sc, DEVNAME(sc)); prcm_enablemodule(PRCM_I2C0 + aa->aa_dev->unit); if (board_id == BOARD_ID_AM335X_BEAGLEBONE) { pin = pins[aa->aa_dev->unit * 2]; snprintf(buf, sizeof buf, "I2C%d_SDA", aa->aa_dev->unit); if (sitara_cm_padconf_set(pin, buf, (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) { printf(": can't switch %s pad\n", buf); return; } if (sitara_cm_padconf_get(pin, &mode, &state) == 0) { printf(": %s state %d ", mode, state); } pin = pins[aa->aa_dev->unit * 2 + 1]; snprintf(buf, sizeof buf, "I2C%d_SCL", aa->aa_dev->unit); if (sitara_cm_padconf_set(pin, buf, (0x01 << 4) | (0x01 << 5) | (0x01 << 6)) != 0) { printf(": can't switch %s pad\n", buf); return; } if (sitara_cm_padconf_get(pin, &mode, &state) == 0) { printf(": %s state %d ", mode, state); } } rev = I2C_READ_REG(sc, AM335X_I2C_REVNB_LO); printf(" rev %d.%d\n", (int)I2C_REVNB_LO_MAJOR(rev), (int)I2C_REVNB_LO_MINOR(rev)); ti_iic_reset(sc); ti_iic_flush(sc); sc->sc_ic.ic_cookie = sc; sc->sc_ic.ic_acquire_bus = ti_iic_acquire_bus; sc->sc_ic.ic_release_bus = ti_iic_release_bus; sc->sc_ic.ic_exec = ti_iic_exec; bzero(&iba, sizeof iba); iba.iba_name = "iic"; iba.iba_tag = &sc->sc_ic; (void) config_found(&sc->sc_dev, &iba, iicbus_print); }
void omehci_attach(struct device *parent, struct device *self, void *aux) { struct omehci_softc *sc = (struct omehci_softc *)self; struct armv7_attach_args *aa = aux; usbd_status r; char *devname = sc->sc.sc_bus.bdev.dv_xname; uint32_t i; sc->sc.iot = aa->aa_iot; sc->sc.sc_bus.dmatag = aa->aa_dmat; sc->sc.sc_size = aa->aa_dev->mem[0].size; /* set defaults */ for (i = 0; i < 3; i++) { sc->phy_reset[i] = 0; sc->port_mode[i] = EHCI_HCD_OMAP_MODE_UNKNOWN; sc->reset_gpio_pin[i] = -1; } switch (board_id) { case BOARD_ID_OMAP4_PANDA: sc->tll_avail = 0; sc->port_mode[0] = EHCI_HCD_OMAP_MODE_PHY; sc->early_init = omehci_v4_early_init; break; default: break; } /* Map I/O space */ if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc.ioh)) { printf(": cannot map mem space\n"); goto out; } if (bus_space_map(sc->sc.iot, aa->aa_dev->mem[1].addr, aa->aa_dev->mem[1].size, 0, &sc->uhh_ioh)) { printf(": cannot map mem space\n"); goto mem0; } if (sc->tll_avail && bus_space_map(sc->sc.iot, aa->aa_dev->mem[2].addr, aa->aa_dev->mem[2].size, 0, &sc->tll_ioh)) { printf(": cannot map mem space\n"); goto mem1; } printf("\n"); if (sc->early_init) sc->early_init(); if (omehci_init(sc)) return; /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); sc->sc_ih = arm_intr_establish(aa->aa_dev->irq[0], IPL_USB, ehci_intr, &sc->sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); printf("XXX - disable ehci and prcm"); goto mem2; } strlcpy(sc->sc.sc_vendor, "TI OMAP", sizeof(sc->sc.sc_vendor)); r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); printf("XXX - disable ehci and prcm"); goto intr; } config_found(self, &sc->sc.sc_bus, usbctlprint); goto out; intr: arm_intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; mem2: bus_space_unmap(sc->sc.iot, sc->tll_ioh, aa->aa_dev->mem[2].size); mem1: bus_space_unmap(sc->sc.iot, sc->uhh_ioh, aa->aa_dev->mem[1].size); mem0: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; out: return; }
void cpsw_attach(struct device *parent, struct device *self, void *aux) { struct cpsw_softc *sc = (struct cpsw_softc *)self; struct armv7_attach_args *aa = aux; struct arpcom * const ac = &sc->sc_ac; struct ifnet * const ifp = &ac->ac_if; u_int32_t idver; int error; u_int i; timeout_set(&sc->sc_tick, cpsw_tick, sc); cpsw_get_mac_addr(sc); sc->sc_rxthih = arm_intr_establish(aa->aa_dev->irq[0] + CPSW_INTROFF_RXTH, IPL_NET, cpsw_rxthintr, sc, DEVNAME(sc)); sc->sc_rxih = arm_intr_establish(aa->aa_dev->irq[0] + CPSW_INTROFF_RX, IPL_NET, cpsw_rxintr, sc, DEVNAME(sc)); sc->sc_txih = arm_intr_establish(aa->aa_dev->irq[0] + CPSW_INTROFF_TX, IPL_NET, cpsw_txintr, sc, DEVNAME(sc)); sc->sc_miscih = arm_intr_establish(aa->aa_dev->irq[0] + CPSW_INTROFF_MISC, IPL_NET, cpsw_miscintr, sc, DEVNAME(sc)); sc->sc_bst = aa->aa_iot; sc->sc_bdt = aa->aa_dmat; error = bus_space_map(sc->sc_bst, aa->aa_dev->mem[0].addr, aa->aa_dev->mem[0].size, 0, &sc->sc_bsh); if (error) { printf("can't map registers: %d\n", error); return; } sc->sc_txdescs_pa = aa->aa_dev->mem[0].addr + CPSW_CPPI_RAM_TXDESCS_BASE; error = bus_space_subregion(sc->sc_bst, sc->sc_bsh, CPSW_CPPI_RAM_TXDESCS_BASE, CPSW_CPPI_RAM_TXDESCS_SIZE, &sc->sc_bsh_txdescs); if (error) { printf("can't subregion tx ring SRAM: %d\n", error); return; } sc->sc_rxdescs_pa = aa->aa_dev->mem[0].addr + CPSW_CPPI_RAM_RXDESCS_BASE; error = bus_space_subregion(sc->sc_bst, sc->sc_bsh, CPSW_CPPI_RAM_RXDESCS_BASE, CPSW_CPPI_RAM_RXDESCS_SIZE, &sc->sc_bsh_rxdescs); if (error) { printf("can't subregion rx ring SRAM: %d\n", error); return; } sc->sc_rdp = malloc(sizeof(*sc->sc_rdp), M_TEMP, M_WAITOK); KASSERT(sc->sc_rdp != NULL); for (i = 0; i < CPSW_NTXDESCS; i++) { if ((error = bus_dmamap_create(sc->sc_bdt, MCLBYTES, CPSW_TXFRAGS, MCLBYTES, 0, 0, &sc->sc_rdp->tx_dm[i])) != 0) { printf("unable to create tx DMA map: %d\n", error); } sc->sc_rdp->tx_mb[i] = NULL; } for (i = 0; i < CPSW_NRXDESCS; i++) { if ((error = bus_dmamap_create(sc->sc_bdt, MCLBYTES, 1, MCLBYTES, 0, 0, &sc->sc_rdp->rx_dm[i])) != 0) { printf("unable to create rx DMA map: %d\n", error); } sc->sc_rdp->rx_mb[i] = NULL; } sc->sc_txpad = dma_alloc(ETHER_MIN_LEN, PR_WAITOK | PR_ZERO); KASSERT(sc->sc_txpad != NULL); bus_dmamap_create(sc->sc_bdt, ETHER_MIN_LEN, 1, ETHER_MIN_LEN, 0, BUS_DMA_WAITOK, &sc->sc_txpad_dm); bus_dmamap_load(sc->sc_bdt, sc->sc_txpad_dm, sc->sc_txpad, ETHER_MIN_LEN, NULL, BUS_DMA_WAITOK|BUS_DMA_WRITE); bus_dmamap_sync(sc->sc_bdt, sc->sc_txpad_dm, 0, ETHER_MIN_LEN, BUS_DMASYNC_PREWRITE); idver = bus_space_read_4(sc->sc_bst, sc->sc_bsh, CPSW_SS_IDVER); printf(": version %d.%d (%d), address %s\n", CPSW_SS_IDVER_MAJ(idver), CPSW_SS_IDVER_MIN(idver), CPSW_SS_IDVER_RTL(idver), ether_sprintf(ac->ac_enaddr)); ifp->if_softc = sc; ifp->if_capabilities = 0; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_start = cpsw_start; ifp->if_ioctl = cpsw_ioctl; ifp->if_watchdog = cpsw_watchdog; IFQ_SET_MAXLEN(&ifp->if_snd, CPSW_NTXDESCS - 1); IFQ_SET_READY(&ifp->if_snd); memcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ); cpsw_stop(ifp); sc->sc_mii.mii_ifp = ifp; sc->sc_mii.mii_readreg = cpsw_mii_readreg; sc->sc_mii.mii_writereg = cpsw_mii_writereg; sc->sc_mii.mii_statchg = cpsw_mii_statchg; ifmedia_init(&sc->sc_mii.mii_media, 0, cpsw_mediachange, cpsw_mediastatus); mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 0); if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { printf("no PHY found!\n"); ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL, 0, NULL); ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL); } else { ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); } if_attach(ifp); ether_ifattach(ifp); return; }