/* Must be called with clk disabled, and returns with clk enabled */ int tegra_powergate_sequence_power_up(int id, struct clk *clk, struct reset_control *rst) { int ret; reset_control_assert(rst); ret = tegra_powergate_power_on(id); if (ret) goto err_power; ret = clk_prepare_enable(clk); if (ret) goto err_clk; udelay(10); ret = tegra_powergate_remove_clamping(id); if (ret) goto err_clamp; udelay(10); reset_control_deassert(rst); return 0; err_clamp: clk_disable_unprepare(clk); err_clk: tegra_powergate_power_off(id); err_power: return ret; }
/* Must be called with clk disabled, and returns with clk enabled */ int tegra_powergate_sequence_power_up(int id, struct clk *clk) { int ret; tegra_periph_reset_assert(clk); ret = tegra_powergate_power_on(id); if (ret) goto err_power; ret = clk_enable(clk); if (ret) goto err_clk; udelay(10); ret = tegra_powergate_remove_clamping(id); if (ret) goto err_clamp; udelay(10); tegra_periph_reset_deassert(clk); return 0; err_clamp: clk_disable(clk); err_clk: tegra_powergate_power_off(id); err_power: return ret; }
static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { int ret; if (tdev->vdd) { ret = regulator_enable(tdev->vdd); if (ret) goto err_power; } ret = clk_prepare_enable(tdev->clk); if (ret) goto err_clk; if (tdev->clk_ref) { ret = clk_prepare_enable(tdev->clk_ref); if (ret) goto err_clk_ref; } ret = clk_prepare_enable(tdev->clk_pwr); if (ret) goto err_clk_pwr; clk_set_rate(tdev->clk_pwr, 204000000); udelay(10); reset_control_assert(tdev->rst); udelay(10); if (!tdev->pdev->dev.pm_domain) { ret = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D); if (ret) goto err_clamp; udelay(10); } reset_control_deassert(tdev->rst); udelay(10); return 0; err_clamp: clk_disable_unprepare(tdev->clk_pwr); err_clk_pwr: if (tdev->clk_ref) clk_disable_unprepare(tdev->clk_ref); err_clk_ref: clk_disable_unprepare(tdev->clk); err_clk: if (tdev->vdd) regulator_disable(tdev->vdd); err_power: return ret; }
int tegra_powergate_sequence_power_up(enum tegra_powergate_id id, clk_t clk, hwreset_t rst) { struct tegra124_pmc_softc *sc; int rv; sc = tegra124_pmc_get_sc(); rv = hwreset_assert(rst); if (rv != 0) { device_printf(sc->dev, "Cannot assert reset\n"); return (rv); } rv = clk_stop(clk); if (rv != 0) { device_printf(sc->dev, "Cannot stop clock\n"); goto clk_fail; } rv = tegra_powergate_power_on(id); if (rv != 0) { device_printf(sc->dev, "Cannot power on powergate\n"); goto clk_fail; } rv = clk_enable(clk); if (rv != 0) { device_printf(sc->dev, "Cannot enable clock\n"); goto clk_fail; } DELAY(20); rv = tegra_powergate_remove_clamping(id); if (rv != 0) { device_printf(sc->dev, "Cannot remove clamping\n"); goto fail; } rv = hwreset_deassert(rst); if (rv != 0) { device_printf(sc->dev, "Cannot unreset reset\n"); goto fail; } return 0; fail: clk_disable(clk); clk_fail: hwreset_assert(rst); tegra_powergate_power_off(id); return (rv); }
int tegra1xx_unpowergate(int id, struct powergate_partition_info *pg_info) { int ret; /* If first clk_ptr is null, fill clk info for the partition */ if (!pg_info->clk_info[0].clk_ptr) get_clk_info(pg_info); if (tegra_powergate_is_powered(id)) return tegra_powergate_reset_module(pg_info); ret = tegra_powergate_set(id, true); if (ret) goto err_power; udelay(10); /* Un-Powergating fails if all clks are not enabled */ ret = partition_clk_enable(pg_info); if (ret) goto err_clk_on; udelay(10); ret = tegra_powergate_remove_clamping(id); if (ret) goto err_clamp; udelay(10); powergate_partition_deassert_reset(pg_info); udelay(10); tegra_powergate_mc_flush_done(id); udelay(10); /* Disable all clks enabled earlier. Drivers should enable clks */ partition_clk_disable(pg_info); return 0; err_clamp: partition_clk_disable(pg_info); err_clk_on: powergate_module(id); err_power: WARN(1, "Could not Un-Powergate %d", id); return ret; }
static int nouveau_platform_power_up(struct nouveau_platform_gpu *gpu) { int err; err = regulator_enable(gpu->vdd); if (err) goto err_power; err = clk_prepare_enable(gpu->clk); if (err) goto err_clk; err = clk_prepare_enable(gpu->clk_pwr); if (err) goto err_clk_pwr; clk_set_rate(gpu->clk_pwr, 204000000); udelay(10); reset_control_assert(gpu->rst); udelay(10); err = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D); if (err) goto err_clamp; udelay(10); reset_control_deassert(gpu->rst); udelay(10); return 0; err_clamp: clk_disable_unprepare(gpu->clk_pwr); err_clk_pwr: clk_disable_unprepare(gpu->clk); err_clk: regulator_disable(gpu->vdd); err_power: return err; }
static int tegra30_power_up_cpu(unsigned int cpu) { u32 reg; int ret, pwrgateid; unsigned long timeout; pwrgateid = tegra_cpu_powergate_id(cpu); if (pwrgateid < 0) return pwrgateid; /* If this is the first boot, toggle powergates directly. */ if (!tegra_powergate_is_powered(pwrgateid)) { ret = tegra_powergate_power_on(pwrgateid); if (ret) return ret; /* Wait for the power to come up. */ timeout = jiffies + 10*HZ; while (tegra_powergate_is_powered(pwrgateid)) { if (time_after(jiffies, timeout)) return -ETIMEDOUT; udelay(10); } } /* CPU partition is powered. Enable the CPU clock. */ writel(CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); udelay(10); /* Remove I/O clamps. */ ret = tegra_powergate_remove_clamping(pwrgateid); udelay(10); /* Clear flow controller CSR. */ flowctrl_write_cpu_csr(cpu, 0); return 0; }
static int power_up_cpu(unsigned int cpu) { u32 reg; int ret = 0; #ifndef CONFIG_ARCH_TEGRA_2x_SOC unsigned long timeout; BUG_ON(cpu == smp_processor_id()); BUG_ON(is_lp_cluster()); /* If this cpu has booted this function is entered after * CPU has been already un-gated by flow controller. Wait * for confirmation that cpu is powered and remove clamps. * On first boot entry do not wait - go to direct ungate. */ if (cpu_isset(cpu, tegra_cpu_init_map)) { timeout = jiffies + 5; do { if (is_cpu_powered(cpu)) goto remove_clamps; udelay(10); } while (time_before(jiffies, timeout)); } /* First boot or Flow controller did not work as expected. Try to directly toggle power gates. Error if direct power on also fails. */ if (!is_cpu_powered(cpu)) { ret = tegra_unpowergate_partition(TEGRA_CPU_POWERGATE_ID(cpu)); if (ret) goto fail; /* Wait for the power to come up. */ timeout = jiffies + 10*HZ; do { if (is_cpu_powered(cpu)) goto remove_clamps; udelay(10); } while (time_before(jiffies, timeout)); ret = -ETIMEDOUT; goto fail; } remove_clamps: /* CPU partition is powered. Enable the CPU clock. */ writel(CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); udelay(10); /* Remove I/O clamps. */ ret = tegra_powergate_remove_clamping(TEGRA_CPU_POWERGATE_ID(cpu)); udelay(10); fail: #else /* Enable the CPU clock. */ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); writel(reg & ~CPU_CLOCK(cpu), CLK_RST_CONTROLLER_CLK_CPU_CMPLX); barrier(); reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); #endif /* Clear flow controller CSR. */ flowctrl_writel(0, FLOW_CTRL_CPU_CSR(cpu)); return ret; }