Tegra: support for System Suspend using sc7entry-fw binary
This patch adds support to enter System Suspend on Tegra210 platforms
without the traditional BPMP firmware. The BPMP firmware will no longer
be supported on Tegra210 platforms and its functionality will be
divided across the CPU and sc7entry-fw.
The sc7entry-fw takes care of performing the hardware sequence required
to enter System Suspend (SC7 power state) from the COP. The CPU is required
to load this firmware to the internal RAM of the COP and start the sequence.
The CPU also make sure that the COP is off after cold boot and is only
powered on when we want to start the actual System Suspend sequence.
The previous bootloader loads the firmware to TZDRAM and passes its base and
size as part of the boot parameters. The EL3 layer is supposed to sanitize
the parameters before touching the firmware blob.
To assist the warmboot code with the PMIC discovery, EL3 is also supposed to
program PMC's scratch register #210, with appropriate values. Without these
settings the warmboot code wont be able to get the device out of System
Suspend.
Change-Id: I5a7b868512dbfd6cfefd55acf3978a1fd7ebf1e2
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
diff --git a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c b/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
index 4f89cf4..bdd3ee7 100644
--- a/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
+++ b/plat/nvidia/tegra/common/drivers/flowctrl/flowctrl.c
@@ -257,22 +257,19 @@
}
/*******************************************************************************
- * Reset BPMP processor
+ * Power ON BPMP processor
******************************************************************************/
-void tegra_fc_reset_bpmp(void)
+void tegra_fc_bpmp_on(uint32_t entrypoint)
{
- uint32_t val;
-
/* halt BPMP */
tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT);
/* Assert BPMP reset */
mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST);
- /* Restore reset address (stored in PMC_SCRATCH39) */
- val = tegra_pmc_read_32(PMC_SCRATCH39);
- mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, val);
- while (val != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
+ /* Set reset address (stored in PMC_SCRATCH39) */
+ mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, entrypoint);
+ while (entrypoint != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
; /* wait till value reaches EVP_BPMP_RESET_VECTOR */
/* Wait for 2us before de-asserting the reset signal. */
@@ -286,6 +283,23 @@
}
/*******************************************************************************
+ * Power OFF BPMP processor
+ ******************************************************************************/
+void tegra_fc_bpmp_off(void)
+{
+ /* halt BPMP */
+ tegra_fc_write_32(FLOWCTRL_HALT_BPMP_EVENTS, FLOWCTRL_WAITEVENT);
+
+ /* Assert BPMP reset */
+ mmio_write_32(TEGRA_CAR_RESET_BASE + CLK_RST_DEV_L_SET, CLK_BPMP_RST);
+
+ /* Clear reset address */
+ mmio_write_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR, 0);
+ while (0 != mmio_read_32(TEGRA_EVP_BASE + EVP_BPMP_RESET_VECTOR))
+ ; /* wait till value reaches EVP_BPMP_RESET_VECTOR */
+}
+
+/*******************************************************************************
* Route legacy FIQ to the GICD
******************************************************************************/
void tegra_fc_enable_fiq_to_ccplex_routing(void)