]>
Commit | Line | Data |
---|---|---|
fe8c2806 WD |
1 | /* |
2 | * genietv/genietv.c | |
3 | * | |
4 | * The GENIETV is using the following physical memorymap (copied from | |
5 | * the FADS configuration): | |
6 | * | |
7 | * ff020000 -> ff02ffff : pcmcia | |
8 | * ff010000 -> ff01ffff : BCSR connected to CS1, setup by 8xxROM | |
9 | * ff000000 -> ff00ffff : IMAP internal in the cpu | |
10 | * 02800000 -> 0287ffff : flash connected to CS0 | |
11 | * 00000000 -> nnnnnnnn : sdram setup by U-Boot | |
12 | * | |
13 | * CS pins are connected as follows: | |
14 | * | |
15 | * CS0 -512Kb boot flash | |
16 | * CS1 - SDRAM #1 | |
17 | * CS2 - SDRAM #2 | |
18 | * CS3 - Flash #1 | |
19 | * CS4 - Flash #2 | |
20 | * CS5 - LON (if present) | |
21 | * CS6 - PCMCIA #1 | |
22 | * CS7 - PCMCIA #2 | |
23 | * | |
24 | * Ports are configured as follows: | |
25 | * | |
26 | * PA7 - SDRAM banks enable | |
27 | */ | |
28 | ||
29 | #include <common.h> | |
30 | #include <mpc8xx.h> | |
31 | ||
32 | #define CFG_PA7 0x0100 | |
33 | ||
34 | /* ------------------------------------------------------------------------- */ | |
35 | ||
36 | static long int dram_size (long int, long int *, long int); | |
37 | ||
38 | /* ------------------------------------------------------------------------- */ | |
39 | ||
40 | #define _NOT_USED_ 0xFFFFFFFF | |
41 | ||
42 | const uint sdram_table[] = | |
43 | { | |
44 | /* | |
45 | * Single Read. (Offset 0 in UPMB RAM) | |
46 | */ | |
47 | 0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBEEC00, | |
48 | 0x1FFDDC47, /* last */ | |
49 | /* | |
50 | * SDRAM Initialization (offset 5 in UPMB RAM) | |
51 | * | |
8bde7f77 WD |
52 | * This is no UPM entry point. The following definition uses |
53 | * the remaining space to establish an initialization | |
54 | * sequence, which is executed by a RUN command. | |
fe8c2806 WD |
55 | * |
56 | */ | |
57 | 0x1FFDDC34, 0xEFEEAC34, 0x1FBD5C35, /* last */ | |
58 | /* | |
59 | * Burst Read. (Offset 8 in UPMB RAM) | |
60 | */ | |
61 | 0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00, | |
62 | 0xF0AFFC00, 0xF1AFFC00, 0xEFBEEC00, 0x1FFDDC47, /* last */ | |
63 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
64 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
65 | /* | |
66 | * Single Write. (Offset 18 in UPMB RAM) | |
67 | */ | |
68 | 0x1F2DFC04, 0xEEAFAC00, 0x01BE4C04, 0x1FFDDC47, /* last */ | |
69 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
70 | /* | |
71 | * Burst Write. (Offset 20 in UPMB RAM) | |
72 | */ | |
73 | 0x1F0DFC04, 0xEEAFAC00, 0x10AF5C00, 0xF0AFFC00, | |
74 | 0xF0AFFC00, 0xE1BEEC04, 0x1FFDDC47, /* last */ | |
75 | _NOT_USED_, | |
76 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
77 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
78 | /* | |
79 | * Refresh (Offset 30 in UPMB RAM) | |
80 | */ | |
81 | 0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04, | |
82 | 0xFFFFFC84, 0xFFFFFC07, /* last */ | |
83 | _NOT_USED_, _NOT_USED_, | |
84 | _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
85 | /* | |
86 | * Exception. (Offset 3c in UPMB RAM) | |
87 | */ | |
88 | 0x7FFFFC07, /* last */ | |
89 | _NOT_USED_, _NOT_USED_, _NOT_USED_, | |
90 | }; | |
91 | ||
92 | /* ------------------------------------------------------------------------- */ | |
93 | ||
94 | ||
95 | /* | |
96 | * Check Board Identity | |
97 | */ | |
98 | ||
99 | int checkboard (void) | |
100 | { | |
101 | puts ("Board: GenieTV\n"); | |
102 | return 0; | |
103 | } | |
104 | ||
105 | #if 0 | |
106 | static void PrintState(void) | |
107 | { | |
108 | volatile immap_t *im = (immap_t *)CFG_IMMR; | |
109 | volatile memctl8xx_t *memctl = &im->im_memctl; | |
110 | ||
111 | printf("\n0 - FLASH: B=%08x O=%08x", memctl->memc_br0, memctl->memc_or0); | |
112 | printf("\n1 - SDRAM: B=%08x O=%08x", memctl->memc_br1, memctl->memc_or1); | |
113 | printf("\n2 - SDRAM: B=%08x O=%08x", memctl->memc_br2, memctl->memc_or2); | |
114 | } | |
115 | #endif | |
116 | ||
117 | /* ------------------------------------------------------------------------- */ | |
118 | ||
119 | long int initdram (int board_type) | |
120 | { | |
121 | volatile immap_t *im = (immap_t *)CFG_IMMR; | |
122 | volatile memctl8xx_t *memctl = &im->im_memctl; | |
123 | long int size_b0, size_b1, size8; | |
124 | ||
125 | /* Enable SDRAM */ | |
126 | ||
127 | /* Configuring PA7 for general purpouse output pin */ | |
128 | im->im_ioport.iop_papar &= ~CFG_PA7 ; /* 0 = general purpouse */ | |
129 | im->im_ioport.iop_padir |= CFG_PA7 ; /* 1 = output */ | |
130 | ||
131 | /* Enable SDRAM - PA7 = 1 */ | |
132 | im->im_ioport.iop_padat |= CFG_PA7 ; /* value of PA7 */ | |
133 | ||
134 | /* | |
135 | * Preliminary prescaler for refresh (depends on number of | |
136 | * banks): This value is selected for four cycles every 62.4 us | |
137 | * with two SDRAM banks or four cycles every 31.2 us with one | |
138 | * bank. It will be adjusted after memory sizing. | |
139 | */ | |
140 | memctl->memc_mptpr = CFG_MPTPR_2BK_4K ; | |
141 | ||
142 | memctl->memc_mbmr = CFG_MBMR_8COL; | |
143 | ||
144 | upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint)); | |
145 | ||
146 | /* | |
147 | * Map controller banks 1 and 2 to the SDRAM banks 1 and 2 at | |
148 | * preliminary addresses - these have to be modified after the | |
149 | * SDRAM size has been determined. | |
150 | */ | |
151 | ||
152 | memctl->memc_or1 = 0xF0000000 | CFG_OR_TIMING_SDRAM; | |
153 | memctl->memc_br1 = ((SDRAM_BASE1_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V); | |
154 | ||
155 | memctl->memc_or2 = 0xF0000000 | CFG_OR_TIMING_SDRAM; | |
156 | memctl->memc_br2 = ((SDRAM_BASE2_PRELIM & BR_BA_MSK) | BR_MS_UPMB | BR_V); | |
157 | ||
158 | /* perform SDRAM initialization sequence */ | |
159 | memctl->memc_mar = 0x00000088; | |
160 | ||
161 | memctl->memc_mcr = 0x80802105; /* SDRAM bank 0 */ | |
162 | ||
163 | memctl->memc_mcr = 0x80804105; /* SDRAM bank 1 */ | |
164 | ||
165 | /* Execute refresh 8 times */ | |
166 | memctl->memc_mbmr = (CFG_MBMR_8COL & ~MAMR_TLFB_MSK) | MAMR_TLFB_8X ; | |
167 | ||
168 | memctl->memc_mcr = 0x80802130; /* SDRAM bank 0 - execute twice */ | |
169 | ||
170 | memctl->memc_mcr = 0x80804130; /* SDRAM bank 1 - execute twice */ | |
171 | ||
172 | /* Execute refresh 4 times */ | |
173 | memctl->memc_mbmr = CFG_MBMR_8COL; | |
174 | ||
175 | /* | |
176 | * Check Bank 0 Memory Size for re-configuration | |
177 | * | |
178 | * try 8 column mode | |
179 | */ | |
180 | ||
181 | #if 0 | |
182 | PrintState(); | |
183 | #endif | |
184 | /* printf ("\nChecking bank1..."); */ | |
185 | size8 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE1_PRELIM, SDRAM_MAX_SIZE); | |
186 | ||
187 | size_b0 = size8 ; | |
188 | ||
189 | /* printf ("\nChecking bank2..."); */ | |
190 | size_b1 = dram_size (memctl->memc_mbmr, (ulong *)SDRAM_BASE2_PRELIM,SDRAM_MAX_SIZE); | |
191 | ||
192 | /* | |
193 | * Final mapping: map bigger bank first | |
194 | */ | |
195 | ||
196 | memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; | |
197 | memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V; | |
198 | ||
199 | if (size_b1 > 0) | |
200 | { | |
8bde7f77 WD |
201 | /* |
202 | * Position Bank 1 immediately above Bank 0 | |
203 | */ | |
204 | memctl->memc_or2 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM; | |
205 | memctl->memc_br2 = ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMB | BR_V) + | |
206 | (size_b0 & BR_BA_MSK); | |
fe8c2806 WD |
207 | } |
208 | else | |
209 | { | |
8bde7f77 WD |
210 | /* |
211 | * No bank 1 | |
212 | * | |
213 | * invalidate bank | |
214 | */ | |
215 | memctl->memc_br2 = 0; | |
fe8c2806 WD |
216 | /* adjust refresh rate depending on SDRAM type, one bank */ |
217 | memctl->memc_mptpr = CFG_MPTPR_1BK_4K; | |
218 | } | |
219 | ||
220 | /* If no memory detected, disable SDRAM */ | |
221 | if ((size_b0 + size_b1) == 0) | |
222 | { | |
223 | printf("disabling SDRAM!\n"); | |
224 | /* Disable SDRAM - PA7 = 1 */ | |
225 | im->im_ioport.iop_padat &= ~CFG_PA7 ; /* value of PA7 */ | |
226 | } | |
227 | /* else */ | |
228 | /* printf("done! (%08lx)\n", size_b0 + size_b1); */ | |
229 | ||
230 | #if 0 | |
231 | PrintState(); | |
232 | #endif | |
233 | return (size_b0 + size_b1); | |
234 | } | |
235 | ||
236 | /* ------------------------------------------------------------------------- */ | |
237 | ||
238 | /* | |
239 | * Check memory range for valid RAM. A simple memory test determines | |
240 | * the actually available RAM size between addresses `base' and | |
241 | * `base + maxsize'. Some (not all) hardware errors are detected: | |
242 | * - short between address lines | |
243 | * - short between data lines | |
244 | */ | |
245 | ||
246 | static long int dram_size (long int mbmr_value, long int *base, long int maxsize) | |
247 | { | |
248 | volatile long int *addr; | |
249 | long int cnt, val; | |
250 | ||
251 | /*memctl->memc_mbmr = mbmr_value; */ | |
252 | ||
253 | for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) { | |
254 | addr = base + cnt; /* pointer arith! */ | |
255 | ||
256 | *addr = ~cnt; | |
257 | } | |
258 | ||
259 | /* write 0 to base address */ | |
260 | addr = base; | |
261 | *addr = 0; | |
262 | ||
263 | /* check at base address */ | |
264 | if ((val = *addr) != 0) { | |
265 | printf("(0)"); | |
266 | return (0); | |
267 | } | |
268 | ||
269 | for (cnt = 1; ; cnt <<= 1) { | |
270 | addr = base + cnt; /* pointer arith! */ | |
271 | ||
272 | val = *addr; | |
273 | if (val != (~cnt)) { | |
274 | /* printf("(%08lx)", cnt*sizeof(long)); */ | |
275 | return (cnt * sizeof(long)); | |
276 | } | |
277 | } | |
278 | /* NOTREACHED */ | |
279 | return (0); | |
280 | } | |
281 | ||
282 | #if (CONFIG_COMMANDS & CFG_CMD_PCMCIA) | |
283 | ||
284 | #ifdef CFG_PCMCIA_MEM_ADDR | |
285 | volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR; | |
286 | #endif | |
287 | ||
288 | int pcmcia_init(void) | |
289 | { | |
290 | volatile pcmconf8xx_t *pcmp; | |
291 | uint v, slota, slotb; | |
292 | ||
293 | /* | |
294 | ** Enable the PCMCIA for a Flash card. | |
295 | */ | |
296 | pcmp = (pcmconf8xx_t *)(&(((immap_t *)CFG_IMMR)->im_pcmcia)); | |
297 | ||
298 | #if 0 | |
299 | pcmp->pcmc_pbr0 = CFG_PCMCIA_MEM_ADDR; | |
300 | pcmp->pcmc_por0 = 0xc00ff05d; | |
301 | #endif | |
302 | ||
303 | /* Set all slots to zero by default. */ | |
304 | pcmp->pcmc_pgcra = 0; | |
305 | pcmp->pcmc_pgcrb = 0; | |
306 | #ifdef PCMCIA_SLOT_A | |
307 | pcmp->pcmc_pgcra = 0x40; | |
308 | #endif | |
309 | #ifdef PCMCIA_SLOT_B | |
310 | pcmp->pcmc_pgcrb = 0x40; | |
311 | #endif | |
312 | ||
313 | /* Check if any PCMCIA card is luged in. */ | |
314 | slota = (pcmp->pcmc_pipr & 0x18000000) == 0 ; | |
315 | slotb = (pcmp->pcmc_pipr & 0x00001800) == 0 ; | |
316 | ||
317 | if (!(slota || slotb)) | |
318 | { | |
319 | printf("No card present\n"); | |
320 | #ifdef PCMCIA_SLOT_A | |
321 | pcmp->pcmc_pgcra = 0; | |
322 | #endif | |
323 | #ifdef PCMCIA_SLOT_B | |
324 | pcmp->pcmc_pgcrb = 0; | |
325 | #endif | |
326 | return -1; | |
327 | } | |
328 | else | |
329 | printf("Unknown card ("); | |
330 | ||
331 | v = 0; | |
332 | ||
333 | switch( (pcmp->pcmc_pipr >> 14) & 3 ) | |
334 | { | |
335 | case 0x00 : | |
336 | printf("5V"); | |
337 | v = 5; | |
338 | break; | |
339 | case 0x01 : | |
340 | printf("5V and 3V"); | |
341 | v = 3; | |
342 | break; | |
343 | case 0x03 : | |
344 | printf("5V, 3V and x.xV"); | |
345 | v = 3; | |
346 | break; | |
347 | } | |
348 | ||
349 | switch(v){ | |
350 | case 3: | |
351 | printf("; using 3V"); | |
352 | /* Enable 3 volt Vcc. */ | |
353 | ||
354 | break; | |
355 | ||
356 | default: | |
357 | printf("; unknown voltage"); | |
358 | return -1; | |
359 | } | |
360 | printf(")\n"); | |
361 | /* disable pcmcia reset after a while */ | |
362 | ||
363 | udelay(20); | |
364 | ||
365 | pcmp->pcmc_pgcrb = 0; | |
366 | ||
367 | /* If you using a real hd you should give a short | |
368 | * spin-up time. */ | |
369 | #ifdef CONFIG_DISK_SPINUP_TIME | |
370 | udelay(CONFIG_DISK_SPINUP_TIME); | |
371 | #endif | |
372 | ||
373 | return 0; | |
374 | } | |
375 | #endif /* CFG_CMD_PCMCIA */ |