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; }
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); }
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); }
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); }