Esempio n. 1
0
void platform_usb_init(void)
{
	/* platform specific init of USB core */
	MMIO_REG_VAL(QRK_PMUX_SLEW_RATE_0) = PIN_MUX_SLEW_4mA_driver;
	MMIO_REG_VAL(QRK_PMUX_SLEW_RATE_1) = PIN_MUX_SLEW_4mA_driver;
	MMIO_REG_VAL(QRK_PMUX_SLEW_RATE_2) = PIN_MUX_SLEW_4mA_driver;
	MMIO_REG_VAL(QRK_PMUX_SLEW_RATE_3) = PIN_MUX_SLEW_4mA_driver;

	enable_usb();

	/* Init the USB driver */
	SCSS_REG_VAL(SCSS_INT_USB_MASK_OFFSET) = QRK_INT_USB_UNMASK_QRK;
}
Esempio n. 2
0
static int
fsl_ehci_attach(device_t self)
{
	ehci_softc_t *sc;
	int rid;
	int err;
	bus_space_handle_t ioh;
	bus_space_tag_t iot;

	sc = device_get_softc(self);
	rid = 0;

	sc->sc_bus.parent = self;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = EHCI_MAX_DEVICES;

	if (usb_bus_mem_alloc_all(&sc->sc_bus,
	    USB_GET_DMA_TAG(self), &ehci_iterate_hw_softc))
		return (ENOMEM);

	/* Allocate io resource for EHCI */
	sc->sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_io_res == NULL) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}
	iot = rman_get_bustag(sc->sc_io_res);

	/*
	 * Set handle to USB related registers subregion used by generic
	 * EHCI driver
	 */
	ioh = rman_get_bushandle(sc->sc_io_res);

	err = bus_space_subregion(iot, ioh, FSL_EHCI_REG_OFF, FSL_EHCI_REG_SIZE,
	    &sc->sc_io_hdl);
	if (err != 0) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Set little-endian tag for use by the generic EHCI driver */
	sc->sc_io_tag = &bs_le_tag;

	/* Allocate irq */
	sc->sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &rid,
	    RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Setup interrupt handler */
	err = bus_setup_intr(self, sc->sc_irq_res, INTR_TYPE_BIO,
	    NULL, (driver_intr_t *)ehci_interrupt, sc, &sc->sc_intr_hdl);
	if (err) {
		device_printf(self, "Could not setup irq, %d\n", err);
		sc->sc_intr_hdl = NULL;
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	/* Add USB device */
	sc->sc_bus.bdev = device_add_child(self, "usbus", -1);
	if (!sc->sc_bus.bdev) {
		device_printf(self, "Could not add USB device\n");
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENOMEM);
	}
	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sc->sc_id_vendor = 0x1234;
	strlcpy(sc->sc_vendor, "Freescale", sizeof(sc->sc_vendor));

	/* Enable USB */
	err = ehci_reset(sc);
	if (err) {
		device_printf(self, "Could not reset the controller\n");
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (ENXIO);
	}

	enable_usb(self, iot, ioh);
	set_snooping(iot, ioh);
	set_to_host_mode(sc);
	set_32b_prefetch(iot, ioh);

	/*
	 * If usb subsystem is enabled in U-Boot, port power has to be turned
	 * off to allow proper discovery of devices during boot up.
	 */
	clear_port_power(sc);

	/* Set flags */
	sc->sc_flags |= EHCI_SCFLG_DONTRESET | EHCI_SCFLG_NORESTERM;

	err = ehci_init(sc);
	if (!err) {
		sc->sc_flags |= EHCI_SCFLG_DONEINIT;
		err = device_probe_and_attach(sc->sc_bus.bdev);
	}

	if (err) {
		device_printf(self, "USB init failed err=%d\n", err);
		err = fsl_ehci_detach(self);
		if (err) {
			device_printf(self,
			    "Detach of the driver failed with error %d\n",
			    err);
		}
		return (EIO);
	}

	return (0);
}