]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/spd8xx/spd8xx.c
Initial revision
[karo-tx-uboot.git] / board / spd8xx / spd8xx.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  * Ulrich Lutz, Speech Design GmbH, ulutz@datalab.de.
5  *
6  * See file CREDITS for list of people who contributed to this
7  * project.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA
23  */
24
25 #include <common.h>
26 #include <mpc8xx.h>
27 #include <commproc.h>
28
29 /* ------------------------------------------------------------------------- */
30
31 static long int dram_size (long int, long int *, long int);
32
33 /* ------------------------------------------------------------------------- */
34
35 #define _NOT_USED_      0xFFFFFFFF
36
37 const uint sharc_table[] =
38 {
39         /*
40          * Single Read. (Offset 0 in UPM RAM)
41          */
42         0x0FF3FC04, 0x0FF3EC00, 0x7FFFEC04, 0xFFFFEC04,
43         0xFFFFEC05, /* last */
44                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
45         /*
46          * Burst Read. (Offset 8 in UPM RAM)
47          */
48         /* last */
49         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
50         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
51         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
52         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
53         /*
54          * Single Write. (Offset 18 in UPM RAM)
55          */
56         0x0FAFFC04, 0x0FAFEC00, 0x7FFFEC04, 0xFFFFEC04,
57         0xFFFFEC05, /* last */
58                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
59         /*
60          * Burst Write. (Offset 20 in UPM RAM)
61          */
62         /* last */
63         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
64         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
65         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
66         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
67         /*
68          * Refresh  (Offset 30 in UPM RAM)
69          */
70         /* last */
71         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
72         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
73         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
74         /*
75          * Exception. (Offset 3c in UPM RAM)
76          */
77         0x7FFFFC07, /* last */
78                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
79 };
80
81
82 const uint sdram_table[] =
83 {
84         /*
85          * Single Read. (Offset 0 in UPM RAM)
86          */
87         0x1F07FC04, 0xEEAEFC04, 0x11ADFC04, 0xEFBBBC00,
88         0x1FF77C47, /* last */
89         /*
90          * SDRAM Initialization (offset 5 in UPM RAM)
91          *
92          * This is no UPM entry point. The following definition uses
93          * the remaining space to establish an initialization
94          * sequence, which is executed by a RUN command.
95          *
96          */
97                     0x1FF77C35, 0xEFEABC34, 0x1FB57C35, /* last */
98         /*
99          * Burst Read. (Offset 8 in UPM RAM)
100          */
101         0x1F07FC04, 0xEEAEFC04, 0x10ADFC04, 0xF0AFFC00,
102         0xF0AFFC00, 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C47, /* last */
103         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
104         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
105         /*
106          * Single Write. (Offset 18 in UPM RAM)
107          */
108         0x1F27FC04, 0xEEAEBC00, 0x01B93C04, 0x1FF77C47, /* last */
109         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
110         /*
111          * Burst Write. (Offset 20 in UPM RAM)
112          */
113         0x1F07FC04, 0xEEAEBC00, 0x10AD7C00, 0xF0AFFC00,
114         0xF0AFFC00, 0xE1BBBC04, 0x1FF77C47, /* last */
115                                             _NOT_USED_,
116         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
117         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
118         /*
119          * Refresh  (Offset 30 in UPM RAM)
120          */
121         0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC04,
122         0xFFFFFC84, 0xFFFFFC07, /* last */
123                                 _NOT_USED_, _NOT_USED_,
124         _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
125         /*
126          * Exception. (Offset 3c in UPM RAM)
127          */
128         0x7FFFFC07, /* last */
129                     _NOT_USED_, _NOT_USED_, _NOT_USED_,
130 };
131
132 /* ------------------------------------------------------------------------- */
133
134
135 /*
136  * Check Board Identity:
137  *
138  */
139
140 int checkboard (void)
141 {
142         puts ("Board: SPD823TS\n");
143         return (0);
144 }
145
146 /* ------------------------------------------------------------------------- */
147
148 long int
149 initdram (int board_type)
150 {
151     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
152     volatile memctl8xx_t *memctl = &immap->im_memctl;
153     long int size_b0;
154
155 #if 0
156     /*
157      * Map controller bank 2 to the SRAM bank at preliminary address.
158      */
159     memctl->memc_or2 = CFG_OR2;
160     memctl->memc_br2 = CFG_BR2;
161 #endif
162
163     /*
164      * Map controller bank 4 to the PER8 bank.
165      */
166     memctl->memc_or4 = CFG_OR4;
167     memctl->memc_br4 = CFG_BR4;
168
169 #if 0
170     /* Configure SHARC at UMA */
171     upmconfig(UPMA, (uint *)sharc_table, sizeof(sharc_table)/sizeof(uint));
172     /* Map controller bank 5 to the SHARC */
173     memctl->memc_or5 = CFG_OR5;
174     memctl->memc_br5 = CFG_BR5;
175 #endif
176
177     memctl->memc_mamr = 0x00001000;
178
179     /* Configure SDRAM at UMB */
180     upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
181
182     memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
183
184     memctl->memc_mar = 0x00000088;
185
186     /*
187      * Map controller bank 3 to the SDRAM bank at preliminary address.
188      */
189     memctl->memc_or3 = CFG_OR3_PRELIM;
190     memctl->memc_br3 = CFG_BR3_PRELIM;
191
192     memctl->memc_mbmr = CFG_MBMR_8COL;  /* refresh not enabled yet */
193
194     udelay(200);
195     memctl->memc_mcr = 0x80806105;
196     udelay(1);
197     memctl->memc_mcr = 0x80806130;
198     udelay(1);
199     memctl->memc_mcr = 0x80806130;
200     udelay(1);
201     memctl->memc_mcr = 0x80806106;
202
203     memctl->memc_mbmr |= MAMR_PTBE;     /* refresh enabled */
204
205     /*
206      * Check Bank 0 Memory Size for re-configuration
207      */
208     size_b0 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE);
209
210     memctl->memc_mbmr = CFG_MBMR_8COL | MAMR_PTBE;
211
212     return (size_b0);
213 }
214
215 /* ------------------------------------------------------------------------- */
216
217 /*
218  * Check memory range for valid RAM. A simple memory test determines
219  * the actually available RAM size between addresses `base' and
220  * `base + maxsize'. Some (not all) hardware errors are detected:
221  * - short between address lines
222  * - short between data lines
223  */
224
225 static long int dram_size (long int mamr_value, long int *base, long int maxsize)
226 {
227     volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
228     volatile memctl8xx_t *memctl = &immap->im_memctl;
229     volatile long int    *addr;
230     ulong                 cnt, val;
231     ulong                 save[32];     /* to make test non-destructive */
232     unsigned char         i = 0;
233
234     memctl->memc_mbmr = mamr_value;
235
236     for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
237         addr = base + cnt;      /* pointer arith! */
238
239         save[i++] = *addr;
240         *addr = ~cnt;
241     }
242
243     /* write 0 to base address */
244     addr = base;
245     save[i] = *addr;
246     *addr = 0;
247
248     /* check at base address */
249     if ((val = *addr) != 0) {
250         *addr = save[i];
251         return (0);
252     }
253
254     for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
255         addr = base + cnt;      /* pointer arith! */
256
257         val = *addr;
258         *addr = save[--i];
259
260         if (val != (~cnt)) {
261             return (cnt * sizeof(long));
262         }
263     }
264     return (maxsize);
265 }
266
267 /* ------------------------------------------------------------------------- */
268
269 void    reset_phy(void)
270 {
271         immap_t *immr = (immap_t *)CFG_IMMR;
272         ushort sreg;
273
274         /* Configure extra port pins for NS DP83843 PHY */
275         immr->im_ioport.iop_papar &= ~(PA_ENET_MDC | PA_ENET_MDIO);
276
277         sreg  = immr->im_ioport.iop_padir;
278         sreg |=   PA_ENET_MDC;          /* Mgmt. Data Clock is Output */
279         sreg &= ~(PA_ENET_MDIO);        /* Mgmt. Data I/O is bidirect. => Input */
280         immr->im_ioport.iop_padir = sreg;
281
282         immr->im_ioport.iop_padat &= ~(PA_ENET_MDC);    /* set MDC = 0 */
283
284         /*
285          * RESET in implemented by a positive pulse of at least 1 us
286          * at the reset pin.
287          *
288          * Configure RESET pins for NS DP83843 PHY, and RESET chip.
289          *
290          * Note: The RESET pin is high active, but there is an
291          *       inverter on the SPD823TS board...
292          */
293         immr->im_ioport.iop_pcpar &= ~(PC_ENET_RESET);
294         immr->im_ioport.iop_pcdir |=   PC_ENET_RESET;
295         /* assert RESET signal of PHY */
296         immr->im_ioport.iop_pcdat &= ~(PC_ENET_RESET);
297         udelay (10);
298         /* de-assert RESET signal of PHY */
299         immr->im_ioport.iop_pcdat |=   PC_ENET_RESET;
300         udelay (10);
301 }
302
303 /* ------------------------------------------------------------------------- */
304
305 void ide_set_reset(int on)
306 {
307         volatile immap_t *immr = (immap_t *)CFG_IMMR;
308
309         /*
310          * Configure PC for IDE Reset Pin
311          */
312         if (on) {               /* assert RESET */
313                 immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
314         } else {                /* release RESET */
315                 immr->im_ioport.iop_pcdat |=   CFG_PC_IDE_RESET;
316         }
317
318         /* program port pin as GPIO output */
319         immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
320         immr->im_ioport.iop_pcso  &= ~(CFG_PC_IDE_RESET);
321         immr->im_ioport.iop_pcdir |=   CFG_PC_IDE_RESET;
322 }
323
324 /* ------------------------------------------------------------------------- */