From 79eb2b3ec6c0b38c6aeaf9a78ab3cb2de9cfcee7 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Wed, 27 Aug 2014 17:51:19 -0500 Subject: [PATCH] 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 Original-Commit-Id: d7da2dcce9be653a3c551c33bbefb3810a6949e9 Original-Change-Id: Ia3f2c10dab2bbfd65ba883451bf4eafc26f2e7cf Original-Signed-off-by: Aaron Durbin Original-Reviewed-on: https://chromium-review.googlesource.com/214776 Original-Reviewed-by: Tom Warren Original-Reviewed-by: Furquan Shaikh Reviewed-on: http://review.coreboot.org/9020 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/nvidia/tegra132/chip.h | 1 + src/soc/nvidia/tegra132/soc.c | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) 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 #include #include +#include +#include #include #include #include +#include #include #include +#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)