summaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra132
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-09-06 02:36:40 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-03-27 08:05:21 +0100
commitb6a81fa94b93319288bd2f3300889a651cab91b4 (patch)
treeea9e9a6ea5dd648c70d1b14e5c0ab6839a47b947 /src/soc/nvidia/tegra132
parent5538e50bc46a1402f7c3b955ca5c74adc1d91cc9 (diff)
tegra132: support arm64 SMP bringup
Use the formal devicetree way for bringing up each of the cpus. This includes providing a cpu_driver as well as calling arch_initialize_cpus() with the proper operations to start the cores. BUG=chrome-os-partner:31761 BRANCH=None TEST=Booted SMP on ryu. Change-Id: I276fe08916bc0c46c8f4dd30e47c7d9b135e2bbd Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 038daec1b74f4c414ab7ad153d34e48d4644183a Original-Change-Id: I13d8bfd645abf66f270d56d48eff4331c4ea1200 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/216926 Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9043 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/nvidia/tegra132')
-rw-r--r--src/soc/nvidia/tegra132/Kconfig3
-rw-r--r--src/soc/nvidia/tegra132/soc.c88
2 files changed, 46 insertions, 45 deletions
diff --git a/src/soc/nvidia/tegra132/Kconfig b/src/soc/nvidia/tegra132/Kconfig
index edb51ba597..d7e2786ffb 100644
--- a/src/soc/nvidia/tegra132/Kconfig
+++ b/src/soc/nvidia/tegra132/Kconfig
@@ -6,7 +6,6 @@ config SOC_NVIDIA_TEGRA132
select ARCH_ROMSTAGE_ARMV4
select ARCH_RAMSTAGE_ARMV8_64
select ARM64_CPUS_START_IN_EL3
- select DYNAMIC_CBMEM
select BOOTBLOCK_CONSOLE
select HAVE_MONOTONIC_TIMER
select HAVE_HARD_RESET
@@ -14,6 +13,8 @@ config SOC_NVIDIA_TEGRA132
select HAVE_UART_MEMORY_MAPPED
select EARLY_CONSOLE
select ARM_BOOTBLOCK_CUSTOM
+ select DYNAMIC_CBMEM
+ select SMP
if SOC_NVIDIA_TEGRA132
diff --git a/src/soc/nvidia/tegra132/soc.c b/src/soc/nvidia/tegra132/soc.c
index 16001f9fb3..f7df27926b 100644
--- a/src/soc/nvidia/tegra132/soc.c
+++ b/src/soc/nvidia/tegra132/soc.c
@@ -22,8 +22,8 @@
#include <console/console.h>
#include <device/device.h>
#include <arch/io.h>
-#include <arch/cpu.h>
#include <arch/cache.h>
+#include <cpu/cpu.h>
#include <cbmem.h>
#include <timer.h>
#include <vendorcode/google/chromeos/chromeos.h>
@@ -40,7 +40,6 @@ static void soc_read_resources(device_t dev)
int i; uintptr_t begin, end;
size_t size;
- printk(BIOS_DEBUG, "%s: entry, device = %p\n", __func__, dev);
for (i = 0; i < CARVEOUT_NUM; i++) {
carveout_range(i, &begin, &size);
if (size == 0)
@@ -63,8 +62,6 @@ static void soc_read_resources(device_t dev)
ram_resource(dev, index++, begin * KiB, size * KiB);
}
-static volatile int secondary_cpu_up;
-
static void *spintable_entry;
static uint64_t * const spintable_magic = (void *)(uintptr_t)0x80000008;
@@ -90,7 +87,7 @@ static void spintable_init(void)
dsb();
}
-static void spintable_wait(void)
+static void spintable_wait(void *monitor_address)
{
uint32_t sctlr_el2;
uint32_t spsr_el3;
@@ -118,56 +115,39 @@ static void spintable_wait(void)
isb();
asm volatile(
"mov x0, %0\n\t"
- "eret\n\t" : : "r" (spintable_magic) : "x0" );
+ "eret\n\t" : : "r" (monitor_address) : "x0" );
}
-void soc_secondary_cpu_init(void)
+static size_t cntrl_total_cpus(void)
{
- printk(BIOS_INFO, "CPU%d is up!\n", smp_processor_id());
- gic_init();
- dmb();
- secondary_cpu_up = 1;
- spintable_wait();
+ return CONFIG_MAX_CPUS;
}
-static void start_secondary_cpu(void)
+static int cntrl_start_cpu(unsigned int id, void (*entry)(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;
- }
- }
+ if (id != 1)
+ return -1;
+ start_cpu(1, entry);
+ return 0;
}
+static struct cpu_control_ops cntrl_ops = {
+ .total_cpus = cntrl_total_cpus,
+ .start_cpu = cntrl_start_cpu,
+};
+
static void soc_init(device_t dev)
{
- struct soc_nvidia_tegra132_config *config = dev->chip_info;
+ struct cpu_action action = {
+ .run = spintable_wait,
+ .arg = spintable_magic,
+ };
- printk(BIOS_INFO, "CPU: Tegra132\n");
clock_init_arm_generic_timer();
- gic_init();
- if (config->bring_up_secondary_cpu) {
- spintable_init();
- start_secondary_cpu();
- }
+ spintable_init();
+ arch_initialize_cpus(dev, &cntrl_ops);
+ arch_run_on_cpu_async(1, &action);
}
static void soc_noop(device_t dev)
@@ -179,12 +159,13 @@ static struct device_operations soc_ops = {
.set_resources = soc_noop,
.enable_resources = soc_noop,
.init = soc_init,
- .scan_bus = 0,
+ .scan_bus = NULL,
};
static void enable_tegra132_dev(device_t dev)
{
- dev->ops = &soc_ops;
+ if (dev->path.type == DEVICE_PATH_CPU_CLUSTER)
+ dev->ops = &soc_ops;
}
static void tegra132_init(void *chip_info)
@@ -204,3 +185,22 @@ struct chip_operations soc_nvidia_tegra132_ops = {
.init = tegra132_init,
.enable_dev = enable_tegra132_dev,
};
+
+static void tegra132_cpu_init(device_t cpu)
+{
+ gic_init();
+}
+
+static const struct cpu_device_id ids[] = {
+ { 0x4e0f0000 },
+ { CPU_ID_END },
+};
+
+static struct device_operations cpu_dev_ops = {
+ .init = tegra132_cpu_init,
+};
+
+static const struct cpu_driver driver __cpu_driver = {
+ .ops = &cpu_dev_ops,
+ .id_table = ids,
+};