aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorFlorian Fainelli <florian@openwrt.org>2013-06-26 14:11:56 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-07-01 09:10:57 -0400
commit4df715aaf566110bedb3751ed235a3bacdebbdde (patch)
treeda36cde86ad23e4bab0077e9528959a2bc93f293 /arch/mips
parent3ddc14add5e6341cf8ef4058c34c67ba7fd15317 (diff)
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>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/kernel/smp-bmips.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
index 8e393b8443f7..aea6c0885838 100644
--- a/arch/mips/kernel/smp-bmips.c
+++ b/arch/mips/kernel/smp-bmips.c
@@ -63,7 +63,7 @@ static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
63 63
64static void __init bmips_smp_setup(void) 64static void __init bmips_smp_setup(void)
65{ 65{
66 int i; 66 int i, cpu = 1, boot_cpu = 0;
67 67
68#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) 68#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
69 /* arbitration priority */ 69 /* arbitration priority */
@@ -72,13 +72,22 @@ static void __init bmips_smp_setup(void)
72 /* NBK and weak order flags */ 72 /* NBK and weak order flags */
73 set_c0_brcm_config_0(0x30000); 73 set_c0_brcm_config_0(0x30000);
74 74
75 /* Find out if we are running on TP0 or TP1 */
76 boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
77
75 /* 78 /*
76 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread 79 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
77 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output 80 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
78 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output 81 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
82 *
83 * If booting from TP1, leave the existing CMT interrupt routing
84 * such that TP0 responds to SW1 and TP1 responds to SW0.
79 */ 85 */
80 change_c0_brcm_cmt_intr(0xf8018000, 86 if (boot_cpu == 0)
81 (0x02 << 27) | (0x03 << 15)); 87 change_c0_brcm_cmt_intr(0xf8018000,
88 (0x02 << 27) | (0x03 << 15));
89 else
90 change_c0_brcm_cmt_intr(0xf8018000, (0x1d << 27));
82 91
83 /* single core, 2 threads (2 pipelines) */ 92 /* single core, 2 threads (2 pipelines) */
84 max_cpus = 2; 93 max_cpus = 2;
@@ -106,9 +115,15 @@ static void __init bmips_smp_setup(void)
106 if (!board_ebase_setup) 115 if (!board_ebase_setup)
107 board_ebase_setup = &bmips_ebase_setup; 116 board_ebase_setup = &bmips_ebase_setup;
108 117
118 __cpu_number_map[boot_cpu] = 0;
119 __cpu_logical_map[0] = boot_cpu;
120
109 for (i = 0; i < max_cpus; i++) { 121 for (i = 0; i < max_cpus; i++) {
110 __cpu_number_map[i] = 1; 122 if (i != boot_cpu) {
111 __cpu_logical_map[i] = 1; 123 __cpu_number_map[i] = cpu;
124 __cpu_logical_map[cpu] = i;
125 cpu++;
126 }
112 set_cpu_possible(i, 1); 127 set_cpu_possible(i, 1);
113 set_cpu_present(i, 1); 128 set_cpu_present(i, 1);
114 } 129 }
@@ -157,7 +172,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle)
157 bmips_send_ipi_single(cpu, 0); 172 bmips_send_ipi_single(cpu, 0);
158 else { 173 else {
159#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380) 174#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
160 set_c0_brcm_cmt_ctrl(0x01); 175 /* Reset slave TP1 if booting from TP0 */
176 if (cpu_logical_map(cpu) == 0)
177 set_c0_brcm_cmt_ctrl(0x01);
161#elif defined(CONFIG_CPU_BMIPS5000) 178#elif defined(CONFIG_CPU_BMIPS5000)
162 if (cpu & 0x01) 179 if (cpu & 0x01)
163 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); 180 write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));