7d0506f5e8703876fba75f30a6435431d2e5880d
[openwrt/svn-archive/archive.git] / target / linux / brcm63xx / patches-3.9 / 042-MIPS-BMIPS-support-booting-from-physical-CPU-other-t.patch
1 From 672d6bea85c7c9c63c086a9423e6d4e5fc286152 Mon Sep 17 00:00:00 2001
2 From: Florian Fainelli <florian@openwrt.org>
3 Date: Wed, 26 Jun 2013 18:11:56 +0000
4 Subject: [PATCH] MIPS: BMIPS: support booting from physical CPU other than 0
5
6 BMIPS43xx CPUs have two hardware threads, and on some SoCs such as 3368,
7 the bootloader has configured the system to boot from TP1 instead of the
8 more usual TP0. Create the physical to logical CPU mapping to cope with
9 that, do not remap the software interrupts to be cross CPUs such that we
10 do not have to do use the logical CPU mapping further down the code, and
11 finally, reset the slave TP1 only if booted from TP0.
12
13 Signed-off-by: Jonas Gorski <jogo@openwrt.org>
14 Signed-off-by: Florian Fainelli <florian@openwrt.org>
15 Cc: linux-mips@linux-mips.org
16 Cc: blogic@openwrt.org
17 Cc: cernekee@gmail.com
18 Patchwork: https://patchwork.linux-mips.org/patch/5553/
19 Patchwork: https://patchwork.linux-mips.org/patch/5556/
20 Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
21 ---
22 arch/mips/kernel/smp-bmips.c | 29 +++++++++++++++++++++++------
23 1 file changed, 23 insertions(+), 6 deletions(-)
24
25 --- a/arch/mips/kernel/smp-bmips.c
26 +++ b/arch/mips/kernel/smp-bmips.c
27 @@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(i
28
29 static void __init bmips_smp_setup(void)
30 {
31 - int i;
32 + int i, cpu = 1, boot_cpu = 0;
33
34 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
35 /* arbitration priority */
36 @@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void)
37 /* NBK and weak order flags */
38 set_c0_brcm_config_0(0x30000);
39
40 + /* Find out if we are running on TP0 or TP1 */
41 + boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
42 +
43 /*
44 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
45 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
46 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
47 + *
48 + * If booting from TP1, leave the existing CMT interrupt routing
49 + * such that TP0 responds to SW1 and TP1 responds to SW0.
50 */
51 - change_c0_brcm_cmt_intr(0xf8018000,
52 - (0x02 << 27) | (0x03 << 15));
53 + if (boot_cpu == 0)
54 + change_c0_brcm_cmt_intr(0xf8018000,
55 + (0x02 << 27) | (0x03 << 15));
56 + else
57 + change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
58
59 /* single core, 2 threads (2 pipelines) */
60 max_cpus = 2;
61 @@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void)
62 if (!board_ebase_setup)
63 board_ebase_setup = &bmips_ebase_setup;
64
65 + __cpu_number_map[boot_cpu] = 0;
66 + __cpu_logical_map[0] = boot_cpu;
67 +
68 for (i = 0; i < max_cpus; i++) {
69 - __cpu_number_map[i] = 1;
70 - __cpu_logical_map[i] = 1;
71 + if (i != boot_cpu) {
72 + __cpu_number_map[i] = cpu;
73 + __cpu_logical_map[cpu] = i;
74 + cpu++;
75 + }
76 set_cpu_possible(i, 1);
77 set_cpu_present(i, 1);
78 }
79 @@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu
80 bmips_send_ipi_single(cpu, 0);
81 else {
82 #if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
83 - set_c0_brcm_cmt_ctrl(0x01);
84 + /* Reset slave TP1 if booting from TP0 */
85 + if (cpu_logical_map(cpu) == 0)
86 + set_c0_brcm_cmt_ctrl(0x01);
87 #elif defined(CONFIG_CPU_BMIPS5000)
88 if (cpu & 0x01)
89 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));