static int musb_set_clock(struct clk *clk, int state)
{
	if (state) {
		if (clk_on > 0)
			return -ENODEV;

		phy_enable();
		clk_enable(clk);
		clk_on = 1;
	} else {
		if (clk_on == 0)
			return -ENODEV;

		clk_disable(clk);
		phy_disable();
		clk_on = 0;
	}

	return 0;
}
예제 #2
0
static int
enable_fdt_resources(struct tegra_ahci_sc *sc)
{
	int rv;

	rv = regulator_enable(sc->supply_hvdd);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable  'hvdd' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_vddio);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable  'vddio' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_avdd);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable  'avdd' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_target_5v);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable  'target-5v' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_target_12v);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable  'sc->target-12v' regulator\n");
		return (rv);
	}

	/* Stop clocks */
	clk_stop(sc->clk_sata);
	clk_stop(sc->clk_sata_oob);
	tegra_powergate_power_off(TEGRA_POWERGATE_SAX);

	rv = hwreset_assert(sc->hwreset_sata);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot assert 'sata' reset\n");
		return (rv);
	}
	rv = hwreset_assert(sc->hwreset_sata_oob);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot assert 'sata oob' reset\n");
		return (rv);
	}

	rv = hwreset_assert(sc->hwreset_sata_cold);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot assert 'sata cold' reset\n");
		return (rv);
	}
	rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SAX,
	    sc->clk_sata, sc->hwreset_sata);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable 'SAX' powergate\n");
		return (rv);
	}

	rv = clk_enable(sc->clk_sata_oob);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable 'sata oob' clock\n");
		return (rv);
	}
	rv = clk_enable(sc->clk_cml);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable 'cml' clock\n");
		return (rv);
	}
	rv = clk_enable(sc->clk_pll_e);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable 'pll e' clock\n");
		return (rv);
	}

	rv = hwreset_deassert(sc->hwreset_sata_cold);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot unreset 'sata cold' reset\n");
		return (rv);
	}
	rv = hwreset_deassert(sc->hwreset_sata_oob);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot unreset 'sata oob' reset\n");
		return (rv);
	}

	rv = phy_enable(sc->dev, sc->phy);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable SATA phy\n");
		return (rv);
	}

	return (0);
}
예제 #3
0
static int
enable_fdt_resources(struct tegra_xhci_softc *sc)
{
	int rv;

	rv = hwreset_assert(sc->hwreset_xusb_host);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot reset 'xusb_host' reset\n");
		return (rv);
	}
	rv = hwreset_assert(sc->hwreset_xusb_ss);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot reset 'xusb_ss' reset\n");
		return (rv);
	}

	rv = regulator_enable(sc->supply_avddio_pex);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'avddio_pex' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_dvddio_pex);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'dvddio_pex' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_avdd_usb);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'avdd_usb' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_avdd_pll_utmip);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'avdd_pll_utmip-5v' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_avdd_pll_erefe);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'avdd_pll_erefe' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_avdd_usb_ss_pll);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'avdd_usb_ss_pll' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_hvdd_usb_ss);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'hvdd_usb_ss' regulator\n");
		return (rv);
	}
	rv = regulator_enable(sc->supply_hvdd_usb_ss_pll_e);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'hvdd_usb_ss_pll_e' regulator\n");
		return (rv);
	}

	/* Power off XUSB host and XUSB SS domains. */
	rv = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBA);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot powerdown  'xusba' domain\n");
		return (rv);
	}
	rv = tegra_powergate_power_off(TEGRA_POWERGATE_XUSBC);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot powerdown  'xusbc' domain\n");
		return (rv);
	}

	/* Setup XUSB ss_src clock first */
	clk_set_freq(sc->clk_xusb_ss, TEGRA_XHCI_SS_HIGH_SPEED, 0);
	if (rv != 0)
		return (rv);

	/* The XUSB gate clock must be enabled before XUSBA can be powered. */
	rv = clk_enable(sc->clk_xusb_gate);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'xusb_gate' clock\n");
		return (rv);
	}

	/* Power on XUSB host and XUSB SS domains. */
	rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBC,
	    sc->clk_xusb_host, sc->hwreset_xusb_host);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot powerup 'xusbc' domain\n");
		return (rv);
	}
	rv = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_XUSBA,
	    sc->clk_xusb_ss, sc->hwreset_xusb_ss);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot powerup 'xusba' domain\n");
		return (rv);
	}

	/* Enable rest of clocks */
	rv = clk_enable(sc->clk_xusb_falcon_src);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'xusb_falcon_src' clock\n");
		return (rv);
	}
	rv = clk_enable(sc->clk_xusb_fs_src);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'xusb_fs_src' clock\n");
		return (rv);
	}
	rv = clk_enable(sc->clk_xusb_hs_src);
	if (rv != 0) {
		device_printf(sc->dev,
		    "Cannot enable 'xusb_hs_src' clock\n");
		return (rv);
	}

	rv = phy_enable(sc->phy_usb2_0);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable USB2_0 phy\n");
		return (rv);
	}
	rv = phy_enable(sc->phy_usb2_1);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable USB2_1 phy\n");
		return (rv);
	}
	rv = phy_enable(sc->phy_usb2_2);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable USB2_2 phy\n");
		return (rv);
	}
	rv = phy_enable(sc->phy_usb3_0);
	if (rv != 0) {
		device_printf(sc->dev, "Cannot enable USB3_0 phy\n");
		return (rv);
	}

	return (0);
}
예제 #4
0
static int
xhci_attach(device_t dev)
{
	struct xhci_softc *sc = device_get_softc(dev);
	int err = 0, rid = 0;
#ifdef EXT_RESOURCES
	phandle_t node;
	phy_t phy;
#endif

	sc->sc_bus.parent = dev;
	sc->sc_bus.devices = sc->sc_devices;
	sc->sc_bus.devices_max = XHCI_MAX_DEVICES;

	sc->sc_io_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (sc->sc_io_res == NULL) {
		device_printf(dev, "Failed to map memory\n");
		xhci_detach(dev);
		return (ENXIO);
	}

	sc->sc_io_tag = rman_get_bustag(sc->sc_io_res);
	sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res);
	sc->sc_io_size = rman_get_size(sc->sc_io_res);

	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->sc_irq_res == NULL) {
		device_printf(dev, "Failed to allocate IRQ\n");
		xhci_detach(dev);
		return (ENXIO);
	}

#ifdef EXT_RESOURCES
	node = ofw_bus_get_node(dev);
	if (phy_get_by_ofw_property(dev, node, "usb-phy", &phy) == 0)
		if (phy_enable(phy) != 0)
			device_printf(dev, "Cannot enable phy\n");
#endif

	sc->sc_bus.bdev = device_add_child(dev, "usbus", -1);
	if (sc->sc_bus.bdev == NULL) {
		device_printf(dev, "Failed to add USB device\n");
		xhci_detach(dev);
		return (ENXIO);
	}

	device_set_ivars(sc->sc_bus.bdev, &sc->sc_bus);

	sprintf(sc->sc_vendor, XHCI_HC_VENDOR);
	device_set_desc(sc->sc_bus.bdev, XHCI_HC_DEVSTR);

	err = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
	    NULL, (driver_intr_t *)xhci_interrupt, sc, &sc->sc_intr_hdl);
	if (err != 0) {
		device_printf(dev, "Failed to setup error IRQ, %d\n", err);
		sc->sc_intr_hdl = NULL;
		xhci_detach(dev);
		return (err);
	}

	err = xhci_init(sc, dev, IS_DMA_32B);
	if (err != 0) {
		device_printf(dev, "Failed to init XHCI, with error %d\n", err);
		xhci_detach(dev);
		return (ENXIO);
	}

	err = xhci_start_controller(sc);
	if (err != 0) {
		device_printf(dev, "Failed to start XHCI controller, with error %d\n", err);
		xhci_detach(dev);
		return (ENXIO);
	}

	err = device_probe_and_attach(sc->sc_bus.bdev);
	if (err != 0) {
		device_printf(dev, "Failed to initialize USB, with error %d\n", err);
		xhci_detach(dev);
		return (ENXIO);
	}

	return (0);
}