diff options
author | Aaron Durbin <adurbin@chromium.org> | 2014-08-27 17:51:19 -0500 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2015-03-27 08:04:13 +0100 |
commit | 79eb2b3ec6c0b38c6aeaf9a78ab3cb2de9cfcee7 (patch) | |
tree | 5fbce21441afc523989817127f59c9b9a64c53b0 | |
parent | da185c17028c8dbef0d57ba3624a50ef1ebd00a0 (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.h | 1 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/soc.c | 45 |
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) |