source: SVN/rincon/u-boot/board/siemens/pcu_e/pcu_e.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 2 years ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 14.9 KB
Line 
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 <i2c.h>
28#include <command.h>
29
30/* ------------------------------------------------------------------------- */
31
32static long int dram_size (long int, long int *, long int);
33static void puma_status (void);
34static void puma_set_mode (int mode);
35static int puma_init_done (void);
36static void puma_load (ulong addr, ulong len);
37
38/* ------------------------------------------------------------------------- */
39
40#define _NOT_USED_      0xFFFFFFFF
41
42/*
43 * 50 MHz SDRAM access using UPM A
44 */
45const uint sdram_table[] = {
46        /*
47         * Single Read. (Offset 0 in UPM RAM)
48         */
49        0x1f0dfc04, 0xeeafbc04, 0x11af7c04, 0xefbeec00,
50        0x1ffddc47,             /* last */
51        /*
52         * SDRAM Initialization (offset 5 in UPM RAM)
53         *
54         * This is no UPM entry point. The following definition uses
55         * the remaining space to establish an initialization
56         * sequence, which is executed by a RUN command.
57         *
58         */
59        0x1ffddc35, 0xefceac34, 0x1f3d5c35,     /* last */
60        /*
61         * Burst Read. (Offset 8 in UPM RAM)
62         */
63        0x1f0dfc04, 0xeeafbc04, 0x10af7c04, 0xf0affc00,
64        0xf0affc00, 0xf1affc00, 0xefbeec00, 0x1ffddc47, /* last */
65        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
66        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
67
68        /*
69         * Single Write. (Offset 18 in UPM RAM)
70         */
71        0x1f0dfc04, 0xeeafac00, 0x01be4c04, 0x1ffddc47, /* last */
72        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
73        /*
74         * Burst Write. (Offset 20 in UPM RAM)
75         */
76        0x1f0dfc04, 0xeeafac00, 0x10af5c00, 0xf0affc00,
77        0xf0affc00, 0xe1beec04, 0x1ffddc47,     /* last */
78        _NOT_USED_,
79        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
80        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
81        /*
82         * Refresh  (Offset 30 in UPM RAM)
83         */
84        0x1ffd7c84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
85        0xfffffc84, 0xfffffc07, /* last */
86        _NOT_USED_, _NOT_USED_,
87        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
88        /*
89         * Exception. (Offset 3c in UPM RAM)
90         */
91        0x7ffffc07,             /* last */
92        _NOT_USED_, _NOT_USED_, _NOT_USED_,
93};
94
95/* ------------------------------------------------------------------------- */
96
97/*
98 * PUMA access using UPM B
99 */
100const uint puma_table[] = {
101        /*
102         * Single Read. (Offset 0 in UPM RAM)
103         */
104        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
105        _NOT_USED_,
106        /*
107         * Precharge and MRS
108         */
109        _NOT_USED_, _NOT_USED_, _NOT_USED_,
110        /*
111         * Burst Read. (Offset 8 in UPM RAM)
112         */
113        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
114        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
115        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
116        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
117        /*
118         * Single Write. (Offset 18 in UPM RAM)
119         */
120        0x0ffff804, 0x0ffff400, 0x3ffffc47,     /* last */
121        _NOT_USED_,
122        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
123        /*
124         * Burst Write. (Offset 20 in UPM RAM)
125         */
126        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
127        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
128        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
129        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
130        /*
131         * Refresh  (Offset 30 in UPM RAM)
132         */
133        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
134        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
135        _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
136        /*
137         * Exception. (Offset 3c in UPM RAM)
138         */
139        0x7ffffc07,             /* last */
140        _NOT_USED_, _NOT_USED_, _NOT_USED_,
141};
142
143/* ------------------------------------------------------------------------- */
144
145
146/*
147 * Check Board Identity:
148 *
149 */
150
151int checkboard (void)
152{
153        puts ("Board: Siemens PCU E\n");
154        return (0);
155}
156
157/* ------------------------------------------------------------------------- */
158
159phys_size_t initdram (int board_type)
160{
161        volatile immap_t *immr = (immap_t *) CFG_IMMR;
162        volatile memctl8xx_t *memctl = &immr->im_memctl;
163        long int size_b0, reg;
164        int i;
165
166        /*
167         * Configure UPMA for SDRAM
168         */
169        upmconfig (UPMA, (uint *) sdram_table,
170                   sizeof (sdram_table) / sizeof (uint));
171
172        memctl->memc_mptpr = CFG_MPTPR;
173
174        /* burst length=4, burst type=sequential, CAS latency=2 */
175        memctl->memc_mar = 0x00000088;
176
177        /*
178         * Map controller bank 2 to the SDRAM bank at preliminary address.
179         */
180#if PCU_E_WITH_SWAPPED_CS       /* XXX */
181        memctl->memc_or5 = CFG_OR5_PRELIM;
182        memctl->memc_br5 = CFG_BR5_PRELIM;
183#else  /* XXX */
184        memctl->memc_or2 = CFG_OR2_PRELIM;
185        memctl->memc_br2 = CFG_BR2_PRELIM;
186#endif /* XXX */
187
188        /* initialize memory address register */
189        memctl->memc_mamr = CFG_MAMR;   /* refresh not enabled yet */
190
191        /* mode initialization (offset 5) */
192#if PCU_E_WITH_SWAPPED_CS       /* XXX */
193        udelay (200);           /* 0x8000A105 */
194        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS5 | MCR_MLCF (1) | MCR_MAD (0x05);
195#else  /* XXX */
196        udelay (200);           /* 0x80004105 */
197        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS2 | MCR_MLCF (1) | MCR_MAD (0x05);
198#endif /* XXX */
199
200        /* run 2 refresh sequence with 4-beat refresh burst (offset 0x30) */
201#if PCU_E_WITH_SWAPPED_CS       /* XXX */
202        udelay (1);             /* 0x8000A830 */
203        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS5 | MCR_MLCF (8) | MCR_MAD (0x30);
204#else  /* XXX */
205        udelay (1);             /* 0x80004830 */
206        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS2 | MCR_MLCF (8) | MCR_MAD (0x30);
207#endif /* XXX */
208
209#if PCU_E_WITH_SWAPPED_CS       /* XXX */
210        udelay (1);             /* 0x8000A106 */
211        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS5 | MCR_MLCF (1) | MCR_MAD (0x06);
212#else  /* XXX */
213        udelay (1);             /* 0x80004106 */
214        memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS2 | MCR_MLCF (1) | MCR_MAD (0x06);
215#endif /* XXX */
216
217        reg = memctl->memc_mamr;
218        reg &= ~MAMR_TLFA_MSK;  /* switch timer loop ... */
219        reg |= MAMR_TLFA_4X;    /* ... to 4x */
220        reg |= MAMR_PTAE;       /* enable refresh */
221        memctl->memc_mamr = reg;
222
223        udelay (200);
224
225        /* Need at least 10 DRAM accesses to stabilize */
226        for (i = 0; i < 10; ++i) {
227#if PCU_E_WITH_SWAPPED_CS       /* XXX */
228                volatile unsigned long *addr =
229                        (volatile unsigned long *) SDRAM_BASE5_PRELIM;
230#else  /* XXX */
231                volatile unsigned long *addr =
232                        (volatile unsigned long *) SDRAM_BASE2_PRELIM;
233#endif /* XXX */
234                unsigned long val;
235
236                val = *(addr + i);
237                *(addr + i) = val;
238        }
239
240        /*
241         * Check Bank 0 Memory Size for re-configuration
242         */
243#if PCU_E_WITH_SWAPPED_CS       /* XXX */
244        size_b0 = dram_size (CFG_MAMR, (long *) SDRAM_BASE5_PRELIM, SDRAM_MAX_SIZE);
245#else  /* XXX */
246        size_b0 = dram_size (CFG_MAMR, (long *) SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
247#endif /* XXX */
248
249        memctl->memc_mamr = CFG_MAMR | MAMR_PTAE;
250
251        /*
252         * Final mapping:
253         */
254
255#if PCU_E_WITH_SWAPPED_CS       /* XXX */
256        memctl->memc_or5 = ((-size_b0) & 0xFFFF0000) | SDRAM_TIMING;
257        memctl->memc_br5 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
258#else  /* XXX */
259        memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | SDRAM_TIMING;
260        memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
261#endif /* XXX */
262        udelay (1000);
263
264        /*
265         * Configure UPMB for PUMA
266         */
267        upmconfig (UPMB, (uint *) puma_table,
268                   sizeof (puma_table) / sizeof (uint));
269
270        return (size_b0);
271}
272
273/* ------------------------------------------------------------------------- */
274
275/*
276 * Check memory range for valid RAM. A simple memory test determines
277 * the actually available RAM size between addresses `base' and
278 * `base + maxsize'. Some (not all) hardware errors are detected:
279 * - short between address lines
280 * - short between data lines
281 */
282
283static long int dram_size (long int mamr_value, long int *base,
284                           long int maxsize)
285{
286        volatile immap_t *immr = (immap_t *) CFG_IMMR;
287        volatile memctl8xx_t *memctl = &immr->im_memctl;
288
289        memctl->memc_mamr = mamr_value;
290
291        return (get_ram_size (base, maxsize));
292}
293
294/* ------------------------------------------------------------------------- */
295
296#if PCU_E_WITH_SWAPPED_CS       /* XXX */
297#define ETH_CFG_BITS    (CFG_PB_ETH_CFG1 | CFG_PB_ETH_CFG2  | CFG_PB_ETH_CFG3 )
298#else  /* XXX */
299#define ETH_CFG_BITS    (CFG_PB_ETH_MDDIS | CFG_PB_ETH_CFG1 | \
300                         CFG_PB_ETH_CFG2  | CFG_PB_ETH_CFG3 )
301#endif /* XXX */
302
303#define ETH_ALL_BITS    (ETH_CFG_BITS | CFG_PB_ETH_POWERDOWN | CFG_PB_ETH_RESET)
304
305void reset_phy (void)
306{
307        immap_t *immr = (immap_t *) CFG_IMMR;
308        ulong value;
309
310        /* Configure all needed port pins for GPIO */
311#if PCU_E_WITH_SWAPPED_CS       /* XXX */
312# ifdef CFG_ETH_MDDIS_VALUE
313        immr->im_ioport.iop_padat |= CFG_PA_ETH_MDDIS;
314# else
315        immr->im_ioport.iop_padat &= ~(CFG_PA_ETH_MDDIS);       /* Set low */
316# endif
317        immr->im_ioport.iop_papar &= ~(CFG_PA_ETH_MDDIS);       /* GPIO */
318        immr->im_ioport.iop_paodr &= ~(CFG_PA_ETH_MDDIS);       /* active output */
319        immr->im_ioport.iop_padir |= CFG_PA_ETH_MDDIS;  /* output */
320#endif /* XXX */
321        immr->im_cpm.cp_pbpar &= ~(ETH_ALL_BITS);       /* GPIO */
322        immr->im_cpm.cp_pbodr &= ~(ETH_ALL_BITS);       /* active output */
323
324        value = immr->im_cpm.cp_pbdat;
325
326        /* Assert Powerdown and Reset signals */
327        value |= CFG_PB_ETH_POWERDOWN;
328        value &= ~(CFG_PB_ETH_RESET);
329
330        /* PHY configuration includes MDDIS and CFG1 ... CFG3 */
331#if !PCU_E_WITH_SWAPPED_CS
332# ifdef CFG_ETH_MDDIS_VALUE
333        value |= CFG_PB_ETH_MDDIS;
334# else
335        value &= ~(CFG_PB_ETH_MDDIS);
336# endif
337#endif
338#ifdef CFG_ETH_CFG1_VALUE
339        value |= CFG_PB_ETH_CFG1;
340#else
341        value &= ~(CFG_PB_ETH_CFG1);
342#endif
343#ifdef CFG_ETH_CFG2_VALUE
344        value |= CFG_PB_ETH_CFG2;
345#else
346        value &= ~(CFG_PB_ETH_CFG2);
347#endif
348#ifdef CFG_ETH_CFG3_VALUE
349        value |= CFG_PB_ETH_CFG3;
350#else
351        value &= ~(CFG_PB_ETH_CFG3);
352#endif
353
354        /* Drive output signals to initial state */
355        immr->im_cpm.cp_pbdat = value;
356        immr->im_cpm.cp_pbdir |= ETH_ALL_BITS;
357        udelay (10000);
358
359        /* De-assert Ethernet Powerdown */
360        immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN);       /* Enable PHY power */
361        udelay (10000);
362
363        /* de-assert RESET signal of PHY */
364        immr->im_cpm.cp_pbdat |= CFG_PB_ETH_RESET;
365        udelay (1000);
366}
367
368/*-----------------------------------------------------------------------
369 * Board Special Commands: access functions for "PUMA" FPGA
370 */
371#if defined(CONFIG_CMD_BSP)
372
373#define PUMA_READ_MODE  0
374#define PUMA_LOAD_MODE  1
375
376int do_puma (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
377{
378        ulong addr, len;
379
380        switch (argc) {
381        case 2:         /* PUMA reset */
382                if (strncmp (argv[1], "stat", 4) == 0) {        /* Reset */
383                        puma_status ();
384                        return 0;
385                }
386                break;
387        case 4:         /* PUMA load addr len */
388                if (strcmp (argv[1], "load") != 0)
389                        break;
390
391                addr = simple_strtoul (argv[2], NULL, 16);
392                len = simple_strtoul (argv[3], NULL, 16);
393
394                printf ("PUMA load: addr %08lX len %ld (0x%lX):  ",
395                        addr, len, len);
396                puma_load (addr, len);
397
398                return 0;
399        default:
400                break;
401        }
402        printf ("Usage:\n%s\n", cmdtp->usage);
403        return 1;
404}
405
406U_BOOT_CMD (puma, 4, 1, do_puma,
407            "puma    - access PUMA FPGA\n",
408            "status - print PUMA status\n"
409            "puma load addr len - load PUMA configuration data\n");
410
411#endif
412
413/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
414
415static void puma_set_mode (int mode)
416{
417        volatile immap_t *immr = (immap_t *) CFG_IMMR;
418        volatile memctl8xx_t *memctl = &immr->im_memctl;
419
420        /* disable PUMA in memory controller */
421#if PCU_E_WITH_SWAPPED_CS       /* XXX */
422        memctl->memc_br3 = 0;
423#else  /* XXX */
424        memctl->memc_br4 = 0;
425#endif /* XXX */
426
427        switch (mode) {
428        case PUMA_READ_MODE:
429#if PCU_E_WITH_SWAPPED_CS       /* XXX */
430                memctl->memc_or3 = PUMA_CONF_OR_READ;
431                memctl->memc_br3 = PUMA_CONF_BR_READ;
432#else  /* XXX */
433                memctl->memc_or4 = PUMA_CONF_OR_READ;
434                memctl->memc_br4 = PUMA_CONF_BR_READ;
435#endif /* XXX */
436                break;
437        case PUMA_LOAD_MODE:
438#if PCU_E_WITH_SWAPPED_CS       /* XXX */
439                memctl->memc_or3 = PUMA_CONF_OR_LOAD;
440                memctl->memc_br3 = PUMA_CONF_BR_LOAD;
441#else  /* XXX */
442                memctl->memc_or4 = PUMA_CONF_OR_READ;
443                memctl->memc_br4 = PUMA_CONF_BR_READ;
444#endif /* XXX */
445                break;
446        }
447}
448
449/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
450
451#define PUMA_INIT_TIMEOUT       1000    /* max. 1000 ms = 1 second */
452
453static void puma_load (ulong addr, ulong len)
454{
455        volatile immap_t *immr = (immap_t *) CFG_IMMR;
456        volatile uchar *fpga_addr = (volatile uchar *) PUMA_CONF_BASE;  /* XXX ??? */
457        uchar *data = (uchar *) addr;
458        int i;
459
460        /* align length */
461        if (len & 1)
462                ++len;
463
464        /* Reset FPGA */
465        immr->im_ioport.iop_pcpar &= ~(CFG_PC_PUMA_INIT);       /* make input */
466        immr->im_ioport.iop_pcso  &= ~(CFG_PC_PUMA_INIT);
467        immr->im_ioport.iop_pcdir &= ~(CFG_PC_PUMA_INIT);
468
469#if PCU_E_WITH_SWAPPED_CS       /* XXX */
470        immr->im_cpm.cp_pbpar &= ~(CFG_PB_PUMA_PROG);           /* GPIO */
471        immr->im_cpm.cp_pbodr &= ~(CFG_PB_PUMA_PROG);           /* active output */
472        immr->im_cpm.cp_pbdat &= ~(CFG_PB_PUMA_PROG);           /* Set low */
473        immr->im_cpm.cp_pbdir |=   CFG_PB_PUMA_PROG;            /* output */
474#else
475        immr->im_ioport.iop_papar &= ~(CFG_PA_PUMA_PROG);       /* GPIO */
476        immr->im_ioport.iop_padat &= ~(CFG_PA_PUMA_PROG);       /* Set low */
477        immr->im_ioport.iop_paodr &= ~(CFG_PA_PUMA_PROG);       /* active output */
478        immr->im_ioport.iop_padir |=   CFG_PA_PUMA_PROG;        /* output */
479#endif /* XXX */
480        udelay (100);
481
482#if PCU_E_WITH_SWAPPED_CS       /* XXX */
483        immr->im_cpm.cp_pbdat |= CFG_PB_PUMA_PROG;      /* release reset */
484#else
485        immr->im_ioport.iop_padat |= CFG_PA_PUMA_PROG;  /* release reset */
486#endif /* XXX */
487
488        /* wait until INIT indicates completion of reset */
489        for (i = 0; i < PUMA_INIT_TIMEOUT; ++i) {
490                udelay (1000);
491                if (immr->im_ioport.iop_pcdat & CFG_PC_PUMA_INIT)
492                        break;
493        }
494        if (i == PUMA_INIT_TIMEOUT) {
495                printf ("*** PUMA init timeout ***\n");
496                return;
497        }
498
499        puma_set_mode (PUMA_LOAD_MODE);
500
501        while (len--)
502                *fpga_addr = *data++;
503
504        puma_set_mode (PUMA_READ_MODE);
505
506        puma_status ();
507}
508
509/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
510
511static void puma_status (void)
512{
513        /* Check state */
514        printf ("PUMA initialization is %scomplete\n",
515                puma_init_done ()? "" : "NOT ");
516}
517
518/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
519
520static int puma_init_done (void)
521{
522        volatile immap_t *immr = (immap_t *) CFG_IMMR;
523
524        /* make sure pin is GPIO input */
525        immr->im_ioport.iop_pcpar &= ~(CFG_PC_PUMA_DONE);
526        immr->im_ioport.iop_pcso &= ~(CFG_PC_PUMA_DONE);
527        immr->im_ioport.iop_pcdir &= ~(CFG_PC_PUMA_DONE);
528
529        return (immr->im_ioport.iop_pcdat & CFG_PC_PUMA_DONE) ? 1 : 0;
530}
531
532/* ------------------------------------------------------------------------- */
533
534int misc_init_r (void)
535{
536        ulong addr = 0;
537        ulong len = 0;
538        char *s;
539
540        printf ("PUMA:  ");
541        if (puma_init_done ()) {
542                printf ("initialized\n");
543                return 0;
544        }
545
546        if ((s = getenv ("puma_addr")) != NULL)
547                addr = simple_strtoul (s, NULL, 16);
548
549        if ((s = getenv ("puma_len")) != NULL)
550                len = simple_strtoul (s, NULL, 16);
551
552        if ((!addr) || (!len)) {
553                printf ("net list undefined\n");
554                return 0;
555        }
556
557        printf ("loading... ");
558
559        puma_load (addr, len);
560        return (0);
561}
562
563/* ------------------------------------------------------------------------- */
Note: See TracBrowser for help on using the repository browser.