aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorJayachandran C <jchandra@broadcom.com>2013-01-14 10:12:01 -0500
committerJohn Crispin <blogic@openwrt.org>2013-02-16 18:15:22 -0500
commitcba3b643039b9d38284a5fd5143558622b9b64d9 (patch)
treec0b48f929d9819f4b2bec16bc3a0a480aa4b1799 /arch/mips
parent37a7059bc4228613867645be50120aff17a162a1 (diff)
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>
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index cb9010642ac3..abb3e08cc052 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -51,7 +51,7 @@
51#include <asm/netlogic/xlp-hal/xlp.h> 51#include <asm/netlogic/xlp-hal/xlp.h>
52#include <asm/netlogic/xlp-hal/sys.h> 52#include <asm/netlogic/xlp-hal/sys.h>
53 53
54static int xlp_wakeup_core(uint64_t sysbase, int core) 54static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
55{ 55{
56 uint32_t coremask, value; 56 uint32_t coremask, value;
57 int count; 57 int count;
@@ -82,36 +82,51 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
82 struct nlm_soc_info *nodep; 82 struct nlm_soc_info *nodep;
83 uint64_t syspcibase; 83 uint64_t syspcibase;
84 uint32_t syscoremask; 84 uint32_t syscoremask;
85 int core, n, cpu; 85 int core, n, cpu, count, val;
86 86
87 for (n = 0; n < NLM_NR_NODES; n++) { 87 for (n = 0; n < NLM_NR_NODES; n++) {
88 syspcibase = nlm_get_sys_pcibase(n); 88 syspcibase = nlm_get_sys_pcibase(n);
89 if (nlm_read_reg(syspcibase, 0) == 0xffffffff) 89 if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
90 break; 90 break;
91 91
92 /* read cores in reset from SYS and account for boot cpu */ 92 /* read cores in reset from SYS */
93 nlm_node_init(n); 93 if (n != 0)
94 nlm_node_init(n);
94 nodep = nlm_get_node(n); 95 nodep = nlm_get_node(n);
95 syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET); 96 syscoremask = nlm_read_sys_reg(nodep->sysbase, SYS_CPU_RESET);
96 if (n == 0) 97 /* The boot cpu */
98 if (n == 0) {
97 syscoremask |= 1; 99 syscoremask |= 1;
100 nodep->coremask = 1;
101 }
98 102
99 for (core = 0; core < NLM_CORES_PER_NODE; core++) { 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 /* see if the core exists */ 108 /* see if the core exists */
101 if ((syscoremask & (1 << core)) == 0) 109 if ((syscoremask & (1 << core)) == 0)
102 continue; 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 cpu = (n * NLM_CORES_PER_NODE + core) 113 cpu = (n * NLM_CORES_PER_NODE + core)
106 * NLM_THREADS_PER_CORE; 114 * NLM_THREADS_PER_CORE;
107 if (!cpumask_test_cpu(cpu, wakeup_mask)) 115 if (!cpumask_test_cpu(cpu, wakeup_mask))
108 continue; 116 continue;
109 117
110 /* wake up the core */ 118 /* wake up the core */
111 if (xlp_wakeup_core(nodep->sysbase, core)) 119 if (!xlp_wakeup_core(nodep->sysbase, n, core))
112 nodep->coremask |= 1u << core; 120 continue;
113 else 121
114 pr_err("Failed to enable core %d\n", core); 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}