]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/siemens/CCM/ccm.c
Initial revision
[karo-tx-uboot.git] / board / siemens / CCM / ccm.c
1 /*
2  * (C) Copyright 2001
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <mpc8xx.h>
26 #include <commproc.h>
27 #include <command.h>
28
29 /* ------------------------------------------------------------------------- */
30
31 static long int dram_size (long int, long int *, long int);
32 void can_driver_enable (void);
33 void can_driver_disable (void);
34
35 int fpga_init(void);
36
37 /* ------------------------------------------------------------------------- */
38
39 #define _NOT_USED_      0xFFFFFFFF
40
41 const uint sdram_table[] =
42 {
43         /*
44          * Single Read. (Offset 0 in UPMA RAM)
45          */
46         0x1F0DFC04, 0xEEAFBC04, 0x11AF7C04, 0xEFBAFC00,
47         0x1FF5FC47, /* last */
48         /*
49          * SDRAM Initialization (offset 5 in UPMA RAM)
50          *
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.
54          *
55          */
56                     0x1FF5FC34, 0xEFEABC34, 0x1FB57C35, /* last */
57         /*
58          * Burst Read. (Offset 8 in UPMA RAM)
59          */
60         0x1F0DFC04, 0xEEAFBC04, 0x10AF7C04, 0xF0AFFC00,
61         0xF0AFFC00, 0xF1AFFC00, 0xEFBAFC00, 0x1FF5FC47, /* last */
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 UPMA RAM)
66          */
67         0x1F0DFC04, 0xEEABBC00, 0x01B27C04, 0x1FF5FC47, /* last */
68         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
69         /*
70          * Burst Write. (Offset 20 in UPMA RAM)
71          */
72         0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
73         0xF0AFFC00, 0xE1BAFC04, 0x1FF5FC47, /* last */
74                                             _NOT_USED_,
75         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
76         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
77         /*
78          * Refresh  (Offset 30 in UPMA RAM)
79          */
80         0x1FFD7C84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
81         0xFFFFFC84, 0xFFFFFC07, /* last */
82                                 _NOT_USED_, _NOT_USED_,
83         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
84         /*
85          * Exception. (Offset 3c in UPMA RAM)
86          */
87         0x7FFFFC07, /* last */
88                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
89 };
90
91 /* ------------------------------------------------------------------------- */
92
93
94 /*
95  * Check Board Identity:
96  *
97  * Always return 1 (no second DRAM bank since based on TQM8xxL module)
98  */
99
100 int checkboard (void)
101 {
102     unsigned char *s;
103     unsigned char buf[64];
104
105     s = (getenv_r ("serial#", buf, sizeof(buf)) > 0) ? buf : NULL;
106
107     puts ("Board: Siemens CCM");
108
109     if (s) {
110             puts (" (");
111
112             for (; *s; ++s) {
113                 if (*s == ' ')
114                     break;
115                 putc (*s);
116             }
117             putc (')');
118     }
119
120     putc ('\n');
121
122     return (0);
123 }
124
125 /* ------------------------------------------------------------------------- */
126
127 /*
128  * If Power-On-Reset switch off the Red and Green LED: At reset, the
129  * data direction registers are cleared and must therefore be restored.
130  */
131 #define RSR_CSRS        0x08000000
132
133 int power_on_reset(void)
134 {
135     /* Test Reset Status Register */
136     return ((volatile immap_t *)CFG_IMMR)->im_clkrst.car_rsr & RSR_CSRS ? 0:1;
137 }
138
139 #define PB_LED_GREEN    0x10000         /* red LED is on PB.15 */
140 #define PB_LED_RED      0x20000         /* red LED is on PB.14 */
141 #define PB_LEDS         (PB_LED_GREEN | PB_LED_RED);
142
143 static void init_leds (void)
144 {
145     volatile immap_t *immap  = (immap_t *)CFG_IMMR;
146
147     immap->im_cpm.cp_pbpar &= ~PB_LEDS;
148     immap->im_cpm.cp_pbodr &= ~PB_LEDS;
149     immap->im_cpm.cp_pbdir |=  PB_LEDS;
150     /* Check stop reset status */
151     if (power_on_reset()) {
152             immap->im_cpm.cp_pbdat &= ~PB_LEDS;
153     }
154 }
155
156 /* ------------------------------------------------------------------------- */
157
158 long int initdram (int board_type)
159 {
160     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
161     volatile memctl8xx_t *memctl = &immap->im_memctl;
162     long int size8, size9;
163     long int size = 0;
164     unsigned long reg;
165
166     upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
167
168     /*
169      * Preliminary prescaler for refresh (depends on number of
170      * banks): This value is selected for four cycles every 62.4 us
171      * with two SDRAM banks or four cycles every 31.2 us with one
172      * bank. It will be adjusted after memory sizing.
173      */
174     memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
175
176     memctl->memc_mar  = 0x00000088;
177
178     /*
179      * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
180      * preliminary addresses - these have to be modified after the
181      * SDRAM size has been determined.
182      */
183     memctl->memc_or2 = CFG_OR2_PRELIM;
184     memctl->memc_br2 = CFG_BR2_PRELIM;
185
186     memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
187
188     udelay(200);
189
190     /* perform SDRAM initializsation sequence */
191
192     memctl->memc_mcr  = 0x80004105;     /* SDRAM bank 0 */
193     udelay(1);
194     memctl->memc_mcr  = 0x80004230;     /* SDRAM bank 0 - execute twice */
195     udelay(1);
196
197     memctl->memc_mamr |= MAMR_PTAE;     /* enable refresh */
198
199     udelay (1000);
200
201     /*
202      * Check Bank 0 Memory Size for re-configuration
203      *
204      * try 8 column mode
205      */
206     size8 = dram_size (CFG_MAMR_8COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
207
208     udelay (1000);
209
210     /*
211      * try 9 column mode
212      */
213     size9 = dram_size (CFG_MAMR_9COL, (ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
214
215     if (size8 < size9) {                /* leave configuration at 9 columns     */
216         size = size9;
217 /*      debug ("SDRAM in 9 column mode: %ld MB\n", size >> 20); */
218     } else {                            /* back to 8 columns                    */
219         size = size8;
220         memctl->memc_mamr = CFG_MAMR_8COL;
221         udelay(500);
222 /*      debug ("SDRAM in 8 column mode: %ld MB\n", size >> 20); */
223     }
224
225     udelay (1000);
226
227     /*
228      * Adjust refresh rate depending on SDRAM type
229      * For types > 128 MBit leave it at the current (fast) rate
230      */
231     if (size < 0x02000000) {
232         /* reduce to 15.6 us (62.4 us / quad) */
233         memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
234         udelay(1000);
235     }
236
237     /*
238      * Final mapping
239      */
240
241     memctl->memc_or2 = ((-size) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
242     memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
243
244
245     /* adjust refresh rate depending on SDRAM type, one bank */
246     reg = memctl->memc_mptpr;
247     reg >>= 1;  /* reduce to CFG_MPTPR_1BK_8K / _4K */
248     memctl->memc_mptpr = reg;
249
250     can_driver_enable ();
251     init_leds ();
252
253     udelay(10000);
254
255     return (size);
256 }
257
258 /* ------------------------------------------------------------------------- */
259
260 /*
261  * Warning - both the PUMA load mode and the CAN driver use UPM B,
262  * so make sure only one of both is active.
263  */
264 void can_driver_enable (void)
265 {
266     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
267     volatile memctl8xx_t *memctl = &immap->im_memctl;
268
269     /* Initialize MBMR */
270     memctl->memc_mbmr = MAMR_GPL_B4DIS; /* GPL_B4 ouput line Disable */
271
272     /* Initialize UPMB for CAN: single read */
273     memctl->memc_mdr = 0xFFFFC004;
274     memctl->memc_mcr = 0x0100 | UPMB;
275
276     memctl->memc_mdr = 0x0FFFD004;
277     memctl->memc_mcr = 0x0101 | UPMB;
278
279     memctl->memc_mdr = 0x0FFFC000;
280     memctl->memc_mcr = 0x0102 | UPMB;
281
282     memctl->memc_mdr = 0x3FFFC004;
283     memctl->memc_mcr = 0x0103 | UPMB;
284
285     memctl->memc_mdr = 0xFFFFDC05;
286     memctl->memc_mcr = 0x0104 | UPMB;
287
288     /* Initialize UPMB for CAN: single write */
289     memctl->memc_mdr = 0xFFFCC004;
290     memctl->memc_mcr = 0x0118 | UPMB;
291
292     memctl->memc_mdr = 0xCFFCD004;
293     memctl->memc_mcr = 0x0119 | UPMB;
294
295     memctl->memc_mdr = 0x0FFCC000;
296     memctl->memc_mcr = 0x011A | UPMB;
297
298     memctl->memc_mdr = 0x7FFCC004;
299     memctl->memc_mcr = 0x011B | UPMB;
300
301     memctl->memc_mdr = 0xFFFDCC05;
302     memctl->memc_mcr = 0x011C | UPMB;
303
304     /* Initialize OR3 / BR3 for CAN Bus Controller */
305     memctl->memc_or3 = CFG_OR3_CAN;
306     memctl->memc_br3 = CFG_BR3_CAN;
307 }
308
309 void can_driver_disable (void)
310 {
311     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
312     volatile memctl8xx_t *memctl = &immap->im_memctl;
313
314     /* Reset OR3 / BR3 to disable  CAN Bus Controller */
315     memctl->memc_br3 = 0;
316     memctl->memc_or3 = 0;
317
318     memctl->memc_mbmr = 0;
319 }
320
321
322 /* ------------------------------------------------------------------------- */
323
324 /*
325  * Check memory range for valid RAM. A simple memory test determines
326  * the actually available RAM size between addresses `base' and
327  * `base + maxsize'. Some (not all) hardware errors are detected:
328  * - short between address lines
329  * - short between data lines
330  */
331
332 static long int dram_size (long int mamr_value, long int *base, long int maxsize)
333 {
334     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
335     volatile memctl8xx_t *memctl = &immap->im_memctl;
336     volatile long int    *addr;
337     ulong                 cnt, val;
338     ulong                 save[32];     /* to make test non-destructive */
339     unsigned char         i = 0;
340
341     memctl->memc_mamr = mamr_value;
342
343     for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
344         addr = base + cnt;      /* pointer arith! */
345
346         save[i++] = *addr;
347         *addr = ~cnt;
348     }
349
350     /* write 0 to base address */
351     addr = base;
352     save[i] = *addr;
353     *addr = 0;
354
355     /* check at base address */
356     if ((val = *addr) != 0) {
357         *addr = save[i];
358         return (0);
359     }
360
361     for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
362         addr = base + cnt;      /* pointer arith! */
363
364         val = *addr;
365         *addr = save[--i];
366
367         if (val != (~cnt)) {
368             return (cnt * sizeof(long));
369         }
370     }
371     return (maxsize);
372 }
373
374 /* ------------------------------------------------------------------------- */
375
376 #define ETH_CFG_BITS    (CFG_PB_ETH_CFG1 | CFG_PB_ETH_CFG2  | CFG_PB_ETH_CFG3 )
377
378 #define ETH_ALL_BITS    (ETH_CFG_BITS | CFG_PB_ETH_POWERDOWN)
379
380 void    reset_phy(void)
381 {
382         immap_t *immr = (immap_t *)CFG_IMMR;
383         ulong value;
384
385         /* Configure all needed port pins for GPIO */
386 #if CFG_ETH_MDDIS_VALUE
387         immr->im_ioport.iop_padat |=   CFG_PA_ETH_MDDIS;
388 #else
389         immr->im_ioport.iop_padat &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);    /* Set low */
390 #endif
391         immr->im_ioport.iop_papar &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);    /* GPIO */
392         immr->im_ioport.iop_paodr &= ~(CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET);    /* active output */
393         immr->im_ioport.iop_padir |=   CFG_PA_ETH_MDDIS | CFG_PA_ETH_RESET;     /* output */
394
395         immr->im_cpm.cp_pbpar &= ~(ETH_ALL_BITS);       /* GPIO */
396         immr->im_cpm.cp_pbodr &= ~(ETH_ALL_BITS);       /* active output */
397
398         value  = immr->im_cpm.cp_pbdat;
399
400         /* Assert Powerdown and Reset signals */
401         value |=  CFG_PB_ETH_POWERDOWN;
402
403         /* PHY configuration includes MDDIS and CFG1 ... CFG3 */
404 #if CFG_ETH_CFG1_VALUE
405         value |=   CFG_PB_ETH_CFG1;
406 #else
407         value &= ~(CFG_PB_ETH_CFG1);
408 #endif
409 #if CFG_ETH_CFG2_VALUE
410         value |=   CFG_PB_ETH_CFG2;
411 #else
412         value &= ~(CFG_PB_ETH_CFG2);
413 #endif
414 #if CFG_ETH_CFG3_VALUE
415         value |=   CFG_PB_ETH_CFG3;
416 #else
417         value &= ~(CFG_PB_ETH_CFG3);
418 #endif
419
420         /* Drive output signals to initial state */
421         immr->im_cpm.cp_pbdat  = value;
422         immr->im_cpm.cp_pbdir |= ETH_ALL_BITS;
423         udelay (10000);
424
425         /* De-assert Ethernet Powerdown */
426         immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN); /* Enable PHY power */
427         udelay (10000);
428
429         /* de-assert RESET signal of PHY */
430         immr->im_ioport.iop_padat |= CFG_PA_ETH_RESET;
431         udelay (1000);
432 }
433
434
435 int misc_init_r (void)
436 {
437         fpga_init();
438         return (0);
439 }
440 /* ------------------------------------------------------------------------- */