summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-08-27 17:51:19 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-03-27 08:04:13 +0100
commit79eb2b3ec6c0b38c6aeaf9a78ab3cb2de9cfcee7 (patch)
tree5fbce21441afc523989817127f59c9b9a64c53b0
parentda185c17028c8dbef0d57ba3624a50ef1ebd00a0 (diff)
tegra132: add option to bring up and init secondary cpu
Optionally bring up secondary cpu according to devicetree. BUG=chrome-os-partner:31545 BRANCH=None TEST=Built and enabled bringing up second core on ryu. Change-Id: I5ede8b2f1b30a6170520cc11c18e263793cea301 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: d7da2dcce9be653a3c551c33bbefb3810a6949e9 Original-Change-Id: Ia3f2c10dab2bbfd65ba883451bf4eafc26f2e7cf Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/214776 Original-Reviewed-by: Tom Warren <twarren@nvidia.com> Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9020 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--src/soc/nvidia/tegra132/chip.h1
-rw-r--r--src/soc/nvidia/tegra132/soc.c45
2 files changed, 46 insertions, 0 deletions
diff --git a/src/soc/nvidia/tegra132/chip.h b/src/soc/nvidia/tegra132/chip.h
index 394f0a4020..654e381236 100644
--- a/src/soc/nvidia/tegra132/chip.h
+++ b/src/soc/nvidia/tegra132/chip.h
@@ -26,6 +26,7 @@
#define EINVAL 2
struct soc_nvidia_tegra132_config {
+ int bring_up_secondary_cpu;
};
#endif /* __SOC_NVIDIA_TEGRA132_CHIP_H__ */
diff --git a/src/soc/nvidia/tegra132/soc.c b/src/soc/nvidia/tegra132/soc.c
index 13050f6c06..024fd805da 100644
--- a/src/soc/nvidia/tegra132/soc.c
+++ b/src/soc/nvidia/tegra132/soc.c
@@ -21,11 +21,15 @@
#include <console/console.h>
#include <device/device.h>
#include <arch/io.h>
+#include <arch/cpu.h>
+#include <timer.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/addressmap.h>
#include <soc/clock.h>
+#include <soc/cpu.h>
#include <soc/ramstage.h>
#include <soc/nvidia/tegra/apbmisc.h>
+#include "chip.h"
static void soc_read_resources(device_t dev)
{
@@ -56,11 +60,52 @@ static void soc_read_resources(device_t dev)
ram_resource(dev, index++, begin * KiB, size * KiB);
}
+static volatile int secondary_cpu_up;
+
+void soc_secondary_cpu_init(void)
+{
+ printk(BIOS_INFO, "CPU%d is up!\n", smp_processor_id());
+ gic_init();
+ dmb();
+ secondary_cpu_up = 1;
+}
+
+static void start_secondary_cpu(void)
+{
+ struct mono_time t1, t2;
+ const long timeout_us = 20 * USECS_PER_MSEC;
+
+ timer_monotonic_get(&t1);
+ start_cpu(1, prepare_secondary_cpu_startup());
+ /* Wait for the other core to come up. */
+ while (1) {
+ long waited_us;
+
+ timer_monotonic_get(&t2);
+ waited_us = mono_time_diff_microseconds(&t1, &t2);
+
+ if (secondary_cpu_up) {
+ printk(BIOS_INFO, "Secondary CPU start took %ld us.\n",
+ waited_us);
+ break;
+ }
+ if (waited_us > timeout_us) {
+ printk(BIOS_WARNING, "CPU startup timeout!\n");
+ break;
+ }
+ }
+}
+
static void soc_init(device_t dev)
{
+ struct soc_nvidia_tegra132_config *config = dev->chip_info;
+
printk(BIOS_INFO, "CPU: Tegra132\n");
clock_init_arm_generic_timer();
gic_init();
+
+ if (config->bring_up_secondary_cpu)
+ start_secondary_cpu();
}
static void soc_noop(device_t dev)