aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/xlp/wakeup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/xlp/wakeup.c')
-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}