MIPS: bugfix: missed cache flush of TLB refill handler
[cascardo/linux.git] / arch / mips / bcm63xx / cpu.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7  * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/cpu.h>
13 #include <asm/cpu.h>
14 #include <asm/cpu-info.h>
15 #include <asm/mipsregs.h>
16 #include <bcm63xx_cpu.h>
17 #include <bcm63xx_regs.h>
18 #include <bcm63xx_io.h>
19 #include <bcm63xx_irq.h>
20
21 const unsigned long *bcm63xx_regs_base;
22 EXPORT_SYMBOL(bcm63xx_regs_base);
23
24 const int *bcm63xx_irqs;
25 EXPORT_SYMBOL(bcm63xx_irqs);
26
27 static u16 bcm63xx_cpu_id;
28 static u8 bcm63xx_cpu_rev;
29 static unsigned int bcm63xx_cpu_freq;
30 static unsigned int bcm63xx_memory_size;
31
32 static const unsigned long bcm3368_regs_base[] = {
33         __GEN_CPU_REGS_TABLE(3368)
34 };
35
36 static const int bcm3368_irqs[] = {
37         __GEN_CPU_IRQ_TABLE(3368)
38 };
39
40 static const unsigned long bcm6328_regs_base[] = {
41         __GEN_CPU_REGS_TABLE(6328)
42 };
43
44 static const int bcm6328_irqs[] = {
45         __GEN_CPU_IRQ_TABLE(6328)
46 };
47
48 static const unsigned long bcm6338_regs_base[] = {
49         __GEN_CPU_REGS_TABLE(6338)
50 };
51
52 static const int bcm6338_irqs[] = {
53         __GEN_CPU_IRQ_TABLE(6338)
54 };
55
56 static const unsigned long bcm6345_regs_base[] = {
57         __GEN_CPU_REGS_TABLE(6345)
58 };
59
60 static const int bcm6345_irqs[] = {
61         __GEN_CPU_IRQ_TABLE(6345)
62 };
63
64 static const unsigned long bcm6348_regs_base[] = {
65         __GEN_CPU_REGS_TABLE(6348)
66 };
67
68 static const int bcm6348_irqs[] = {
69         __GEN_CPU_IRQ_TABLE(6348)
70
71 };
72
73 static const unsigned long bcm6358_regs_base[] = {
74         __GEN_CPU_REGS_TABLE(6358)
75 };
76
77 static const int bcm6358_irqs[] = {
78         __GEN_CPU_IRQ_TABLE(6358)
79
80 };
81
82 static const unsigned long bcm6362_regs_base[] = {
83         __GEN_CPU_REGS_TABLE(6362)
84 };
85
86 static const int bcm6362_irqs[] = {
87         __GEN_CPU_IRQ_TABLE(6362)
88
89 };
90
91 static const unsigned long bcm6368_regs_base[] = {
92         __GEN_CPU_REGS_TABLE(6368)
93 };
94
95 static const int bcm6368_irqs[] = {
96         __GEN_CPU_IRQ_TABLE(6368)
97
98 };
99
100 u16 __bcm63xx_get_cpu_id(void)
101 {
102         return bcm63xx_cpu_id;
103 }
104
105 EXPORT_SYMBOL(__bcm63xx_get_cpu_id);
106
107 u8 bcm63xx_get_cpu_rev(void)
108 {
109         return bcm63xx_cpu_rev;
110 }
111
112 EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
113
114 unsigned int bcm63xx_get_cpu_freq(void)
115 {
116         return bcm63xx_cpu_freq;
117 }
118
119 unsigned int bcm63xx_get_memory_size(void)
120 {
121         return bcm63xx_memory_size;
122 }
123
124 static unsigned int detect_cpu_clock(void)
125 {
126         u16 cpu_id = bcm63xx_get_cpu_id();
127
128         switch (cpu_id) {
129         case BCM3368_CPU_ID:
130                 return 300000000;
131
132         case BCM6328_CPU_ID:
133         {
134                 unsigned int tmp, mips_pll_fcvo;
135
136                 tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
137                 mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
138                                 >> STRAPBUS_6328_FCVO_SHIFT;
139
140                 switch (mips_pll_fcvo) {
141                 case 0x12:
142                 case 0x14:
143                 case 0x19:
144                         return 160000000;
145                 case 0x1c:
146                         return 192000000;
147                 case 0x13:
148                 case 0x15:
149                         return 200000000;
150                 case 0x1a:
151                         return 384000000;
152                 case 0x16:
153                         return 400000000;
154                 default:
155                         return 320000000;
156                 }
157
158         }
159         case BCM6338_CPU_ID:
160                 /* BCM6338 has a fixed 240 Mhz frequency */
161                 return 240000000;
162
163         case BCM6345_CPU_ID:
164                 /* BCM6345 has a fixed 140Mhz frequency */
165                 return 140000000;
166
167         case BCM6348_CPU_ID:
168         {
169                 unsigned int tmp, n1, n2, m1;
170
171                 /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
172                 tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
173                 n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
174                 n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
175                 m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
176                 n1 += 1;
177                 n2 += 2;
178                 m1 += 1;
179                 return (16 * 1000000 * n1 * n2) / m1;
180         }
181
182         case BCM6358_CPU_ID:
183         {
184                 unsigned int tmp, n1, n2, m1;
185
186                 /* 16MHz * N1 * N2 / M1_CPU */
187                 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
188                 n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
189                 n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
190                 m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
191                 return (16 * 1000000 * n1 * n2) / m1;
192         }
193
194         case BCM6362_CPU_ID:
195         {
196                 unsigned int tmp, mips_pll_fcvo;
197
198                 tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
199                 mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK)
200                                 >> STRAPBUS_6362_FCVO_SHIFT;
201                 switch (mips_pll_fcvo) {
202                 case 0x03:
203                 case 0x0b:
204                 case 0x13:
205                 case 0x1b:
206                         return 240000000;
207                 case 0x04:
208                 case 0x0c:
209                 case 0x14:
210                 case 0x1c:
211                         return 160000000;
212                 case 0x05:
213                 case 0x0e:
214                 case 0x16:
215                 case 0x1e:
216                 case 0x1f:
217                         return 400000000;
218                 case 0x06:
219                         return 440000000;
220                 case 0x07:
221                 case 0x17:
222                         return 384000000;
223                 case 0x15:
224                 case 0x1d:
225                         return 200000000;
226                 default:
227                         return 320000000;
228                 }
229         }
230         case BCM6368_CPU_ID:
231         {
232                 unsigned int tmp, p1, p2, ndiv, m1;
233
234                 /* (64MHz / P1) * P2 * NDIV / M1_CPU */
235                 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
236
237                 p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
238                         DMIPSPLLCFG_6368_P1_SHIFT;
239
240                 p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
241                         DMIPSPLLCFG_6368_P2_SHIFT;
242
243                 ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
244                         DMIPSPLLCFG_6368_NDIV_SHIFT;
245
246                 tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
247                 m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
248                         DMIPSPLLDIV_6368_MDIV_SHIFT;
249
250                 return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
251         }
252
253         default:
254                 panic("Failed to detect clock for CPU with id=%04X\n", cpu_id);
255         }
256 }
257
258 /*
259  * attempt to detect the amount of memory installed
260  */
261 static unsigned int detect_memory_size(void)
262 {
263         unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
264         u32 val;
265
266         if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
267                 return bcm_ddr_readl(DDR_CSEND_REG) << 24;
268
269         if (BCMCPU_IS_6345()) {
270                 val = bcm_sdram_readl(SDRAM_MBASE_REG);
271                 return (val * 8 * 1024 * 1024);
272         }
273
274         if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
275                 val = bcm_sdram_readl(SDRAM_CFG_REG);
276                 rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
277                 cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
278                 is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
279                 banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
280         }
281
282         if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
283                 val = bcm_memc_readl(MEMC_CFG_REG);
284                 rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
285                 cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
286                 is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
287                 banks = 2;
288         }
289
290         /* 0 => 11 address bits ... 2 => 13 address bits */
291         rows += 11;
292
293         /* 0 => 8 address bits ... 2 => 10 address bits */
294         cols += 8;
295
296         return 1 << (cols + rows + (is_32bits + 1) + banks);
297 }
298
299 void __init bcm63xx_cpu_init(void)
300 {
301         unsigned int tmp;
302         unsigned int cpu = smp_processor_id();
303         u32 chipid_reg;
304
305         /* soc registers location depends on cpu type */
306         chipid_reg = 0;
307
308         switch (current_cpu_type()) {
309         case CPU_BMIPS3300:
310                 if ((read_c0_prid() & PRID_IMP_MASK) != PRID_IMP_BMIPS3300_ALT)
311                         __cpu_name[cpu] = "Broadcom BCM6338";
312                 /* fall-through */
313         case CPU_BMIPS32:
314                 chipid_reg = BCM_6345_PERF_BASE;
315                 break;
316         case CPU_BMIPS4350:
317                 switch ((read_c0_prid() & PRID_REV_MASK)) {
318                 case 0x04:
319                         chipid_reg = BCM_3368_PERF_BASE;
320                         break;
321                 case 0x10:
322                         chipid_reg = BCM_6345_PERF_BASE;
323                         break;
324                 default:
325                         chipid_reg = BCM_6368_PERF_BASE;
326                         break;
327                 }
328                 break;
329         }
330
331         /*
332          * really early to panic, but delaying panic would not help since we
333          * will never get any working console
334          */
335         if (!chipid_reg)
336                 panic("unsupported Broadcom CPU");
337
338         /* read out CPU type */
339         tmp = bcm_readl(chipid_reg);
340         bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
341         bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
342
343         switch (bcm63xx_cpu_id) {
344         case BCM3368_CPU_ID:
345                 bcm63xx_regs_base = bcm3368_regs_base;
346                 bcm63xx_irqs = bcm3368_irqs;
347                 break;
348         case BCM6328_CPU_ID:
349                 bcm63xx_regs_base = bcm6328_regs_base;
350                 bcm63xx_irqs = bcm6328_irqs;
351                 break;
352         case BCM6338_CPU_ID:
353                 bcm63xx_regs_base = bcm6338_regs_base;
354                 bcm63xx_irqs = bcm6338_irqs;
355                 break;
356         case BCM6345_CPU_ID:
357                 bcm63xx_regs_base = bcm6345_regs_base;
358                 bcm63xx_irqs = bcm6345_irqs;
359                 break;
360         case BCM6348_CPU_ID:
361                 bcm63xx_regs_base = bcm6348_regs_base;
362                 bcm63xx_irqs = bcm6348_irqs;
363                 break;
364         case BCM6358_CPU_ID:
365                 bcm63xx_regs_base = bcm6358_regs_base;
366                 bcm63xx_irqs = bcm6358_irqs;
367                 break;
368         case BCM6362_CPU_ID:
369                 bcm63xx_regs_base = bcm6362_regs_base;
370                 bcm63xx_irqs = bcm6362_irqs;
371                 break;
372         case BCM6368_CPU_ID:
373                 bcm63xx_regs_base = bcm6368_regs_base;
374                 bcm63xx_irqs = bcm6368_irqs;
375                 break;
376         default:
377                 panic("unsupported broadcom CPU %x", bcm63xx_cpu_id);
378                 break;
379         }
380
381         bcm63xx_cpu_freq = detect_cpu_clock();
382         bcm63xx_memory_size = detect_memory_size();
383
384         printk(KERN_INFO "Detected Broadcom 0x%04x CPU revision %02x\n",
385                bcm63xx_cpu_id, bcm63xx_cpu_rev);
386         printk(KERN_INFO "CPU frequency is %u MHz\n",
387                bcm63xx_cpu_freq / 1000000);
388         printk(KERN_INFO "%uMB of RAM installed\n",
389                bcm63xx_memory_size >> 20);
390 }