Subject: [PATCH 2/2] MIPS: BMIPS: fix slave CPU booting when physical CPU is not 0

From: "Florian Fainelli" <[email-masked]>
Date: Wed, 24 Jul 2013 17:12:11 +0100

From: Florian Fainelli <[email-masked]>

The current BMIPS SMP code assumes that the slave CPU is physical and
logical CPU 1, but on some systems such as BCM3368, the slave CPU is
physical CPU0. Fix the code to read the physical CPU (thread ID) we are
running this code on, and adjust the relocation vector address based on
it. This allows bringing up the second CPU on BCM3368 for instance.

Signed-off-by: Florian Fainelli <[email-masked]>
---
 arch/mips/kernel/bmips_vec.S |  6 +++++-
 arch/mips/kernel/smp-bmips.c | 10 ++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S
index f739aed..bd79c4f 100644
--- a/arch/mips/kernel/bmips_vec.S
+++ b/arch/mips/kernel/bmips_vec.S
@@ -54,7 +54,11 @@ LEAF(bmips_smp_movevec)
 	/* set up CPU1 CBR; move BASE to 0xa000_0000 */
 	li	k0, 0xff400000
 	mtc0	k0, $22, 6
-	li	k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_1
+	/* set up relocation vector address based on thread ID */
+	mfc0	k1, $22, 3
+	srl	k1, 16
+	andi	k1, 0x8000
+	or	k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_0
 	or	k0, k1
 	li	k1, 0xa0080000
 	sw	k1, 0(k0)
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 89417c9..159abc8 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -196,9 +196,15 @@ static void bmips_init_secondary(void)
 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
 	void __iomem *cbr = BMIPS_GET_CBR();
 	unsigned long old_vec;
+	unsigned long relo_vector;
+	int boot_cpu;
 
-	old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
-	__raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+	boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
+	relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 :
+			  BMIPS_RELO_VECTOR_CONTROL_1;
+
+	old_vec = __raw_readl(cbr + relo_vector);
+	__raw_writel(old_vec & ~0x20000000, cbr + relo_vector);
 
 	clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
 #elif defined(CONFIG_CPU_BMIPS5000)
-- 
1.8.1.2

---

From: "Florian Fainelli" <[email-masked]>
Date: Wed, 24 Jul 2013 17:12:10 +0100

Commit 4df715aa ("MIPS: BMIPS: support booting from physical CPU other
than 0") changed the interupt routing when we are booting from physical
CPU 0, but the settings are actually correct if we are booting from
physical CPU 0 or CPU 1. Revert that specific change.

Signed-off-by: Florian Fainelli <[email-masked]>
---
 arch/mips/kernel/smp-bmips.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index c0bb4d5..89417c9 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -79,15 +79,9 @@ static void __init bmips_smp_setup(void)
 	 * 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.
 	 */
-	if (boot_cpu == 0)
-		change_c0_brcm_cmt_intr(0xf8018000,
+	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;
-- 
1.8.1.2

---

From: "Florian Fainelli" <[email-masked]>
Date: Wed, 24 Jul 2013 17:12:09 +0100

Ralf,

Here are two more BMIPS SMP fixes targetted at 3.11-rcX, thanks!

Florian Fainelli (2):
  MIPS: BMIPS: do not change interrupt routing depending on boot CPU
  MIPS: BMIPS: fix slave CPU booting when physical CPU is not 0

 arch/mips/kernel/bmips_vec.S |  6 +++++-
 arch/mips/kernel/smp-bmips.c | 18 +++++++++---------
 2 files changed, 14 insertions(+), 10 deletions(-)

-- 
1.8.1.2