aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx/prom.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/bcm63xx/prom.c')
-rw-r--r--arch/mips/bcm63xx/prom.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index fd698087fbfd..8ac4e095e68e 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -8,7 +8,11 @@
8 8
9#include <linux/init.h> 9#include <linux/init.h>
10#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/smp.h>
11#include <asm/bootinfo.h> 12#include <asm/bootinfo.h>
13#include <asm/bmips.h>
14#include <asm/smp-ops.h>
15#include <asm/mipsregs.h>
12#include <bcm63xx_board.h> 16#include <bcm63xx_board.h>
13#include <bcm63xx_cpu.h> 17#include <bcm63xx_cpu.h>
14#include <bcm63xx_io.h> 18#include <bcm63xx_io.h>
@@ -26,7 +30,9 @@ void __init prom_init(void)
26 bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); 30 bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
27 31
28 /* disable all hardware blocks clock for now */ 32 /* disable all hardware blocks clock for now */
29 if (BCMCPU_IS_6328()) 33 if (BCMCPU_IS_3368())
34 mask = CKCTL_3368_ALL_SAFE_EN;
35 else if (BCMCPU_IS_6328())
30 mask = CKCTL_6328_ALL_SAFE_EN; 36 mask = CKCTL_6328_ALL_SAFE_EN;
31 else if (BCMCPU_IS_6338()) 37 else if (BCMCPU_IS_6338())
32 mask = CKCTL_6338_ALL_SAFE_EN; 38 mask = CKCTL_6338_ALL_SAFE_EN;
@@ -52,6 +58,47 @@ void __init prom_init(void)
52 58
53 /* do low level board init */ 59 /* do low level board init */
54 board_prom_init(); 60 board_prom_init();
61
62 if (IS_ENABLED(CONFIG_CPU_BMIPS4350) && IS_ENABLED(CONFIG_SMP)) {
63 /* set up SMP */
64 register_smp_ops(&bmips_smp_ops);
65
66 /*
67 * BCM6328 might not have its second CPU enabled, while BCM6358
68 * needs special handling for its shared TLB, so disable SMP
69 * for now.
70 */
71 if (BCMCPU_IS_6328()) {
72 reg = bcm_readl(BCM_6328_OTP_BASE +
73 OTP_USER_BITS_6328_REG(3));
74
75 if (reg & OTP_6328_REG3_TP1_DISABLED)
76 bmips_smp_enabled = 0;
77 } else if (BCMCPU_IS_6358()) {
78 bmips_smp_enabled = 0;
79 }
80
81 if (!bmips_smp_enabled)
82 return;
83
84 /*
85 * The bootloader has set up the CPU1 reset vector at
86 * 0xa000_0200.
87 * This conflicts with the special interrupt vector (IV).
88 * The bootloader has also set up CPU1 to respond to the wrong
89 * IPI interrupt.
90 * Here we will start up CPU1 in the background and ask it to
91 * reconfigure itself then go back to sleep.
92 */
93 memcpy((void *)0xa0000200, &bmips_smp_movevec, 0x20);
94 __sync();
95 set_c0_cause(C_SW0);
96 cpumask_set_cpu(1, &bmips_booted_mask);
97
98 /*
99 * FIXME: we really should have some sort of hazard barrier here
100 */
101 }
55} 102}
56 103
57void __init prom_free_prom_memory(void) 104void __init prom_free_prom_memory(void)