Exemple #1
0
/**
 * Initialize power management for application processors
 */
void psci_board_init(void)
{
	struct flow_ctlr *flow = (struct flow_ctlr *)NV_PA_FLOW_BASE;

	writel((u32)park_cpu, EXCEP_VECTOR_CPU_RESET_VECTOR);

	/*
	 * The naturally expected order of putting these CPUs under Flow
	 * Controller regime would be
	 *  - configure the Flow Controller
	 *  - power up the CPUs
	 *  - wait for the CPUs to hit wfi and be powered down again
	 *
	 * However, this doesn't work in practice. We rather need to power them
	 * up first and park them in wfi. While they are waiting there, we can
	 * indeed program the Flow Controller to powergate them on wfi, which
	 * will then happen immediately as they are already in that state.
	 */
	tegra_powergate_power_on(TEGRA_POWERGATE_CPU1);
	tegra_powergate_power_on(TEGRA_POWERGATE_CPU2);
	tegra_powergate_power_on(TEGRA_POWERGATE_CPU3);

	writel((2 << CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, &flow->cpu1_csr);
	writel((4 << CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, &flow->cpu2_csr);
	writel((8 << CSR_WAIT_WFI_SHIFT) | CSR_ENABLE, &flow->cpu3_csr);

	writel(EVENT_MODE_STOP, &flow->halt_cpu1_events);
	writel(EVENT_MODE_STOP, &flow->halt_cpu2_events);
	writel(EVENT_MODE_STOP, &flow->halt_cpu3_events);

	while (!(readl(&flow->cpu1_csr) & CSR_PWR_OFF_STS) ||
		!(readl(&flow->cpu2_csr) & CSR_PWR_OFF_STS) ||
		!(readl(&flow->cpu3_csr) & CSR_PWR_OFF_STS))
		/* wait */;
}
Exemple #2
0
/* 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;
}
Exemple #3
0
/* 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;
}
Exemple #4
0
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);
}
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;
}