aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayachandran C <jchandra@broadcom.com>2013-12-21 06:22:23 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-24 16:39:48 -0500
commit861c056953dc4354414881a5e1d382297ef4ea53 (patch)
tree9bfdf545e1335f0dbf41bfd081bfebb72f759460
parentd150cef4e8cc723d90226e503ef6aff2ca9fc57c (diff)
MIPS: Netlogic: SYS block updates of XLP9XX
Add the SYS block registers for XLP9XX, most of them have changed. The wakeup sequence has been updated to set the coherent mode from the main thread rather than the woken up thread. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6280/
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/sys.h18
-rw-r--r--arch/mips/netlogic/common/reset.S8
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c5
-rw-r--r--arch/mips/netlogic/xlp/setup.c5
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c74
5 files changed, 84 insertions, 26 deletions
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
index fcf2833c16ca..d9b107ffca93 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/sys.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
@@ -147,13 +147,29 @@
147#define SYS_SYS_PLL_MEM_REQ 0x2a3 147#define SYS_SYS_PLL_MEM_REQ 0x2a3
148#define SYS_PLL_MEM_STAT 0x2a4 148#define SYS_PLL_MEM_STAT 0x2a4
149 149
150/* Registers changed on 9XX */
151#define SYS_9XX_POWER_ON_RESET_CFG 0x00
152#define SYS_9XX_CHIP_RESET 0x01
153#define SYS_9XX_CPU_RESET 0x02
154#define SYS_9XX_CPU_NONCOHERENT_MODE 0x03
155
156/* XLP 9XX fuse block registers */
157#define FUSE_9XX_DEVCFG6 0xc6
158
150#ifndef __ASSEMBLY__ 159#ifndef __ASSEMBLY__
151 160
152#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r) 161#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
153#define nlm_write_sys_reg(b, r, v) nlm_write_reg(b, r, v) 162#define nlm_write_sys_reg(b, r, v) nlm_write_reg(b, r, v)
154#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node)) 163#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(cpu_is_xlp9xx() ? \
164 XLP9XX_IO_SYS_OFFSET(node) : XLP_IO_SYS_OFFSET(node))
155#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ) 165#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
156 166
167/* XLP9XX fuse block */
168#define nlm_get_fuse_pcibase(node) \
169 nlm_pcicfg_base(XLP9XX_IO_FUSE_OFFSET(node))
170#define nlm_get_fuse_regbase(node) \
171 (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
172
157unsigned int nlm_get_pic_frequency(int node); 173unsigned int nlm_get_pic_frequency(int node);
158#endif 174#endif
159#endif 175#endif
diff --git a/arch/mips/netlogic/common/reset.S b/arch/mips/netlogic/common/reset.S
index 57eb7a141fbf..dfbf94d4df22 100644
--- a/arch/mips/netlogic/common/reset.S
+++ b/arch/mips/netlogic/common/reset.S
@@ -159,6 +159,13 @@ FEXPORT(nlm_reset_entry)
159 nop 159 nop
160 160
1611: /* Entry point on core wakeup */ 1611: /* Entry point on core wakeup */
162 mfc0 t0, CP0_EBASE, 0 /* processor ID */
163 andi t0, 0xff00
164 li t1, 0x1500 /* XLP 9xx */
165 beq t0, t1, 2f /* does not need to set coherent */
166 nop
167
168 /* set bit in SYS coherent register for the core */
162 mfc0 t0, CP0_EBASE, 1 169 mfc0 t0, CP0_EBASE, 1
163 mfc0 t1, CP0_EBASE, 1 170 mfc0 t1, CP0_EBASE, 1
164 srl t1, 5 171 srl t1, 5
@@ -180,6 +187,7 @@ FEXPORT(nlm_reset_entry)
180 lw t1, 0(t2) 187 lw t1, 0(t2)
181 sync 188 sync
182 189
1902:
183 /* Configure LSU on Non-0 Cores. */ 191 /* Configure LSU on Non-0 Cores. */
184 xlp_config_lsu 192 xlp_config_lsu
185 /* FALL THROUGH */ 193 /* FALL THROUGH */
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 2d31cf1137fb..61f325d06e95 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -174,7 +174,10 @@ unsigned int nlm_get_core_frequency(int node, int core)
174 uint64_t num, sysbase; 174 uint64_t num, sysbase;
175 175
176 sysbase = nlm_get_node(node)->sysbase; 176 sysbase = nlm_get_node(node)->sysbase;
177 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 177 if (cpu_is_xlp9xx())
178 rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG);
179 else
180 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
178 if (cpu_is_xlpii()) { 181 if (cpu_is_xlpii()) {
179 num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26)); 182 num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
180 denom = 3; 183 denom = 3;
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index e92adec8a63b..310d88a82abe 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -56,7 +56,10 @@ static void nlm_linux_exit(void)
56{ 56{
57 uint64_t sysbase = nlm_get_node(0)->sysbase; 57 uint64_t sysbase = nlm_get_node(0)->sysbase;
58 58
59 nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1); 59 if (cpu_is_xlp9xx())
60 nlm_write_sys_reg(sysbase, SYS_9XX_CHIP_RESET, 1);
61 else
62 nlm_write_sys_reg(sysbase, SYS_CHIP_RESET, 1);
60 for ( ; ; ) 63 for ( ; ; )
61 cpu_wait(); 64 cpu_wait();
62} 65}
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
index f11035b1ad11..a5d6647e5fe8 100644
--- a/arch/mips/netlogic/xlp/wakeup.c
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -54,7 +54,7 @@
54static int xlp_wakeup_core(uint64_t sysbase, int node, 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, resetreg;
58 58
59 coremask = (1 << core); 59 coremask = (1 << core);
60 60
@@ -65,12 +65,24 @@ static int xlp_wakeup_core(uint64_t sysbase, int node, int core)
65 nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value); 65 nlm_write_sys_reg(sysbase, SYS_CORE_DFS_DIS_CTRL, value);
66 } 66 }
67 67
68 /* On 9XX, mark coherent first */
69 if (cpu_is_xlp9xx()) {
70 value = nlm_read_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE);
71 value &= ~coremask;
72 nlm_write_sys_reg(sysbase, SYS_9XX_CPU_NONCOHERENT_MODE, value);
73 }
74
68 /* Remove CPU Reset */ 75 /* Remove CPU Reset */
69 value = nlm_read_sys_reg(sysbase, SYS_CPU_RESET); 76 resetreg = cpu_is_xlp9xx() ? SYS_9XX_CPU_RESET : SYS_CPU_RESET;
77 value = nlm_read_sys_reg(sysbase, resetreg);
70 value &= ~coremask; 78 value &= ~coremask;
71 nlm_write_sys_reg(sysbase, SYS_CPU_RESET, value); 79 nlm_write_sys_reg(sysbase, resetreg, value);
80
81 /* We are done on 9XX */
82 if (cpu_is_xlp9xx())
83 return 1;
72 84
73 /* Poll for CPU to mark itself coherent */ 85 /* Poll for CPU to mark itself coherent on other type of XLP */
74 count = 100000; 86 count = 100000;
75 do { 87 do {
76 value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE); 88 value = nlm_read_sys_reg(sysbase, SYS_CPU_NONCOHERENT_MODE);
@@ -98,33 +110,48 @@ static int wait_for_cpus(int cpu, int bootcpu)
98static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask) 110static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
99{ 111{
100 struct nlm_soc_info *nodep; 112 struct nlm_soc_info *nodep;
101 uint64_t syspcibase; 113 uint64_t syspcibase, fusebase;
102 uint32_t syscoremask, mask, fusemask; 114 uint32_t syscoremask, mask, fusemask;
103 int core, n, cpu; 115 int core, n, cpu;
104 116
105 for (n = 0; n < NLM_NR_NODES; n++) { 117 for (n = 0; n < NLM_NR_NODES; n++) {
106 syspcibase = nlm_get_sys_pcibase(n); 118 if (n != 0) {
107 if (nlm_read_reg(syspcibase, 0) == 0xffffffff) 119 /* check if node exists and is online */
108 break; 120 if (cpu_is_xlp9xx()) {
121 int b = xlp9xx_get_socbus(n);
122 pr_info("Node %d SoC PCI bus %d.\n", n, b);
123 if (b == 0)
124 break;
125 } else {
126 syspcibase = nlm_get_sys_pcibase(n);
127 if (nlm_read_reg(syspcibase, 0) == 0xffffffff)
128 break;
129 }
130 nlm_node_init(n);
131 }
109 132
110 /* read cores in reset from SYS */ 133 /* read cores in reset from SYS */
111 if (n != 0)
112 nlm_node_init(n);
113 nodep = nlm_get_node(n); 134 nodep = nlm_get_node(n);
114 135
115 fusemask = nlm_read_sys_reg(nodep->sysbase, 136 if (cpu_is_xlp9xx()) {
116 SYS_EFUSE_DEVICE_CFG_STATUS0); 137 fusebase = nlm_get_fuse_regbase(n);
117 switch (read_c0_prid() & 0xff00) { 138 fusemask = nlm_read_reg(fusebase, FUSE_9XX_DEVCFG6);
118 case PRID_IMP_NETLOGIC_XLP3XX: 139 mask = 0xfffff;
119 mask = 0xf; 140 } else {
120 break; 141 fusemask = nlm_read_sys_reg(nodep->sysbase,
121 case PRID_IMP_NETLOGIC_XLP2XX: 142 SYS_EFUSE_DEVICE_CFG_STATUS0);
122 mask = 0x3; 143 switch (read_c0_prid() & 0xff00) {
123 break; 144 case PRID_IMP_NETLOGIC_XLP3XX:
124 case PRID_IMP_NETLOGIC_XLP8XX: 145 mask = 0xf;
125 default: 146 break;
126 mask = 0xff; 147 case PRID_IMP_NETLOGIC_XLP2XX:
127 break; 148 mask = 0x3;
149 break;
150 case PRID_IMP_NETLOGIC_XLP8XX:
151 default:
152 mask = 0xff;
153 break;
154 }
128 } 155 }
129 156
130 /* 157 /*
@@ -137,6 +164,7 @@ static void xlp_enable_secondary_cores(const cpumask_t *wakeup_mask)
137 if (n == 0) 164 if (n == 0)
138 nodep->coremask = 1; 165 nodep->coremask = 1;
139 166
167 pr_info("Node %d - SYS/FUSE coremask %x\n", n, syscoremask);
140 for (core = 0; core < NLM_CORES_PER_NODE; core++) { 168 for (core = 0; core < NLM_CORES_PER_NODE; core++) {
141 /* we will be on node 0 core 0 */ 169 /* we will be on node 0 core 0 */
142 if (n == 0 && core == 0) 170 if (n == 0 && core == 0)