aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh4/probe.c')
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c138
1 files changed, 118 insertions, 20 deletions
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index 42427b79697b..c294de1e14a3 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * CPU Subtype Probing for SH-4. 4 * CPU Subtype Probing for SH-4.
5 * 5 *
6 * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt 6 * Copyright (C) 2001 - 2006 Paul Mundt
7 * Copyright (C) 2003 Richard Curnow 7 * Copyright (C) 2003 Richard Curnow
8 * 8 *
9 * This file is subject to the terms and conditions of the GNU General Public 9 * This file is subject to the terms and conditions of the GNU General Public
@@ -29,7 +29,7 @@ int __init detect_cpu_and_cache_system(void)
29 [9] = (1 << 16) 29 [9] = (1 << 16)
30 }; 30 };
31 31
32 pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff; 32 pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff;
33 prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; 33 prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff;
34 cvr = (ctrl_inl(CCN_CVR)); 34 cvr = (ctrl_inl(CCN_CVR));
35 35
@@ -38,7 +38,6 @@ int __init detect_cpu_and_cache_system(void)
38 */ 38 */
39 cpu_data->icache.way_incr = (1 << 13); 39 cpu_data->icache.way_incr = (1 << 13);
40 cpu_data->icache.entry_shift = 5; 40 cpu_data->icache.entry_shift = 5;
41 cpu_data->icache.entry_mask = 0x1fe0;
42 cpu_data->icache.sets = 256; 41 cpu_data->icache.sets = 256;
43 cpu_data->icache.ways = 1; 42 cpu_data->icache.ways = 1;
44 cpu_data->icache.linesz = L1_CACHE_BYTES; 43 cpu_data->icache.linesz = L1_CACHE_BYTES;
@@ -48,13 +47,29 @@ int __init detect_cpu_and_cache_system(void)
48 */ 47 */
49 cpu_data->dcache.way_incr = (1 << 14); 48 cpu_data->dcache.way_incr = (1 << 14);
50 cpu_data->dcache.entry_shift = 5; 49 cpu_data->dcache.entry_shift = 5;
51 cpu_data->dcache.entry_mask = 0x3fe0;
52 cpu_data->dcache.sets = 512; 50 cpu_data->dcache.sets = 512;
53 cpu_data->dcache.ways = 1; 51 cpu_data->dcache.ways = 1;
54 cpu_data->dcache.linesz = L1_CACHE_BYTES; 52 cpu_data->dcache.linesz = L1_CACHE_BYTES;
55 53
56 /* Set the FPU flag, virtually all SH-4's have one */ 54 /*
57 cpu_data->flags |= CPU_HAS_FPU; 55 * Setup some generic flags we can probe
56 * (L2 and DSP detection only work on SH-4A)
57 */
58 if (((pvr >> 16) & 0xff) == 0x10) {
59 if ((cvr & 0x02000000) == 0)
60 cpu_data->flags |= CPU_HAS_L2_CACHE;
61 if ((cvr & 0x10000000) == 0)
62 cpu_data->flags |= CPU_HAS_DSP;
63
64 cpu_data->flags |= CPU_HAS_LLSC;
65 }
66
67 /* FPU detection works for everyone */
68 if ((cvr & 0x20000000) == 1)
69 cpu_data->flags |= CPU_HAS_FPU;
70
71 /* Mask off the upper chip ID */
72 pvr &= 0xffff;
58 73
59 /* 74 /*
60 * Probe the underlying processor version/revision and 75 * Probe the underlying processor version/revision and
@@ -63,56 +78,101 @@ int __init detect_cpu_and_cache_system(void)
63 switch (pvr) { 78 switch (pvr) {
64 case 0x205: 79 case 0x205:
65 cpu_data->type = CPU_SH7750; 80 cpu_data->type = CPU_SH7750;
66 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; 81 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
82 CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
67 break; 83 break;
68 case 0x206: 84 case 0x206:
69 cpu_data->type = CPU_SH7750S; 85 cpu_data->type = CPU_SH7750S;
70 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; 86 cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU |
87 CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA;
71 break; 88 break;
72 case 0x1100: 89 case 0x1100:
73 cpu_data->type = CPU_SH7751; 90 cpu_data->type = CPU_SH7751;
91 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
74 break; 92 break;
75 case 0x2000: 93 case 0x2000:
76 cpu_data->type = CPU_SH73180; 94 cpu_data->type = CPU_SH73180;
77 cpu_data->icache.ways = 4; 95 cpu_data->icache.ways = 4;
78 cpu_data->dcache.ways = 4; 96 cpu_data->dcache.ways = 4;
79 cpu_data->flags &= ~CPU_HAS_FPU; 97 cpu_data->flags |= CPU_HAS_LLSC;
98 break;
99 case 0x2001:
100 case 0x2004:
101 cpu_data->type = CPU_SH7770;
102 cpu_data->icache.ways = 4;
103 cpu_data->dcache.ways = 4;
104
105 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC;
106 break;
107 case 0x2006:
108 case 0x200A:
109 if (prr == 0x61)
110 cpu_data->type = CPU_SH7781;
111 else
112 cpu_data->type = CPU_SH7780;
113
114 cpu_data->icache.ways = 4;
115 cpu_data->dcache.ways = 4;
116
117 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER |
118 CPU_HAS_LLSC;
119 break;
120 case 0x3000:
121 case 0x3003:
122 cpu_data->type = CPU_SH7343;
123 cpu_data->icache.ways = 4;
124 cpu_data->dcache.ways = 4;
125 cpu_data->flags |= CPU_HAS_LLSC;
80 break; 126 break;
81 case 0x8000: 127 case 0x8000:
82 cpu_data->type = CPU_ST40RA; 128 cpu_data->type = CPU_ST40RA;
129 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
83 break; 130 break;
84 case 0x8100: 131 case 0x8100:
85 cpu_data->type = CPU_ST40GX1; 132 cpu_data->type = CPU_ST40GX1;
133 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
86 break; 134 break;
87 case 0x700: 135 case 0x700:
88 cpu_data->type = CPU_SH4_501; 136 cpu_data->type = CPU_SH4_501;
89 cpu_data->icache.ways = 2; 137 cpu_data->icache.ways = 2;
90 cpu_data->dcache.ways = 2; 138 cpu_data->dcache.ways = 2;
91 139 cpu_data->flags |= CPU_HAS_PTEA;
92 /* No FPU on the SH4-500 series.. */
93 cpu_data->flags &= ~CPU_HAS_FPU;
94 break; 140 break;
95 case 0x600: 141 case 0x600:
96 cpu_data->type = CPU_SH4_202; 142 cpu_data->type = CPU_SH4_202;
97 cpu_data->icache.ways = 2; 143 cpu_data->icache.ways = 2;
98 cpu_data->dcache.ways = 2; 144 cpu_data->dcache.ways = 2;
145 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
99 break; 146 break;
100 case 0x500 ... 0x501: 147 case 0x500 ... 0x501:
101 switch (prr) { 148 switch (prr) {
102 case 0x10: cpu_data->type = CPU_SH7750R; break; 149 case 0x10:
103 case 0x11: cpu_data->type = CPU_SH7751R; break; 150 cpu_data->type = CPU_SH7750R;
104 case 0x50: cpu_data->type = CPU_SH7760; break; 151 break;
152 case 0x11:
153 cpu_data->type = CPU_SH7751R;
154 break;
155 case 0x50 ... 0x5f:
156 cpu_data->type = CPU_SH7760;
157 break;
105 } 158 }
106 159
107 cpu_data->icache.ways = 2; 160 cpu_data->icache.ways = 2;
108 cpu_data->dcache.ways = 2; 161 cpu_data->dcache.ways = 2;
109 162
163 cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA;
164
110 break; 165 break;
111 default: 166 default:
112 cpu_data->type = CPU_SH_NONE; 167 cpu_data->type = CPU_SH_NONE;
113 break; 168 break;
114 } 169 }
115 170
171#ifdef CONFIG_SH_DIRECT_MAPPED
172 cpu_data->icache.ways = 1;
173 cpu_data->dcache.ways = 1;
174#endif
175
116 /* 176 /*
117 * On anything that's not a direct-mapped cache, look to the CVR 177 * On anything that's not a direct-mapped cache, look to the CVR
118 * for I/D-cache specifics. 178 * for I/D-cache specifics.
@@ -121,18 +181,56 @@ int __init detect_cpu_and_cache_system(void)
121 size = sizes[(cvr >> 20) & 0xf]; 181 size = sizes[(cvr >> 20) & 0xf];
122 cpu_data->icache.way_incr = (size >> 1); 182 cpu_data->icache.way_incr = (size >> 1);
123 cpu_data->icache.sets = (size >> 6); 183 cpu_data->icache.sets = (size >> 6);
124 cpu_data->icache.entry_mask = 184
125 (cpu_data->icache.way_incr - (1 << 5));
126 } 185 }
127 186
187 /* Setup the rest of the I-cache info */
188 cpu_data->icache.entry_mask = cpu_data->icache.way_incr -
189 cpu_data->icache.linesz;
190
191 cpu_data->icache.way_size = cpu_data->icache.sets *
192 cpu_data->icache.linesz;
193
194 /* And the rest of the D-cache */
128 if (cpu_data->dcache.ways > 1) { 195 if (cpu_data->dcache.ways > 1) {
129 size = sizes[(cvr >> 16) & 0xf]; 196 size = sizes[(cvr >> 16) & 0xf];
130 cpu_data->dcache.way_incr = (size >> 1); 197 cpu_data->dcache.way_incr = (size >> 1);
131 cpu_data->dcache.sets = (size >> 6); 198 cpu_data->dcache.sets = (size >> 6);
132 cpu_data->dcache.entry_mask = 199 }
133 (cpu_data->dcache.way_incr - (1 << 5)); 200
201 cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr -
202 cpu_data->dcache.linesz;
203
204 cpu_data->dcache.way_size = cpu_data->dcache.sets *
205 cpu_data->dcache.linesz;
206
207 /*
208 * Setup the L2 cache desc
209 *
210 * SH-4A's have an optional PIPT L2.
211 */
212 if (cpu_data->flags & CPU_HAS_L2_CACHE) {
213 /*
214 * Size calculation is much more sensible
215 * than it is for the L1.
216 *
217 * Sizes are 128KB, 258KB, 512KB, and 1MB.
218 */
219 size = (cvr & 0xf) << 17;
220
221 BUG_ON(!size);
222
223 cpu_data->scache.way_incr = (1 << 16);
224 cpu_data->scache.entry_shift = 5;
225 cpu_data->scache.ways = 4;
226 cpu_data->scache.linesz = L1_CACHE_BYTES;
227 cpu_data->scache.entry_mask =
228 (cpu_data->scache.way_incr - cpu_data->scache.linesz);
229 cpu_data->scache.sets = size /
230 (cpu_data->scache.linesz * cpu_data->scache.ways);
231 cpu_data->scache.way_size =
232 (cpu_data->scache.sets * cpu_data->scache.linesz);
134 } 233 }
135 234
136 return 0; 235 return 0;
137} 236}
138