Commit cba3b643039b9d38284a5fd5143558622b9b64d9
Committed by
John Crispin
1 parent
37a7059bc4
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
MIPS: Netlogic: Fix for quad-XLP boot
On multi-chip boards, the first core on slave SoCs may take much more time to wakeup. Add code to wait for the core to come up before proceeding with the rest of the boot up. Update xlp_wakeup_core to also skip the boot node and the boot CPU initialization which is already complete. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Patchwork: http://patchwork.linux-mips.org/patch/4783/ Signed-off-by: John Crispin <blogic@openwrt.org>
Showing 1 changed file with 25 additions and 10 deletions Side-by-side Diff
arch/mips/netlogic/xlp/wakeup.c
... | ... | @@ -51,7 +51,7 @@ |
51 | 51 | #include <asm/netlogic/xlp-hal/xlp.h> |
52 | 52 | #include <asm/netlogic/xlp-hal/sys.h> |
53 | 53 | |
54 | -static int xlp_wakeup_core(uint64_t sysbase, int core) | |
54 | +static int xlp_wakeup_core(uint64_t sysbase, int node, int core) | |
55 | 55 | { |
56 | 56 | uint32_t coremask, value; |
57 | 57 | int count; |
58 | 58 | |
59 | 59 | |
60 | 60 | |
61 | 61 | |
62 | 62 | |
63 | 63 | |
... | ... | @@ -82,36 +82,51 @@ |
82 | 82 | struct nlm_soc_info *nodep; |
83 | 83 | uint64_t syspcibase; |
84 | 84 | uint32_t syscoremask; |
85 | - int core, n, cpu; | |
85 | + int core, n, cpu, count, val; | |
86 | 86 | |
87 | 87 | for (n = 0; n < NLM_NR_NODES; n++) { |
88 | 88 | syspcibase = nlm_get_sys_pcibase(n); |
89 | 89 | if (nlm_read_reg(syspcibase, 0) == 0xffffffff) |
90 | 90 | break; |
91 | 91 | |
92 | - /* read cores in reset from SYS and account for boot cpu */ | |
93 | - nlm_node_init(n); | |
92 | + /* read cores in reset from SYS */ | |
93 | + if (n != 0) | |
94 | + nlm_node_init(n); | |
94 | 95 | nodep = nlm_get_node(n); |
95 | 96 | syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); |
96 | - if (n == 0) | |
97 | + /* The boot cpu */ | |
98 | + if (n == 0) { | |
97 | 99 | syscoremask |= 1; |
100 | + nodep->coremask = 1; | |
101 | + } | |
98 | 102 | |
99 | 103 | for (core = 0; core < NLM_CORES_PER_NODE; core++) { |
104 | + /* we will be on node 0 core 0 */ | |
105 | + if (n == 0 && core == 0) | |
106 | + continue; | |
107 | + | |
100 | 108 | /* see if the core exists */ |
101 | 109 | if ((syscoremask & (1 << core)) == 0) |
102 | 110 | continue; |
103 | 111 | |
104 | - /* see if at least the first thread is enabled */ | |
112 | + /* see if at least the first hw thread is enabled */ | |
105 | 113 | cpu = (n * NLM_CORES_PER_NODE + core) |
106 | 114 | * NLM_THREADS_PER_CORE; |
107 | 115 | if (!cpumask_test_cpu(cpu, wakeup_mask)) |
108 | 116 | continue; |
109 | 117 | |
110 | 118 | /* wake up the core */ |
111 | - if (xlp_wakeup_core(nodep->sysbase, core)) | |
112 | - nodep->coremask |= 1u << core; | |
113 | - else | |
114 | - pr_err("Failed to enable core %d\n", core); | |
119 | + if (!xlp_wakeup_core(nodep->sysbase, n, core)) | |
120 | + continue; | |
121 | + | |
122 | + /* core is up */ | |
123 | + nodep->coremask |= 1u << core; | |
124 | + | |
125 | + /* spin until the first hw thread sets its ready */ | |
126 | + count = 0x20000000; | |
127 | + do { | |
128 | + val = *(volatile int *)&nlm_cpu_ready[cpu]; | |
129 | + } while (val == 0 && --count > 0); | |
115 | 130 | } |
116 | 131 | } |
117 | 132 | } |