]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/ppc4xx/sdram.c
rename CFG_ macros to CONFIG_SYS
[people/ms/u-boot.git] / cpu / ppc4xx / sdram.c
CommitLineData
c609719b 1/*
5fb692ca 2 * (C) Copyright 2005-2007
5568e613
SR
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
4 *
62534beb
SR
5 * (C) Copyright 2006
6 * DAVE Srl <www.dave-tech.it>
7 *
de8d5a36 8 * (C) Copyright 2002-2004
c609719b
WD
9 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
10 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
cf48eb9a 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
c609719b
WD
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <common.h>
31#include <ppc4xx.h>
32#include <asm/processor.h>
62534beb 33#include "sdram.h"
c821b5f1 34#include "ecc.h"
c609719b 35
c609719b
WD
36#ifdef CONFIG_SDRAM_BANK0
37
5fb692ca 38#ifndef CONFIG_440
c609719b 39
6d0f6bcf 40#ifndef CONFIG_SYS_SDRAM_TABLE
de8d5a36 41sdram_conf_t mb0cf[] = {
cf48eb9a
WD
42 {(128 << 20), 13, 0x000A4001}, /* (0-128MB) Address Mode 3, 13x10(4) */
43 {(64 << 20), 13, 0x00084001}, /* (0-64MB) Address Mode 3, 13x9(4) */
44 {(32 << 20), 12, 0x00062001}, /* (0-32MB) Address Mode 2, 12x9(4) */
45 {(16 << 20), 12, 0x00046001}, /* (0-16MB) Address Mode 4, 12x8(4) */
46 {(4 << 20), 11, 0x00008001}, /* (0-4MB) Address Mode 5, 11x8(2) */
de8d5a36 47};
5568e613 48#else
6d0f6bcf 49sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
5568e613
SR
50#endif
51
cf48eb9a 52#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
c609719b 53
6d0f6bcf 54#ifdef CONFIG_SYS_SDRAM_CASL
62534beb
SR
55static ulong ns2clks(ulong ns)
56{
57 ulong bus_period_x_10 = ONE_BILLION / (get_bus_freq(0) / 10);
58
59 return ((ns * 10) + bus_period_x_10) / bus_period_x_10;
60}
6d0f6bcf 61#endif /* CONFIG_SYS_SDRAM_CASL */
62534beb
SR
62
63static ulong compute_sdtr1(ulong speed)
64{
6d0f6bcf 65#ifdef CONFIG_SYS_SDRAM_CASL
cf48eb9a
WD
66 ulong tmp;
67 ulong sdtr1 = 0;
68
69 /* CASL */
6d0f6bcf 70 if (CONFIG_SYS_SDRAM_CASL < 2)
cf48eb9a
WD
71 sdtr1 |= (1 << SDRAM0_TR_CASL);
72 else
6d0f6bcf 73 if (CONFIG_SYS_SDRAM_CASL > 4)
cf48eb9a
WD
74 sdtr1 |= (3 << SDRAM0_TR_CASL);
75 else
6d0f6bcf 76 sdtr1 |= ((CONFIG_SYS_SDRAM_CASL-1) << SDRAM0_TR_CASL);
cf48eb9a
WD
77
78 /* PTA */
6d0f6bcf 79 tmp = ns2clks(CONFIG_SYS_SDRAM_PTA);
cf48eb9a
WD
80 if ((tmp >= 2) && (tmp <= 4))
81 sdtr1 |= ((tmp-1) << SDRAM0_TR_PTA);
82 else
83 sdtr1 |= ((4-1) << SDRAM0_TR_PTA);
84
85 /* CTP */
6d0f6bcf 86 tmp = ns2clks(CONFIG_SYS_SDRAM_CTP);
cf48eb9a
WD
87 if ((tmp >= 2) && (tmp <= 4))
88 sdtr1 |= ((tmp-1) << SDRAM0_TR_CTP);
89 else
90 sdtr1 |= ((4-1) << SDRAM0_TR_CTP);
91
92 /* LDF */
6d0f6bcf 93 tmp = ns2clks(CONFIG_SYS_SDRAM_LDF);
cf48eb9a
WD
94 if ((tmp >= 2) && (tmp <= 4))
95 sdtr1 |= ((tmp-1) << SDRAM0_TR_LDF);
96 else
97 sdtr1 |= ((2-1) << SDRAM0_TR_LDF);
98
99 /* RFTA */
6d0f6bcf 100 tmp = ns2clks(CONFIG_SYS_SDRAM_RFTA);
cf48eb9a
WD
101 if ((tmp >= 4) && (tmp <= 10))
102 sdtr1 |= ((tmp-4) << SDRAM0_TR_RFTA);
103 else
104 sdtr1 |= ((10-4) << SDRAM0_TR_RFTA);
105
106 /* RCD */
6d0f6bcf 107 tmp = ns2clks(CONFIG_SYS_SDRAM_RCD);
cf48eb9a
WD
108 if ((tmp >= 2) && (tmp <= 4))
109 sdtr1 |= ((tmp-1) << SDRAM0_TR_RCD);
110 else
111 sdtr1 |= ((4-1) << SDRAM0_TR_RCD);
112
113 return sdtr1;
6d0f6bcf 114#else /* CONFIG_SYS_SDRAM_CASL */
cf48eb9a
WD
115 /*
116 * If no values are configured in the board config file
117 * use the default values, which seem to be ok for most
118 * boards.
119 *
120 * REMARK:
121 * For new board ports we strongly recommend to define the
122 * correct values for the used SDRAM chips in your board
123 * config file (see PPChameleonEVB.h)
124 */
125 if (speed > 100000000) {
126 /*
127 * 133 MHz SDRAM
128 */
129 return 0x01074015;
130 } else {
131 /*
132 * default: 100 MHz SDRAM
133 */
134 return 0x0086400d;
135 }
6d0f6bcf 136#endif /* CONFIG_SYS_SDRAM_CASL */
62534beb
SR
137}
138
139/* refresh is expressed in ms */
140static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
141{
6d0f6bcf 142#ifdef CONFIG_SYS_SDRAM_CASL
cf48eb9a 143 ulong tmp;
62534beb 144
cf48eb9a
WD
145 tmp = ((refresh*1000*1000) / (1 << rows)) * (speed / 1000);
146 tmp /= 1000000;
62534beb 147
cf48eb9a 148 return ((tmp & 0x00003FF8) << 16);
6d0f6bcf 149#else /* CONFIG_SYS_SDRAM_CASL */
cf48eb9a
WD
150 if (speed > 100000000) {
151 /*
152 * 133 MHz SDRAM
153 */
62534beb 154 return 0x07f00000;
cf48eb9a
WD
155 } else {
156 /*
157 * default: 100 MHz SDRAM
158 */
62534beb 159 return 0x05f00000;
cf48eb9a 160 }
6d0f6bcf 161#endif /* CONFIG_SYS_SDRAM_CASL */
62534beb
SR
162}
163
5568e613
SR
164/*
165 * Autodetect onboard SDRAM on 405 platforms
166 */
9973e3c6 167phys_size_t initdram(int board_type)
c609719b 168{
62534beb 169 ulong speed;
c609719b 170 ulong sdtr1;
de8d5a36 171 int i;
c609719b 172
cf48eb9a
WD
173 /*
174 * Determine SDRAM speed
175 */
176 speed = get_bus_freq(0); /* parameter not used on ppc4xx */
62534beb 177
cf48eb9a
WD
178 /*
179 * sdtr1 (register SDRAM0_TR) must take into account timings listed
180 * in SDRAM chip datasheet. rtr (register SDRAM0_RTR) must take into
181 * account actual SDRAM size. So we can set up sdtr1 according to what
182 * is specified in board configuration file while rtr dependds on SDRAM
183 * size we are assuming before detection.
184 */
185 sdtr1 = compute_sdtr1(speed);
c609719b 186
de8d5a36 187 for (i=0; i<N_MB0CF; i++) {
6177445d 188 /*
de8d5a36 189 * Disable memory controller.
6177445d 190 */
779e9751 191 mtsdram(mem_mcopt1, 0x00000000);
e5ad56b1 192
c609719b 193 /*
de8d5a36 194 * Set MB0CF for bank 0.
c609719b 195 */
779e9751
SR
196 mtsdram(mem_mb0cf, mb0cf[i].reg);
197 mtsdram(mem_sdtr1, sdtr1);
198 mtsdram(mem_rtr, compute_rtr(speed, mb0cf[i].rows, 64));
e5ad56b1 199
de8d5a36 200 udelay(200);
c609719b 201
c609719b 202 /*
de8d5a36
SR
203 * Set memory controller options reg, MCOPT1.
204 * Set DC_EN to '1' and BRD_PRF to '01' for 16 byte PLB Burst
205 * read/prefetch.
c609719b 206 */
779e9751 207 mtsdram(mem_mcopt1, 0x80800000);
c609719b 208
de8d5a36 209 udelay(10000);
c609719b 210
de8d5a36 211 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
7bf5ecfa
SR
212 phys_size_t size = mb0cf[i].size;
213
de8d5a36 214 /*
d4024bb7
JO
215 * OK, size detected. Enable second bank if
216 * defined (assumes same type as bank 0)
de8d5a36 217 */
d4024bb7 218#ifdef CONFIG_SDRAM_BANK1
779e9751 219 mtsdram(mem_mcopt1, 0x00000000);
7bf5ecfa 220 mtsdram(mem_mb1cf, mb0cf[i].size | mb0cf[i].reg);
779e9751 221 mtsdram(mem_mcopt1, 0x80800000);
d4024bb7 222 udelay(10000);
779e9751
SR
223
224 /*
225 * Check if 2nd bank is really available.
226 * If the size not equal to the size of the first
227 * bank, then disable the 2nd bank completely.
228 */
229 if (get_ram_size((long *)mb0cf[i].size, mb0cf[i].size) !=
230 mb0cf[i].size) {
231 mtsdram(mem_mb1cf, 0);
232 mtsdram(mem_mcopt1, 0);
7bf5ecfa
SR
233 } else {
234 /*
235 * We have two identical banks, so the size
236 * is twice the bank size
237 */
238 size = 2 * size;
779e9751 239 }
d4024bb7 240#endif
bbeff30c
SR
241
242 /*
243 * OK, size detected -> all done
244 */
7bf5ecfa 245 return size;
de8d5a36 246 }
6177445d 247 }
bbeff30c
SR
248
249 return 0;
c609719b
WD
250}
251
5568e613
SR
252#else /* CONFIG_440 */
253
5fb692ca
SR
254/*
255 * Define some default values. Those can be overwritten in the
256 * board config file.
257 */
258
6d0f6bcf 259#ifndef CONFIG_SYS_SDRAM_TABLE
5fb692ca
SR
260sdram_conf_t mb0cf[] = {
261 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
262 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
263};
264#else
6d0f6bcf 265sdram_conf_t mb0cf[] = CONFIG_SYS_SDRAM_TABLE;
5fb692ca
SR
266#endif
267
6d0f6bcf
JCPV
268#ifndef CONFIG_SYS_SDRAM0_TR0
269#define CONFIG_SYS_SDRAM0_TR0 0x41094012
5fb692ca
SR
270#endif
271
272#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
273
62534beb
SR
274#define NUM_TRIES 64
275#define NUM_READS 10
276
277static void sdram_tr1_set(int ram_address, int* tr1_value)
278{
279 int i;
280 int j, k;
281 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
282 int first_good = -1, last_bad = 0x1ff;
283
284 unsigned long test[NUM_TRIES] = {
285 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
286 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
287 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
288 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
289 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
290 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
291 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
292 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
293 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
294 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
295 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
296 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
297 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
298 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
299 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
300 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
301
302 /* go through all possible SDRAM0_TR1[RDCT] values */
303 for (i=0; i<=0x1ff; i++) {
304 /* set the current value for TR1 */
305 mtsdram(mem_tr1, (0x80800800 | i));
306
307 /* write values */
308 for (j=0; j<NUM_TRIES; j++) {
309 ram_pointer[j] = test[j];
310
311 /* clear any cache at ram location */
312 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
313 }
314
315 /* read values back */
316 for (j=0; j<NUM_TRIES; j++) {
317 for (k=0; k<NUM_READS; k++) {
318 /* clear any cache at ram location */
319 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
320
321 if (ram_pointer[j] != test[j])
322 break;
323 }
324
325 /* read error */
326 if (k != NUM_READS)
327 break;
328 }
329
330 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
331 if (j == NUM_TRIES) {
332 if (first_good == -1)
333 first_good = i; /* found beginning of window */
334 } else { /* bad read */
335 /* if we have not had a good read then don't care */
336 if (first_good != -1) {
337 /* first failure after a good read */
338 last_bad = i-1;
339 break;
340 }
341 }
342 }
343
344 /* return the current value for TR1 */
345 *tr1_value = (first_good + last_bad) / 2;
346}
347
5568e613
SR
348/*
349 * Autodetect onboard DDR SDRAM on 440 platforms
350 *
351 * NOTE: Some of the hardcoded values are hardware dependant,
cf48eb9a
WD
352 * so this should be extended for other future boards
353 * using this routine!
5568e613 354 */
9973e3c6 355phys_size_t initdram(int board_type)
5568e613
SR
356{
357 int i;
62534beb 358 int tr1_bank1;
5568e613 359
5fb692ca
SR
360#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
361 defined(CONFIG_440GR) || defined(CONFIG_440SP)
899620c2
SR
362 /*
363 * Soft-reset SDRAM controller.
364 */
365 mtsdr(sdr_srst, SDR0_SRST_DMC);
366 mtsdr(sdr_srst, 0x00000000);
367#endif
368
5568e613
SR
369 for (i=0; i<N_MB0CF; i++) {
370 /*
371 * Disable memory controller.
372 */
373 mtsdram(mem_cfg0, 0x00000000);
374
375 /*
376 * Setup some default
377 */
cf48eb9a
WD
378 mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
379 mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
5568e613
SR
380 mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
381 mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
cf48eb9a 382 mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
5568e613
SR
383
384 /*
385 * Following for CAS Latency = 2.5 @ 133 MHz PLB
386 */
387 mtsdram(mem_b0cr, mb0cf[i].reg);
6d0f6bcf 388 mtsdram(mem_tr0, CONFIG_SYS_SDRAM0_TR0);
5568e613 389 mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
f07ae7a9 390