blob: 3bfb25e9b8dcacacfa0976b1784c34f6a6c08285 [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
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
36static long int dram_size (long int, long int *, long int);
37
38/* ------------------------------------------------------------------------- */
39
40#define _NOT_USED_ 0xFFFFFFFF
41
42const 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 *
wdenk8bde7f72003-06-27 21:31:46 +000052 * 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.
wdenkfe8c2802002-11-03 00:38:21 +000055 *
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
99int checkboard (void)
100{
101 puts ("Board: GenieTV\n");
102 return 0;
103}
104
105#if 0
106static 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
119long 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 */
wdenk2535d602003-07-17 23:16:40 +0000166 memctl->memc_mbmr = (CFG_MBMR_8COL & ~MBMR_TLFB_MSK) | MBMR_TLFB_8X ;
wdenkfe8c2802002-11-03 00:38:21 +0000167
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 {
wdenk8bde7f72003-06-27 21:31:46 +0000201 /*
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);
wdenkfe8c2802002-11-03 00:38:21 +0000207 }
208 else
209 {
wdenk8bde7f72003-06-27 21:31:46 +0000210 /*
211 * No bank 1
212 *
213 * invalidate bank
214 */
215 memctl->memc_br2 = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000216 /* 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
246static 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
285volatile unsigned char *pcmcia_mem = (unsigned char*)CFG_PCMCIA_MEM_ADDR;
286#endif
287
288int 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 */