blob: 2719a9585faa7e03006c1784f9662e197a5c23da [file] [log] [blame]
wdenkafd7f3d2002-11-03 01:41:26 +00001/*
2 * (C) Copyright 2000
3 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4 * Marius Groeger <mgroeger@sysgo.de>
5 *
6 * (C) Copyright 2001
7 * Advent Networks, Inc. <http://www.adventnetworks.com>
8 * Jay Monkman <jtm@smoothsmoothie.com>
9 *
10 * (C) Copyright 2001
11 * Advent Networks, Inc. <http://www.adventnetworks.com>
12 * Oliver Brown <oliverb@alumni.utexas.net>
13 *
14 * See file CREDITS for list of people who contributed to this
15 * project.
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License as
19 * published by the Free Software Foundation; either version 2 of
20 * the License, or (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 * MA 02111-1307 USA
31 */
32
33/*********************************************************************/
34/* DESCRIPTION:
35 * This file contains the board routines for the GW8260 board.
36 *
37 * MODULE DEPENDENCY:
38 * None
39 *
40 * RESTRICTIONS/LIMITATIONS:
41 * None
42 *
43 * Copyright (c) 2001, Advent Networks, Inc.
44 */
45/*********************************************************************/
46
47#include <common.h>
48#include <ioports.h>
49#include <mpc8260.h>
50
51/*
52 * I/O Port configuration table
53 *
54 */
55const iop_conf_t iop_conf_tab[4][32] = {
56
57 /* Port A configuration */
58 { /* conf ppar psor pdir podr pdat */
59 /* PA31 */ { 1, 0, 0, 1, 0, 0 }, /* TP14 */
60 /* PA30 */ { 1, 1, 1, 1, 0, 0 }, /* US_RTS */
61 /* PA29 */ { 1, 0, 0, 1, 0, 1 }, /* LSSI_DATA */
62 /* PA28 */ { 1, 0, 0, 1, 0, 1 }, /* LSSI_CLK */
63 /* PA27 */ { 1, 0, 0, 1, 0, 0 }, /* TP12 */
64 /* PA26 */ { 1, 0, 0, 0, 0, 0 }, /* IO_STATUS */
65 /* PA25 */ { 1, 0, 0, 0, 0, 0 }, /* IO_CLOCK */
66 /* PA24 */ { 1, 0, 0, 0, 0, 0 }, /* IO_CONFIG */
67 /* PA23 */ { 1, 0, 0, 0, 0, 0 }, /* IO_DONE */
68 /* PA22 */ { 1, 0, 0, 0, 0, 0 }, /* IO_DATA */
69 /* PA21 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD3 */
70 /* PA20 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD2 */
71 /* PA19 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD1 */
72 /* PA18 */ { 1, 1, 0, 1, 0, 0 }, /* US_TXD0 */
73 /* PA17 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD0 */
74 /* PA16 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD1 */
75 /* PA15 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD2 */
76 /* PA14 */ { 1, 1, 0, 0, 0, 0 }, /* DS_RXD3 */
77 /* PA13 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE7 */
78 /* PA12 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE6 */
79 /* PA11 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE5 */
80 /* PA10 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE4 */
81 /* PA9 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE3 */
82 /* PA8 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE2 */
83 /* PA7 */ { 1, 0, 0, 0, 0, 0 }, /* LSSI_IN */
84 /* PA6 */ { 1, 0, 0, 1, 0, 0 }, /* SPARE0 */
85 /* PA5 */ { 1, 0, 0, 1, 0, 0 }, /* DEMOD_RESET_ */
86 /* PA4 */ { 1, 0, 0, 1, 0, 0 }, /* MOD_RESET_ */
87 /* PA3 */ { 1, 0, 0, 1, 0, 0 }, /* IO_RESET */
88 /* PA2 */ { 1, 0, 0, 1, 0, 0 }, /* TX_ENABLE */
89 /* PA1 */ { 1, 0, 0, 0, 0, 0 }, /* RX_LOCK */
90 /* PA0 */ { 1, 0, 0, 1, 0, 1 } /* MPC_RESET_ */
91 },
92
93 /* Port B configuration */
94 { /* conf ppar psor pdir podr pdat */
95 /* PB31 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TX_ER */
96 /* PB30 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_DV */
97 /* PB29 */ { 1, 1, 1, 1, 0, 0 }, /* FETH0_TX_EN */
98 /* PB28 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_ER */
99 /* PB27 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_COL */
100 /* PB26 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_CRS */
101 /* PB25 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD3 */
102 /* PB24 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD2 */
103 /* PB23 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD1 */
104 /* PB22 */ { 1, 1, 0, 1, 0, 0 }, /* FETH0_TXD0 */
105 /* PB21 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD0 */
106 /* PB20 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD1 */
107 /* PB19 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD2 */
108 /* PB18 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RXD3 */
109 /* PB17 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_DV */
110 /* PB16 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_ER */
111 /* PB15 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TX_ER */
112 /* PB14 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TX_EN */
113 /* PB13 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_COL */
114 /* PB12 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_CRS */
115 /* PB11 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD3 */
116 /* PB10 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD2 */
117 /* PB9 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD1 */
118 /* PB8 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RXD0 */
119 /* PB7 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD0 */
120 /* PB6 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD1 */
121 /* PB5 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD2 */
122 /* PB4 */ { 1, 1, 0, 1, 0, 0 }, /* FETH1_TXD3 */
123 /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
124 /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
125 /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
126 /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
127 },
128
129 /* Port C */
130 { /* conf ppar psor pdir podr pdat */
131 /* PC31 */ { 1, 0, 0, 1, 0, 1 }, /* FAST_RESET_ */
132 /* PC30 */ { 1, 0, 0, 1, 0, 1 }, /* FAST_PAUSE_ */
133 /* PC29 */ { 1, 0, 0, 1, 0, 0 }, /* FAST_SLEW1 */
134 /* PC28 */ { 1, 0, 0, 1, 0, 0 }, /* FAST_SLEW0 */
135 /* PC27 */ { 1, 0, 0, 1, 0, 0 }, /* TP13 */
136 /* PC26 */ { 1, 0, 0, 0, 0, 0 }, /* RXDECDFLG */
137 /* PC25 */ { 1, 0, 0, 0, 0, 0 }, /* RXACQFAIL */
138 /* PC24 */ { 1, 0, 0, 0, 0, 0 }, /* RXACQFLG */
139 /* PC23 */ { 1, 0, 0, 1, 0, 0 }, /* WD_TCL */
140 /* PC22 */ { 1, 0, 0, 1, 0, 0 }, /* WD_EN */
141 /* PC21 */ { 1, 0, 0, 1, 0, 0 }, /* US_TXCLK */
142 /* PC20 */ { 1, 0, 0, 0, 0, 0 }, /* DS_RXCLK */
143 /* PC19 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_RX_CLK */
144 /* PC18 */ { 1, 1, 0, 0, 0, 0 }, /* FETH0_TX_CLK */
145 /* PC17 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_RX_CLK */
146 /* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* FETH1_TX_CLK */
147 /* PC15 */ { 1, 0, 0, 1, 0, 0 }, /* TX_SHUTDOWN_ */
148 /* PC14 */ { 1, 0, 0, 0, 0, 0 }, /* RS_232_DTR_ */
149 /* PC13 */ { 1, 0, 0, 0, 0, 0 }, /* TXERR */
150 /* PC12 */ { 1, 0, 0, 1, 0, 1 }, /* FETH1_MDDIS */
151 /* PC11 */ { 1, 0, 0, 1, 0, 1 }, /* FETH0_MDDIS */
152 /* PC10 */ { 1, 0, 0, 1, 0, 0 }, /* MDC */
153 /* PC9 */ { 1, 0, 0, 1, 1, 1 }, /* MDIO */
154 /* PC8 */ { 1, 0, 0, 1, 1, 1 }, /* SER_NUM */
155 /* PC7 */ { 1, 1, 0, 0, 0, 0 }, /* US_CTS */
156 /* PC6 */ { 1, 1, 0, 0, 0, 0 }, /* DS_CD_ */
157 /* PC5 */ { 1, 0, 0, 1, 0, 0 }, /* FETH1_PWRDWN */
158 /* PC4 */ { 1, 0, 0, 1, 0, 0 }, /* FETH0_PWRDWN */
159 /* PC3 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED3 */
160 /* PC2 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED2 */
161 /* PC1 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED1 */
162 /* PC0 */ { 1, 0, 0, 1, 0, 1 }, /* MPULED0 */
163 },
164
165 /* Port D */
166 { /* conf ppar psor pdir podr pdat */
167 /* PD31 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
168 /* PD30 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
169 /* PD29 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
170 /* PD28 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
171 /* PD27 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
172 /* PD26 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
173 /* PD25 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
174 /* PD24 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
175 /* PD23 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
176 /* PD22 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
177 /* PD21 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
178 /* PD20 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
179 /* PD19 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
180 /* PD18 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
181 /* PD17 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
182 /* PD16 */ { 1, 1, 1, 0, 0, 0 }, /* not used */
183 /* PD15 */ { 1, 1, 1, 0, 1, 1 }, /* SDRAM_SDA */
184 /* PD14 */ { 1, 1, 1, 0, 1, 1 }, /* SDRAM_SCL */
185 /* PD13 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED7 */
186 /* PD12 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED6 */
187 /* PD11 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED5 */
188 /* PD10 */ { 1, 0, 0, 1, 0, 0 }, /* MPULED4 */
189 /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* RS232_TXD */
190 /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* RD232_RXD */
191 /* PD7 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
192 /* PD6 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
193 /* PD5 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
194 /* PD4 */ { 1, 0, 0, 0, 0, 0 }, /* not used */
195 /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
196 /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
197 /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
198 /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
199 }
200};
201
202/*********************************************************************/
203/* NAME: checkboard() - Displays the board type and serial number */
204/* */
205/* OUTPUTS: */
206/* Displays the board type and serial number */
207/* */
208/* RETURNS: */
209/* Always returns 1 */
210/* */
211/* RESTRICTIONS/LIMITATIONS: */
212/* */
213/* */
214/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000215int checkboard (void)
wdenkafd7f3d2002-11-03 01:41:26 +0000216{
wdenkbf9e3b32004-02-12 00:47:09 +0000217 char *str;
wdenkafd7f3d2002-11-03 01:41:26 +0000218
wdenkbf9e3b32004-02-12 00:47:09 +0000219 puts ("Board: Advent Networks gw8260\n");
220
221 str = getenv ("serial#");
222 if (str != NULL) {
223 printf ("SN: %s\n", str);
224 }
225 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000226}
227
228
229#if defined (CFG_DRAM_TEST)
230/*********************************************************************/
231/* NAME: move64() - moves a double word (64-bit) */
232/* */
233/* DESCRIPTION: */
234/* this function performs a double word move from the data at */
235/* the source pointer to the location at the destination pointer. */
236/* */
237/* INPUTS: */
238/* unsigned long long *src - pointer to data to move */
239/* */
240/* OUTPUTS: */
241/* unsigned long long *dest - pointer to locate to move data */
242/* */
243/* RETURNS: */
244/* None */
245/* */
246/* RESTRICTIONS/LIMITATIONS: */
247/* May cloober fr0. */
248/* */
249/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000250static void move64 (unsigned long long *src, unsigned long long *dest)
wdenkafd7f3d2002-11-03 01:41:26 +0000251{
wdenkbf9e3b32004-02-12 00:47:09 +0000252 asm ("lfd 0, 0(3)\n\t" /* fpr0 = *scr */
253 "stfd 0, 0(4)" /* *dest = fpr0 */
254 : : : "fr0"); /* Clobbers fr0 */
255 return;
wdenkafd7f3d2002-11-03 01:41:26 +0000256}
257
258
259#if defined (CFG_DRAM_TEST_DATA)
260
wdenkbf9e3b32004-02-12 00:47:09 +0000261unsigned long long pattern[] = {
wdenkeedcd072004-09-08 22:03:11 +0000262 0xaaaaaaaaaaaaaaaaULL,
263 0xccccccccccccccccULL,
264 0xf0f0f0f0f0f0f0f0ULL,
265 0xff00ff00ff00ff00ULL,
266 0xffff0000ffff0000ULL,
267 0xffffffff00000000ULL,
268 0x00000000ffffffffULL,
269 0x0000ffff0000ffffULL,
270 0x00ff00ff00ff00ffULL,
271 0x0f0f0f0f0f0f0f0fULL,
272 0x3333333333333333ULL,
273 0x5555555555555555ULL,
wdenkbf9e3b32004-02-12 00:47:09 +0000274};
wdenkafd7f3d2002-11-03 01:41:26 +0000275
276/*********************************************************************/
277/* NAME: mem_test_data() - test data lines for shorts and opens */
278/* */
279/* DESCRIPTION: */
280/* Tests data lines for shorts and opens by forcing adjacent data */
281/* to opposite states. Because the data lines could be routed in */
282/* an arbitrary manner the must ensure test patterns ensure that */
283/* every case is tested. By using the following series of binary */
284/* patterns every combination of adjacent bits is test regardless */
285/* of routing. */
286/* */
287/* ...101010101010101010101010 */
288/* ...110011001100110011001100 */
289/* ...111100001111000011110000 */
290/* ...111111110000000011111111 */
291/* */
292/* Carrying this out, gives us six hex patterns as follows: */
293/* */
294/* 0xaaaaaaaaaaaaaaaa */
295/* 0xcccccccccccccccc */
296/* 0xf0f0f0f0f0f0f0f0 */
297/* 0xff00ff00ff00ff00 */
298/* 0xffff0000ffff0000 */
299/* 0xffffffff00000000 */
300/* */
301/* The number test patterns will always be given by: */
302/* */
303/* log(base 2)(number data bits) = log2 (64) = 6 */
304/* */
305/* To test for short and opens to other signals on our boards. we */
306/* simply */
307/* test with the 1's complemnt of the paterns as well. */
308/* */
309/* OUTPUTS: */
310/* Displays failing test pattern */
311/* */
312/* RETURNS: */
313/* 0 - Passed test */
314/* 1 - Failed test */
315/* */
316/* RESTRICTIONS/LIMITATIONS: */
317/* Assumes only one one SDRAM bank */
318/* */
319/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000320int mem_test_data (void)
wdenkafd7f3d2002-11-03 01:41:26 +0000321{
wdenkbf9e3b32004-02-12 00:47:09 +0000322 unsigned long long *pmem = (unsigned long long *) CFG_SDRAM_BASE;
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200323 unsigned long long temp64 = 0;
wdenkbf9e3b32004-02-12 00:47:09 +0000324 int num_patterns = sizeof (pattern) / sizeof (pattern[0]);
325 int i;
326 unsigned int hi, lo;
wdenkafd7f3d2002-11-03 01:41:26 +0000327
wdenkbf9e3b32004-02-12 00:47:09 +0000328 for (i = 0; i < num_patterns; i++) {
329 move64 (&(pattern[i]), pmem);
330 move64 (pmem, &temp64);
wdenkafd7f3d2002-11-03 01:41:26 +0000331
wdenkbf9e3b32004-02-12 00:47:09 +0000332 /* hi = (temp64>>32) & 0xffffffff; */
333 /* lo = temp64 & 0xffffffff; */
334 /* printf("\ntemp64 = 0x%08x%08x", hi, lo); */
wdenkafd7f3d2002-11-03 01:41:26 +0000335
wdenkbf9e3b32004-02-12 00:47:09 +0000336 hi = (pattern[i] >> 32) & 0xffffffff;
337 lo = pattern[i] & 0xffffffff;
338 /* printf("\npattern[%d] = 0x%08x%08x", i, hi, lo); */
wdenkafd7f3d2002-11-03 01:41:26 +0000339
wdenkbf9e3b32004-02-12 00:47:09 +0000340 if (temp64 != pattern[i]) {
341 printf ("\n Data Test Failed, pattern 0x%08x%08x",
342 hi, lo);
343 return 1;
344 }
wdenkafd7f3d2002-11-03 01:41:26 +0000345 }
wdenkafd7f3d2002-11-03 01:41:26 +0000346
wdenkbf9e3b32004-02-12 00:47:09 +0000347 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000348}
349#endif /* CFG_DRAM_TEST_DATA */
350
351#if defined (CFG_DRAM_TEST_ADDRESS)
352/*********************************************************************/
353/* NAME: mem_test_address() - test address lines */
354/* */
355/* DESCRIPTION: */
356/* This function performs a test to verify that each word im */
357/* memory is uniquly addressable. The test sequence is as follows: */
358/* */
359/* 1) write the address of each word to each word. */
360/* 2) verify that each location equals its address */
361/* */
362/* OUTPUTS: */
363/* Displays failing test pattern and address */
364/* */
365/* RETURNS: */
366/* 0 - Passed test */
367/* 1 - Failed test */
368/* */
369/* RESTRICTIONS/LIMITATIONS: */
370/* */
371/* */
372/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000373int mem_test_address (void)
wdenkafd7f3d2002-11-03 01:41:26 +0000374{
wdenkbf9e3b32004-02-12 00:47:09 +0000375 volatile unsigned int *pmem =
376 (volatile unsigned int *) CFG_SDRAM_BASE;
377 const unsigned int size = (CFG_SDRAM_SIZE * 1024 * 1024) / 4;
378 unsigned int i;
wdenkafd7f3d2002-11-03 01:41:26 +0000379
wdenkbf9e3b32004-02-12 00:47:09 +0000380 /* write address to each location */
381 for (i = 0; i < size; i++) {
382 pmem[i] = i;
wdenkafd7f3d2002-11-03 01:41:26 +0000383 }
wdenkbf9e3b32004-02-12 00:47:09 +0000384
385 /* verify each loaction */
386 for (i = 0; i < size; i++) {
387 if (pmem[i] != i) {
388 printf ("\n Address Test Failed at 0x%x", i);
389 return 1;
390 }
391 }
392 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000393}
394#endif /* CFG_DRAM_TEST_ADDRESS */
395
396#if defined (CFG_DRAM_TEST_WALK)
397/*********************************************************************/
398/* NAME: mem_march() - memory march */
399/* */
400/* DESCRIPTION: */
401/* Marches up through memory. At each location verifies rmask if */
402/* read = 1. At each location write wmask if write = 1. Displays */
403/* failing address and pattern. */
404/* */
405/* INPUTS: */
406/* volatile unsigned long long * base - start address of test */
407/* unsigned int size - number of dwords(64-bit) to test */
408/* unsigned long long rmask - read verify mask */
409/* unsigned long long wmask - wrtie verify mask */
410/* short read - verifies rmask if read = 1 */
411/* short write - writes wmask if write = 1 */
412/* */
413/* OUTPUTS: */
414/* Displays failing test pattern and address */
415/* */
416/* RETURNS: */
417/* 0 - Passed test */
418/* 1 - Failed test */
419/* */
420/* RESTRICTIONS/LIMITATIONS: */
421/* */
422/* */
423/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000424int mem_march (volatile unsigned long long *base,
425 unsigned int size,
426 unsigned long long rmask,
427 unsigned long long wmask, short read, short write)
wdenkafd7f3d2002-11-03 01:41:26 +0000428{
wdenkbf9e3b32004-02-12 00:47:09 +0000429 unsigned int i;
Wolfgang Denk77ddac92005-10-13 16:45:02 +0200430 unsigned long long temp = 0;
wdenkbf9e3b32004-02-12 00:47:09 +0000431 unsigned int hitemp, lotemp, himask, lomask;
wdenkafd7f3d2002-11-03 01:41:26 +0000432
wdenkbf9e3b32004-02-12 00:47:09 +0000433 for (i = 0; i < size; i++) {
434 if (read != 0) {
435 /* temp = base[i]; */
436 move64 ((unsigned long long *) &(base[i]), &temp);
437 if (rmask != temp) {
438 hitemp = (temp >> 32) & 0xffffffff;
439 lotemp = temp & 0xffffffff;
440 himask = (rmask >> 32) & 0xffffffff;
441 lomask = rmask & 0xffffffff;
wdenkafd7f3d2002-11-03 01:41:26 +0000442
wdenkbf9e3b32004-02-12 00:47:09 +0000443 printf ("\n Walking one's test failed: address = 0x%08x," "\n\texpected 0x%08x%08x, found 0x%08x%08x", i << 3, himask, lomask, hitemp, lotemp);
444 return 1;
445 }
446 }
447 if (write != 0) {
448 /* base[i] = wmask; */
449 move64 (&wmask, (unsigned long long *) &(base[i]));
450 }
wdenkafd7f3d2002-11-03 01:41:26 +0000451 }
wdenkbf9e3b32004-02-12 00:47:09 +0000452 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000453}
454#endif /* CFG_DRAM_TEST_WALK */
455
456/*********************************************************************/
457/* NAME: mem_test_walk() - a simple walking ones test */
458/* */
459/* DESCRIPTION: */
460/* Performs a walking ones through entire physical memory. The */
461/* test uses as series of memory marches, mem_march(), to verify */
462/* and write the test patterns to memory. The test sequence is as */
463/* follows: */
464/* 1) march writing 0000...0001 */
465/* 2) march verifying 0000...0001 , writing 0000...0010 */
466/* 3) repeat step 2 shifting masks left 1 bit each time unitl */
467/* the write mask equals 1000...0000 */
468/* 4) march verifying 1000...0000 */
469/* The test fails if any of the memory marches return a failure. */
470/* */
471/* OUTPUTS: */
472/* Displays which pass on the memory test is executing */
473/* */
474/* RETURNS: */
475/* 0 - Passed test */
476/* 1 - Failed test */
477/* */
478/* RESTRICTIONS/LIMITATIONS: */
479/* */
480/* */
481/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000482int mem_test_walk (void)
wdenkafd7f3d2002-11-03 01:41:26 +0000483{
wdenkbf9e3b32004-02-12 00:47:09 +0000484 unsigned long long mask;
485 volatile unsigned long long *pmem =
486 (volatile unsigned long long *) CFG_SDRAM_BASE;
487 const unsigned long size = (CFG_SDRAM_SIZE * 1024 * 1024) / 8;
wdenkafd7f3d2002-11-03 01:41:26 +0000488
wdenkbf9e3b32004-02-12 00:47:09 +0000489 unsigned int i;
wdenkafd7f3d2002-11-03 01:41:26 +0000490
wdenkbf9e3b32004-02-12 00:47:09 +0000491 mask = 0x01;
wdenkafd7f3d2002-11-03 01:41:26 +0000492
wdenkbf9e3b32004-02-12 00:47:09 +0000493 printf ("Initial Pass");
494 mem_march (pmem, size, 0x0, 0x1, 0, 1);
wdenkafd7f3d2002-11-03 01:41:26 +0000495
wdenkbf9e3b32004-02-12 00:47:09 +0000496 printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
497 printf (" ");
498 printf ("\b\b\b\b\b\b\b\b\b\b\b\b");
499
500 for (i = 0; i < 63; i++) {
501 printf ("Pass %2d", i + 2);
502 if (mem_march (pmem, size, mask, mask << 1, 1, 1) != 0) {
503 /*printf("mask: 0x%x, pass: %d, ", mask, i); */
504 return 1;
505 }
506 mask = mask << 1;
507 printf ("\b\b\b\b\b\b\b");
wdenkafd7f3d2002-11-03 01:41:26 +0000508 }
wdenkafd7f3d2002-11-03 01:41:26 +0000509
wdenkbf9e3b32004-02-12 00:47:09 +0000510 printf ("Last Pass");
511 if (mem_march (pmem, size, 0, mask, 0, 1) != 0) {
512 /* printf("mask: 0x%x", mask); */
513 return 1;
514 }
515 printf ("\b\b\b\b\b\b\b\b\b");
516 printf (" ");
517 printf ("\b\b\b\b\b\b\b\b\b");
wdenkafd7f3d2002-11-03 01:41:26 +0000518
wdenkbf9e3b32004-02-12 00:47:09 +0000519 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000520}
521
522/*********************************************************************/
523/* NAME: testdram() - calls any enabled memory tests */
524/* */
525/* DESCRIPTION: */
526/* Runs memory tests if the environment test variables are set to */
527/* 'y'. */
528/* */
529/* INPUTS: */
530/* testdramdata - If set to 'y', data test is run. */
531/* testdramaddress - If set to 'y', address test is run. */
532/* testdramwalk - If set to 'y', walking ones test is run */
533/* */
534/* OUTPUTS: */
535/* None */
536/* */
537/* RETURNS: */
538/* 0 - Passed test */
539/* 1 - Failed test */
540/* */
541/* RESTRICTIONS/LIMITATIONS: */
542/* */
543/* */
544/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000545int testdram (void)
wdenkafd7f3d2002-11-03 01:41:26 +0000546{
wdenkbf9e3b32004-02-12 00:47:09 +0000547 char *s;
548 int rundata, runaddress, runwalk;
wdenkafd7f3d2002-11-03 01:41:26 +0000549
wdenkbf9e3b32004-02-12 00:47:09 +0000550 s = getenv ("testdramdata");
551 rundata = (s && (*s == 'y')) ? 1 : 0;
552 s = getenv ("testdramaddress");
553 runaddress = (s && (*s == 'y')) ? 1 : 0;
554 s = getenv ("testdramwalk");
555 runwalk = (s && (*s == 'y')) ? 1 : 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000556
wdenkbf9e3b32004-02-12 00:47:09 +0000557 if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
558 printf ("Testing RAM ... ");
wdenkafd7f3d2002-11-03 01:41:26 +0000559 }
wdenkbf9e3b32004-02-12 00:47:09 +0000560#ifdef CFG_DRAM_TEST_DATA
561 if (rundata == 1) {
562 if (mem_test_data () == 1) {
563 return 1;
564 }
565 }
wdenkafd7f3d2002-11-03 01:41:26 +0000566#endif
567#ifdef CFG_DRAM_TEST_ADDRESS
wdenkbf9e3b32004-02-12 00:47:09 +0000568 if (runaddress == 1) {
569 if (mem_test_address () == 1) {
570 return 1;
571 }
wdenkafd7f3d2002-11-03 01:41:26 +0000572 }
wdenkafd7f3d2002-11-03 01:41:26 +0000573#endif
574#ifdef CFG_DRAM_TEST_WALK
wdenkbf9e3b32004-02-12 00:47:09 +0000575 if (runwalk == 1) {
576 if (mem_test_walk () == 1) {
577 return 1;
578 }
wdenkafd7f3d2002-11-03 01:41:26 +0000579 }
wdenkafd7f3d2002-11-03 01:41:26 +0000580#endif
wdenkbf9e3b32004-02-12 00:47:09 +0000581 if ((rundata == 1) || (runaddress == 1) || (runwalk == 1)) {
582 printf ("passed");
583 }
584 return 0;
wdenkafd7f3d2002-11-03 01:41:26 +0000585
586}
587#endif /* CFG_DRAM_TEST */
588
589/*********************************************************************/
590/* NAME: initdram() - initializes SDRAM controller */
591/* */
592/* DESCRIPTION: */
593/* Initializes the MPC8260's SDRAM controller. */
594/* */
595/* INPUTS: */
596/* CFG_IMMR - MPC8260 Internal memory map */
597/* CFG_SDRAM_BASE - Physical start address of SDRAM */
598/* CFG_PSDMR - SDRAM mode register */
599/* CFG_MPTPR - Memory refresh timer prescaler register */
600/* CFG_SDRAM0_SIZE - SDRAM size */
601/* */
602/* RETURNS: */
603/* SDRAM size in bytes */
604/* */
605/* RESTRICTIONS/LIMITATIONS: */
606/* */
607/* */
608/*********************************************************************/
wdenkbf9e3b32004-02-12 00:47:09 +0000609long int initdram (int board_type)
wdenkafd7f3d2002-11-03 01:41:26 +0000610{
wdenkbf9e3b32004-02-12 00:47:09 +0000611 volatile immap_t *immap = (immap_t *) CFG_IMMR;
612 volatile memctl8260_t *memctl = &immap->im_memctl;
613 volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8);
614 ulong psdmr = CFG_PSDMR;
615 int i;
wdenkafd7f3d2002-11-03 01:41:26 +0000616
wdenkbf9e3b32004-02-12 00:47:09 +0000617 /*
618 * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
619 *
620 * "At system reset, initialization software must set up the
621 * programmable parameters in the memory controller banks registers
622 * (ORx, BRx, P/LSDMR). After all memory parameters are configured,
623 * system software should execute the following initialization sequence
624 * for each SDRAM device.
625 *
626 * 1. Issue a PRECHARGE-ALL-BANKS command
627 * 2. Issue eight CBR REFRESH commands
628 * 3. Issue a MODE-SET command to initialize the mode register
629 *
630 * The initial commands are executed by setting P/LSDMR[OP] and
631 * accessing the SDRAM with a single-byte transaction."
632 *
633 * The appropriate BRx/ORx registers have already been set when we
634 * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
635 */
wdenkafd7f3d2002-11-03 01:41:26 +0000636
wdenkbf9e3b32004-02-12 00:47:09 +0000637 memctl->memc_psrt = CFG_PSRT;
638 memctl->memc_mptpr = CFG_MPTPR;
wdenkafd7f3d2002-11-03 01:41:26 +0000639
wdenkbf9e3b32004-02-12 00:47:09 +0000640 memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
wdenkafd7f3d2002-11-03 01:41:26 +0000641 *ramaddr = c;
wdenkafd7f3d2002-11-03 01:41:26 +0000642
wdenkbf9e3b32004-02-12 00:47:09 +0000643 memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
644 for (i = 0; i < 8; i++) {
645 *ramaddr = c;
646 }
647 memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
648 *ramaddr = c;
wdenkafd7f3d2002-11-03 01:41:26 +0000649
wdenkbf9e3b32004-02-12 00:47:09 +0000650 memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
651 *ramaddr = c;
652
653 /* return total ram size */
654 return (CFG_SDRAM0_SIZE * 1024 * 1024);
wdenkafd7f3d2002-11-03 01:41:26 +0000655}
656
657/*********************************************************************/
658/* End of gw8260.c */
659/*********************************************************************/