]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/mips/kernel/bmips_5xxx_init.S
Merge ath-next from ath.git
[mirror_ubuntu-artful-kernel.git] / arch / mips / kernel / bmips_5xxx_init.S
1
2 /*
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 2011-2012 by Broadcom Corporation
8 *
9 * Init for bmips 5000.
10 * Used to init second core in dual core 5000's.
11 */
12
13 #include <linux/init.h>
14
15 #include <asm/asm.h>
16 #include <asm/asmmacro.h>
17 #include <asm/cacheops.h>
18 #include <asm/regdef.h>
19 #include <asm/mipsregs.h>
20 #include <asm/stackframe.h>
21 #include <asm/addrspace.h>
22 #include <asm/hazards.h>
23 #include <asm/bmips.h>
24
25 #ifdef CONFIG_CPU_BMIPS5000
26
27
28 #define cacheop(kva, size, linesize, op) \
29 .set noreorder ; \
30 addu t1, kva, size ; \
31 subu t2, linesize, 1 ; \
32 not t2 ; \
33 and t0, kva, t2 ; \
34 addiu t1, t1, -1 ; \
35 and t1, t2 ; \
36 9: cache op, 0(t0) ; \
37 bne t0, t1, 9b ; \
38 addu t0, linesize ; \
39 .set reorder ;
40
41
42
43 #define IS_SHIFT 22
44 #define IL_SHIFT 19
45 #define IA_SHIFT 16
46 #define DS_SHIFT 13
47 #define DL_SHIFT 10
48 #define DA_SHIFT 7
49 #define IS_MASK 7
50 #define IL_MASK 7
51 #define IA_MASK 7
52 #define DS_MASK 7
53 #define DL_MASK 7
54 #define DA_MASK 7
55 #define ICE_MASK 0x80000000
56 #define DCE_MASK 0x40000000
57
58 #define CP0_BRCM_CONFIG0 $22, 0
59 #define CP0_BRCM_MODE $22, 1
60 #define CP0_CONFIG_K0_MASK 7
61
62 #define CP0_ICACHE_TAG_LO $28
63 #define CP0_ICACHE_DATA_LO $28, 1
64 #define CP0_DCACHE_TAG_LO $28, 2
65 #define CP0_D_SEC_CACHE_DATA_LO $28, 3
66 #define CP0_ICACHE_TAG_HI $29
67 #define CP0_ICACHE_DATA_HI $29, 1
68 #define CP0_DCACHE_TAG_HI $29, 2
69
70 #define CP0_BRCM_MODE_Luc_MASK (1 << 11)
71 #define CP0_BRCM_CONFIG0_CWF_MASK (1 << 20)
72 #define CP0_BRCM_CONFIG0_TSE_MASK (1 << 19)
73 #define CP0_BRCM_MODE_SET_MASK (1 << 7)
74 #define CP0_BRCM_MODE_ClkRATIO_MASK (7 << 4)
75 #define CP0_BRCM_MODE_BrPRED_MASK (3 << 24)
76 #define CP0_BRCM_MODE_BrPRED_SHIFT 24
77 #define CP0_BRCM_MODE_BrHIST_MASK (0x1f << 20)
78 #define CP0_BRCM_MODE_BrHIST_SHIFT 20
79
80 /* ZSC L2 Cache Register Access Register Definitions */
81 #define BRCM_ZSC_ALL_REGS_SELECT 0x7 << 24
82
83 #define BRCM_ZSC_CONFIG_REG 0 << 3
84 #define BRCM_ZSC_REQ_BUFFER_REG 2 << 3
85 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG0 4 << 3
86 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG1 6 << 3
87 #define BRCM_ZSC_RBUS_ADDR_MAPPING_REG2 8 << 3
88
89 #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG0 0xa << 3
90 #define BRCM_ZSC_SCB0_ADDR_MAPPING_REG1 0xc << 3
91
92 #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG0 0xe << 3
93 #define BRCM_ZSC_SCB1_ADDR_MAPPING_REG1 0x10 << 3
94
95 #define BRCM_ZSC_CONFIG_LMB1En 1 << (15)
96 #define BRCM_ZSC_CONFIG_LMB0En 1 << (14)
97
98 /* branch predition values */
99
100 #define BRCM_BrPRED_ALL_TAKEN (0x0)
101 #define BRCM_BrPRED_ALL_NOT_TAKEN (0x1)
102 #define BRCM_BrPRED_BHT_ENABLE (0x2)
103 #define BRCM_BrPRED_PREDICT_BACKWARD (0x3)
104
105
106
107 .align 2
108 /*
109 * Function: size_i_cache
110 * Arguments: None
111 * Returns: v0 = i cache size, v1 = I cache line size
112 * Description: compute the I-cache size and I-cache line size
113 * Trashes: v0, v1, a0, t0
114 *
115 * pseudo code:
116 *
117 */
118
119 LEAF(size_i_cache)
120 .set noreorder
121
122 mfc0 a0, CP0_CONFIG, 1
123 move t0, a0
124
125 /*
126 * Determine sets per way: IS
127 *
128 * This field contains the number of sets (i.e., indices) per way of
129 * the instruction cache:
130 * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
131 * vi) 0x5 - 0x7: Reserved.
132 */
133
134 srl a0, a0, IS_SHIFT
135 and a0, a0, IS_MASK
136
137 /* sets per way = (64<<IS) */
138
139 li v0, 0x40
140 sllv v0, v0, a0
141
142 /*
143 * Determine line size
144 *
145 * This field contains the line size of the instruction cache:
146 * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
147 * 0x5: 64 bytes, iv) the rest: Reserved.
148 */
149
150 move a0, t0
151
152 srl a0, a0, IL_SHIFT
153 and a0, a0, IL_MASK
154
155 beqz a0, no_i_cache
156 nop
157
158 /* line size = 2 ^ (IL+1) */
159
160 addi a0, a0, 1
161 li v1, 1
162 sll v1, v1, a0
163
164 /* v0 now have sets per way, multiply it by line size now
165 * that will give the set size
166 */
167
168 sll v0, v0, a0
169
170 /*
171 * Determine set associativity
172 *
173 * This field contains the set associativity of the instruction cache.
174 * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
175 * 4-way, v) 0x4 - 0x7: Reserved.
176 */
177
178 move a0, t0
179
180 srl a0, a0, IA_SHIFT
181 and a0, a0, IA_MASK
182 addi a0, a0, 0x1
183
184 /* v0 has the set size, multiply it by
185 * set associativiy, to get the cache size
186 */
187
188 multu v0, a0 /*multu is interlocked, so no need to insert nops */
189 mflo v0
190 b 1f
191 nop
192
193 no_i_cache:
194 move v0, zero
195 move v1, zero
196 1:
197 jr ra
198 nop
199 .set reorder
200
201 END(size_i_cache)
202
203 /*
204 * Function: size_d_cache
205 * Arguments: None
206 * Returns: v0 = d cache size, v1 = d cache line size
207 * Description: compute the D-cache size and D-cache line size.
208 * Trashes: v0, v1, a0, t0
209 *
210 */
211
212 LEAF(size_d_cache)
213 .set noreorder
214
215 mfc0 a0, CP0_CONFIG, 1
216 move t0, a0
217
218 /*
219 * Determine sets per way: IS
220 *
221 * This field contains the number of sets (i.e., indices) per way of
222 * the instruction cache:
223 * i) 0x0: 64, ii) 0x1: 128, iii) 0x2: 256, iv) 0x3: 512, v) 0x4: 1k
224 * vi) 0x5 - 0x7: Reserved.
225 */
226
227 srl a0, a0, DS_SHIFT
228 and a0, a0, DS_MASK
229
230 /* sets per way = (64<<IS) */
231
232 li v0, 0x40
233 sllv v0, v0, a0
234
235 /*
236 * Determine line size
237 *
238 * This field contains the line size of the instruction cache:
239 * i) 0x0: No I-cache present, i) 0x3: 16 bytes, ii) 0x4: 32 bytes, iii)
240 * 0x5: 64 bytes, iv) the rest: Reserved.
241 */
242 move a0, t0
243
244 srl a0, a0, DL_SHIFT
245 and a0, a0, DL_MASK
246
247 beqz a0, no_d_cache
248 nop
249
250 /* line size = 2 ^ (IL+1) */
251
252 addi a0, a0, 1
253 li v1, 1
254 sll v1, v1, a0
255
256 /* v0 now have sets per way, multiply it by line size now
257 * that will give the set size
258 */
259
260 sll v0, v0, a0
261
262 /* determine set associativity
263 *
264 * This field contains the set associativity of the instruction cache.
265 * i) 0x0: Direct mapped, ii) 0x1: 2-way, iii) 0x2: 3-way, iv) 0x3:
266 * 4-way, v) 0x4 - 0x7: Reserved.
267 */
268
269 move a0, t0
270
271 srl a0, a0, DA_SHIFT
272 and a0, a0, DA_MASK
273 addi a0, a0, 0x1
274
275 /* v0 has the set size, multiply it by
276 * set associativiy, to get the cache size
277 */
278
279 multu v0, a0 /*multu is interlocked, so no need to insert nops */
280 mflo v0
281
282 b 1f
283 nop
284
285 no_d_cache:
286 move v0, zero
287 move v1, zero
288 1:
289 jr ra
290 nop
291 .set reorder
292
293 END(size_d_cache)
294
295
296 /*
297 * Function: enable_ID
298 * Arguments: None
299 * Returns: None
300 * Description: Enable I and D caches, initialize I and D-caches, also set
301 * hardware delay for d-cache (TP0).
302 * Trashes: t0
303 *
304 */
305 .global enable_ID
306 .ent enable_ID
307 .set noreorder
308 enable_ID:
309 mfc0 t0, CP0_BRCM_CONFIG0
310 or t0, t0, (ICE_MASK | DCE_MASK)
311 mtc0 t0, CP0_BRCM_CONFIG0
312 jr ra
313 nop
314
315 .end enable_ID
316 .set reorder
317
318
319 /*
320 * Function: l1_init
321 * Arguments: None
322 * Returns: None
323 * Description: Enable I and D caches, and initialize I and D-caches
324 * Trashes: a0, v0, v1, t0, t1, t2, t8
325 *
326 */
327 .globl l1_init
328 .ent l1_init
329 .set noreorder
330 l1_init:
331
332 /* save return address */
333 move t8, ra
334
335
336 /* initialize I and D cache Data and Tag registers. */
337 mtc0 zero, CP0_ICACHE_TAG_LO
338 mtc0 zero, CP0_ICACHE_TAG_HI
339 mtc0 zero, CP0_ICACHE_DATA_LO
340 mtc0 zero, CP0_ICACHE_DATA_HI
341 mtc0 zero, CP0_DCACHE_TAG_LO
342 mtc0 zero, CP0_DCACHE_TAG_HI
343
344 /* Enable Caches before Clearing. If the caches are disabled
345 * then the cache operations to clear the cache will be ignored
346 */
347
348 jal enable_ID
349 nop
350
351 jal size_i_cache /* v0 = i-cache size, v1 = i-cache line size */
352 nop
353
354 /* run uncached in kseg 1 */
355 la k0, 1f
356 lui k1, 0x2000
357 or k0, k1, k0
358 jr k0
359 nop
360 1:
361
362 /*
363 * set K0 cache mode
364 */
365
366 mfc0 t0, CP0_CONFIG
367 and t0, t0, ~CP0_CONFIG_K0_MASK
368 or t0, t0, 3 /* Write Back mode */
369 mtc0 t0, CP0_CONFIG
370
371 /*
372 * Initialize instruction cache.
373 */
374
375 li a0, KSEG0
376 cacheop(a0, v0, v1, Index_Store_Tag_I)
377
378 /*
379 * Now we can run from I-$, kseg 0
380 */
381 la k0, 1f
382 lui k1, 0x2000
383 or k0, k1, k0
384 xor k0, k1, k0
385 jr k0
386 nop
387 1:
388 /*
389 * Initialize data cache.
390 */
391
392 jal size_d_cache /* v0 = d-cache size, v1 = d-cache line size */
393 nop
394
395
396 li a0, KSEG0
397 cacheop(a0, v0, v1, Index_Store_Tag_D)
398
399 jr t8
400 nop
401
402 .end l1_init
403 .set reorder
404
405
406 /*
407 * Function: set_other_config
408 * Arguments: none
409 * Returns: None
410 * Description: initialize other remainder configuration to defaults.
411 * Trashes: t0, t1
412 *
413 * pseudo code:
414 *
415 */
416 LEAF(set_other_config)
417 .set noreorder
418
419 /* enable Bus error for I-fetch */
420 mfc0 t0, CP0_CACHEERR, 0
421 li t1, 0x4
422 or t0, t1
423 mtc0 t0, CP0_CACHEERR, 0
424
425 /* enable Bus error for Load */
426 mfc0 t0, CP0_CACHEERR, 1
427 li t1, 0x4
428 or t0, t1
429 mtc0 t0, CP0_CACHEERR, 1
430
431 /* enable Bus Error for Store */
432 mfc0 t0, CP0_CACHEERR, 2
433 li t1, 0x4
434 or t0, t1
435 mtc0 t0, CP0_CACHEERR, 2
436
437 jr ra
438 nop
439 .set reorder
440 END(set_other_config)
441
442 /*
443 * Function: set_branch_pred
444 * Arguments: none
445 * Returns: None
446 * Description:
447 * Trashes: t0, t1
448 *
449 * pseudo code:
450 *
451 */
452
453 LEAF(set_branch_pred)
454 .set noreorder
455 mfc0 t0, CP0_BRCM_MODE
456 li t1, ~(CP0_BRCM_MODE_BrPRED_MASK | CP0_BRCM_MODE_BrHIST_MASK )
457 and t0, t0, t1
458
459 /* enable Branch prediction */
460 li t1, BRCM_BrPRED_BHT_ENABLE
461 sll t1, CP0_BRCM_MODE_BrPRED_SHIFT
462 or t0, t0, t1
463
464 /* set history count to 8 */
465 li t1, 8
466 sll t1, CP0_BRCM_MODE_BrHIST_SHIFT
467 or t0, t0, t1
468
469 mtc0 t0, CP0_BRCM_MODE
470 jr ra
471 nop
472 .set reorder
473 END(set_branch_pred)
474
475
476 /*
477 * Function: set_luc
478 * Arguments: set link uncached.
479 * Returns: None
480 * Description:
481 * Trashes: t0, t1
482 *
483 */
484 LEAF(set_luc)
485 .set noreorder
486 mfc0 t0, CP0_BRCM_MODE
487 li t1, ~(CP0_BRCM_MODE_Luc_MASK)
488 and t0, t0, t1
489
490 /* set Luc */
491 ori t0, t0, CP0_BRCM_MODE_Luc_MASK
492
493 mtc0 t0, CP0_BRCM_MODE
494 jr ra
495 nop
496 .set reorder
497 END(set_luc)
498
499 /*
500 * Function: set_cwf_tse
501 * Arguments: set CWF and TSE bits
502 * Returns: None
503 * Description:
504 * Trashes: t0, t1
505 *
506 */
507 LEAF(set_cwf_tse)
508 .set noreorder
509 mfc0 t0, CP0_BRCM_CONFIG0
510 li t1, (CP0_BRCM_CONFIG0_CWF_MASK | CP0_BRCM_CONFIG0_TSE_MASK)
511 or t0, t0, t1
512
513 mtc0 t0, CP0_BRCM_CONFIG0
514 jr ra
515 nop
516 .set reorder
517 END(set_cwf_tse)
518
519 /*
520 * Function: set_clock_ratio
521 * Arguments: set clock ratio specified by a0
522 * Returns: None
523 * Description:
524 * Trashes: v0, v1, a0, a1
525 *
526 * pseudo code:
527 *
528 */
529 LEAF(set_clock_ratio)
530 .set noreorder
531
532 mfc0 t0, CP0_BRCM_MODE
533 li t1, ~(CP0_BRCM_MODE_SET_MASK | CP0_BRCM_MODE_ClkRATIO_MASK)
534 and t0, t0, t1
535 li t1, CP0_BRCM_MODE_SET_MASK
536 or t0, t0, t1
537 or t0, t0, a0
538 mtc0 t0, CP0_BRCM_MODE
539 jr ra
540 nop
541 .set reorder
542 END(set_clock_ratio)
543 /*
544 * Function: set_zephyr
545 * Arguments: None
546 * Returns: None
547 * Description: Set any zephyr bits
548 * Trashes: t0 & t1
549 *
550 */
551 LEAF(set_zephyr)
552 .set noreorder
553
554 /* enable read/write of CP0 #22 sel. 8 */
555 li t0, 0x5a455048
556 .word 0x4088b00f /* mtc0 t0, $22, 15 */
557
558 .word 0x4008b008 /* mfc0 t0, $22, 8 */
559 li t1, 0x09008000 /* turn off pref, jtb */
560 or t0, t0, t1
561 .word 0x4088b008 /* mtc0 t0, $22, 8 */
562 sync
563
564 /* disable read/write of CP0 #22 sel 8 */
565 li t0, 0x0
566 .word 0x4088b00f /* mtc0 t0, $22, 15 */
567
568
569 jr ra
570 nop
571 .set reorder
572
573 END(set_zephyr)
574
575
576 /*
577 * Function: set_llmb
578 * Arguments: a0=0 disable llmb, a0=1 enables llmb
579 * Returns: None
580 * Description:
581 * Trashes: t0, t1, t2
582 *
583 * pseudo code:
584 *
585 */
586 LEAF(set_llmb)
587 .set noreorder
588
589 li t2, 0x90000000 | BRCM_ZSC_ALL_REGS_SELECT | BRCM_ZSC_CONFIG_REG
590 sync
591 cache 0x7, 0x0(t2)
592 sync
593 mfc0 t0, CP0_D_SEC_CACHE_DATA_LO
594 li t1, ~(BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
595 and t0, t0, t1
596
597 beqz a0, svlmb
598 nop
599
600 enable_lmb:
601 li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
602 or t0, t0, t1
603
604 svlmb:
605 mtc0 t0, CP0_D_SEC_CACHE_DATA_LO
606 sync
607 cache 0xb, 0x0(t2)
608 sync
609
610 jr ra
611 nop
612 .set reorder
613
614 END(set_llmb)
615 /*
616 * Function: core_init
617 * Arguments: none
618 * Returns: None
619 * Description: initialize core related configuration
620 * Trashes: v0,v1,a0,a1,t8
621 *
622 * pseudo code:
623 *
624 */
625 .globl core_init
626 .ent core_init
627 .set noreorder
628 core_init:
629 move t8, ra
630
631 /* set Zephyr bits. */
632 bal set_zephyr
633 nop
634
635 #if ENABLE_FPU==1
636 /* initialize the Floating point unit (both TPs) */
637 bal init_fpu
638 nop
639 #endif
640
641 /* set low latency memory bus */
642 li a0, 1
643 bal set_llmb
644 nop
645
646 /* set branch prediction (TP0 only) */
647 bal set_branch_pred
648 nop
649
650 /* set link uncached */
651 bal set_luc
652 nop
653
654 /* set CWF and TSE */
655 bal set_cwf_tse
656 nop
657
658 /*
659 *set clock ratio by setting 1 to 'set'
660 * and 0 to ClkRatio, (TP0 only)
661 */
662 li a0, 0
663 bal set_clock_ratio
664 nop
665
666 /* set other configuration to defaults */
667 bal set_other_config
668 nop
669
670 move ra, t8
671 jr ra
672 nop
673
674 .set reorder
675 .end core_init
676
677 /*
678 * Function: clear_jump_target_buffer
679 * Arguments: None
680 * Returns: None
681 * Description:
682 * Trashes: t0, t1, t2
683 *
684 */
685 #define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16)
686 #define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16)
687 #define JTB_CS_CNTL_MASK (0xFF<<16)
688
689 .globl clear_jump_target_buffer
690 .ent clear_jump_target_buffer
691 .set noreorder
692 clear_jump_target_buffer:
693
694 mfc0 t0, $22, 2
695 nop
696 nop
697
698 li t1, ~JTB_CS_CNTL_MASK
699 and t0, t0, t1
700 li t2, RESET_CALL_RETURN_STACK_THIS_THREAD
701 or t0, t0, t2
702 mtc0 t0, $22, 2
703 nop
704 nop
705
706 and t0, t0, t1
707 li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD
708 or t0, t0, t2
709 mtc0 t0, $22, 2
710 nop
711 nop
712 jr ra
713 nop
714
715 .end clear_jump_target_buffer
716 .set reorder
717 /*
718 * Function: bmips_cache_init
719 * Arguments: None
720 * Returns: None
721 * Description: Enable I and D caches, and initialize I and D-caches
722 * Trashes: v0, v1, t0, t1, t2, t5, t7, t8
723 *
724 */
725 .globl bmips_5xxx_init
726 .ent bmips_5xxx_init
727 .set noreorder
728 bmips_5xxx_init:
729
730 /* save return address and A0 */
731 move t7, ra
732 move t5, a0
733
734 jal l1_init
735 nop
736
737 jal core_init
738 nop
739
740 jal clear_jump_target_buffer
741 nop
742
743 mtc0 zero, CP0_CAUSE
744
745 move a0, t5
746 jr t7
747 nop
748
749 .end bmips_5xxx_init
750 .set reorder
751
752
753 #endif