treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157
[sfrench/cifs-2.6.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         /* 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
686 clear_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
722 bmips_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