You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.1 KiB
90 lines
3.1 KiB
11 years ago
|
From 672d6bea85c7c9c63c086a9423e6d4e5fc286152 Mon Sep 17 00:00:00 2001
|
||
|
From: Florian Fainelli <florian@openwrt.org>
|
||
|
Date: Wed, 26 Jun 2013 18:11:56 +0000
|
||
|
Subject: [PATCH] MIPS: BMIPS: support booting from physical CPU other than 0
|
||
|
|
||
|
BMIPS43xx CPUs have two hardware threads, and on some SoCs such as 3368,
|
||
|
the bootloader has configured the system to boot from TP1 instead of the
|
||
|
more usual TP0. Create the physical to logical CPU mapping to cope with
|
||
|
that, do not remap the software interrupts to be cross CPUs such that we
|
||
|
do not have to do use the logical CPU mapping further down the code, and
|
||
|
finally, reset the slave TP1 only if booted from TP0.
|
||
|
|
||
|
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
||
|
Signed-off-by: Florian Fainelli <florian@openwrt.org>
|
||
|
Cc: linux-mips@linux-mips.org
|
||
|
Cc: blogic@openwrt.org
|
||
|
Cc: cernekee@gmail.com
|
||
|
Patchwork: https://patchwork.linux-mips.org/patch/5553/
|
||
|
Patchwork: https://patchwork.linux-mips.org/patch/5556/
|
||
|
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
|
||
|
---
|
||
|
arch/mips/kernel/smp-bmips.c | 29 +++++++++++++++++++++++------
|
||
|
1 file changed, 23 insertions(+), 6 deletions(-)
|
||
|
|
||
|
--- a/arch/mips/kernel/smp-bmips.c
|
||
|
+++ b/arch/mips/kernel/smp-bmips.c
|
||
|
@@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(i
|
||
|
|
||
|
static void __init bmips_smp_setup(void)
|
||
|
{
|
||
|
- int i;
|
||
|
+ int i, cpu = 1, boot_cpu = 0;
|
||
|
|
||
|
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
|
||
|
/* arbitration priority */
|
||
|
@@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void)
|
||
|
/* NBK and weak order flags */
|
||
|
set_c0_brcm_config_0(0x30000);
|
||
|
|
||
|
+ /* Find out if we are running on TP0 or TP1 */
|
||
|
+ boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
|
||
|
+
|
||
|
/*
|
||
|
* MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
|
||
|
* MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
|
||
|
* MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
|
||
|
+ *
|
||
|
+ * If booting from TP1, leave the existing CMT interrupt routing
|
||
|
+ * such that TP0 responds to SW1 and TP1 responds to SW0.
|
||
|
*/
|
||
|
- change_c0_brcm_cmt_intr(0xf8018000,
|
||
|
- (0x02 << 27) | (0x03 << 15));
|
||
|
+ if (boot_cpu == 0)
|
||
|
+ change_c0_brcm_cmt_intr(0xf8018000,
|
||
|
+ (0x02 << 27) | (0x03 << 15));
|
||
|
+ else
|
||
|
+ change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
|
||
|
|
||
|
/* single core, 2 threads (2 pipelines) */
|
||
|
max_cpus = 2;
|
||
|
@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void)
|
||
|
if (!board_ebase_setup)
|
||
|
board_ebase_setup = &bmips_ebase_setup;
|
||
|
|
||
|
+ __cpu_number_map[boot_cpu] = 0;
|
||
|
+ __cpu_logical_map[0] = boot_cpu;
|
||
|
+
|
||
|
for (i = 0; i < max_cpus; i++) {
|
||
|
- __cpu_number_map[i] = 1;
|
||
|
- __cpu_logical_map[i] = 1;
|
||
|
+ if (i != boot_cpu) {
|
||
|
+ __cpu_number_map[i] = cpu;
|
||
|
+ __cpu_logical_map[cpu] = i;
|
||
|
+ cpu++;
|
||
|
+ }
|
||
|
set_cpu_possible(i, 1);
|
||
|
set_cpu_present(i, 1);
|
||
|
}
|
||
|
@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu
|
||
|
bmips_send_ipi_single(cpu, 0);
|
||
|
else {
|
||
|
#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
|
||
|
- set_c0_brcm_cmt_ctrl(0x01);
|
||
|
+ /* Reset slave TP1 if booting from TP0 */
|
||
|
+ if (cpu_logical_map(cpu) == 0)
|
||
|
+ set_c0_brcm_cmt_ctrl(0x01);
|
||
|
#elif defined(CONFIG_CPU_BMIPS5000)
|
||
|
if (cpu & 0x01)
|
||
|
write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
|