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