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: I13d8bfd645abf66f270d56d48eff4331c4ea1200 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/216926 Reviewed-by: Furquan Shaikh <furquan@chromium.org>
This commit is contained in:
parent
a733fd566a
commit
038daec1b7
2 changed files with 45 additions and 44 deletions
|
|
@ -13,6 +13,7 @@ config SOC_NVIDIA_TEGRA132
|
|||
select EARLY_CONSOLE
|
||||
select ARM_BOOTBLOCK_CUSTOM
|
||||
select DYNAMIC_CBMEM
|
||||
select SMP
|
||||
|
||||
if SOC_NVIDIA_TEGRA132
|
||||
|
||||
|
|
|
|||
|
|
@ -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, framebuffer_begin;
|
||||
size_t size, framebuffer_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)
|
||||
|
|
@ -60,8 +59,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;
|
||||
|
||||
|
|
@ -87,7 +84,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;
|
||||
|
|
@ -115,56 +112,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)
|
||||
|
|
@ -176,12 +156,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)
|
||||
|
|
@ -201,3 +182,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,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue