]> git.ipfire.org Git - people/ms/u-boot.git/blame - cpu/ppc4xx/sdram.c
Change initdram() return type to phys_size_t
[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
5568e613 40#ifndef CFG_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
SR
48#else
49sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
50#endif
51
cf48eb9a 52#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
c609719b 53
62534beb
SR
54#ifdef CFG_SDRAM_CASL
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}
61#endif /* CFG_SDRAM_CASL */
62
63static ulong compute_sdtr1(ulong speed)
64{
65#ifdef CFG_SDRAM_CASL
cf48eb9a
WD
66 ulong tmp;
67 ulong sdtr1 = 0;
68
69 /* CASL */
70 if (CFG_SDRAM_CASL < 2)
71 sdtr1 |= (1 << SDRAM0_TR_CASL);
72 else
73 if (CFG_SDRAM_CASL > 4)
74 sdtr1 |= (3 << SDRAM0_TR_CASL);
75 else
76 sdtr1 |= ((CFG_SDRAM_CASL-1) << SDRAM0_TR_CASL);
77
78 /* PTA */
79 tmp = ns2clks(CFG_SDRAM_PTA);
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 */
86 tmp = ns2clks(CFG_SDRAM_CTP);
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 */
93 tmp = ns2clks(CFG_SDRAM_LDF);
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 */
100 tmp = ns2clks(CFG_SDRAM_RFTA);
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 */
107 tmp = ns2clks(CFG_SDRAM_RCD);
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;
62534beb 114#else /* CFG_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 }
62534beb
SR
136#endif /* CFG_SDRAM_CASL */
137}
138
139/* refresh is expressed in ms */
140static ulong compute_rtr(ulong speed, ulong rows, ulong refresh)
141{
142#ifdef CFG_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);
62534beb 149#else /* CFG_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 }
62534beb
SR
161#endif /* CFG_SDRAM_CASL */
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
SR
211 if (get_ram_size(0, mb0cf[i].size) == mb0cf[i].size) {
212 /*
d4024bb7
JO
213 * OK, size detected. Enable second bank if
214 * defined (assumes same type as bank 0)
de8d5a36 215 */
d4024bb7
JO
216#ifdef CONFIG_SDRAM_BANK1
217 u32 b1cr = mb0cf[i].size | mb0cf[i].reg;
218
779e9751
SR
219 mtsdram(mem_mcopt1, 0x00000000);
220 mtsdram(mem_mb1cf, b1cr); /* SDRAM0_B1CR */
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);
233 }
d4024bb7 234#endif
bbeff30c
SR
235
236 /*
237 * OK, size detected -> all done
238 */
239 return mb0cf[i].size;
de8d5a36 240 }
6177445d 241 }
bbeff30c
SR
242
243 return 0;
c609719b
WD
244}
245
5568e613
SR
246#else /* CONFIG_440 */
247
5fb692ca
SR
248/*
249 * Define some default values. Those can be overwritten in the
250 * board config file.
251 */
252
253#ifndef CFG_SDRAM_TABLE
254sdram_conf_t mb0cf[] = {
255 {(256 << 20), 13, 0x000C4001}, /* 256MB mode 3, 13x10(4) */
256 {(64 << 20), 12, 0x00082001} /* 64MB mode 2, 12x9(4) */
257};
258#else
259sdram_conf_t mb0cf[] = CFG_SDRAM_TABLE;
260#endif
261
262#ifndef CFG_SDRAM0_TR0
263#define CFG_SDRAM0_TR0 0x41094012
264#endif
265
266#define N_MB0CF (sizeof(mb0cf) / sizeof(mb0cf[0]))
267
62534beb
SR
268#define NUM_TRIES 64
269#define NUM_READS 10
270
271static void sdram_tr1_set(int ram_address, int* tr1_value)
272{
273 int i;
274 int j, k;
275 volatile unsigned int* ram_pointer = (unsigned int *)ram_address;
276 int first_good = -1, last_bad = 0x1ff;
277
278 unsigned long test[NUM_TRIES] = {
279 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
280 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
281 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
282 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
283 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
284 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
285 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
286 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
287 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
288 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
289 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
290 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
291 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
292 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
293 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
294 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55 };
295
296 /* go through all possible SDRAM0_TR1[RDCT] values */
297 for (i=0; i<=0x1ff; i++) {
298 /* set the current value for TR1 */
299 mtsdram(mem_tr1, (0x80800800 | i));
300
301 /* write values */
302 for (j=0; j<NUM_TRIES; j++) {
303 ram_pointer[j] = test[j];
304
305 /* clear any cache at ram location */
306 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
307 }
308
309 /* read values back */
310 for (j=0; j<NUM_TRIES; j++) {
311 for (k=0; k<NUM_READS; k++) {
312 /* clear any cache at ram location */
313 __asm__("dcbf 0,%0": :"r" (&ram_pointer[j]));
314
315 if (ram_pointer[j] != test[j])
316 break;
317 }
318
319 /* read error */
320 if (k != NUM_READS)
321 break;
322 }
323
324 /* we have a SDRAM0_TR1[RDCT] that is part of the window */
325 if (j == NUM_TRIES) {
326 if (first_good == -1)
327 first_good = i; /* found beginning of window */
328 } else { /* bad read */
329 /* if we have not had a good read then don't care */
330 if (first_good != -1) {
331 /* first failure after a good read */
332 last_bad = i-1;
333 break;
334 }
335 }
336 }
337
338 /* return the current value for TR1 */
339 *tr1_value = (first_good + last_bad) / 2;
340}
341
5568e613
SR
342/*
343 * Autodetect onboard DDR SDRAM on 440 platforms
344 *
345 * NOTE: Some of the hardcoded values are hardware dependant,
cf48eb9a
WD
346 * so this should be extended for other future boards
347 * using this routine!
5568e613 348 */
9973e3c6 349phys_size_t initdram(int board_type)
5568e613
SR
350{
351 int i;
62534beb 352 int tr1_bank1;
5568e613 353
5fb692ca
SR
354#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
355 defined(CONFIG_440GR) || defined(CONFIG_440SP)
899620c2
SR
356 /*
357 * Soft-reset SDRAM controller.
358 */
359 mtsdr(sdr_srst, SDR0_SRST_DMC);
360 mtsdr(sdr_srst, 0x00000000);
361#endif
362
5568e613
SR
363 for (i=0; i<N_MB0CF; i++) {
364 /*
365 * Disable memory controller.
366 */
367 mtsdram(mem_cfg0, 0x00000000);
368
369 /*
370 * Setup some default
371 */
cf48eb9a
WD
372 mtsdram(mem_uabba, 0x00000000); /* ubba=0 (default) */
373 mtsdram(mem_slio, 0x00000000); /* rdre=0 wrre=0 rarw=0 */
5568e613
SR
374 mtsdram(mem_devopt, 0x00000000); /* dll=0 ds=0 (normal) */
375 mtsdram(mem_wddctr, 0x00000000); /* wrcp=0 dcd=0 */
cf48eb9a 376 mtsdram(mem_clktr, 0x40000000); /* clkp=1 (90 deg wr) dcdt=0 */
5568e613
SR
377
378 /*
379 * Following for CAS Latency = 2.5 @ 133 MHz PLB
380 */
381 mtsdram(mem_b0cr, mb0cf[i].reg);
5fb692ca 382 mtsdram(mem_tr0, CFG_SDRAM0_TR0);
5568e613 383 mtsdram(mem_tr1, 0x80800800); /* SS=T2 SL=STAGE 3 CD=1 CT=0x00*/
f07ae7a9 384