blob: 8a6b5b00a9cbf9b59e61a51299de540d0b86ab75 [file] [log] [blame]
wdenk7ca202f2004-08-28 22:45:57 +00001/*
dzu@denx.dea367d422006-04-19 11:52:46 +02002 * (C) Copyright 2006 Detlev Zundel, dzu@denx.de
wdenk7ca202f2004-08-28 22:45:57 +00003 * (C) Copyright 2001
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.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 <config.h>
27#include <mpc8xx.h>
28
29/*
30 * Memory Controller Using
31 *
32 * CS0 - Flash memory (0x40000000)
33 * CS3 - SDRAM (0x00000000}
34 */
35
36/* ------------------------------------------------------------------------- */
37
38#define _not_used_ 0xffffffff
39
40const uint sdram_table[] = {
41 /* single read. (offset 0 in upm RAM) */
42 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
43 0x1ff77c47,
44
45 /* MRS initialization (offset 5) */
46
47 0x1ff77c34, 0xefeabc34, 0x1fb57c35,
48
49 /* burst read. (offset 8 in upm RAM) */
50 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
51 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
52 _not_used_, _not_used_, _not_used_, _not_used_,
53 _not_used_, _not_used_, _not_used_, _not_used_,
54
55 /* single write. (offset 18 in upm RAM) */
56 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
57 _not_used_, _not_used_, _not_used_, _not_used_,
58
59 /* burst write. (offset 20 in upm RAM) */
60 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
61 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
62 _not_used_, _not_used_, _not_used_, _not_used_,
63 _not_used_, _not_used_, _not_used_, _not_used_,
64
65 /* refresh. (offset 30 in upm RAM) */
66 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
67 0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
68 _not_used_, _not_used_, _not_used_, _not_used_,
69
70 /* exception. (offset 3c in upm RAM) */
71 0x7ffffc07, _not_used_, _not_used_, _not_used_
72};
73
wdenkc3fafec2005-03-14 23:01:03 +000074const uint nand_flash_table[] = {
75 /* single read. (offset 0 in upm RAM) */
76 0x0ff3fc04, 0x0ff3fc04, 0x0ff3fc04, 0x0ffffc04,
77 0xfffffc00, 0xfffffc05, 0xfffffc05, 0xfffffc05,
78
79 /* burst read. (offset 8 in upm RAM) */
80 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
81 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
82 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
83 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
84
85 /* single write. (offset 18 in upm RAM) */
86 0x00fffc04, 0x00fffc04, 0x00fffc04, 0x0ffffc04,
87 0x0ffffc84, 0x0ffffc84, 0xfffffc00, 0xfffffc05,
88
89 /* burst write. (offset 20 in upm RAM) */
90 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
91 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
92 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
93 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
94
95 /* refresh. (offset 30 in upm RAM) */
96 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
97 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
98 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05,
99
100 /* exception. (offset 3c in upm RAM) */
101 0xffffcc05, 0xffffcc05, 0xffffcc05, 0xffffcc05
102};
103
wdenk7ca202f2004-08-28 22:45:57 +0000104/* ------------------------------------------------------------------------- */
105
106/*
107 * Check Board Identity:
108 */
109
110int checkboard (void)
111{
dzu@denx.dea367d422006-04-19 11:52:46 +0200112#if !defined(CONFIG_CP850)
113 puts ("Board: NC650");
114#else
115 puts ("Board: CP850");
116#endif
117#if defined(CONFIG_IDS852_REV1)
118 puts (" with IDS852 rev 1 module\n");
119#elif defined(CONFIG_IDS852_REV2)
120 puts (" with IDS852 rev 2 module\n");
121#endif
wdenk7ca202f2004-08-28 22:45:57 +0000122 return 0;
123}
124
125/* ------------------------------------------------------------------------- */
126
127static long int dram_size (long int, long int *, long int);
128
129/* ------------------------------------------------------------------------- */
130
131long int initdram (int board_type)
132{
133 volatile immap_t *immap = (immap_t *) CFG_IMMR;
134 volatile memctl8xx_t *memctl = &immap->im_memctl;
135 long int size8, size9;
136 long int size_b0 = 0;
137 unsigned long reg;
138
139 upmconfig (UPMA, (uint *) sdram_table,
140 sizeof (sdram_table) / sizeof (uint));
141
142 /*
143 * Preliminary prescaler for refresh (depends on number of
144 * banks): This value is selected for four cycles every 62.4 us
145 * with two SDRAM banks or four cycles every 31.2 us with one
146 * bank. It will be adjusted after memory sizing.
147 */
148 memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
149
150 memctl->memc_mar = 0x00000088;
151
152 /*
153 * Map controller bank 1 to the SDRAM bank at
154 * preliminary address - these have to be modified after the
155 * SDRAM size has been determined.
156 */
157 memctl->memc_or3 = CFG_OR3_PRELIM;
158 memctl->memc_br3 = CFG_BR3_PRELIM;
159
160 memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
161
162 udelay (200);
163
164 /* perform SDRAM initializsation sequence */
165
166 memctl->memc_mcr = 0x80006105; /* SDRAM bank 0 */
167 udelay (200);
168 memctl->memc_mcr = 0x80006230; /* SDRAM bank 0 - execute twice */
169 udelay (200);
170
171 memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
172
173 udelay (1000);
174
175 /*
176 * Check Bank 0 Memory Size for re-configuration
177 *
178 * try 8 column mode
179 */
180 size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE3_PRELIM,
181 SDRAM_MAX_SIZE);
182
183 udelay (1000);
184
185 /*
186 * try 9 column mode
187 */
188 size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE3_PRELIM,
189 SDRAM_MAX_SIZE);
190
191 udelay (1000);
192
193 if (size8 < size9) {
194 size_b0 = size9;
195 } else {
196 size_b0 = size8;
197 memctl->memc_mamr = CFG_MAMR_8COL;
198 udelay (500);
199 }
200
201 /*
202 * Adjust refresh rate depending on SDRAM type, both banks.
203 * For types > 128 MBit leave it at the current (fast) rate
204 */
205 if ((size_b0 < 0x02000000)) {
206 /* reduce to 15.6 us (62.4 us / quad) */
207 memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
208 udelay (1000);
209 }
210
211 /*
212 * Final mapping
213 */
214
215 memctl->memc_or3 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
216 memctl->memc_br3 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
217
218 /* adjust refresh rate depending on SDRAM type, one bank */
219 reg = memctl->memc_mptpr;
220 reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
221 memctl->memc_mptpr = reg;
222
223 udelay (10000);
224
wdenkc3fafec2005-03-14 23:01:03 +0000225 /* Configure UPMB for NAND flash access */
226 upmconfig (UPMB, (uint *) nand_flash_table,
227 sizeof (nand_flash_table) / sizeof (uint));
228
229 memctl->memc_mbmr = CFG_MBMR_NAND;
230
wdenk7ca202f2004-08-28 22:45:57 +0000231 return (size_b0);
232}
233
234/* ------------------------------------------------------------------------- */
235
236/*
237 * Check memory range for valid RAM. A simple memory test determines
238 * the actually available RAM size between addresses `base' and
239 * `base + maxsize'. Some (not all) hardware errors are detected:
240 * - short between address lines
241 * - short between data lines
242 */
243
wdenk8b74bf32004-10-11 23:10:30 +0000244static long int dram_size (long int mamr_value, long int *base, long int maxsize)
wdenk7ca202f2004-08-28 22:45:57 +0000245{
246 volatile immap_t *immap = (immap_t *) CFG_IMMR;
247 volatile memctl8xx_t *memctl = &immap->im_memctl;
248
249 memctl->memc_mamr = mamr_value;
250
251 return (get_ram_size(base, maxsize));
252}
wdenk4cfaf552004-10-11 23:03:10 +0000253
dzu@denx.dea367d422006-04-19 11:52:46 +0200254
255#if defined(CONFIG_CP850)
256
257#define DPRAM_VARNAME "KP850DIP"
258#define PARAM_ADDR 0x7C0
259#define NAME_ADDR 0x7F8
260#define BOARD_NAME "KP01"
261#define DEFAULT_LB "241111"
262
263int misc_init_r(void)
wdenk4cfaf552004-10-11 23:03:10 +0000264{
dzu@denx.dea367d422006-04-19 11:52:46 +0200265 int iCompatMode = 0;
266 char *pParam = NULL;
267 char *envlb;
Wolfgang Denk610cf362006-05-03 01:24:04 +0200268
269 /*
dzu@denx.dea367d422006-04-19 11:52:46 +0200270 First byte in CPLD read address space signals compatibility mode
271 0 - cp850
272 1 - kp852
273 */
274 pParam = (char*)(CFG_CPLD_BASE);
275 if( *pParam != 0)
276 iCompatMode = 1;
Wolfgang Denk610cf362006-05-03 01:24:04 +0200277
dzu@denx.dea367d422006-04-19 11:52:46 +0200278 if ( iCompatMode != 0) {
Wolfgang Denk610cf362006-05-03 01:24:04 +0200279 /*
dzu@denx.dea367d422006-04-19 11:52:46 +0200280 In KP852 compatibility mode we have to write to
281 DPRAM as early as possible the binary coded
282 line config and board name.
283 The line config is derived from the environment
284 variable DPRAM_VARNAME by converting from ASCII
285 to binary per character.
286 */
287 if ( (envlb = getenv ( DPRAM_VARNAME )) == 0) {
288 setenv( DPRAM_VARNAME, DEFAULT_LB);
289 envlb = DEFAULT_LB;
290 }
Wolfgang Denk610cf362006-05-03 01:24:04 +0200291
dzu@denx.dea367d422006-04-19 11:52:46 +0200292 /* Status string */
293 printf("Mode: KP852(LB=%s)\n", envlb);
wdenk8b74bf32004-10-11 23:10:30 +0000294
dzu@denx.dea367d422006-04-19 11:52:46 +0200295 /* copy appl init */
296 pParam = (char*)(DPRAM_BASE_ADDR + PARAM_ADDR);
297 while (*envlb) {
298 *(pParam++) = *(envlb++) - '0';
299 }
300 *pParam = '\0';
wdenk4cfaf552004-10-11 23:03:10 +0000301
dzu@denx.dea367d422006-04-19 11:52:46 +0200302 /* copy board id */
303 pParam = (char*)(DPRAM_BASE_ADDR + NAME_ADDR);
304 strcpy( pParam, BOARD_NAME);
305 } else {
306 puts("Mode: CP850\n");
307 }
Wolfgang Denk610cf362006-05-03 01:24:04 +0200308
dzu@denx.dea367d422006-04-19 11:52:46 +0200309 return 0;
wdenk4cfaf552004-10-11 23:03:10 +0000310}
311#endif