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 ; \
369: 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
119LEAF(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
193no_i_cache:
194 move v0, zero
195 move v1, zero
1961:
197 jr ra
198 nop
199 .set reorder
200
201END(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
212LEAF(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
285no_d_cache:
286 move v0, zero
287 move v1, zero
2881:
289 jr ra
290 nop
291 .set reorder
292
293END(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
308enable_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
330l1_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
3601:
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
3871:
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 */
416LEAF(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
440END(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
453LEAF(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
473END(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 */
484LEAF(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
497END(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 */
507LEAF(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
517END(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 */
529LEAF(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
542END(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 */
551LEAF(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
573END(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 */
586LEAF(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
600enable_lmb:
601 li t1, (BRCM_ZSC_CONFIG_LMB1En | BRCM_ZSC_CONFIG_LMB0En)
602 or t0, t0, t1
603
604svlmb:
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
614END(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
628core_init:
629 move t8, ra
630
631 /* set Zephyr bits. */
632 bal set_zephyr
633 nop
634
635 /* set low latency memory bus */
636 li a0, 1
637 bal set_llmb
638 nop
639
640 /* set branch prediction (TP0 only) */
641 bal set_branch_pred
642 nop
643
644 /* set link uncached */
645 bal set_luc
646 nop
647
648 /* set CWF and TSE */
649 bal set_cwf_tse
650 nop
651
652 /*
653 *set clock ratio by setting 1 to 'set'
654 * and 0 to ClkRatio, (TP0 only)
655 */
656 li a0, 0
657 bal set_clock_ratio
658 nop
659
660 /* set other configuration to defaults */
661 bal set_other_config
662 nop
663
664 move ra, t8
665 jr ra
666 nop
667
668 .set reorder
669 .end core_init
670
671/*
672 * Function: clear_jump_target_buffer
673 * Arguments: None
674 * Returns: None
675 * Description:
676 * Trashes: t0, t1, t2
677 *
678 */
679#define RESET_CALL_RETURN_STACK_THIS_THREAD (0x06<<16)
680#define RESET_JUMP_TARGET_BUFFER_THIS_THREAD (0x04<<16)
681#define JTB_CS_CNTL_MASK (0xFF<<16)
682
683 .globl clear_jump_target_buffer
684 .ent clear_jump_target_buffer
685 .set noreorder
686clear_jump_target_buffer:
687
688 mfc0 t0, $22, 2
689 nop
690 nop
691
692 li t1, ~JTB_CS_CNTL_MASK
693 and t0, t0, t1
694 li t2, RESET_CALL_RETURN_STACK_THIS_THREAD
695 or t0, t0, t2
696 mtc0 t0, $22, 2
697 nop
698 nop
699
700 and t0, t0, t1
701 li t2, RESET_JUMP_TARGET_BUFFER_THIS_THREAD
702 or t0, t0, t2
703 mtc0 t0, $22, 2
704 nop
705 nop
706 jr ra
707 nop
708
709 .end clear_jump_target_buffer
710 .set reorder
711/*
712 * Function: bmips_cache_init
713 * Arguments: None
714 * Returns: None
715 * Description: Enable I and D caches, and initialize I and D-caches
716 * Trashes: v0, v1, t0, t1, t2, t5, t7, t8
717 *
718 */
719 .globl bmips_5xxx_init
720 .ent bmips_5xxx_init
721 .set noreorder
722bmips_5xxx_init:
723
724 /* save return address and A0 */
725 move t7, ra
726 move t5, a0
727
728 jal l1_init
729 nop
730
731 jal core_init
732 nop
733
734 jal clear_jump_target_buffer
735 nop
736
737 mtc0 zero, CP0_CAUSE
738
739 move a0, t5
740 jr t7
741 nop
742
743 .end bmips_5xxx_init
744 .set reorder
745
746
747#endif
748

source code of linux/arch/mips/kernel/bmips_5xxx_init.S