Exemplo n.º 1
0
/* 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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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;
}