Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / include / asm-mips / mach-pnx8550 / kernel-entry-init.h
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) 2005 Embedded Alley Solutions, Inc
7  */
8 #ifndef __ASM_MACH_KERNEL_ENTRY_INIT_H
9 #define __ASM_MACH_KERNEL_ENTRY_INIT_H
10
11 #include <asm/cacheops.h>
12 #include <asm/addrspace.h>
13
14 #define CO_CONFIGPR_VALID  0x3F1F41FF    /* valid bits to write to ConfigPR */
15 #define HAZARD_CP0 nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;
16 #define CACHE_OPC      0xBC000000  /* MIPS cache instruction opcode */
17 #define ICACHE_LINE_SIZE        32      /* Instruction cache line size bytes */
18 #define DCACHE_LINE_SIZE        32      /* Data cache line size in bytes */
19
20 #define ICACHE_SET_COUNT        256     /* Instruction cache set count */
21 #define DCACHE_SET_COUNT        128     /* Data cache set count */
22
23 #define ICACHE_SET_SIZE         (ICACHE_SET_COUNT * ICACHE_LINE_SIZE)
24 #define DCACHE_SET_SIZE         (DCACHE_SET_COUNT * DCACHE_LINE_SIZE)
25
26         .macro  kernel_entry_setup
27         .set    push
28         .set    noreorder
29         /*
30          * PNX8550 entry point, when running a non compressed
31          * kernel. When loading a zImage, the head.S code in
32          * arch/mips/zboot/pnx8550 will init the caches and,
33          * decompress the kernel, and branch to kernel_entry.
34                  */
35 cache_begin:    li      t0, (1<<28)
36         mtc0    t0, CP0_STATUS /* cp0 usable */
37         HAZARD_CP0
38
39         mtc0    zero, CP0_CAUSE
40         HAZARD_CP0
41
42
43         /* Set static virtual to phys address translation and TLB disabled */
44         mfc0    t0, CP0_CONFIG, 7
45         HAZARD_CP0
46
47         and t0,~((1<<19) | (1<<20))     /* TLB/MAP cleared */
48         mtc0    t0, CP0_CONFIG, 7
49         HAZARD_CP0
50
51         /* CPU boots with kseg0 cache algo set to 0x2 -- uncached */
52
53         init_icache
54         nop
55         init_dcache
56         nop
57
58         cachePr4450ICReset
59         nop
60
61         cachePr4450DCReset
62         nop
63
64         /* read ConfigPR into t0 */
65         mfc0    t0, CP0_CONFIG, 7
66         HAZARD_CP0
67
68         /*  enable the TLB */
69         or      t0, (1<<19)
70
71         /* disable the ICACHE: at least 10x slower */
72         /* or      t0, (1<<26) */
73
74         /* disable the DCACHE; CONFIG_CPU_HAS_LLSC should not be set  */
75         /* or      t0, (1<<27) */
76
77         and     t0, CO_CONFIGPR_VALID
78
79         /* enable TLB. */
80         mtc0    t0, CP0_CONFIG, 7
81         HAZARD_CP0
82 cache_end:
83         /* Setup CMEM_0 to MMIO address space, 2MB */
84         lui    t0, 0x1BE0
85         addi   t0, t0, 0x3
86         mtc0   $8, $22, 4
87         nop
88
89         /* Setup CMEM_1, 128MB */
90         lui    t0, 0x1000
91         addi   t0, t0, 0xf
92         mtc0   $8, $22, 5
93         nop
94
95
96         /* Setup CMEM_2, 32MB */
97         lui    t0, 0x1C00
98         addi   t0, t0, 0xb
99         mtc0   $8, $22, 6
100         nop
101
102         /* Setup CMEM_3, 0MB */
103         lui    t0, 0x0
104         addi   t0, t0, 0x0
105         mtc0   $8, $22, 7
106         nop
107
108         /* Enable cache */
109         mfc0    t0, CP0_CONFIG
110         HAZARD_CP0
111         and     t0, t0, 0xFFFFFFF8
112         or      t0, t0, 3
113         mtc0    t0, CP0_CONFIG
114         HAZARD_CP0
115         .set    pop
116         .endm
117
118         .macro  init_icache
119         .set    push
120         .set    noreorder
121
122         /* Get Cache Configuration */
123         mfc0    t3, CP0_CONFIG, 1
124         HAZARD_CP0
125
126         /* get cache Line size */
127
128         srl   t1, t3, 19   /* C0_CONFIGPR_IL_SHIFT */
129         andi  t1, t1, 0x7  /* C0_CONFIGPR_IL_MASK */
130         beq   t1, zero, pr4450_instr_cache_invalidated /* if zero instruction cache is absent */
131         nop
132         addiu t0, t1, 1
133         ori   t1, zero, 1
134         sllv  t1, t1, t0
135
136         /* get max cache Index */
137         srl   t2, t3, 22  /* C0_CONFIGPR_IS_SHIFT */
138         andi  t2, t2, 0x7 /* C0_CONFIGPR_IS_MASK */
139         addiu t0, t2, 6
140         ori   t2, zero, 1
141         sllv  t2, t2, t0
142
143         /* get max cache way */
144         srl   t3, t3, 16  /* C0_CONFIGPR_IA_SHIFT */
145         andi  t3, t3, 0x7 /* C0_CONFIGPR_IA_MASK */
146         addiu t3, t3, 1
147
148         /* total no of cache lines */
149         multu t2, t3             /* max index * max way */
150         mflo  t2
151         addiu t2, t2, -1
152
153         move  t0, zero
154 pr4450_next_instruction_cache_set:
155         cache  Index_Invalidate_I, 0(t0)
156         addu  t0, t0, t1         /* add bytes in a line */
157         bne   t2, zero, pr4450_next_instruction_cache_set
158         addiu t2, t2, -1   /* reduce no of lines to invalidate by one */
159 pr4450_instr_cache_invalidated:
160         .set    pop
161         .endm
162
163         .macro  init_dcache
164         .set    push
165         .set    noreorder
166         move t1, zero
167
168         /* Store Tag Information */
169         mtc0    zero, CP0_TAGLO, 0
170         HAZARD_CP0
171
172         mtc0    zero, CP0_TAGHI, 0
173         HAZARD_CP0
174
175         /* Cache size is 16384 = 512 lines x 32 bytes per line */
176         or       t2, zero, (128*4)-1  /* 512 lines  */
177         /* Invalidate all lines */
178 2:
179         cache Index_Store_Tag_D, 0(t1)
180         addiu    t2, t2, -1
181         bne      t2, zero, 2b
182         addiu    t1, t1, 32        /* 32 bytes in a line */
183         .set pop
184         .endm
185
186         .macro  cachePr4450ICReset
187         .set    push
188         .set    noreorder
189
190         /* Save CP0 status reg on entry; */
191         /* disable interrupts during cache reset */
192         mfc0    t0, CP0_STATUS      /* T0 = interrupt status on entry */
193         HAZARD_CP0
194
195         mtc0    zero, CP0_STATUS   /* disable CPU interrupts */
196         HAZARD_CP0
197
198         or      t1, zero, zero              /* T1 = starting cache index (0) */
199         ori     t2, zero, (256 - 1) /* T2 = inst cache set cnt - 1 */
200
201         icache_invd_loop:
202         /* 9 == register t1 */
203         .word   (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
204                 (0 * ICACHE_SET_SIZE))  /* invalidate inst cache WAY0 */
205         .word   (CACHE_OPC | (9 << 21) | (Index_Invalidate_I << 16) | \
206                 (1 * ICACHE_SET_SIZE))  /* invalidate inst cache WAY1 */
207
208         addiu   t1, t1, ICACHE_LINE_SIZE    /* T1 = next cache line index */
209         bne     t2, zero, icache_invd_loop /* T2 = 0 if all sets invalidated */
210         addiu   t2, t2, -1        /* decrement T2 set cnt (delay slot) */
211
212         /* Initialize the latches in the instruction cache tag */
213         /* that drive the way selection tri-state bus drivers, by doing a */
214         /* dummy load while the instruction cache is still disabled. */
215         /* TODO: Is this needed ? */
216         la      t1, KSEG0            /* T1 = cached memory base address */
217         lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
218
219         mtc0    t0, CP0_STATUS        /* restore interrupt status on entry */
220         HAZARD_CP0
221         .set    pop
222         .endm
223
224         .macro  cachePr4450DCReset
225         .set    push
226         .set    noreorder
227         mfc0    t0, CP0_STATUS           /* T0 = interrupt status on entry */
228         HAZARD_CP0
229         mtc0    zero, CP0_STATUS         /* disable CPU interrupts */
230         HAZARD_CP0
231
232         /* Writeback/invalidate entire data cache sets/ways/lines */
233         or      t1, zero, zero              /* T1 = starting cache index (0) */
234         ori     t2, zero, (DCACHE_SET_COUNT - 1) /* T2 = data cache set cnt - 1 */
235
236         dcache_wbinvd_loop:
237         /* 9 == register t1 */
238         .word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
239                 (0 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY0 */
240         .word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
241                 (1 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY1 */
242         .word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
243                 (2 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY2 */
244         .word   (CACHE_OPC | (9 << 21) | (Index_Writeback_Inv_D << 16) | \
245                 (3 * DCACHE_SET_SIZE))  /* writeback/invalidate WAY3 */
246
247         addiu   t1, t1, DCACHE_LINE_SIZE  /* T1 = next data cache line index */
248         bne     t2, zero, dcache_wbinvd_loop /* T2 = 0 when wbinvd entire cache */
249         addiu   t2, t2, -1          /* decrement T2 set cnt (delay slot) */
250
251         /* Initialize the latches in the data cache tag that drive the way
252         selection tri-state bus drivers, by doing a dummy load while the
253         data cache is still in the disabled mode.  TODO: Is this needed ? */
254         la      t1, KSEG0            /* T1 = cached memory base address */
255         lw      zero, 0x0000(t1)      /* (dummy read of first memory word) */
256
257         mtc0    t0, CP0_STATUS       /* restore interrupt status on entry */
258         HAZARD_CP0
259         .set    pop
260         .endm
261
262 #endif /* __ASM_MACH_KERNEL_ENTRY_INIT_H */