diff options
Diffstat (limited to 'arch/mips/kernel/smp-bmips.c')
-rw-r--r-- | arch/mips/kernel/smp-bmips.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 8e393b8443f7..c0bb4d59076a 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 | ||
64 | static void __init bmips_smp_setup(void) | 64 | static 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) == 1) | ||
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)); |
@@ -381,7 +398,7 @@ struct plat_smp_ops bmips_smp_ops = { | |||
381 | * UP BMIPS systems as well. | 398 | * UP BMIPS systems as well. |
382 | ***********************************************************************/ | 399 | ***********************************************************************/ |
383 | 400 | ||
384 | static void __cpuinit bmips_wr_vec(unsigned long dst, char *start, char *end) | 401 | static void bmips_wr_vec(unsigned long dst, char *start, char *end) |
385 | { | 402 | { |
386 | memcpy((void *)dst, start, end - start); | 403 | memcpy((void *)dst, start, end - start); |
387 | dma_cache_wback((unsigned long)start, end - start); | 404 | dma_cache_wback((unsigned long)start, end - start); |
@@ -389,7 +406,7 @@ static void __cpuinit bmips_wr_vec(unsigned long dst, char *start, char *end) | |||
389 | instruction_hazard(); | 406 | instruction_hazard(); |
390 | } | 407 | } |
391 | 408 | ||
392 | static inline void __cpuinit bmips_nmi_handler_setup(void) | 409 | static inline void bmips_nmi_handler_setup(void) |
393 | { | 410 | { |
394 | bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec, | 411 | bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec, |
395 | &bmips_reset_nmi_vec_end); | 412 | &bmips_reset_nmi_vec_end); |
@@ -397,7 +414,7 @@ static inline void __cpuinit bmips_nmi_handler_setup(void) | |||
397 | &bmips_smp_int_vec_end); | 414 | &bmips_smp_int_vec_end); |
398 | } | 415 | } |
399 | 416 | ||
400 | void __cpuinit bmips_ebase_setup(void) | 417 | void bmips_ebase_setup(void) |
401 | { | 418 | { |
402 | unsigned long new_ebase = ebase; | 419 | unsigned long new_ebase = ebase; |
403 | void __iomem __maybe_unused *cbr; | 420 | void __iomem __maybe_unused *cbr; |