blob: b7eeaf2fe26984bd91ff5423bd66bd7a20fcf909 [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
Stefan Roese36d830c2007-02-20 10:35:42 +01002 * cpu/ppc4xx/44x_spd_ddr.c
3 * This SPD DDR detection code supports IBM/AMCC PPC44x cpu with a
4 * DDR controller. Those are 440GP/GX/EP/GR.
5 *
wdenkfe8c2802002-11-03 00:38:21 +00006 * (C) Copyright 2001
7 * Bill Hunter, Wave 7 Optics, williamhunter@attbi.com
8 *
9 * Based on code by:
10 *
wdenkdb2f721f2003-03-06 00:58:30 +000011 * Kenneth Johansson ,Ericsson AB.
12 * kenneth.johansson@etx.ericsson.se
wdenkfe8c2802002-11-03 00:38:21 +000013 *
14 * hacked up by bill hunter. fixed so we could run before
15 * serial_init and console_init. previous version avoided this by
16 * running out of cache memory during serial/console init, then running
17 * this code later.
18 *
19 * (C) Copyright 2002
20 * Jun Gu, Artesyn Technology, jung@artesyncp.com
Wolfgang Denk0c8721a2005-09-23 11:05:55 +020021 * Support for AMCC 440 based on OpenBIOS draminit.c from IBM.
wdenkfe8c2802002-11-03 00:38:21 +000022 *
Stefan Roesed2d43272007-06-01 15:09:50 +020023 * (C) Copyright 2005-2007
Stefan Roesec157d8e2005-08-01 16:41:48 +020024 * Stefan Roese, DENX Software Engineering, sr@denx.de.
25 *
wdenkfe8c2802002-11-03 00:38:21 +000026 * See file CREDITS for list of people who contributed to this
27 * project.
28 *
29 * This program is free software; you can redistribute it and/or
30 * modify it under the terms of the GNU General Public License as
31 * published by the Free Software Foundation; either version 2 of
32 * the License, or (at your option) any later version.
33 *
34 * This program is distributed in the hope that it will be useful,
35 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 * GNU General Public License for more details.
38 *
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
42 * MA 02111-1307 USA
43 */
44
Stefan Roesed2d43272007-06-01 15:09:50 +020045/* define DEBUG for debugging output (obviously ;-)) */
46#if 0
47#define DEBUG
48#endif
49
wdenkfe8c2802002-11-03 00:38:21 +000050#include <common.h>
51#include <asm/processor.h>
52#include <i2c.h>
53#include <ppc4xx.h>
Stefan Roesee2ebe692007-03-07 16:39:36 +010054#include <asm/mmu.h>
wdenkfe8c2802002-11-03 00:38:21 +000055
Grant Ericksonc821b5f2008-05-22 14:44:14 -070056#include "ecc.h"
57
Stefan Roese36d830c2007-02-20 10:35:42 +010058#if defined(CONFIG_SPD_EEPROM) && \
59 (defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
60 defined(CONFIG_440EP) || defined(CONFIG_440GR))
wdenkfe8c2802002-11-03 00:38:21 +000061
62/*
63 * Set default values
64 */
Wolfgang Denkf013dac2005-12-04 00:40:34 +010065#ifndef CFG_I2C_SPEED
66#define CFG_I2C_SPEED 50000
wdenkfe8c2802002-11-03 00:38:21 +000067#endif
68
Wolfgang Denkf013dac2005-12-04 00:40:34 +010069#ifndef CFG_I2C_SLAVE
70#define CFG_I2C_SLAVE 0xFE
wdenkfe8c2802002-11-03 00:38:21 +000071#endif
72
Wolfgang Denkf013dac2005-12-04 00:40:34 +010073#define ONE_BILLION 1000000000
Stefan Roesec157d8e2005-08-01 16:41:48 +020074
Heiko Schochera5d71e22007-06-25 19:11:37 +020075/*
76 * Board-specific Platform code can reimplement spd_ddr_init_hang () if needed
77 */
78void __spd_ddr_init_hang (void)
79{
80 hang ();
81}
82void spd_ddr_init_hang (void) __attribute__((weak, alias("__spd_ddr_init_hang")));
Heiko Schocher566a4942007-06-22 19:11:54 +020083
wdenkfe8c2802002-11-03 00:38:21 +000084/*-----------------------------------------------------------------------------
Stefan Roesec157d8e2005-08-01 16:41:48 +020085 | Memory Controller Options 0
86 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +010087#define SDRAM_CFG0_DCEN 0x80000000 /* SDRAM Controller Enable */
88#define SDRAM_CFG0_MCHK_MASK 0x30000000 /* Memory data errchecking mask */
89#define SDRAM_CFG0_MCHK_NON 0x00000000 /* No ECC generation */
90#define SDRAM_CFG0_MCHK_GEN 0x20000000 /* ECC generation */
91#define SDRAM_CFG0_MCHK_CHK 0x30000000 /* ECC generation and checking */
92#define SDRAM_CFG0_RDEN 0x08000000 /* Registered DIMM enable */
93#define SDRAM_CFG0_PMUD 0x04000000 /* Page management unit */
94#define SDRAM_CFG0_DMWD_MASK 0x02000000 /* DRAM width mask */
95#define SDRAM_CFG0_DMWD_32 0x00000000 /* 32 bits */
96#define SDRAM_CFG0_DMWD_64 0x02000000 /* 64 bits */
97#define SDRAM_CFG0_UIOS_MASK 0x00C00000 /* Unused IO State */
98#define SDRAM_CFG0_PDP 0x00200000 /* Page deallocation policy */
wdenkfe8c2802002-11-03 00:38:21 +000099
100/*-----------------------------------------------------------------------------
Stefan Roesec157d8e2005-08-01 16:41:48 +0200101 | Memory Controller Options 1
102 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100103#define SDRAM_CFG1_SRE 0x80000000 /* Self-Refresh Entry */
104#define SDRAM_CFG1_PMEN 0x40000000 /* Power Management Enable */
wdenkfe8c2802002-11-03 00:38:21 +0000105
106/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200107 | SDRAM DEVPOT Options
108 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100109#define SDRAM_DEVOPT_DLL 0x80000000
110#define SDRAM_DEVOPT_DS 0x40000000
wdenkfe8c2802002-11-03 00:38:21 +0000111
112/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200113 | SDRAM MCSTS Options
114 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100115#define SDRAM_MCSTS_MRSC 0x80000000
116#define SDRAM_MCSTS_SRMS 0x40000000
117#define SDRAM_MCSTS_CIS 0x20000000
wdenkfe8c2802002-11-03 00:38:21 +0000118
119/*-----------------------------------------------------------------------------
Stefan Roesec157d8e2005-08-01 16:41:48 +0200120 | SDRAM Refresh Timer Register
121 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100122#define SDRAM_RTR_RINT_MASK 0xFFFF0000
wdenkfe8c2802002-11-03 00:38:21 +0000123#define SDRAM_RTR_RINT_ENCODE(n) (((n) << 16) & SDRAM_RTR_RINT_MASK)
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100124#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
wdenkfe8c2802002-11-03 00:38:21 +0000125
126/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200127 | SDRAM UABus Base Address Reg
128 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100129#define SDRAM_UABBA_UBBA_MASK 0x0000000F
wdenkfe8c2802002-11-03 00:38:21 +0000130
131/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200132 | Memory Bank 0-7 configuration
133 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100134#define SDRAM_BXCR_SDBA_MASK 0xff800000 /* Base address */
135#define SDRAM_BXCR_SDSZ_MASK 0x000e0000 /* Size */
136#define SDRAM_BXCR_SDSZ_8 0x00020000 /* 8M */
137#define SDRAM_BXCR_SDSZ_16 0x00040000 /* 16M */
138#define SDRAM_BXCR_SDSZ_32 0x00060000 /* 32M */
139#define SDRAM_BXCR_SDSZ_64 0x00080000 /* 64M */
140#define SDRAM_BXCR_SDSZ_128 0x000a0000 /* 128M */
141#define SDRAM_BXCR_SDSZ_256 0x000c0000 /* 256M */
142#define SDRAM_BXCR_SDSZ_512 0x000e0000 /* 512M */
143#define SDRAM_BXCR_SDAM_MASK 0x0000e000 /* Addressing mode */
144#define SDRAM_BXCR_SDAM_1 0x00000000 /* Mode 1 */
145#define SDRAM_BXCR_SDAM_2 0x00002000 /* Mode 2 */
146#define SDRAM_BXCR_SDAM_3 0x00004000 /* Mode 3 */
147#define SDRAM_BXCR_SDAM_4 0x00006000 /* Mode 4 */
148#define SDRAM_BXCR_SDBE 0x00000001 /* Memory Bank Enable */
wdenkfe8c2802002-11-03 00:38:21 +0000149
150/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200151 | SDRAM TR0 Options
152 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100153#define SDRAM_TR0_SDWR_MASK 0x80000000
154#define SDRAM_TR0_SDWR_2_CLK 0x00000000
155#define SDRAM_TR0_SDWR_3_CLK 0x80000000
156#define SDRAM_TR0_SDWD_MASK 0x40000000
157#define SDRAM_TR0_SDWD_0_CLK 0x00000000
158#define SDRAM_TR0_SDWD_1_CLK 0x40000000
159#define SDRAM_TR0_SDCL_MASK 0x01800000
160#define SDRAM_TR0_SDCL_2_0_CLK 0x00800000
161#define SDRAM_TR0_SDCL_2_5_CLK 0x01000000
162#define SDRAM_TR0_SDCL_3_0_CLK 0x01800000
163#define SDRAM_TR0_SDPA_MASK 0x000C0000
164#define SDRAM_TR0_SDPA_2_CLK 0x00040000
165#define SDRAM_TR0_SDPA_3_CLK 0x00080000
166#define SDRAM_TR0_SDPA_4_CLK 0x000C0000
167#define SDRAM_TR0_SDCP_MASK 0x00030000
168#define SDRAM_TR0_SDCP_2_CLK 0x00000000
169#define SDRAM_TR0_SDCP_3_CLK 0x00010000
170#define SDRAM_TR0_SDCP_4_CLK 0x00020000
171#define SDRAM_TR0_SDCP_5_CLK 0x00030000
172#define SDRAM_TR0_SDLD_MASK 0x0000C000
173#define SDRAM_TR0_SDLD_1_CLK 0x00000000
174#define SDRAM_TR0_SDLD_2_CLK 0x00004000
175#define SDRAM_TR0_SDRA_MASK 0x0000001C
176#define SDRAM_TR0_SDRA_6_CLK 0x00000000
177#define SDRAM_TR0_SDRA_7_CLK 0x00000004
178#define SDRAM_TR0_SDRA_8_CLK 0x00000008
179#define SDRAM_TR0_SDRA_9_CLK 0x0000000C
180#define SDRAM_TR0_SDRA_10_CLK 0x00000010
181#define SDRAM_TR0_SDRA_11_CLK 0x00000014
182#define SDRAM_TR0_SDRA_12_CLK 0x00000018
183#define SDRAM_TR0_SDRA_13_CLK 0x0000001C
184#define SDRAM_TR0_SDRD_MASK 0x00000003
185#define SDRAM_TR0_SDRD_2_CLK 0x00000001
186#define SDRAM_TR0_SDRD_3_CLK 0x00000002
187#define SDRAM_TR0_SDRD_4_CLK 0x00000003
wdenkfe8c2802002-11-03 00:38:21 +0000188
189/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200190 | SDRAM TR1 Options
191 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100192#define SDRAM_TR1_RDSS_MASK 0xC0000000
193#define SDRAM_TR1_RDSS_TR0 0x00000000
194#define SDRAM_TR1_RDSS_TR1 0x40000000
195#define SDRAM_TR1_RDSS_TR2 0x80000000
196#define SDRAM_TR1_RDSS_TR3 0xC0000000
197#define SDRAM_TR1_RDSL_MASK 0x00C00000
198#define SDRAM_TR1_RDSL_STAGE1 0x00000000
199#define SDRAM_TR1_RDSL_STAGE2 0x00400000
200#define SDRAM_TR1_RDSL_STAGE3 0x00800000
201#define SDRAM_TR1_RDCD_MASK 0x00000800
202#define SDRAM_TR1_RDCD_RCD_0_0 0x00000000
203#define SDRAM_TR1_RDCD_RCD_1_2 0x00000800
204#define SDRAM_TR1_RDCT_MASK 0x000001FF
205#define SDRAM_TR1_RDCT_ENCODE(x) (((x) << 0) & SDRAM_TR1_RDCT_MASK)
206#define SDRAM_TR1_RDCT_DECODE(x) (((x) & SDRAM_TR1_RDCT_MASK) >> 0)
207#define SDRAM_TR1_RDCT_MIN 0x00000000
208#define SDRAM_TR1_RDCT_MAX 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000209
210/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200211 | SDRAM WDDCTR Options
212 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100213#define SDRAM_WDDCTR_WRCP_MASK 0xC0000000
214#define SDRAM_WDDCTR_WRCP_0DEG 0x00000000
215#define SDRAM_WDDCTR_WRCP_90DEG 0x40000000
216#define SDRAM_WDDCTR_WRCP_180DEG 0x80000000
217#define SDRAM_WDDCTR_DCD_MASK 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000218
219/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200220 | SDRAM CLKTR Options
221 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100222#define SDRAM_CLKTR_CLKP_MASK 0xC0000000
223#define SDRAM_CLKTR_CLKP_0DEG 0x00000000
224#define SDRAM_CLKTR_CLKP_90DEG 0x40000000
225#define SDRAM_CLKTR_CLKP_180DEG 0x80000000
226#define SDRAM_CLKTR_DCDT_MASK 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000227
228/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200229 | SDRAM DLYCAL Options
230 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100231#define SDRAM_DLYCAL_DLCV_MASK 0x000003FC
232#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
233#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
wdenkfe8c2802002-11-03 00:38:21 +0000234
235/*-----------------------------------------------------------------------------+
Stefan Roesec157d8e2005-08-01 16:41:48 +0200236 | General Definition
237 +-----------------------------------------------------------------------------*/
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100238#define DEFAULT_SPD_ADDR1 0x53
239#define DEFAULT_SPD_ADDR2 0x52
240#define MAXBANKS 4 /* at most 4 dimm banks */
241#define MAX_SPD_BYTES 256
242#define NUMHALFCYCLES 4
243#define NUMMEMTESTS 8
244#define NUMMEMWORDS 8
245#define MAXBXCR 4
246#define TRUE 1
247#define FALSE 0
wdenkfe8c2802002-11-03 00:38:21 +0000248
Stefan Roesee2ebe692007-03-07 16:39:36 +0100249/*
250 * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
251 * region. Right now the cache should still be disabled in U-Boot because of the
252 * EMAC driver, that need it's buffer descriptor to be located in non cached
253 * memory.
254 *
255 * If at some time this restriction doesn't apply anymore, just define
Stefan Roeseea2e1422007-10-31 20:57:11 +0100256 * CONFIG_4xx_DCACHE in the board config file and this code should setup
Stefan Roesee2ebe692007-03-07 16:39:36 +0100257 * everything correctly.
258 */
Stefan Roeseea2e1422007-10-31 20:57:11 +0100259#ifdef CONFIG_4xx_DCACHE
Stefan Roesee2ebe692007-03-07 16:39:36 +0100260#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
261#else
262#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
263#endif
264
Stefan Roesefd49bf02005-11-15 16:04:58 +0100265/* bank_parms is used to sort the bank sizes by descending order */
266struct bank_param {
267 unsigned long cr;
268 unsigned long bank_size_bytes;
269};
270
271typedef struct bank_param BANKPARMS;
272
273#ifdef CFG_SIMULATE_SPD_EEPROM
Eugene OBriend2f68002007-07-31 10:24:56 +0200274extern const unsigned char cfg_simulate_spd_eeprom[128];
Stefan Roesefd49bf02005-11-15 16:04:58 +0100275#endif
wdenkfe8c2802002-11-03 00:38:21 +0000276
Stefan Roesed2d43272007-06-01 15:09:50 +0200277static unsigned char spd_read(uchar chip, uint addr);
278static void get_spd_info(unsigned long *dimm_populated,
279 unsigned char *iic0_dimm_addr,
280 unsigned long num_dimm_banks);
281static void check_mem_type(unsigned long *dimm_populated,
282 unsigned char *iic0_dimm_addr,
283 unsigned long num_dimm_banks);
284static void check_volt_type(unsigned long *dimm_populated,
285 unsigned char *iic0_dimm_addr,
286 unsigned long num_dimm_banks);
287static void program_cfg0(unsigned long *dimm_populated,
288 unsigned char *iic0_dimm_addr,
289 unsigned long num_dimm_banks);
290static void program_cfg1(unsigned long *dimm_populated,
291 unsigned char *iic0_dimm_addr,
292 unsigned long num_dimm_banks);
293static void program_rtr(unsigned long *dimm_populated,
294 unsigned char *iic0_dimm_addr,
295 unsigned long num_dimm_banks);
296static void program_tr0(unsigned long *dimm_populated,
297 unsigned char *iic0_dimm_addr,
298 unsigned long num_dimm_banks);
299static void program_tr1(void);
wdenkfe8c2802002-11-03 00:38:21 +0000300
Stefan Roesed2d43272007-06-01 15:09:50 +0200301static unsigned long program_bxcr(unsigned long *dimm_populated,
302 unsigned char *iic0_dimm_addr,
303 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000304
305/*
306 * This function is reading data from the DIMM module EEPROM over the SPD bus
307 * and uses that to program the sdram controller.
308 *
Wolfgang Denk0c8721a2005-09-23 11:05:55 +0200309 * This works on boards that has the same schematics that the AMCC walnut has.
wdenkfe8c2802002-11-03 00:38:21 +0000310 *
311 * BUG: Don't handle ECC memory
312 * BUG: A few values in the TR register is currently hardcoded
313 */
wdenkfe8c2802002-11-03 00:38:21 +0000314long int spd_sdram(void) {
Stefan Roesec157d8e2005-08-01 16:41:48 +0200315 unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
316 unsigned long dimm_populated[sizeof(iic0_dimm_addr)];
317 unsigned long total_size;
318 unsigned long cfg0;
319 unsigned long mcsts;
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100320 unsigned long num_dimm_banks; /* on board dimm banks */
wdenkfe8c2802002-11-03 00:38:21 +0000321
Stefan Roesec157d8e2005-08-01 16:41:48 +0200322 num_dimm_banks = sizeof(iic0_dimm_addr);
wdenkfe8c2802002-11-03 00:38:21 +0000323
324 /*
325 * Make sure I2C controller is initialized
326 * before continuing.
327 */
328 i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
329
Stefan Roesec157d8e2005-08-01 16:41:48 +0200330 /*
331 * Read the SPD information using I2C interface. Check to see if the
332 * DIMM slots are populated.
333 */
334 get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000335
Stefan Roesec157d8e2005-08-01 16:41:48 +0200336 /*
337 * Check the memory type for the dimms plugged.
338 */
339 check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000340
Stefan Roesec157d8e2005-08-01 16:41:48 +0200341 /*
342 * Check the voltage type for the dimms plugged.
343 */
344 check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000345
Stefan Roeseea2e1422007-10-31 20:57:11 +0100346#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
Stefan Roesec157d8e2005-08-01 16:41:48 +0200347 /*
348 * Soft-reset SDRAM controller.
349 */
350 mtsdr(sdr_srst, SDR0_SRST_DMC);
351 mtsdr(sdr_srst, 0x00000000);
wdenk63153492005-04-03 20:55:38 +0000352#endif
353
Stefan Roesec157d8e2005-08-01 16:41:48 +0200354 /*
355 * program 440GP SDRAM controller options (SDRAM0_CFG0)
356 */
357 program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000358
Stefan Roesec157d8e2005-08-01 16:41:48 +0200359 /*
360 * program 440GP SDRAM controller options (SDRAM0_CFG1)
361 */
362 program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000363
Stefan Roesec157d8e2005-08-01 16:41:48 +0200364 /*
365 * program SDRAM refresh register (SDRAM0_RTR)
366 */
367 program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000368
Stefan Roesec157d8e2005-08-01 16:41:48 +0200369 /*
370 * program SDRAM Timing Register 0 (SDRAM0_TR0)
371 */
372 program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000373
Stefan Roesec157d8e2005-08-01 16:41:48 +0200374 /*
375 * program the BxCR registers to find out total sdram installed
376 */
377 total_size = program_bxcr(dimm_populated, iic0_dimm_addr,
378 num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000379
Stefan Roesee2ebe692007-03-07 16:39:36 +0100380#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
381 /* and program tlb entries for this size (dynamic) */
Stefan Roesedbca2082007-06-14 11:14:32 +0200382 program_tlb(0, 0, total_size, MY_TLB_WORD2_I_ENABLE);
Stefan Roesee2ebe692007-03-07 16:39:36 +0100383#endif
384
Stefan Roesec157d8e2005-08-01 16:41:48 +0200385 /*
386 * program SDRAM Clock Timing Register (SDRAM0_CLKTR)
387 */
388 mtsdram(mem_clktr, 0x40000000);
wdenkfe8c2802002-11-03 00:38:21 +0000389
Stefan Roesec157d8e2005-08-01 16:41:48 +0200390 /*
391 * delay to ensure 200 usec has elapsed
392 */
393 udelay(400);
wdenkfe8c2802002-11-03 00:38:21 +0000394
Stefan Roesec157d8e2005-08-01 16:41:48 +0200395 /*
396 * enable the memory controller
397 */
398 mfsdram(mem_cfg0, cfg0);
399 mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN);
wdenkfe8c2802002-11-03 00:38:21 +0000400
Stefan Roesec157d8e2005-08-01 16:41:48 +0200401 /*
402 * wait for SDRAM_CFG0_DC_EN to complete
403 */
404 while (1) {
405 mfsdram(mem_mcsts, mcsts);
Stefan Roesed2d43272007-06-01 15:09:50 +0200406 if ((mcsts & SDRAM_MCSTS_MRSC) != 0)
Stefan Roesec157d8e2005-08-01 16:41:48 +0200407 break;
wdenk8bde7f72003-06-27 21:31:46 +0000408 }
wdenkfe8c2802002-11-03 00:38:21 +0000409
Stefan Roesec157d8e2005-08-01 16:41:48 +0200410 /*
411 * program SDRAM Timing Register 1, adding some delays
412 */
413 program_tr1();
wdenkfe8c2802002-11-03 00:38:21 +0000414
Stefan Roesed2d43272007-06-01 15:09:50 +0200415#ifdef CONFIG_DDR_ECC
Stefan Roesec157d8e2005-08-01 16:41:48 +0200416 /*
Stefan Roesed2d43272007-06-01 15:09:50 +0200417 * If ecc is enabled, initialize the parity bits.
Stefan Roesec157d8e2005-08-01 16:41:48 +0200418 */
Grant Ericksonc821b5f2008-05-22 14:44:14 -0700419 ecc_init(CFG_SDRAM_BASE, total_size);
Stefan Roesed2d43272007-06-01 15:09:50 +0200420#endif
wdenkfe8c2802002-11-03 00:38:21 +0000421
422 return total_size;
423}
424
Stefan Roesed2d43272007-06-01 15:09:50 +0200425static unsigned char spd_read(uchar chip, uint addr)
Stefan Roesefd49bf02005-11-15 16:04:58 +0100426{
wdenkfe8c2802002-11-03 00:38:21 +0000427 unsigned char data[2];
428
Stefan Roesefd49bf02005-11-15 16:04:58 +0100429#ifdef CFG_SIMULATE_SPD_EEPROM
430 if (chip == CFG_SIMULATE_SPD_EEPROM) {
431 /*
432 * Onboard spd eeprom requested -> simulate values
433 */
434 return cfg_simulate_spd_eeprom[addr];
435 }
436#endif /* CFG_SIMULATE_SPD_EEPROM */
437
Stefan Roesec157d8e2005-08-01 16:41:48 +0200438 if (i2c_probe(chip) == 0) {
439 if (i2c_read(chip, addr, 1, data, 1) == 0) {
440 return data[0];
441 }
442 }
443
444 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000445}
446
Stefan Roesed2d43272007-06-01 15:09:50 +0200447static void get_spd_info(unsigned long *dimm_populated,
448 unsigned char *iic0_dimm_addr,
449 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000450{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200451 unsigned long dimm_num;
452 unsigned long dimm_found;
453 unsigned char num_of_bytes;
454 unsigned char total_size;
wdenkfe8c2802002-11-03 00:38:21 +0000455
Stefan Roesec157d8e2005-08-01 16:41:48 +0200456 dimm_found = FALSE;
457 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
458 num_of_bytes = 0;
459 total_size = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000460
Stefan Roesec157d8e2005-08-01 16:41:48 +0200461 num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
462 total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
wdenkfe8c2802002-11-03 00:38:21 +0000463
Stefan Roesec157d8e2005-08-01 16:41:48 +0200464 if ((num_of_bytes != 0) && (total_size != 0)) {
465 dimm_populated[dimm_num] = TRUE;
466 dimm_found = TRUE;
Stefan Roesed2d43272007-06-01 15:09:50 +0200467 debug("DIMM slot %lu: populated\n", dimm_num);
Stefan Roesec157d8e2005-08-01 16:41:48 +0200468 } else {
469 dimm_populated[dimm_num] = FALSE;
Stefan Roesed2d43272007-06-01 15:09:50 +0200470 debug("DIMM slot %lu: Not populated\n", dimm_num);
Stefan Roesec157d8e2005-08-01 16:41:48 +0200471 }
wdenk8bde7f72003-06-27 21:31:46 +0000472 }
wdenkfe8c2802002-11-03 00:38:21 +0000473
Stefan Roesec157d8e2005-08-01 16:41:48 +0200474 if (dimm_found == FALSE) {
475 printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +0200476 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200477 }
wdenkfe8c2802002-11-03 00:38:21 +0000478}
479
Stefan Roesed2d43272007-06-01 15:09:50 +0200480static void check_mem_type(unsigned long *dimm_populated,
481 unsigned char *iic0_dimm_addr,
482 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000483{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200484 unsigned long dimm_num;
485 unsigned char dimm_type;
wdenkfe8c2802002-11-03 00:38:21 +0000486
Stefan Roesec157d8e2005-08-01 16:41:48 +0200487 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
488 if (dimm_populated[dimm_num] == TRUE) {
489 dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
490 switch (dimm_type) {
491 case 7:
Stefan Roesed2d43272007-06-01 15:09:50 +0200492 debug("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
Stefan Roesec157d8e2005-08-01 16:41:48 +0200493 break;
494 default:
495 printf("ERROR: Unsupported DIMM detected in slot %lu.\n",
496 dimm_num);
497 printf("Only DDR SDRAM DIMMs are supported.\n");
498 printf("Replace the DIMM module with a supported DIMM.\n\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +0200499 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200500 break;
501 }
502 }
wdenk8bde7f72003-06-27 21:31:46 +0000503 }
wdenkfe8c2802002-11-03 00:38:21 +0000504}
505
Stefan Roesed2d43272007-06-01 15:09:50 +0200506static void check_volt_type(unsigned long *dimm_populated,
507 unsigned char *iic0_dimm_addr,
508 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000509{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200510 unsigned long dimm_num;
511 unsigned long voltage_type;
wdenkfe8c2802002-11-03 00:38:21 +0000512
Stefan Roesec157d8e2005-08-01 16:41:48 +0200513 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
514 if (dimm_populated[dimm_num] == TRUE) {
515 voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
516 if (voltage_type != 0x04) {
517 printf("ERROR: DIMM %lu with unsupported voltage level.\n",
518 dimm_num);
Heiko Schochera5d71e22007-06-25 19:11:37 +0200519 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200520 } else {
Stefan Roesed2d43272007-06-01 15:09:50 +0200521 debug("DIMM %lu voltage level supported.\n", dimm_num);
Stefan Roesec157d8e2005-08-01 16:41:48 +0200522 }
523 break;
524 }
wdenk8bde7f72003-06-27 21:31:46 +0000525 }
wdenkfe8c2802002-11-03 00:38:21 +0000526}
527
Stefan Roesed2d43272007-06-01 15:09:50 +0200528static void program_cfg0(unsigned long *dimm_populated,
529 unsigned char *iic0_dimm_addr,
530 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000531{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200532 unsigned long dimm_num;
533 unsigned long cfg0;
534 unsigned long ecc_enabled;
535 unsigned char ecc;
536 unsigned char attributes;
537 unsigned long data_width;
538 unsigned long dimm_32bit;
539 unsigned long dimm_64bit;
wdenkfe8c2802002-11-03 00:38:21 +0000540
Stefan Roesec157d8e2005-08-01 16:41:48 +0200541 /*
542 * get Memory Controller Options 0 data
543 */
544 mfsdram(mem_cfg0, cfg0);
wdenkfe8c2802002-11-03 00:38:21 +0000545
Stefan Roesec157d8e2005-08-01 16:41:48 +0200546 /*
547 * clear bits
548 */
549 cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK |
550 SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD |
551 SDRAM_CFG0_DMWD_MASK |
552 SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP);
wdenkfe8c2802002-11-03 00:38:21 +0000553
554
Stefan Roesec157d8e2005-08-01 16:41:48 +0200555 /*
556 * FIXME: assume the DDR SDRAMs in both banks are the same
557 */
558 ecc_enabled = TRUE;
559 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
560 if (dimm_populated[dimm_num] == TRUE) {
561 ecc = spd_read(iic0_dimm_addr[dimm_num], 11);
562 if (ecc != 0x02) {
563 ecc_enabled = FALSE;
564 }
wdenkfe8c2802002-11-03 00:38:21 +0000565
Stefan Roesec157d8e2005-08-01 16:41:48 +0200566 /*
567 * program Registered DIMM Enable
568 */
569 attributes = spd_read(iic0_dimm_addr[dimm_num], 21);
570 if ((attributes & 0x02) != 0x00) {
571 cfg0 |= SDRAM_CFG0_RDEN;
572 }
wdenkfe8c2802002-11-03 00:38:21 +0000573
Stefan Roesec157d8e2005-08-01 16:41:48 +0200574 /*
575 * program DDR SDRAM Data Width
576 */
577 data_width =
578 (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) +
579 (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8);
580 if (data_width == 64 || data_width == 72) {
581 dimm_64bit = TRUE;
582 cfg0 |= SDRAM_CFG0_DMWD_64;
583 } else if (data_width == 32 || data_width == 40) {
584 dimm_32bit = TRUE;
585 cfg0 |= SDRAM_CFG0_DMWD_32;
586 } else {
587 printf("WARNING: DIMM with datawidth of %lu bits.\n",
588 data_width);
589 printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +0200590 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200591 }
592 break;
593 }
wdenk8bde7f72003-06-27 21:31:46 +0000594 }
wdenkfe8c2802002-11-03 00:38:21 +0000595
Stefan Roesec157d8e2005-08-01 16:41:48 +0200596 /*
597 * program Memory Data Error Checking
598 */
599 if (ecc_enabled == TRUE) {
600 cfg0 |= SDRAM_CFG0_MCHK_GEN;
601 } else {
602 cfg0 |= SDRAM_CFG0_MCHK_NON;
603 }
wdenkfe8c2802002-11-03 00:38:21 +0000604
Stefan Roesec157d8e2005-08-01 16:41:48 +0200605 /*
Stefan Roesea2c95a72006-07-28 18:34:58 +0200606 * program Page Management Unit (0 == enabled)
Stefan Roesec157d8e2005-08-01 16:41:48 +0200607 */
Stefan Roesea2c95a72006-07-28 18:34:58 +0200608 cfg0 &= ~SDRAM_CFG0_PMUD;
wdenkfe8c2802002-11-03 00:38:21 +0000609
Stefan Roesec157d8e2005-08-01 16:41:48 +0200610 /*
611 * program Memory Controller Options 0
612 * Note: DCEN must be enabled after all DDR SDRAM controller
613 * configuration registers get initialized.
614 */
615 mtsdram(mem_cfg0, cfg0);
wdenkfe8c2802002-11-03 00:38:21 +0000616}
617
Stefan Roesed2d43272007-06-01 15:09:50 +0200618static void program_cfg1(unsigned long *dimm_populated,
619 unsigned char *iic0_dimm_addr,
620 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000621{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200622 unsigned long cfg1;
623 mfsdram(mem_cfg1, cfg1);
wdenkfe8c2802002-11-03 00:38:21 +0000624
Stefan Roesec157d8e2005-08-01 16:41:48 +0200625 /*
626 * Self-refresh exit, disable PM
627 */
628 cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN);
wdenkfe8c2802002-11-03 00:38:21 +0000629
Stefan Roesec157d8e2005-08-01 16:41:48 +0200630 /*
631 * program Memory Controller Options 1
632 */
633 mtsdram(mem_cfg1, cfg1);
wdenkfe8c2802002-11-03 00:38:21 +0000634}
635
Stefan Roesed2d43272007-06-01 15:09:50 +0200636static void program_rtr(unsigned long *dimm_populated,
637 unsigned char *iic0_dimm_addr,
638 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000639{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200640 unsigned long dimm_num;
641 unsigned long bus_period_x_10;
642 unsigned long refresh_rate = 0;
643 unsigned char refresh_rate_type;
644 unsigned long refresh_interval;
645 unsigned long sdram_rtr;
Stefan Roese087dfdb2007-10-21 08:12:41 +0200646 PPC4xx_SYS_INFO sys_info;
wdenkfe8c2802002-11-03 00:38:21 +0000647
Stefan Roesec157d8e2005-08-01 16:41:48 +0200648 /*
649 * get the board info
650 */
651 get_sys_info(&sys_info);
652 bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
wdenkfe8c2802002-11-03 00:38:21 +0000653
Stefan Roesec157d8e2005-08-01 16:41:48 +0200654 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
655 if (dimm_populated[dimm_num] == TRUE) {
656 refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);
657 switch (refresh_rate_type) {
658 case 0x00:
659 refresh_rate = 15625;
660 break;
661 case 0x01:
662 refresh_rate = 15625/4;
663 break;
664 case 0x02:
665 refresh_rate = 15625/2;
666 break;
667 case 0x03:
668 refresh_rate = 15626*2;
669 break;
670 case 0x04:
671 refresh_rate = 15625*4;
672 break;
673 case 0x05:
674 refresh_rate = 15625*8;
675 break;
676 default:
677 printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n",
678 dimm_num);
679 printf("Replace the DIMM module with a supported DIMM.\n");
680 break;
681 }
wdenkfe8c2802002-11-03 00:38:21 +0000682
Stefan Roesec157d8e2005-08-01 16:41:48 +0200683 break;
684 }
wdenk8bde7f72003-06-27 21:31:46 +0000685 }
wdenkfe8c2802002-11-03 00:38:21 +0000686
Stefan Roesec157d8e2005-08-01 16:41:48 +0200687 refresh_interval = refresh_rate * 10 / bus_period_x_10;
688 sdram_rtr = (refresh_interval & 0x3ff8) << 16;
wdenkfe8c2802002-11-03 00:38:21 +0000689
Stefan Roesec157d8e2005-08-01 16:41:48 +0200690 /*
691 * program Refresh Timer Register (SDRAM0_RTR)
692 */
693 mtsdram(mem_rtr, sdram_rtr);
wdenkfe8c2802002-11-03 00:38:21 +0000694}
695
Stefan Roesed2d43272007-06-01 15:09:50 +0200696static void program_tr0(unsigned long *dimm_populated,
697 unsigned char *iic0_dimm_addr,
698 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000699{
Stefan Roesec157d8e2005-08-01 16:41:48 +0200700 unsigned long dimm_num;
701 unsigned long tr0;
702 unsigned char wcsbc;
703 unsigned char t_rp_ns;
704 unsigned char t_rcd_ns;
705 unsigned char t_ras_ns;
706 unsigned long t_rp_clk;
707 unsigned long t_ras_rcd_clk;
708 unsigned long t_rcd_clk;
709 unsigned long t_rfc_clk;
710 unsigned long plb_check;
711 unsigned char cas_bit;
712 unsigned long cas_index;
713 unsigned char cas_2_0_available;
714 unsigned char cas_2_5_available;
715 unsigned char cas_3_0_available;
716 unsigned long cycle_time_ns_x_10[3];
717 unsigned long tcyc_3_0_ns_x_10;
718 unsigned long tcyc_2_5_ns_x_10;
719 unsigned long tcyc_2_0_ns_x_10;
720 unsigned long tcyc_reg;
721 unsigned long bus_period_x_10;
Stefan Roese087dfdb2007-10-21 08:12:41 +0200722 PPC4xx_SYS_INFO sys_info;
Stefan Roesec157d8e2005-08-01 16:41:48 +0200723 unsigned long residue;
wdenkfe8c2802002-11-03 00:38:21 +0000724
Stefan Roesec157d8e2005-08-01 16:41:48 +0200725 /*
726 * get the board info
727 */
728 get_sys_info(&sys_info);
729 bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
wdenkfe8c2802002-11-03 00:38:21 +0000730
Stefan Roesec157d8e2005-08-01 16:41:48 +0200731 /*
732 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
733 */
734 mfsdram(mem_tr0, tr0);
735 tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK |
736 SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK |
737 SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK |
738 SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK);
wdenkfe8c2802002-11-03 00:38:21 +0000739
Stefan Roesec157d8e2005-08-01 16:41:48 +0200740 /*
741 * initialization
742 */
743 wcsbc = 0;
744 t_rp_ns = 0;
745 t_rcd_ns = 0;
746 t_ras_ns = 0;
747 cas_2_0_available = TRUE;
748 cas_2_5_available = TRUE;
749 cas_3_0_available = TRUE;
750 tcyc_2_0_ns_x_10 = 0;
751 tcyc_2_5_ns_x_10 = 0;
752 tcyc_3_0_ns_x_10 = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000753
Stefan Roesec157d8e2005-08-01 16:41:48 +0200754 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
755 if (dimm_populated[dimm_num] == TRUE) {
756 wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15);
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100757 t_rp_ns = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2;
Stefan Roesec157d8e2005-08-01 16:41:48 +0200758 t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2;
759 t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30);
760 cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
wdenkfe8c2802002-11-03 00:38:21 +0000761
Stefan Roesec157d8e2005-08-01 16:41:48 +0200762 for (cas_index = 0; cas_index < 3; cas_index++) {
763 switch (cas_index) {
764 case 0:
765 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
766 break;
767 case 1:
768 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);
769 break;
770 default:
771 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);
772 break;
773 }
774
775 if ((tcyc_reg & 0x0F) >= 10) {
776 printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n",
777 dimm_num);
Heiko Schochera5d71e22007-06-25 19:11:37 +0200778 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200779 }
780
781 cycle_time_ns_x_10[cas_index] =
782 (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F);
783 }
784
785 cas_index = 0;
786
787 if ((cas_bit & 0x80) != 0) {
788 cas_index += 3;
789 } else if ((cas_bit & 0x40) != 0) {
790 cas_index += 2;
791 } else if ((cas_bit & 0x20) != 0) {
792 cas_index += 1;
793 }
794
795 if (((cas_bit & 0x10) != 0) && (cas_index < 3)) {
796 tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
797 cas_index++;
798 } else {
799 if (cas_index != 0) {
800 cas_index++;
801 }
802 cas_3_0_available = FALSE;
803 }
804
805 if (((cas_bit & 0x08) != 0) || (cas_index < 3)) {
806 tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index];
807 cas_index++;
808 } else {
809 if (cas_index != 0) {
810 cas_index++;
811 }
812 cas_2_5_available = FALSE;
813 }
814
815 if (((cas_bit & 0x04) != 0) || (cas_index < 3)) {
816 tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
817 cas_index++;
818 } else {
819 if (cas_index != 0) {
820 cas_index++;
821 }
822 cas_2_0_available = FALSE;
823 }
824
825 break;
wdenk8bde7f72003-06-27 21:31:46 +0000826 }
wdenk8bde7f72003-06-27 21:31:46 +0000827 }
wdenkfe8c2802002-11-03 00:38:21 +0000828
Stefan Roesec157d8e2005-08-01 16:41:48 +0200829 /*
830 * Program SD_WR and SD_WCSBC fields
831 */
Wolfgang Denkf013dac2005-12-04 00:40:34 +0100832 tr0 |= SDRAM_TR0_SDWR_2_CLK; /* Write Recovery: 2 CLK */
Stefan Roesec157d8e2005-08-01 16:41:48 +0200833 switch (wcsbc) {
834 case 0:
835 tr0 |= SDRAM_TR0_SDWD_0_CLK;
836 break;
837 default:
838 tr0 |= SDRAM_TR0_SDWD_1_CLK;
839 break;
840 }
wdenkfe8c2802002-11-03 00:38:21 +0000841
Stefan Roesec157d8e2005-08-01 16:41:48 +0200842 /*
843 * Program SD_CASL field
844 */
845 if ((cas_2_0_available == TRUE) &&
846 (bus_period_x_10 >= tcyc_2_0_ns_x_10)) {
847 tr0 |= SDRAM_TR0_SDCL_2_0_CLK;
848 } else if ((cas_2_5_available == TRUE) &&
849 (bus_period_x_10 >= tcyc_2_5_ns_x_10)) {
850 tr0 |= SDRAM_TR0_SDCL_2_5_CLK;
851 } else if ((cas_3_0_available == TRUE) &&
852 (bus_period_x_10 >= tcyc_3_0_ns_x_10)) {
853 tr0 |= SDRAM_TR0_SDCL_3_0_CLK;
854 } else {
855 printf("ERROR: No supported CAS latency with the installed DIMMs.\n");
856 printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
857 printf("Make sure the PLB speed is within the supported range.\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +0200858 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +0200859 }
wdenkfe8c2802002-11-03 00:38:21 +0000860
Stefan Roesec157d8e2005-08-01 16:41:48 +0200861 /*
862 * Calculate Trp in clock cycles and round up if necessary
863 * Program SD_PTA field
864 */
865 t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION;
866 plb_check = ONE_BILLION * t_rp_clk / t_rp_ns;
867 if (sys_info.freqPLB != plb_check) {
868 t_rp_clk++;
869 }
870 switch ((unsigned long)t_rp_clk) {
871 case 0:
872 case 1:
873 case 2:
874 tr0 |= SDRAM_TR0_SDPA_2_CLK;
875 break;
876 case 3:
877 tr0 |= SDRAM_TR0_SDPA_3_CLK;
878 break;
879 default:
880 tr0 |= SDRAM_TR0_SDPA_4_CLK;
881 break;
882 }
wdenkfe8c2802002-11-03 00:38:21 +0000883
Stefan Roesec157d8e2005-08-01 16:41:48 +0200884 /*
885 * Program SD_CTP field
886 */
887 t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION;
888 plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns);
889 if (sys_info.freqPLB != plb_check) {
890 t_ras_rcd_clk++;
891 }
892 switch (t_ras_rcd_clk) {
893 case 0:
894 case 1:
895 case 2:
896 tr0 |= SDRAM_TR0_SDCP_2_CLK;
897 break;
898 case 3:
899 tr0 |= SDRAM_TR0_SDCP_3_CLK;
900 break;
901 case 4:
902 tr0 |= SDRAM_TR0_SDCP_4_CLK;
903 break;
904 default:
905 tr0 |= SDRAM_TR0_SDCP_5_CLK;
906 break;
907 }
wdenkfe8c2802002-11-03 00:38:21 +0000908
Stefan Roesec157d8e2005-08-01 16:41:48 +0200909 /*
910 * Program SD_LDF field
911 */
912 tr0 |= SDRAM_TR0_SDLD_2_CLK;
wdenkfe8c2802002-11-03 00:38:21 +0000913
Stefan Roesec157d8e2005-08-01 16:41:48 +0200914 /*
915 * Program SD_RFTA field
916 * FIXME tRFC hardcoded as 75 nanoseconds
917 */
918 t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75);
919 residue = sys_info.freqPLB % (ONE_BILLION / 75);
920 if (residue >= (ONE_BILLION / 150)) {
921 t_rfc_clk++;
922 }
923 switch (t_rfc_clk) {
924 case 0:
925 case 1:
926 case 2:
927 case 3:
928 case 4:
929 case 5:
930 case 6:
931 tr0 |= SDRAM_TR0_SDRA_6_CLK;
932 break;
933 case 7:
934 tr0 |= SDRAM_TR0_SDRA_7_CLK;
935 break;
936 case 8:
937 tr0 |= SDRAM_TR0_SDRA_8_CLK;
938 break;
939 case 9:
940 tr0 |= SDRAM_TR0_SDRA_9_CLK;
941 break;
942 case 10:
943 tr0 |= SDRAM_TR0_SDRA_10_CLK;
944 break;
945 case 11:
946 tr0 |= SDRAM_TR0_SDRA_11_CLK;
947 break;
948 case 12:
949 tr0 |= SDRAM_TR0_SDRA_12_CLK;
950 break;
951 default:
952 tr0 |= SDRAM_TR0_SDRA_13_CLK;
953 break;
954 }
wdenkfe8c2802002-11-03 00:38:21 +0000955
Stefan Roesec157d8e2005-08-01 16:41:48 +0200956 /*
957 * Program SD_RCD field
958 */
959 t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;
960 plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;
961 if (sys_info.freqPLB != plb_check) {
962 t_rcd_clk++;
963 }
964 switch (t_rcd_clk) {
965 case 0:
966 case 1:
967 case 2:
968 tr0 |= SDRAM_TR0_SDRD_2_CLK;
969 break;
970 case 3:
971 tr0 |= SDRAM_TR0_SDRD_3_CLK;
972 break;
973 default:
974 tr0 |= SDRAM_TR0_SDRD_4_CLK;
975 break;
976 }
wdenkfe8c2802002-11-03 00:38:21 +0000977
Stefan Roesed2d43272007-06-01 15:09:50 +0200978 debug("tr0: %x\n", tr0);
Stefan Roesec157d8e2005-08-01 16:41:48 +0200979 mtsdram(mem_tr0, tr0);
wdenkfe8c2802002-11-03 00:38:21 +0000980}
981
Stefan Roesed2d43272007-06-01 15:09:50 +0200982static int short_mem_test(void)
983{
984 unsigned long i, j;
985 unsigned long bxcr_num;
986 unsigned long *membase;
987 const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
988 {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
989 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF},
990 {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
991 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000},
992 {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
993 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555},
994 {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
995 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA},
996 {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
997 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A},
998 {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
999 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5},
1000 {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
1001 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA},
1002 {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
1003 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55}};
1004
1005 for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
1006 mtdcr(memcfga, mem_b0cr + (bxcr_num << 2));
1007 if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
1008 /* Bank is enabled */
1009 membase = (unsigned long*)
1010 (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);
1011
1012 /*
1013 * Run the short memory test
1014 */
1015 for (i = 0; i < NUMMEMTESTS; i++) {
1016 for (j = 0; j < NUMMEMWORDS; j++) {
Wolfgang Denk239f05e2007-07-12 01:45:34 +02001017 /* printf("bank enabled base:%x\n", &membase[j]); */
Stefan Roesed2d43272007-06-01 15:09:50 +02001018 membase[j] = test[i][j];
1019 ppcDcbf((unsigned long)&(membase[j]));
1020 }
1021
1022 for (j = 0; j < NUMMEMWORDS; j++) {
1023 if (membase[j] != test[i][j]) {
1024 ppcDcbf((unsigned long)&(membase[j]));
1025 return 0;
1026 }
1027 ppcDcbf((unsigned long)&(membase[j]));
1028 }
1029
1030 if (j < NUMMEMWORDS)
1031 return 0;
1032 }
1033
1034 /*
1035 * see if the rdclt value passed
1036 */
1037 if (i < NUMMEMTESTS)
1038 return 0;
1039 }
1040 }
1041
1042 return 1;
1043}
1044
1045static void program_tr1(void)
wdenkfe8c2802002-11-03 00:38:21 +00001046{
Stefan Roesec157d8e2005-08-01 16:41:48 +02001047 unsigned long tr0;
1048 unsigned long tr1;
1049 unsigned long cfg0;
1050 unsigned long ecc_temp;
1051 unsigned long dlycal;
1052 unsigned long dly_val;
Stefan Roesed2d43272007-06-01 15:09:50 +02001053 unsigned long k;
Stefan Roesec157d8e2005-08-01 16:41:48 +02001054 unsigned long max_pass_length;
1055 unsigned long current_pass_length;
1056 unsigned long current_fail_length;
1057 unsigned long current_start;
1058 unsigned long rdclt;
1059 unsigned long rdclt_offset;
1060 long max_start;
1061 long max_end;
1062 long rdclt_average;
1063 unsigned char window_found;
1064 unsigned char fail_found;
1065 unsigned char pass_found;
Stefan Roese087dfdb2007-10-21 08:12:41 +02001066 PPC4xx_SYS_INFO sys_info;
wdenkfe8c2802002-11-03 00:38:21 +00001067
Stefan Roesec157d8e2005-08-01 16:41:48 +02001068 /*
1069 * get the board info
1070 */
1071 get_sys_info(&sys_info);
wdenkfe8c2802002-11-03 00:38:21 +00001072
Stefan Roesec157d8e2005-08-01 16:41:48 +02001073 /*
1074 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
1075 */
1076 mfsdram(mem_tr1, tr1);
1077 tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK |
1078 SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);
wdenkfe8c2802002-11-03 00:38:21 +00001079
Stefan Roesec157d8e2005-08-01 16:41:48 +02001080 mfsdram(mem_tr0, tr0);
1081 if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) &&
1082 (sys_info.freqPLB > 100000000)) {
1083 tr1 |= SDRAM_TR1_RDSS_TR2;
1084 tr1 |= SDRAM_TR1_RDSL_STAGE3;
1085 tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
1086 } else {
1087 tr1 |= SDRAM_TR1_RDSS_TR1;
1088 tr1 |= SDRAM_TR1_RDSL_STAGE2;
1089 tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
wdenk8bde7f72003-06-27 21:31:46 +00001090 }
wdenkfe8c2802002-11-03 00:38:21 +00001091
Stefan Roesec157d8e2005-08-01 16:41:48 +02001092 /*
1093 * save CFG0 ECC setting to a temporary variable and turn ECC off
1094 */
1095 mfsdram(mem_cfg0, cfg0);
1096 ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;
1097 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);
1098
1099 /*
1100 * get the delay line calibration register value
1101 */
1102 mfsdram(mem_dlycal, dlycal);
1103 dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;
1104
1105 max_pass_length = 0;
1106 max_start = 0;
1107 max_end = 0;
1108 current_pass_length = 0;
1109 current_fail_length = 0;
1110 current_start = 0;
1111 rdclt_offset = 0;
1112 window_found = FALSE;
1113 fail_found = FALSE;
1114 pass_found = FALSE;
Stefan Roesed2d43272007-06-01 15:09:50 +02001115 debug("Starting memory test ");
1116
Stefan Roesec157d8e2005-08-01 16:41:48 +02001117 for (k = 0; k < NUMHALFCYCLES; k++) {
Stefan Roesed2d43272007-06-01 15:09:50 +02001118 for (rdclt = 0; rdclt < dly_val; rdclt++) {
Stefan Roesec157d8e2005-08-01 16:41:48 +02001119 /*
1120 * Set the timing reg for the test.
1121 */
1122 mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));
1123
Stefan Roesed2d43272007-06-01 15:09:50 +02001124 if (short_mem_test()) {
Stefan Roesec157d8e2005-08-01 16:41:48 +02001125 if (fail_found == TRUE) {
1126 pass_found = TRUE;
1127 if (current_pass_length == 0) {
1128 current_start = rdclt_offset + rdclt;
1129 }
1130
1131 current_fail_length = 0;
1132 current_pass_length++;
1133
1134 if (current_pass_length > max_pass_length) {
1135 max_pass_length = current_pass_length;
1136 max_start = current_start;
1137 max_end = rdclt_offset + rdclt;
1138 }
1139 }
1140 } else {
1141 current_pass_length = 0;
1142 current_fail_length++;
1143
1144 if (current_fail_length >= (dly_val>>2)) {
1145 if (fail_found == FALSE) {
1146 fail_found = TRUE;
1147 } else if (pass_found == TRUE) {
1148 window_found = TRUE;
1149 break;
1150 }
1151 }
1152 }
1153 }
Stefan Roesed2d43272007-06-01 15:09:50 +02001154 debug(".");
1155
Stefan Roesec157d8e2005-08-01 16:41:48 +02001156 if (window_found == TRUE) {
1157 break;
1158 }
1159
1160 tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1161 rdclt_offset += dly_val;
1162 }
Stefan Roesed2d43272007-06-01 15:09:50 +02001163 debug("\n");
wdenkfe8c2802002-11-03 00:38:21 +00001164
Stefan Roesec157d8e2005-08-01 16:41:48 +02001165 /*
1166 * make sure we find the window
1167 */
1168 if (window_found == FALSE) {
1169 printf("ERROR: Cannot determine a common read delay.\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +02001170 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +02001171 }
wdenkfe8c2802002-11-03 00:38:21 +00001172
Stefan Roesec157d8e2005-08-01 16:41:48 +02001173 /*
1174 * restore the orignal ECC setting
1175 */
1176 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);
wdenkfe8c2802002-11-03 00:38:21 +00001177
Stefan Roesec157d8e2005-08-01 16:41:48 +02001178 /*
1179 * set the SDRAM TR1 RDCD value
1180 */
1181 tr1 &= ~SDRAM_TR1_RDCD_MASK;
1182 if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {
1183 tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
1184 } else {
1185 tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
1186 }
wdenkfe8c2802002-11-03 00:38:21 +00001187
Stefan Roesec157d8e2005-08-01 16:41:48 +02001188 /*
1189 * set the SDRAM TR1 RDCLT value
1190 */
1191 tr1 &= ~SDRAM_TR1_RDCT_MASK;
1192 while (max_end >= (dly_val << 1)) {
1193 max_end -= (dly_val << 1);
1194 max_start -= (dly_val << 1);
1195 }
wdenkfe8c2802002-11-03 00:38:21 +00001196
Stefan Roesec157d8e2005-08-01 16:41:48 +02001197 rdclt_average = ((max_start + max_end) >> 1);
wdenkfe8c2802002-11-03 00:38:21 +00001198
Stefan Roesec157d8e2005-08-01 16:41:48 +02001199 if (rdclt_average < 0) {
1200 rdclt_average = 0;
1201 }
wdenkfe8c2802002-11-03 00:38:21 +00001202
Stefan Roesec157d8e2005-08-01 16:41:48 +02001203 if (rdclt_average >= dly_val) {
1204 rdclt_average -= dly_val;
1205 tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1206 }
1207 tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
wdenkfe8c2802002-11-03 00:38:21 +00001208
Stefan Roesed2d43272007-06-01 15:09:50 +02001209 debug("tr1: %x\n", tr1);
1210
Stefan Roesec157d8e2005-08-01 16:41:48 +02001211 /*
1212 * program SDRAM Timing Register 1 TR1
1213 */
1214 mtsdram(mem_tr1, tr1);
wdenkfe8c2802002-11-03 00:38:21 +00001215}
1216
Stefan Roesed2d43272007-06-01 15:09:50 +02001217static unsigned long program_bxcr(unsigned long *dimm_populated,
1218 unsigned char *iic0_dimm_addr,
1219 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +00001220{
Stefan Roesec157d8e2005-08-01 16:41:48 +02001221 unsigned long dimm_num;
Stefan Roesec157d8e2005-08-01 16:41:48 +02001222 unsigned long bank_base_addr;
Stefan Roesec157d8e2005-08-01 16:41:48 +02001223 unsigned long cr;
1224 unsigned long i;
Stefan Roesefd49bf02005-11-15 16:04:58 +01001225 unsigned long j;
Stefan Roesec157d8e2005-08-01 16:41:48 +02001226 unsigned long temp;
1227 unsigned char num_row_addr;
1228 unsigned char num_col_addr;
1229 unsigned char num_banks;
1230 unsigned char bank_size_id;
Stefan Roesefd49bf02005-11-15 16:04:58 +01001231 unsigned long ctrl_bank_num[MAXBANKS];
1232 unsigned long bx_cr_num;
1233 unsigned long largest_size_index;
Wolfgang Denkf013dac2005-12-04 00:40:34 +01001234 unsigned long largest_size;
1235 unsigned long current_size_index;
Stefan Roesefd49bf02005-11-15 16:04:58 +01001236 BANKPARMS bank_parms[MAXBXCR];
1237 unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */
1238 unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/
wdenkfe8c2802002-11-03 00:38:21 +00001239
Stefan Roesec157d8e2005-08-01 16:41:48 +02001240 /*
1241 * Set the BxCR regs. First, wipe out the bank config registers.
1242 */
Stefan Roesefd49bf02005-11-15 16:04:58 +01001243 for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1244 mtdcr(memcfga, mem_b0cr + (bx_cr_num << 2));
Stefan Roesec157d8e2005-08-01 16:41:48 +02001245 mtdcr(memcfgd, 0x00000000);
Stefan Roesefd49bf02005-11-15 16:04:58 +01001246 bank_parms[bx_cr_num].bank_size_bytes = 0;
wdenk8bde7f72003-06-27 21:31:46 +00001247 }
Stefan Roesefd49bf02005-11-15 16:04:58 +01001248
1249#ifdef CONFIG_BAMBOO
1250 /*
1251 * This next section is hardware dependent and must be programmed
Stefan Roesed2d43272007-06-01 15:09:50 +02001252 * to match the hardware. For bamboo, the following holds...
1253 * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0 (soldered onboard)
Stefan Roesefd49bf02005-11-15 16:04:58 +01001254 * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1
1255 * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1
1256 * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3
1257 * ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM
1258 */
1259 ctrl_bank_num[0] = 0;
1260 ctrl_bank_num[1] = 1;
1261 ctrl_bank_num[2] = 3;
1262#else
Stefan Roesed2d43272007-06-01 15:09:50 +02001263 /*
1264 * Ocotea, Ebony and the other IBM/AMCC eval boards have
1265 * 2 DIMM slots with each max 2 banks
1266 */
Stefan Roesefd49bf02005-11-15 16:04:58 +01001267 ctrl_bank_num[0] = 0;
Stefan Roesed2d43272007-06-01 15:09:50 +02001268 ctrl_bank_num[1] = 2;
Stefan Roese17f50f222005-08-04 17:09:16 +02001269#endif
wdenkfe8c2802002-11-03 00:38:21 +00001270
Stefan Roesec157d8e2005-08-01 16:41:48 +02001271 /*
1272 * reset the bank_base address
1273 */
1274 bank_base_addr = CFG_SDRAM_BASE;
1275
1276 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
1277 if (dimm_populated[dimm_num] == TRUE) {
1278 num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);
1279 num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
1280 num_banks = spd_read(iic0_dimm_addr[dimm_num], 5);
1281 bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
Stefan Roesed2d43272007-06-01 15:09:50 +02001282 debug("DIMM%d: row=%d col=%d banks=%d\n", dimm_num,
1283 num_row_addr, num_col_addr, num_banks);
Stefan Roesec157d8e2005-08-01 16:41:48 +02001284
1285 /*
1286 * Set the SDRAM0_BxCR regs
1287 */
1288 cr = 0;
Stefan Roesec157d8e2005-08-01 16:41:48 +02001289 switch (bank_size_id) {
1290 case 0x02:
1291 cr |= SDRAM_BXCR_SDSZ_8;
1292 break;
1293 case 0x04:
1294 cr |= SDRAM_BXCR_SDSZ_16;
1295 break;
1296 case 0x08:
1297 cr |= SDRAM_BXCR_SDSZ_32;
1298 break;
1299 case 0x10:
1300 cr |= SDRAM_BXCR_SDSZ_64;
1301 break;
1302 case 0x20:
1303 cr |= SDRAM_BXCR_SDSZ_128;
1304 break;
1305 case 0x40:
1306 cr |= SDRAM_BXCR_SDSZ_256;
1307 break;
1308 case 0x80:
1309 cr |= SDRAM_BXCR_SDSZ_512;
1310 break;
1311 default:
1312 printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1313 dimm_num);
1314 printf("ERROR: Unsupported value for the banksize: %d.\n",
1315 bank_size_id);
1316 printf("Replace the DIMM module with a supported DIMM.\n\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +02001317 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +02001318 }
1319
1320 switch (num_col_addr) {
1321 case 0x08:
1322 cr |= SDRAM_BXCR_SDAM_1;
1323 break;
1324 case 0x09:
1325 cr |= SDRAM_BXCR_SDAM_2;
1326 break;
1327 case 0x0A:
1328 cr |= SDRAM_BXCR_SDAM_3;
1329 break;
1330 case 0x0B:
1331 cr |= SDRAM_BXCR_SDAM_4;
1332 break;
1333 default:
1334 printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1335 dimm_num);
1336 printf("ERROR: Unsupported value for number of "
1337 "column addresses: %d.\n", num_col_addr);
1338 printf("Replace the DIMM module with a supported DIMM.\n\n");
Heiko Schochera5d71e22007-06-25 19:11:37 +02001339 spd_ddr_init_hang ();
Stefan Roesec157d8e2005-08-01 16:41:48 +02001340 }
1341
1342 /*
1343 * enable the bank
1344 */
1345 cr |= SDRAM_BXCR_SDBE;
1346
Wolfgang Denk1636d1c2007-06-22 23:59:00 +02001347 for (i = 0; i < num_banks; i++) {
Stefan Roesed2d43272007-06-01 15:09:50 +02001348 bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes =
1349 (4 << 20) * bank_size_id;
1350 bank_parms[ctrl_bank_num[dimm_num]+i].cr = cr;
1351 debug("DIMM%d-bank %d (SDRAM0_B%dCR): bank_size_bytes=%d\n",
1352 dimm_num, i, ctrl_bank_num[dimm_num]+i,
1353 bank_parms[ctrl_bank_num[dimm_num]+i].bank_size_bytes);
Wolfgang Denk1636d1c2007-06-22 23:59:00 +02001354 }
Stefan Roesec157d8e2005-08-01 16:41:48 +02001355 }
1356 }
1357
Stefan Roesefd49bf02005-11-15 16:04:58 +01001358 /* Initialize sort tables */
1359 for (i = 0; i < MAXBXCR; i++) {
1360 sorted_bank_num[i] = i;
1361 sorted_bank_size[i] = bank_parms[i].bank_size_bytes;
1362 }
1363
1364 for (i = 0; i < MAXBXCR-1; i++) {
1365 largest_size = sorted_bank_size[i];
1366 largest_size_index = 255;
1367
1368 /* Find the largest remaining value */
1369 for (j = i + 1; j < MAXBXCR; j++) {
1370 if (sorted_bank_size[j] > largest_size) {
1371 /* Save largest remaining value and its index */
1372 largest_size = sorted_bank_size[j];
1373 largest_size_index = j;
1374 }
1375 }
1376
1377 if (largest_size_index != 255) {
1378 /* Swap the current and largest values */
1379 current_size_index = sorted_bank_num[largest_size_index];
1380 sorted_bank_size[largest_size_index] = sorted_bank_size[i];
1381 sorted_bank_size[i] = largest_size;
1382 sorted_bank_num[largest_size_index] = sorted_bank_num[i];
1383 sorted_bank_num[i] = current_size_index;
1384 }
1385 }
1386
1387 /* Set the SDRAM0_BxCR regs thanks to sort tables */
1388 for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1389 if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) {
1390 mtdcr(memcfga, mem_b0cr + (sorted_bank_num[bx_cr_num] << 2));
1391 temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |
1392 SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE);
1393 temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) |
1394 bank_parms[sorted_bank_num[bx_cr_num]].cr;
1395 mtdcr(memcfgd, temp);
1396 bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
Stefan Roesed2d43272007-06-01 15:09:50 +02001397 debug("SDRAM0_B%dCR=0x%08lx\n", sorted_bank_num[bx_cr_num], temp);
Stefan Roesefd49bf02005-11-15 16:04:58 +01001398 }
1399 }
1400
Stefan Roesec157d8e2005-08-01 16:41:48 +02001401 return(bank_base_addr);
wdenkfe8c2802002-11-03 00:38:21 +00001402}
wdenkfe8c2802002-11-03 00:38:21 +00001403#endif /* CONFIG_SPD_EEPROM */