/* ARGSUSED */ static void mvusb_attach(device_t parent, device_t self, void *aux) { struct mvusb_softc *sc = device_private(self); struct marvell_attach_args *mva = aux; usbd_status r; aprint_normal(": Marvell USB 2.0 Interface\n"); aprint_naive("\n"); sc->sc.sc_dev = self; sc->sc.sc_bus.hci_private = sc; sc->sc_model = mva->mva_model; sc->sc_rev = mva->mva_revision; sc->sc_iot = mva->mva_iot; /* Map I/O registers for marvell usb */ if (bus_space_subregion(mva->mva_iot, mva->mva_ioh, mva->mva_offset, mva->mva_size, &sc->sc_ioh)) { aprint_error_dev(self, "can't map registers\n"); return; } mvusb_init(sc, mva->mva_tags); /* Map I/O registers for ehci */ sc->sc.sc_size = MARVELL_USB_EHCI_SIZE; if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, MARVELL_USB_EHCI_BASE, sc->sc.sc_size, &sc->sc.ioh)) { aprint_error_dev(self, "can't subregion registers\n"); return; } sc->sc.iot = sc->sc_iot; sc->sc.sc_bus.dmatag = mva->mva_dmat; /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); DPRINTF(("%s: offs=%d\n", device_xname(self), sc->sc.sc_offs)); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); marvell_intr_establish(mva->mva_irq, IPL_USB, ehci_intr, sc); sc->sc.sc_bus.usbrev = USBREV_2_0; /* Figure out vendor for root hub descriptor. */ sc->sc.sc_id_vendor = 0x0000; /* XXXXX */ strcpy(sc->sc.sc_vendor, "Marvell"); sc->sc.sc_vendor_init = mvusb_vendor_init; sc->sc.sc_vendor_port_status = mvusb_vendor_port_status; r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "init failed, error=%d\n", r); return; } /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void ehci_obio_attach(device_t parent, device_t self, void *aux) { struct ehci_softc * const sc = device_private(self); struct obio_attach_args * const obio = aux; const char * const devname = device_xname(self); usbd_status r; sc->sc_dev = self; sc->sc_bus.hci_private = sc; sc->iot = obio->obio_iot; aprint_naive(": EHCI USB controller\n"); aprint_normal(": EHCI USB controller\n"); /* Map I/O registers */ if (bus_space_map(sc->iot, obio->obio_addr, obio->obio_size, 0, &sc->ioh)) { aprint_error("%s: can't map memory space\n", devname); return; } sc->sc_bus.dmatag = obio->obio_dmat; /* Disable interrupts, so we don't get any spurious ones. */ sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); DPRINTF(("%s: offs=%d\n", devname, sc->sc_offs)); EOWRITE2(sc, EHCI_USBINTR, 0); bus_space_write_4(sc->iot, sc->ioh, EHCI_HCOTGDEV_INTR_MASK, OTG_INT|DEV_INT); if (obio->obio_intr != OBIOCF_INTR_DEFAULT) { intr_establish(obio->obio_intr, IPL_USB, IST_LEVEL, ehci_obio_intr, sc); } sc->sc_bus.usbrev = USBREV_2_0; /* Figure out vendor for root hub descriptor. */ sc->sc_id_vendor = PCI_VENDOR_FARADAY; strlcpy(sc->sc_vendor, "SL351x", sizeof(sc->sc_vendor)); r = ehci_init(sc); if (r != USBD_NORMAL_COMPLETION) { aprint_error("%s: init failed, error=%d\n", devname, r); return; } /* Attach usb device. */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); }
void ehci_obio_attach(struct device *parent, struct device *self, void *aux) { struct ehci_softc *sc = (void *)self; struct obio_attach_args *oa = aux; usbd_status r; int s; sc->iot = oa->oa_iot; sc->sc_size = 1028; if (bus_space_map(sc->iot, oa->oa_offset + USB_EHCI_OFFSET, sc->sc_size, 0, &sc->ioh)) { printf(": can't map registers\n"); return; } sc->sc_id_vendor = PCI_VENDOR_FREESCALE; strlcpy(sc->sc_vendor, "Freescale", sizeof sc->sc_vendor); sc->sc_bus.dmatag = &ehci_bus_dma_tag; bus_space_write_4(sc->iot, sc->ioh, USB_CONTROL, USB_CONTROL_USB_EN); bus_space_write_4(sc->iot, sc->ioh, USB_SNOOP1, USB_SNOOP_2GB); s = splhardusb(); sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); EOWRITE2(sc, EHCI_USBINTR, 0); intr_establish(oa->oa_ivec, IST_LEVEL, IPL_USB, ehci_intr, sc, sc->sc_bus.bdev.dv_xname); r = ehci_init(sc); if (r != USBD_NORMAL_COMPLETION) { printf(": init failed, error=%d\n", r); goto unmap_ret; } splx(s); printf("\n"); /* Attach usb device. */ sc->sc_child = config_found((void *)sc, &sc->sc_bus, usbctlprint); return; unmap_ret: bus_space_unmap(sc->iot, sc->ioh, sc->sc_size); splx(s); }
void ehci_pci_attach(struct device *parent, struct device *self, void *aux) { struct ehci_pci_softc *sc = (struct ehci_pci_softc *)self; struct pci_attach_args *pa = (struct pci_attach_args *)aux; pci_chipset_tag_t pc = pa->pa_pc; pcitag_t tag = pa->pa_tag; char const *intrstr; pci_intr_handle_t ih; const char *vendor; char *devname = sc->sc.sc_bus.bdev.dv_xname; usbd_status r; int s; /* Map I/O registers */ if (pci_mapreg_map(pa, PCI_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size, 0)) { printf(": can't map mem space\n"); return; } sc->sc_pc = pc; sc->sc_tag = tag; sc->sc.sc_bus.dmatag = pa->pa_dmat; /* Disable interrupts, so we don't get any spurious ones. */ s = splhardusb(); sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); DPRINTF(("%s: offs=%d\n", devname, sc->sc.sc_offs)); EOWRITE2(&sc->sc, EHCI_USBINTR, 0); /* Handle quirks */ switch (PCI_VENDOR(pa->pa_id)) { case PCI_VENDOR_ATI: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_EHCI || (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB700_EHCI && pci_find_device(NULL, ehci_sb700_match))) { pcireg_t value; /* apply the ATI SB600/SB700 workaround */ value = pci_conf_read(sc->sc_pc, sc->sc_tag, EHCI_SBx00_WORKAROUND_REG); pci_conf_write(sc->sc_pc, sc->sc_tag, EHCI_SBx00_WORKAROUND_REG, value | EHCI_SBx00_WORKAROUND_ENABLE); } break; case PCI_VENDOR_VIATECH: if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT6202 && (PCI_REVISION(pa->pa_class) & 0xf0) == 0x60) { pcireg_t value; /* * The VT6202 defaults to a 1 usec EHCI sleep time * which hogs the PCI bus *badly*. Setting bit 5 of * the register makes that sleep time use the conventional * 10 usec. */ value = pci_conf_read(sc->sc_pc, sc->sc_tag, EHCI_VT6202_WORKAROUND_REG); pci_conf_write(sc->sc_pc, sc->sc_tag, EHCI_VT6202_WORKAROUND_REG, value | 0x20000000); } break; } /* Map and establish the interrupt. */ if (pci_intr_map(pa, &ih)) { printf(": couldn't map interrupt\n"); goto unmap_ret; } intrstr = pci_intr_string(pc, ih); sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB | IPL_MPSAFE, ehci_intr, sc, devname); if (sc->sc_ih == NULL) { printf(": couldn't establish interrupt"); if (intrstr != NULL) printf(" at %s", intrstr); printf("\n"); goto unmap_ret; } printf(": %s\n", intrstr); switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: case PCI_USBREV_1_0: case PCI_USBREV_1_1: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; printf("%s: pre-2.0 USB rev\n", devname); goto disestablish_ret; case PCI_USBREV_2_0: sc->sc.sc_bus.usbrev = USBREV_2_0; break; default: sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; break; } /* Figure out vendor for root hub descriptor. */ vendor = pci_findvendor(pa->pa_id); sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(pa->pa_id)); /* Enable workaround for dropped interrupts as required */ if (sc->sc.sc_id_vendor == PCI_VENDOR_VIATECH) sc->sc.sc_flags |= EHCIF_DROPPED_INTR_WORKAROUND; ehci_pci_takecontroller(sc, 0); r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); goto disestablish_ret; } /* Attach usb device. */ config_found(self, &sc->sc.sc_bus, usbctlprint); splx(s); return; disestablish_ret: pci_intr_disestablish(sc->sc_pc, sc->sc_ih); unmap_ret: bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); splx(s); }
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 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; }
void ehci_cardbus_attach(struct device *parent, struct device *self, void *aux) { struct ehci_cardbus_softc *sc = (struct ehci_cardbus_softc *)self; struct cardbus_attach_args *ca = aux; cardbus_devfunc_t ct = ca->ca_ct; cardbus_chipset_tag_t cc = ct->ct_cc; pci_chipset_tag_t pc = ca->ca_pc; cardbus_function_tag_t cf = ct->ct_cf; pcireg_t csr; usbd_status r; const char *vendor; const char *devname = sc->sc.sc_bus.bdev.dv_xname; /* Map I/O registers */ if (Cardbus_mapreg_map(ct, CARDBUS_CBMEM, PCI_MAPREG_TYPE_MEM, 0, &sc->sc.iot, &sc->sc.ioh, NULL, &sc->sc.sc_size)) { printf(": can't map mem space\n"); return; } sc->sc_cc = cc; sc->sc_cf = cf; sc->sc_ct = ct; sc->sc.sc_bus.dmatag = ca->ca_dmat; (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_MEM_ENABLE); (ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE); /* Enable the device. */ csr = pci_conf_read(pc, ca->ca_tag, PCI_COMMAND_STATUS_REG); pci_conf_write(pc, ca->ca_tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE); /* 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 = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_USB, ehci_intr, sc, devname); if (sc->sc_ih == NULL) { printf(": unable to establish interrupt\n"); return; } printf(": irq %d\n", ca->ca_intrline); /* Figure out vendor for root hub descriptor. */ vendor = cardbus_findvendor(ca->ca_id); sc->sc.sc_id_vendor = PCI_VENDOR(ca->ca_id); if (vendor) strlcpy(sc->sc.sc_vendor, vendor, sizeof(sc->sc.sc_vendor)); else snprintf(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), "vendor 0x%04x", PCI_VENDOR(ca->ca_id)); r = ehci_init(&sc->sc); if (r != USBD_NORMAL_COMPLETION) { printf("%s: init failed, error=%d\n", devname, r); /* Avoid spurious interrupts. */ cardbus_intr_disestablish(sc->sc_cc, sc->sc_cf, sc->sc_ih); sc->sc_ih = NULL; return; } /* Attach usb device. */ config_found(self, &sc->sc.sc_bus, usbctlprint); }
static void pq3ehci_attach(device_t parent, device_t self, void *aux) { struct cpunode_softc * const psc = device_private(parent); struct pq3ehci_softc * const sc = device_private(self); struct cpunode_attach_args * const cna = aux; struct cpunode_locators * const cnl = &cna->cna_locs; int error; psc->sc_children |= cna->cna_childmask; sc->sc.iot = cna->cna_le_memt; /* EHCI registers are little endian */ sc->sc.sc_dev = self; sc->sc.sc_bus.ub_dmatag = cna->cna_dmat; sc->sc.sc_bus.ub_hcpriv = sc; sc->sc.sc_bus.ub_revision = USBREV_2_0; sc->sc.sc_ncomp = 0; sc->sc.sc_flags |= EHCIF_ETTF; sc->sc.sc_vendor_init = pq3ehci_init; aprint_naive(": USB controller\n"); aprint_normal(": USB controller\n"); error = bus_space_map(sc->sc.iot, cnl->cnl_addr, cnl->cnl_size, 0, &sc->sc.ioh); if (error) { aprint_error_dev(self, "can't map registers for %s#%u: %d\n", cnl->cnl_name, cnl->cnl_instance, error); return; } sc->sc.sc_size = cnl->cnl_size; /* * We need to tell the USB interface to snoop all off RAM starting * at 0. Since it can do it by powers of 2, get the highest RAM * address and roughly round it to the next power of 2 and find * the number of leading zero bits. */ cpu_write_4(cnl->cnl_addr + USB_SNOOP1, SNOOP_2GB - __builtin_clz(curcpu()->ci_softc->cpu_highmem * 2 - 1)); cpu_write_4(cnl->cnl_addr + USB_CONTROL, USB_EN); sc->sc_ih = intr_establish(cnl->cnl_intrs[0], IPL_USB, IST_ONCHIP, ehci_intr, sc); if (sc->sc_ih == NULL) { aprint_error_dev(self, "failed to establish interrupt %d\n", cnl->cnl_intrs[0]); goto fail; } aprint_normal_dev(self, "interrupting on irq %d\n", cnl->cnl_intrs[0]); /* offs is needed for EOWRITEx */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); /* Disable interrupts, so we don't get any spurious ones. */ DPRINTF(("%s: offs=%d\n", device_xname(self), sc->sc.sc_offs)); EOWRITE4(&sc->sc, EHCI_USBINTR, 0); error = ehci_init(&sc->sc); if (error) { aprint_error_dev(self, "init failed, error=%d\n", error); goto fail; } /* Attach usb device. */ sc->sc.sc_child = config_found(self, &sc->sc.sc_bus, usbctlprint); return; fail: if (sc->sc_ih) { intr_disestablish(sc->sc_ih); sc->sc_ih = NULL; } if (sc->sc.sc_size) { bus_space_unmap(sc->sc.iot, sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; } return; }
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 ehci_arbus_attach(device_t parent, device_t self, void *aux) { ehci_softc_t *sc = device_private(self); struct arbus_attach_args * const aa = aux; void *ih = NULL; int error; sc->iot = aa->aa_bst_le; sc->sc_size = aa->aa_size; //sc->sc_bus.ub_hcpriv = sc; sc->sc_bus.ub_dmatag = aa->aa_dmat; sc->sc_bus.ub_revision = USBREV_1_0; sc->sc_flags |= EHCIF_ETTF; sc->sc_vendor_init = ehci_arbus_init; error = bus_space_map(aa->aa_bst, aa->aa_addr, aa->aa_size, 0, &sc->ioh); if (error) { aprint_error(": failed to map registers: %d\n", error); return; } /* The recommended value is 0x20 for both ports and the host */ REGVAL(AR9344_USB_CONFIG_BASE) = 0x20c00; /* magic */ DELAY(1000); /* get offset to operational regs */ uint32_t r = bus_space_read_4(aa->aa_bst, sc->ioh, 0); if (r != 0x40) { aprint_error(": error: CAPLENGTH (%#x) != 0x40\n", sc->sc_offs); return; } sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH); aprint_normal("\n"); /* Disable EHCI interrupts */ EOWRITE4(sc, EHCI_USBINTR, 0); /* establish interrupt */ ih = arbus_intr_establish(aa->aa_cirq, aa->aa_mirq, ehci_intr, sc); if (ih == NULL) panic("%s: couldn't establish interrupt", device_xname(self)); /* * There are no companion controllers */ sc->sc_ncomp = 0; error = ehci_init(sc); if (error) { aprint_error("%s: init failed, error=%d\n", device_xname(self), error); if (ih != NULL) arbus_intr_disestablish(ih); return; } /* Attach USB device */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); }