tegra124: Correct cpu power on sequence and CPUPWRGOOD_TIME

Based on TRM, cpu clock enabling and reset vector setting should
all be done properly before ungating cpu power partition. Otherwise,
with current code, a race condition could occur where cpu starts but
reset vector has not been set.

BUG=chrome-os-partner:30064
BRANCH=none
TEST=run nyan_big reboot test. No issue is experienced.

Original-Signed-off-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Change-Id: I571e128693bb2763ee673bd183b8cf60921dc475
Original-Reviewed-on: https://chromium-review.googlesource.com/206682
Original-Tested-by: Jimmy Zhang <jimmzhang@nvidia.com>
Original-Reviewed-by: Julius Werner <jwerner@chromium.org>
Original-Commit-Queue: Jimmy Zhang <jimmzhang@nvidia.com>
(cherry picked from commit 106480ff32406c899a24544fdfab858db5afd1d9)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>

Change-Id: I3da6018dd68e4c15d2c58db566a9745b0b26c365
Reviewed-on: http://review.coreboot.org/8414
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/src/soc/nvidia/tegra124/power.c b/src/soc/nvidia/tegra124/power.c
index 760d058..ec44a0f 100644
--- a/src/soc/nvidia/tegra124/power.c
+++ b/src/soc/nvidia/tegra124/power.c
@@ -21,6 +21,7 @@
 #include <arch/io.h>
 #include <console/console.h>
 #include <soc/addressmap.h>
+#include <soc/clock.h>
 
 #include "pmc.h"
 #include "power.h"
@@ -32,6 +33,11 @@
 	return read32(&pmc->pwrgate_status) & (0x1 << id);
 }
 
+static int partition_clamp_on(int id)
+{
+	return read32(&pmc->clamp_status) & (0x1 << id);
+}
+
 static void power_ungate_partition(uint32_t id)
 {
 	printk(BIOS_INFO, "Ungating power partition %d.\n", id);
@@ -51,34 +57,30 @@
 		// Wait for the partition to be powered.
 		while (!partition_powered(id))
 			;
+
+		// Wait for clamp off.
+		while (partition_clamp_on(id))
+			;
 	}
 
 	printk(BIOS_INFO, "Ungated power partition %d.\n", id);
 }
 
-void power_enable_cpu_rail(void)
+void power_enable_and_ungate_cpu(void)
 {
-	// Set the power gate timer multiplier to 8 (why 8?).
-	uint32_t pwrgate_timer_mult = read32(&pmc->pwrgate_timer_mult);
-	pwrgate_timer_mult |= (0x3 << 0);
-
 	/*
-	 * From U-Boot:
-	 * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (102MHz),
-	 * set it for 5ms as per SysEng (102MHz/5mS = 510000).
+	 * Set CPUPWRGOOD_TIMER - APB clock is 1/2 of SCLK (150MHz),
+	 * set it for 5ms as per SysEng (5ms * PCLK_KHZ * 1000 / 1s).
 	 */
-	write32(510000, &pmc->cpupwrgood_timer);
-
-	power_ungate_partition(POWER_PARTID_CRAIL);
+	write32((TEGRA_PCLK_KHZ * 5), &pmc->cpupwrgood_timer);
 
 	uint32_t cntrl = read32(&pmc->cntrl);
 	cntrl &= ~PMC_CNTRL_CPUPWRREQ_POLARITY;
 	cntrl |= PMC_CNTRL_CPUPWRREQ_OE;
 	write32(cntrl, &pmc->cntrl);
-}
 
-void power_ungate_cpu(void)
-{
+	power_ungate_partition(POWER_PARTID_CRAIL);
+
 	// Ungate power to the non-core parts of the fast cluster.
 	power_ungate_partition(POWER_PARTID_C0NC);