blob: 10b4c18978932305f7b1c2bc71f197f4a610deac [file] [log] [blame]
wdenkfe8c2802002-11-03 00:38:21 +00001/*
Stefan Roesec2295332007-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 *
wdenkb666c8f2003-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 Denk0ee70772005-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 Roese326c9712005-08-01 16:41:48 +020023 * (C) Copyright 2005
24 * 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
45#include <common.h>
46#include <asm/processor.h>
47#include <i2c.h>
48#include <ppc4xx.h>
Stefan Roese5b89fc12007-03-07 16:39:36 +010049#include <asm/mmu.h>
wdenkfe8c2802002-11-03 00:38:21 +000050
Stefan Roesec2295332007-02-20 10:35:42 +010051#if defined(CONFIG_SPD_EEPROM) && \
52 (defined(CONFIG_440GP) || defined(CONFIG_440GX) || \
53 defined(CONFIG_440EP) || defined(CONFIG_440GR))
wdenkfe8c2802002-11-03 00:38:21 +000054
55/*
56 * Set default values
57 */
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010058#ifndef CFG_I2C_SPEED
59#define CFG_I2C_SPEED 50000
wdenkfe8c2802002-11-03 00:38:21 +000060#endif
61
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010062#ifndef CFG_I2C_SLAVE
63#define CFG_I2C_SLAVE 0xFE
wdenkfe8c2802002-11-03 00:38:21 +000064#endif
65
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010066#define ONE_BILLION 1000000000
Stefan Roese326c9712005-08-01 16:41:48 +020067
wdenkfe8c2802002-11-03 00:38:21 +000068/*-----------------------------------------------------------------------------
Stefan Roese326c9712005-08-01 16:41:48 +020069 | Memory Controller Options 0
70 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010071#define SDRAM_CFG0_DCEN 0x80000000 /* SDRAM Controller Enable */
72#define SDRAM_CFG0_MCHK_MASK 0x30000000 /* Memory data errchecking mask */
73#define SDRAM_CFG0_MCHK_NON 0x00000000 /* No ECC generation */
74#define SDRAM_CFG0_MCHK_GEN 0x20000000 /* ECC generation */
75#define SDRAM_CFG0_MCHK_CHK 0x30000000 /* ECC generation and checking */
76#define SDRAM_CFG0_RDEN 0x08000000 /* Registered DIMM enable */
77#define SDRAM_CFG0_PMUD 0x04000000 /* Page management unit */
78#define SDRAM_CFG0_DMWD_MASK 0x02000000 /* DRAM width mask */
79#define SDRAM_CFG0_DMWD_32 0x00000000 /* 32 bits */
80#define SDRAM_CFG0_DMWD_64 0x02000000 /* 64 bits */
81#define SDRAM_CFG0_UIOS_MASK 0x00C00000 /* Unused IO State */
82#define SDRAM_CFG0_PDP 0x00200000 /* Page deallocation policy */
wdenkfe8c2802002-11-03 00:38:21 +000083
84/*-----------------------------------------------------------------------------
Stefan Roese326c9712005-08-01 16:41:48 +020085 | Memory Controller Options 1
86 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010087#define SDRAM_CFG1_SRE 0x80000000 /* Self-Refresh Entry */
88#define SDRAM_CFG1_PMEN 0x40000000 /* Power Management Enable */
wdenkfe8c2802002-11-03 00:38:21 +000089
90/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +020091 | SDRAM DEVPOT Options
92 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010093#define SDRAM_DEVOPT_DLL 0x80000000
94#define SDRAM_DEVOPT_DS 0x40000000
wdenkfe8c2802002-11-03 00:38:21 +000095
96/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +020097 | SDRAM MCSTS Options
98 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +010099#define SDRAM_MCSTS_MRSC 0x80000000
100#define SDRAM_MCSTS_SRMS 0x40000000
101#define SDRAM_MCSTS_CIS 0x20000000
wdenkfe8c2802002-11-03 00:38:21 +0000102
103/*-----------------------------------------------------------------------------
Stefan Roese326c9712005-08-01 16:41:48 +0200104 | SDRAM Refresh Timer Register
105 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100106#define SDRAM_RTR_RINT_MASK 0xFFFF0000
wdenkfe8c2802002-11-03 00:38:21 +0000107#define SDRAM_RTR_RINT_ENCODE(n) (((n) << 16) & SDRAM_RTR_RINT_MASK)
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100108#define sdram_HZ_to_ns(hertz) (1000000000/(hertz))
wdenkfe8c2802002-11-03 00:38:21 +0000109
110/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200111 | SDRAM UABus Base Address Reg
112 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100113#define SDRAM_UABBA_UBBA_MASK 0x0000000F
wdenkfe8c2802002-11-03 00:38:21 +0000114
115/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200116 | Memory Bank 0-7 configuration
117 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100118#define SDRAM_BXCR_SDBA_MASK 0xff800000 /* Base address */
119#define SDRAM_BXCR_SDSZ_MASK 0x000e0000 /* Size */
120#define SDRAM_BXCR_SDSZ_8 0x00020000 /* 8M */
121#define SDRAM_BXCR_SDSZ_16 0x00040000 /* 16M */
122#define SDRAM_BXCR_SDSZ_32 0x00060000 /* 32M */
123#define SDRAM_BXCR_SDSZ_64 0x00080000 /* 64M */
124#define SDRAM_BXCR_SDSZ_128 0x000a0000 /* 128M */
125#define SDRAM_BXCR_SDSZ_256 0x000c0000 /* 256M */
126#define SDRAM_BXCR_SDSZ_512 0x000e0000 /* 512M */
127#define SDRAM_BXCR_SDAM_MASK 0x0000e000 /* Addressing mode */
128#define SDRAM_BXCR_SDAM_1 0x00000000 /* Mode 1 */
129#define SDRAM_BXCR_SDAM_2 0x00002000 /* Mode 2 */
130#define SDRAM_BXCR_SDAM_3 0x00004000 /* Mode 3 */
131#define SDRAM_BXCR_SDAM_4 0x00006000 /* Mode 4 */
132#define SDRAM_BXCR_SDBE 0x00000001 /* Memory Bank Enable */
wdenkfe8c2802002-11-03 00:38:21 +0000133
134/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200135 | SDRAM TR0 Options
136 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100137#define SDRAM_TR0_SDWR_MASK 0x80000000
138#define SDRAM_TR0_SDWR_2_CLK 0x00000000
139#define SDRAM_TR0_SDWR_3_CLK 0x80000000
140#define SDRAM_TR0_SDWD_MASK 0x40000000
141#define SDRAM_TR0_SDWD_0_CLK 0x00000000
142#define SDRAM_TR0_SDWD_1_CLK 0x40000000
143#define SDRAM_TR0_SDCL_MASK 0x01800000
144#define SDRAM_TR0_SDCL_2_0_CLK 0x00800000
145#define SDRAM_TR0_SDCL_2_5_CLK 0x01000000
146#define SDRAM_TR0_SDCL_3_0_CLK 0x01800000
147#define SDRAM_TR0_SDPA_MASK 0x000C0000
148#define SDRAM_TR0_SDPA_2_CLK 0x00040000
149#define SDRAM_TR0_SDPA_3_CLK 0x00080000
150#define SDRAM_TR0_SDPA_4_CLK 0x000C0000
151#define SDRAM_TR0_SDCP_MASK 0x00030000
152#define SDRAM_TR0_SDCP_2_CLK 0x00000000
153#define SDRAM_TR0_SDCP_3_CLK 0x00010000
154#define SDRAM_TR0_SDCP_4_CLK 0x00020000
155#define SDRAM_TR0_SDCP_5_CLK 0x00030000
156#define SDRAM_TR0_SDLD_MASK 0x0000C000
157#define SDRAM_TR0_SDLD_1_CLK 0x00000000
158#define SDRAM_TR0_SDLD_2_CLK 0x00004000
159#define SDRAM_TR0_SDRA_MASK 0x0000001C
160#define SDRAM_TR0_SDRA_6_CLK 0x00000000
161#define SDRAM_TR0_SDRA_7_CLK 0x00000004
162#define SDRAM_TR0_SDRA_8_CLK 0x00000008
163#define SDRAM_TR0_SDRA_9_CLK 0x0000000C
164#define SDRAM_TR0_SDRA_10_CLK 0x00000010
165#define SDRAM_TR0_SDRA_11_CLK 0x00000014
166#define SDRAM_TR0_SDRA_12_CLK 0x00000018
167#define SDRAM_TR0_SDRA_13_CLK 0x0000001C
168#define SDRAM_TR0_SDRD_MASK 0x00000003
169#define SDRAM_TR0_SDRD_2_CLK 0x00000001
170#define SDRAM_TR0_SDRD_3_CLK 0x00000002
171#define SDRAM_TR0_SDRD_4_CLK 0x00000003
wdenkfe8c2802002-11-03 00:38:21 +0000172
173/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200174 | SDRAM TR1 Options
175 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100176#define SDRAM_TR1_RDSS_MASK 0xC0000000
177#define SDRAM_TR1_RDSS_TR0 0x00000000
178#define SDRAM_TR1_RDSS_TR1 0x40000000
179#define SDRAM_TR1_RDSS_TR2 0x80000000
180#define SDRAM_TR1_RDSS_TR3 0xC0000000
181#define SDRAM_TR1_RDSL_MASK 0x00C00000
182#define SDRAM_TR1_RDSL_STAGE1 0x00000000
183#define SDRAM_TR1_RDSL_STAGE2 0x00400000
184#define SDRAM_TR1_RDSL_STAGE3 0x00800000
185#define SDRAM_TR1_RDCD_MASK 0x00000800
186#define SDRAM_TR1_RDCD_RCD_0_0 0x00000000
187#define SDRAM_TR1_RDCD_RCD_1_2 0x00000800
188#define SDRAM_TR1_RDCT_MASK 0x000001FF
189#define SDRAM_TR1_RDCT_ENCODE(x) (((x) << 0) & SDRAM_TR1_RDCT_MASK)
190#define SDRAM_TR1_RDCT_DECODE(x) (((x) & SDRAM_TR1_RDCT_MASK) >> 0)
191#define SDRAM_TR1_RDCT_MIN 0x00000000
192#define SDRAM_TR1_RDCT_MAX 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000193
194/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200195 | SDRAM WDDCTR Options
196 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100197#define SDRAM_WDDCTR_WRCP_MASK 0xC0000000
198#define SDRAM_WDDCTR_WRCP_0DEG 0x00000000
199#define SDRAM_WDDCTR_WRCP_90DEG 0x40000000
200#define SDRAM_WDDCTR_WRCP_180DEG 0x80000000
201#define SDRAM_WDDCTR_DCD_MASK 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000202
203/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200204 | SDRAM CLKTR Options
205 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100206#define SDRAM_CLKTR_CLKP_MASK 0xC0000000
207#define SDRAM_CLKTR_CLKP_0DEG 0x00000000
208#define SDRAM_CLKTR_CLKP_90DEG 0x40000000
209#define SDRAM_CLKTR_CLKP_180DEG 0x80000000
210#define SDRAM_CLKTR_DCDT_MASK 0x000001FF
wdenkfe8c2802002-11-03 00:38:21 +0000211
212/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200213 | SDRAM DLYCAL Options
214 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100215#define SDRAM_DLYCAL_DLCV_MASK 0x000003FC
216#define SDRAM_DLYCAL_DLCV_ENCODE(x) (((x)<<2) & SDRAM_DLYCAL_DLCV_MASK)
217#define SDRAM_DLYCAL_DLCV_DECODE(x) (((x) & SDRAM_DLYCAL_DLCV_MASK)>>2)
wdenkfe8c2802002-11-03 00:38:21 +0000218
219/*-----------------------------------------------------------------------------+
Stefan Roese326c9712005-08-01 16:41:48 +0200220 | General Definition
221 +-----------------------------------------------------------------------------*/
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100222#define DEFAULT_SPD_ADDR1 0x53
223#define DEFAULT_SPD_ADDR2 0x52
224#define MAXBANKS 4 /* at most 4 dimm banks */
225#define MAX_SPD_BYTES 256
226#define NUMHALFCYCLES 4
227#define NUMMEMTESTS 8
228#define NUMMEMWORDS 8
229#define MAXBXCR 4
230#define TRUE 1
231#define FALSE 0
wdenkfe8c2802002-11-03 00:38:21 +0000232
Stefan Roese5b89fc12007-03-07 16:39:36 +0100233/*
234 * This DDR2 setup code can dynamically setup the TLB entries for the DDR2 memory
235 * region. Right now the cache should still be disabled in U-Boot because of the
236 * EMAC driver, that need it's buffer descriptor to be located in non cached
237 * memory.
238 *
239 * If at some time this restriction doesn't apply anymore, just define
240 * CFG_ENABLE_SDRAM_CACHE in the board config file and this code should setup
241 * everything correctly.
242 */
243#ifdef CFG_ENABLE_SDRAM_CACHE
244#define MY_TLB_WORD2_I_ENABLE 0 /* enable caching on SDRAM */
245#else
246#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE /* disable caching on SDRAM */
247#endif
248
wdenkfe8c2802002-11-03 00:38:21 +0000249const unsigned long test[NUMMEMTESTS][NUMMEMWORDS] = {
Stefan Roese326c9712005-08-01 16:41:48 +0200250 {0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000,
251 0xFFFFFFFF, 0xFFFFFFFF},
252 {0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF,
253 0x00000000, 0x00000000},
254 {0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA,
255 0x55555555, 0x55555555},
256 {0x55555555, 0x55555555, 0xAAAAAAAA, 0xAAAAAAAA, 0x55555555, 0x55555555,
257 0xAAAAAAAA, 0xAAAAAAAA},
258 {0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5,
259 0x5A5A5A5A, 0x5A5A5A5A},
260 {0x5A5A5A5A, 0x5A5A5A5A, 0xA5A5A5A5, 0xA5A5A5A5, 0x5A5A5A5A, 0x5A5A5A5A,
261 0xA5A5A5A5, 0xA5A5A5A5},
262 {0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55,
263 0x55AA55AA, 0x55AA55AA},
264 {0x55AA55AA, 0x55AA55AA, 0xAA55AA55, 0xAA55AA55, 0x55AA55AA, 0x55AA55AA,
265 0xAA55AA55, 0xAA55AA55}
wdenkfe8c2802002-11-03 00:38:21 +0000266};
267
Stefan Roesec45d1e32005-11-15 16:04:58 +0100268/* bank_parms is used to sort the bank sizes by descending order */
269struct bank_param {
270 unsigned long cr;
271 unsigned long bank_size_bytes;
272};
273
274typedef struct bank_param BANKPARMS;
275
276#ifdef CFG_SIMULATE_SPD_EEPROM
277extern unsigned char cfg_simulate_spd_eeprom[128];
278#endif
Stefan Roese5b89fc12007-03-07 16:39:36 +0100279void program_tlb(u32 start, u32 size, u32 tlb_word2_i_value);
wdenkfe8c2802002-11-03 00:38:21 +0000280
281unsigned char spd_read(uchar chip, uint addr);
282
283void get_spd_info(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000284 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100285 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000286
287void check_mem_type
Stefan Roese326c9712005-08-01 16:41:48 +0200288(unsigned long* dimm_populated,
289 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100290 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000291
292void check_volt_type
Stefan Roese326c9712005-08-01 16:41:48 +0200293(unsigned long* dimm_populated,
294 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100295 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000296
297void program_cfg0(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000298 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100299 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000300
301void program_cfg1(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000302 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100303 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000304
305void program_rtr (unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000306 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100307 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000308
309void program_tr0 (unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000310 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100311 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000312
313void program_tr1 (void);
314
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100315void program_ecc (unsigned long num_bytes);
wdenkfe8c2802002-11-03 00:38:21 +0000316
317unsigned
318long program_bxcr(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000319 unsigned char* iic0_dimm_addr,
320 unsigned long num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000321
322/*
323 * This function is reading data from the DIMM module EEPROM over the SPD bus
324 * and uses that to program the sdram controller.
325 *
Wolfgang Denk0ee70772005-09-23 11:05:55 +0200326 * This works on boards that has the same schematics that the AMCC walnut has.
wdenkfe8c2802002-11-03 00:38:21 +0000327 *
328 * BUG: Don't handle ECC memory
329 * BUG: A few values in the TR register is currently hardcoded
330 */
331
332long int spd_sdram(void) {
Stefan Roese326c9712005-08-01 16:41:48 +0200333 unsigned char iic0_dimm_addr[] = SPD_EEPROM_ADDRESS;
334 unsigned long dimm_populated[sizeof(iic0_dimm_addr)];
335 unsigned long total_size;
336 unsigned long cfg0;
337 unsigned long mcsts;
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100338 unsigned long num_dimm_banks; /* on board dimm banks */
wdenkfe8c2802002-11-03 00:38:21 +0000339
Stefan Roese326c9712005-08-01 16:41:48 +0200340 num_dimm_banks = sizeof(iic0_dimm_addr);
wdenkfe8c2802002-11-03 00:38:21 +0000341
342 /*
343 * Make sure I2C controller is initialized
344 * before continuing.
345 */
346 i2c_init(CFG_I2C_SPEED, CFG_I2C_SLAVE);
347
Stefan Roese326c9712005-08-01 16:41:48 +0200348 /*
349 * Read the SPD information using I2C interface. Check to see if the
350 * DIMM slots are populated.
351 */
352 get_spd_info(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000353
Stefan Roese326c9712005-08-01 16:41:48 +0200354 /*
355 * Check the memory type for the dimms plugged.
356 */
357 check_mem_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000358
Stefan Roese326c9712005-08-01 16:41:48 +0200359 /*
360 * Check the voltage type for the dimms plugged.
361 */
362 check_volt_type(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000363
Stefan Roese82041f52006-06-13 18:55:07 +0200364#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP)
Stefan Roese326c9712005-08-01 16:41:48 +0200365 /*
366 * Soft-reset SDRAM controller.
367 */
368 mtsdr(sdr_srst, SDR0_SRST_DMC);
369 mtsdr(sdr_srst, 0x00000000);
wdenk6148e742005-04-03 20:55:38 +0000370#endif
371
Stefan Roese326c9712005-08-01 16:41:48 +0200372 /*
373 * program 440GP SDRAM controller options (SDRAM0_CFG0)
374 */
375 program_cfg0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000376
Stefan Roese326c9712005-08-01 16:41:48 +0200377 /*
378 * program 440GP SDRAM controller options (SDRAM0_CFG1)
379 */
380 program_cfg1(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000381
Stefan Roese326c9712005-08-01 16:41:48 +0200382 /*
383 * program SDRAM refresh register (SDRAM0_RTR)
384 */
385 program_rtr(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000386
Stefan Roese326c9712005-08-01 16:41:48 +0200387 /*
388 * program SDRAM Timing Register 0 (SDRAM0_TR0)
389 */
390 program_tr0(dimm_populated, iic0_dimm_addr, num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000391
Stefan Roese326c9712005-08-01 16:41:48 +0200392 /*
393 * program the BxCR registers to find out total sdram installed
394 */
395 total_size = program_bxcr(dimm_populated, iic0_dimm_addr,
396 num_dimm_banks);
wdenkfe8c2802002-11-03 00:38:21 +0000397
Stefan Roese5b89fc12007-03-07 16:39:36 +0100398#ifdef CONFIG_PROG_SDRAM_TLB /* this define should eventually be removed */
399 /* and program tlb entries for this size (dynamic) */
400 program_tlb(0, total_size, MY_TLB_WORD2_I_ENABLE);
401#endif
402
Stefan Roese326c9712005-08-01 16:41:48 +0200403 /*
404 * program SDRAM Clock Timing Register (SDRAM0_CLKTR)
405 */
406 mtsdram(mem_clktr, 0x40000000);
wdenkfe8c2802002-11-03 00:38:21 +0000407
Stefan Roese326c9712005-08-01 16:41:48 +0200408 /*
409 * delay to ensure 200 usec has elapsed
410 */
411 udelay(400);
wdenkfe8c2802002-11-03 00:38:21 +0000412
Stefan Roese326c9712005-08-01 16:41:48 +0200413 /*
414 * enable the memory controller
415 */
416 mfsdram(mem_cfg0, cfg0);
417 mtsdram(mem_cfg0, cfg0 | SDRAM_CFG0_DCEN);
wdenkfe8c2802002-11-03 00:38:21 +0000418
Stefan Roese326c9712005-08-01 16:41:48 +0200419 /*
420 * wait for SDRAM_CFG0_DC_EN to complete
421 */
422 while (1) {
423 mfsdram(mem_mcsts, mcsts);
424 if ((mcsts & SDRAM_MCSTS_MRSC) != 0) {
425 break;
426 }
wdenk57b2d802003-06-27 21:31:46 +0000427 }
wdenkfe8c2802002-11-03 00:38:21 +0000428
Stefan Roese326c9712005-08-01 16:41:48 +0200429 /*
430 * program SDRAM Timing Register 1, adding some delays
431 */
432 program_tr1();
wdenkfe8c2802002-11-03 00:38:21 +0000433
Stefan Roese326c9712005-08-01 16:41:48 +0200434 /*
435 * if ECC is enabled, initialize parity bits
436 */
wdenkfe8c2802002-11-03 00:38:21 +0000437
438 return total_size;
439}
440
Stefan Roesec45d1e32005-11-15 16:04:58 +0100441unsigned char spd_read(uchar chip, uint addr)
442{
wdenkfe8c2802002-11-03 00:38:21 +0000443 unsigned char data[2];
444
Stefan Roesec45d1e32005-11-15 16:04:58 +0100445#ifdef CFG_SIMULATE_SPD_EEPROM
446 if (chip == CFG_SIMULATE_SPD_EEPROM) {
447 /*
448 * Onboard spd eeprom requested -> simulate values
449 */
450 return cfg_simulate_spd_eeprom[addr];
451 }
452#endif /* CFG_SIMULATE_SPD_EEPROM */
453
Stefan Roese326c9712005-08-01 16:41:48 +0200454 if (i2c_probe(chip) == 0) {
455 if (i2c_read(chip, addr, 1, data, 1) == 0) {
456 return data[0];
457 }
458 }
459
460 return 0;
wdenkfe8c2802002-11-03 00:38:21 +0000461}
462
463void get_spd_info(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000464 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100465 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000466{
Stefan Roese326c9712005-08-01 16:41:48 +0200467 unsigned long dimm_num;
468 unsigned long dimm_found;
469 unsigned char num_of_bytes;
470 unsigned char total_size;
wdenkfe8c2802002-11-03 00:38:21 +0000471
Stefan Roese326c9712005-08-01 16:41:48 +0200472 dimm_found = FALSE;
473 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
474 num_of_bytes = 0;
475 total_size = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000476
Stefan Roese326c9712005-08-01 16:41:48 +0200477 num_of_bytes = spd_read(iic0_dimm_addr[dimm_num], 0);
478 total_size = spd_read(iic0_dimm_addr[dimm_num], 1);
wdenkfe8c2802002-11-03 00:38:21 +0000479
Stefan Roese326c9712005-08-01 16:41:48 +0200480 if ((num_of_bytes != 0) && (total_size != 0)) {
481 dimm_populated[dimm_num] = TRUE;
482 dimm_found = TRUE;
wdenkfe8c2802002-11-03 00:38:21 +0000483#if 0
Stefan Roese326c9712005-08-01 16:41:48 +0200484 printf("DIMM slot %lu: populated\n", dimm_num);
wdenkfe8c2802002-11-03 00:38:21 +0000485#endif
Stefan Roese326c9712005-08-01 16:41:48 +0200486 } else {
487 dimm_populated[dimm_num] = FALSE;
wdenkfe8c2802002-11-03 00:38:21 +0000488#if 0
Stefan Roese326c9712005-08-01 16:41:48 +0200489 printf("DIMM slot %lu: Not populated\n", dimm_num);
wdenkfe8c2802002-11-03 00:38:21 +0000490#endif
Stefan Roese326c9712005-08-01 16:41:48 +0200491 }
wdenk57b2d802003-06-27 21:31:46 +0000492 }
wdenkfe8c2802002-11-03 00:38:21 +0000493
Stefan Roese326c9712005-08-01 16:41:48 +0200494 if (dimm_found == FALSE) {
495 printf("ERROR - No memory installed. Install a DDR-SDRAM DIMM.\n\n");
496 hang();
497 }
wdenkfe8c2802002-11-03 00:38:21 +0000498}
499
500void check_mem_type(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000501 unsigned char* iic0_dimm_addr,
502 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000503{
Stefan Roese326c9712005-08-01 16:41:48 +0200504 unsigned long dimm_num;
505 unsigned char dimm_type;
wdenkfe8c2802002-11-03 00:38:21 +0000506
Stefan Roese326c9712005-08-01 16:41:48 +0200507 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
508 if (dimm_populated[dimm_num] == TRUE) {
509 dimm_type = spd_read(iic0_dimm_addr[dimm_num], 2);
510 switch (dimm_type) {
511 case 7:
wdenkfe8c2802002-11-03 00:38:21 +0000512#if 0
Stefan Roese326c9712005-08-01 16:41:48 +0200513 printf("DIMM slot %lu: DDR SDRAM detected\n", dimm_num);
wdenkfe8c2802002-11-03 00:38:21 +0000514#endif
Stefan Roese326c9712005-08-01 16:41:48 +0200515 break;
516 default:
517 printf("ERROR: Unsupported DIMM detected in slot %lu.\n",
518 dimm_num);
519 printf("Only DDR SDRAM DIMMs are supported.\n");
520 printf("Replace the DIMM module with a supported DIMM.\n\n");
521 hang();
522 break;
523 }
524 }
wdenk57b2d802003-06-27 21:31:46 +0000525 }
wdenkfe8c2802002-11-03 00:38:21 +0000526}
527
528
529void check_volt_type(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000530 unsigned char* iic0_dimm_addr,
531 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000532{
Stefan Roese326c9712005-08-01 16:41:48 +0200533 unsigned long dimm_num;
534 unsigned long voltage_type;
wdenkfe8c2802002-11-03 00:38:21 +0000535
Stefan Roese326c9712005-08-01 16:41:48 +0200536 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
537 if (dimm_populated[dimm_num] == TRUE) {
538 voltage_type = spd_read(iic0_dimm_addr[dimm_num], 8);
539 if (voltage_type != 0x04) {
540 printf("ERROR: DIMM %lu with unsupported voltage level.\n",
541 dimm_num);
542 hang();
543 } else {
wdenkfe8c2802002-11-03 00:38:21 +0000544#if 0
Stefan Roese326c9712005-08-01 16:41:48 +0200545 printf("DIMM %lu voltage level supported.\n", dimm_num);
wdenkfe8c2802002-11-03 00:38:21 +0000546#endif
Stefan Roese326c9712005-08-01 16:41:48 +0200547 }
548 break;
549 }
wdenk57b2d802003-06-27 21:31:46 +0000550 }
wdenkfe8c2802002-11-03 00:38:21 +0000551}
552
553void program_cfg0(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000554 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100555 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000556{
Stefan Roese326c9712005-08-01 16:41:48 +0200557 unsigned long dimm_num;
558 unsigned long cfg0;
559 unsigned long ecc_enabled;
560 unsigned char ecc;
561 unsigned char attributes;
562 unsigned long data_width;
563 unsigned long dimm_32bit;
564 unsigned long dimm_64bit;
wdenkfe8c2802002-11-03 00:38:21 +0000565
Stefan Roese326c9712005-08-01 16:41:48 +0200566 /*
567 * get Memory Controller Options 0 data
568 */
569 mfsdram(mem_cfg0, cfg0);
wdenkfe8c2802002-11-03 00:38:21 +0000570
Stefan Roese326c9712005-08-01 16:41:48 +0200571 /*
572 * clear bits
573 */
574 cfg0 &= ~(SDRAM_CFG0_DCEN | SDRAM_CFG0_MCHK_MASK |
575 SDRAM_CFG0_RDEN | SDRAM_CFG0_PMUD |
576 SDRAM_CFG0_DMWD_MASK |
577 SDRAM_CFG0_UIOS_MASK | SDRAM_CFG0_PDP);
wdenkfe8c2802002-11-03 00:38:21 +0000578
579
Stefan Roese326c9712005-08-01 16:41:48 +0200580 /*
581 * FIXME: assume the DDR SDRAMs in both banks are the same
582 */
583 ecc_enabled = TRUE;
584 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
585 if (dimm_populated[dimm_num] == TRUE) {
586 ecc = spd_read(iic0_dimm_addr[dimm_num], 11);
587 if (ecc != 0x02) {
588 ecc_enabled = FALSE;
589 }
wdenkfe8c2802002-11-03 00:38:21 +0000590
Stefan Roese326c9712005-08-01 16:41:48 +0200591 /*
592 * program Registered DIMM Enable
593 */
594 attributes = spd_read(iic0_dimm_addr[dimm_num], 21);
595 if ((attributes & 0x02) != 0x00) {
596 cfg0 |= SDRAM_CFG0_RDEN;
597 }
wdenkfe8c2802002-11-03 00:38:21 +0000598
Stefan Roese326c9712005-08-01 16:41:48 +0200599 /*
600 * program DDR SDRAM Data Width
601 */
602 data_width =
603 (unsigned long)spd_read(iic0_dimm_addr[dimm_num],6) +
604 (((unsigned long)spd_read(iic0_dimm_addr[dimm_num],7)) << 8);
605 if (data_width == 64 || data_width == 72) {
606 dimm_64bit = TRUE;
607 cfg0 |= SDRAM_CFG0_DMWD_64;
608 } else if (data_width == 32 || data_width == 40) {
609 dimm_32bit = TRUE;
610 cfg0 |= SDRAM_CFG0_DMWD_32;
611 } else {
612 printf("WARNING: DIMM with datawidth of %lu bits.\n",
613 data_width);
614 printf("Only DIMMs with 32 or 64 bit datawidths supported.\n");
615 hang();
616 }
617 break;
618 }
wdenk57b2d802003-06-27 21:31:46 +0000619 }
wdenkfe8c2802002-11-03 00:38:21 +0000620
Stefan Roese326c9712005-08-01 16:41:48 +0200621 /*
622 * program Memory Data Error Checking
623 */
624 if (ecc_enabled == TRUE) {
625 cfg0 |= SDRAM_CFG0_MCHK_GEN;
626 } else {
627 cfg0 |= SDRAM_CFG0_MCHK_NON;
628 }
wdenkfe8c2802002-11-03 00:38:21 +0000629
Stefan Roese326c9712005-08-01 16:41:48 +0200630 /*
Stefan Roesee335ee02006-07-28 18:34:58 +0200631 * program Page Management Unit (0 == enabled)
Stefan Roese326c9712005-08-01 16:41:48 +0200632 */
Stefan Roesee335ee02006-07-28 18:34:58 +0200633 cfg0 &= ~SDRAM_CFG0_PMUD;
wdenkfe8c2802002-11-03 00:38:21 +0000634
Stefan Roese326c9712005-08-01 16:41:48 +0200635 /*
636 * program Memory Controller Options 0
637 * Note: DCEN must be enabled after all DDR SDRAM controller
638 * configuration registers get initialized.
639 */
640 mtsdram(mem_cfg0, cfg0);
wdenkfe8c2802002-11-03 00:38:21 +0000641}
642
643void program_cfg1(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000644 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100645 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000646{
Stefan Roese326c9712005-08-01 16:41:48 +0200647 unsigned long cfg1;
648 mfsdram(mem_cfg1, cfg1);
wdenkfe8c2802002-11-03 00:38:21 +0000649
Stefan Roese326c9712005-08-01 16:41:48 +0200650 /*
651 * Self-refresh exit, disable PM
652 */
653 cfg1 &= ~(SDRAM_CFG1_SRE | SDRAM_CFG1_PMEN);
wdenkfe8c2802002-11-03 00:38:21 +0000654
Stefan Roese326c9712005-08-01 16:41:48 +0200655 /*
656 * program Memory Controller Options 1
657 */
658 mtsdram(mem_cfg1, cfg1);
wdenkfe8c2802002-11-03 00:38:21 +0000659}
660
661void program_rtr (unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000662 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100663 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000664{
Stefan Roese326c9712005-08-01 16:41:48 +0200665 unsigned long dimm_num;
666 unsigned long bus_period_x_10;
667 unsigned long refresh_rate = 0;
668 unsigned char refresh_rate_type;
669 unsigned long refresh_interval;
670 unsigned long sdram_rtr;
671 PPC440_SYS_INFO sys_info;
wdenkfe8c2802002-11-03 00:38:21 +0000672
Stefan Roese326c9712005-08-01 16:41:48 +0200673 /*
674 * get the board info
675 */
676 get_sys_info(&sys_info);
677 bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
wdenkfe8c2802002-11-03 00:38:21 +0000678
679
Stefan Roese326c9712005-08-01 16:41:48 +0200680 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
681 if (dimm_populated[dimm_num] == TRUE) {
682 refresh_rate_type = 0x7F & spd_read(iic0_dimm_addr[dimm_num], 12);
683 switch (refresh_rate_type) {
684 case 0x00:
685 refresh_rate = 15625;
686 break;
687 case 0x01:
688 refresh_rate = 15625/4;
689 break;
690 case 0x02:
691 refresh_rate = 15625/2;
692 break;
693 case 0x03:
694 refresh_rate = 15626*2;
695 break;
696 case 0x04:
697 refresh_rate = 15625*4;
698 break;
699 case 0x05:
700 refresh_rate = 15625*8;
701 break;
702 default:
703 printf("ERROR: DIMM %lu, unsupported refresh rate/type.\n",
704 dimm_num);
705 printf("Replace the DIMM module with a supported DIMM.\n");
706 break;
707 }
wdenkfe8c2802002-11-03 00:38:21 +0000708
Stefan Roese326c9712005-08-01 16:41:48 +0200709 break;
710 }
wdenk57b2d802003-06-27 21:31:46 +0000711 }
wdenkfe8c2802002-11-03 00:38:21 +0000712
Stefan Roese326c9712005-08-01 16:41:48 +0200713 refresh_interval = refresh_rate * 10 / bus_period_x_10;
714 sdram_rtr = (refresh_interval & 0x3ff8) << 16;
wdenkfe8c2802002-11-03 00:38:21 +0000715
Stefan Roese326c9712005-08-01 16:41:48 +0200716 /*
717 * program Refresh Timer Register (SDRAM0_RTR)
718 */
719 mtsdram(mem_rtr, sdram_rtr);
wdenkfe8c2802002-11-03 00:38:21 +0000720}
721
722void program_tr0 (unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +0000723 unsigned char* iic0_dimm_addr,
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100724 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +0000725{
Stefan Roese326c9712005-08-01 16:41:48 +0200726 unsigned long dimm_num;
727 unsigned long tr0;
728 unsigned char wcsbc;
729 unsigned char t_rp_ns;
730 unsigned char t_rcd_ns;
731 unsigned char t_ras_ns;
732 unsigned long t_rp_clk;
733 unsigned long t_ras_rcd_clk;
734 unsigned long t_rcd_clk;
735 unsigned long t_rfc_clk;
736 unsigned long plb_check;
737 unsigned char cas_bit;
738 unsigned long cas_index;
739 unsigned char cas_2_0_available;
740 unsigned char cas_2_5_available;
741 unsigned char cas_3_0_available;
742 unsigned long cycle_time_ns_x_10[3];
743 unsigned long tcyc_3_0_ns_x_10;
744 unsigned long tcyc_2_5_ns_x_10;
745 unsigned long tcyc_2_0_ns_x_10;
746 unsigned long tcyc_reg;
747 unsigned long bus_period_x_10;
748 PPC440_SYS_INFO sys_info;
749 unsigned long residue;
wdenkfe8c2802002-11-03 00:38:21 +0000750
Stefan Roese326c9712005-08-01 16:41:48 +0200751 /*
752 * get the board info
753 */
754 get_sys_info(&sys_info);
755 bus_period_x_10 = ONE_BILLION / (sys_info.freqPLB / 10);
wdenkfe8c2802002-11-03 00:38:21 +0000756
Stefan Roese326c9712005-08-01 16:41:48 +0200757 /*
758 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
759 */
760 mfsdram(mem_tr0, tr0);
761 tr0 &= ~(SDRAM_TR0_SDWR_MASK | SDRAM_TR0_SDWD_MASK |
762 SDRAM_TR0_SDCL_MASK | SDRAM_TR0_SDPA_MASK |
763 SDRAM_TR0_SDCP_MASK | SDRAM_TR0_SDLD_MASK |
764 SDRAM_TR0_SDRA_MASK | SDRAM_TR0_SDRD_MASK);
wdenkfe8c2802002-11-03 00:38:21 +0000765
Stefan Roese326c9712005-08-01 16:41:48 +0200766 /*
767 * initialization
768 */
769 wcsbc = 0;
770 t_rp_ns = 0;
771 t_rcd_ns = 0;
772 t_ras_ns = 0;
773 cas_2_0_available = TRUE;
774 cas_2_5_available = TRUE;
775 cas_3_0_available = TRUE;
776 tcyc_2_0_ns_x_10 = 0;
777 tcyc_2_5_ns_x_10 = 0;
778 tcyc_3_0_ns_x_10 = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000779
Stefan Roese326c9712005-08-01 16:41:48 +0200780 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
781 if (dimm_populated[dimm_num] == TRUE) {
782 wcsbc = spd_read(iic0_dimm_addr[dimm_num], 15);
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100783 t_rp_ns = spd_read(iic0_dimm_addr[dimm_num], 27) >> 2;
Stefan Roese326c9712005-08-01 16:41:48 +0200784 t_rcd_ns = spd_read(iic0_dimm_addr[dimm_num], 29) >> 2;
785 t_ras_ns = spd_read(iic0_dimm_addr[dimm_num], 30);
786 cas_bit = spd_read(iic0_dimm_addr[dimm_num], 18);
wdenkfe8c2802002-11-03 00:38:21 +0000787
Stefan Roese326c9712005-08-01 16:41:48 +0200788 for (cas_index = 0; cas_index < 3; cas_index++) {
789 switch (cas_index) {
790 case 0:
791 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 9);
792 break;
793 case 1:
794 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 23);
795 break;
796 default:
797 tcyc_reg = spd_read(iic0_dimm_addr[dimm_num], 25);
798 break;
799 }
wdenkfe8c2802002-11-03 00:38:21 +0000800
Stefan Roese326c9712005-08-01 16:41:48 +0200801 if ((tcyc_reg & 0x0F) >= 10) {
802 printf("ERROR: Tcyc incorrect for DIMM in slot %lu\n",
803 dimm_num);
804 hang();
805 }
wdenkfe8c2802002-11-03 00:38:21 +0000806
Stefan Roese326c9712005-08-01 16:41:48 +0200807 cycle_time_ns_x_10[cas_index] =
808 (((tcyc_reg & 0xF0) >> 4) * 10) + (tcyc_reg & 0x0F);
809 }
wdenkfe8c2802002-11-03 00:38:21 +0000810
Stefan Roese326c9712005-08-01 16:41:48 +0200811 cas_index = 0;
wdenkfe8c2802002-11-03 00:38:21 +0000812
Stefan Roese326c9712005-08-01 16:41:48 +0200813 if ((cas_bit & 0x80) != 0) {
814 cas_index += 3;
815 } else if ((cas_bit & 0x40) != 0) {
816 cas_index += 2;
817 } else if ((cas_bit & 0x20) != 0) {
818 cas_index += 1;
819 }
wdenkfe8c2802002-11-03 00:38:21 +0000820
Stefan Roese326c9712005-08-01 16:41:48 +0200821 if (((cas_bit & 0x10) != 0) && (cas_index < 3)) {
822 tcyc_3_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
823 cas_index++;
824 } else {
825 if (cas_index != 0) {
826 cas_index++;
827 }
828 cas_3_0_available = FALSE;
829 }
wdenkfe8c2802002-11-03 00:38:21 +0000830
Stefan Roese326c9712005-08-01 16:41:48 +0200831 if (((cas_bit & 0x08) != 0) || (cas_index < 3)) {
832 tcyc_2_5_ns_x_10 = cycle_time_ns_x_10[cas_index];
833 cas_index++;
834 } else {
835 if (cas_index != 0) {
836 cas_index++;
837 }
838 cas_2_5_available = FALSE;
839 }
wdenkfe8c2802002-11-03 00:38:21 +0000840
Stefan Roese326c9712005-08-01 16:41:48 +0200841 if (((cas_bit & 0x04) != 0) || (cas_index < 3)) {
842 tcyc_2_0_ns_x_10 = cycle_time_ns_x_10[cas_index];
843 cas_index++;
844 } else {
845 if (cas_index != 0) {
846 cas_index++;
847 }
848 cas_2_0_available = FALSE;
849 }
wdenkfe8c2802002-11-03 00:38:21 +0000850
Stefan Roese326c9712005-08-01 16:41:48 +0200851 break;
852 }
wdenk57b2d802003-06-27 21:31:46 +0000853 }
wdenkfe8c2802002-11-03 00:38:21 +0000854
Stefan Roese326c9712005-08-01 16:41:48 +0200855 /*
856 * Program SD_WR and SD_WCSBC fields
857 */
Wolfgang Denkf6a692b2005-12-04 00:40:34 +0100858 tr0 |= SDRAM_TR0_SDWR_2_CLK; /* Write Recovery: 2 CLK */
Stefan Roese326c9712005-08-01 16:41:48 +0200859 switch (wcsbc) {
860 case 0:
861 tr0 |= SDRAM_TR0_SDWD_0_CLK;
862 break;
863 default:
864 tr0 |= SDRAM_TR0_SDWD_1_CLK;
865 break;
866 }
wdenkfe8c2802002-11-03 00:38:21 +0000867
Stefan Roese326c9712005-08-01 16:41:48 +0200868 /*
869 * Program SD_CASL field
870 */
871 if ((cas_2_0_available == TRUE) &&
872 (bus_period_x_10 >= tcyc_2_0_ns_x_10)) {
873 tr0 |= SDRAM_TR0_SDCL_2_0_CLK;
874 } else if ((cas_2_5_available == TRUE) &&
875 (bus_period_x_10 >= tcyc_2_5_ns_x_10)) {
876 tr0 |= SDRAM_TR0_SDCL_2_5_CLK;
877 } else if ((cas_3_0_available == TRUE) &&
878 (bus_period_x_10 >= tcyc_3_0_ns_x_10)) {
879 tr0 |= SDRAM_TR0_SDCL_3_0_CLK;
880 } else {
881 printf("ERROR: No supported CAS latency with the installed DIMMs.\n");
882 printf("Only CAS latencies of 2.0, 2.5, and 3.0 are supported.\n");
883 printf("Make sure the PLB speed is within the supported range.\n");
884 hang();
885 }
wdenkfe8c2802002-11-03 00:38:21 +0000886
Stefan Roese326c9712005-08-01 16:41:48 +0200887 /*
888 * Calculate Trp in clock cycles and round up if necessary
889 * Program SD_PTA field
890 */
891 t_rp_clk = sys_info.freqPLB * t_rp_ns / ONE_BILLION;
892 plb_check = ONE_BILLION * t_rp_clk / t_rp_ns;
893 if (sys_info.freqPLB != plb_check) {
894 t_rp_clk++;
895 }
896 switch ((unsigned long)t_rp_clk) {
897 case 0:
898 case 1:
899 case 2:
900 tr0 |= SDRAM_TR0_SDPA_2_CLK;
901 break;
902 case 3:
903 tr0 |= SDRAM_TR0_SDPA_3_CLK;
904 break;
905 default:
906 tr0 |= SDRAM_TR0_SDPA_4_CLK;
907 break;
908 }
wdenkfe8c2802002-11-03 00:38:21 +0000909
Stefan Roese326c9712005-08-01 16:41:48 +0200910 /*
911 * Program SD_CTP field
912 */
913 t_ras_rcd_clk = sys_info.freqPLB * (t_ras_ns - t_rcd_ns) / ONE_BILLION;
914 plb_check = ONE_BILLION * t_ras_rcd_clk / (t_ras_ns - t_rcd_ns);
915 if (sys_info.freqPLB != plb_check) {
916 t_ras_rcd_clk++;
917 }
918 switch (t_ras_rcd_clk) {
919 case 0:
920 case 1:
921 case 2:
922 tr0 |= SDRAM_TR0_SDCP_2_CLK;
923 break;
924 case 3:
925 tr0 |= SDRAM_TR0_SDCP_3_CLK;
926 break;
927 case 4:
928 tr0 |= SDRAM_TR0_SDCP_4_CLK;
929 break;
930 default:
931 tr0 |= SDRAM_TR0_SDCP_5_CLK;
932 break;
933 }
wdenkfe8c2802002-11-03 00:38:21 +0000934
Stefan Roese326c9712005-08-01 16:41:48 +0200935 /*
936 * Program SD_LDF field
937 */
938 tr0 |= SDRAM_TR0_SDLD_2_CLK;
wdenkfe8c2802002-11-03 00:38:21 +0000939
Stefan Roese326c9712005-08-01 16:41:48 +0200940 /*
941 * Program SD_RFTA field
942 * FIXME tRFC hardcoded as 75 nanoseconds
943 */
944 t_rfc_clk = sys_info.freqPLB / (ONE_BILLION / 75);
945 residue = sys_info.freqPLB % (ONE_BILLION / 75);
946 if (residue >= (ONE_BILLION / 150)) {
947 t_rfc_clk++;
948 }
949 switch (t_rfc_clk) {
950 case 0:
951 case 1:
952 case 2:
953 case 3:
954 case 4:
955 case 5:
956 case 6:
957 tr0 |= SDRAM_TR0_SDRA_6_CLK;
958 break;
959 case 7:
960 tr0 |= SDRAM_TR0_SDRA_7_CLK;
961 break;
962 case 8:
963 tr0 |= SDRAM_TR0_SDRA_8_CLK;
964 break;
965 case 9:
966 tr0 |= SDRAM_TR0_SDRA_9_CLK;
967 break;
968 case 10:
969 tr0 |= SDRAM_TR0_SDRA_10_CLK;
970 break;
971 case 11:
972 tr0 |= SDRAM_TR0_SDRA_11_CLK;
973 break;
974 case 12:
975 tr0 |= SDRAM_TR0_SDRA_12_CLK;
976 break;
977 default:
978 tr0 |= SDRAM_TR0_SDRA_13_CLK;
979 break;
980 }
wdenkfe8c2802002-11-03 00:38:21 +0000981
Stefan Roese326c9712005-08-01 16:41:48 +0200982 /*
983 * Program SD_RCD field
984 */
985 t_rcd_clk = sys_info.freqPLB * t_rcd_ns / ONE_BILLION;
986 plb_check = ONE_BILLION * t_rcd_clk / t_rcd_ns;
987 if (sys_info.freqPLB != plb_check) {
988 t_rcd_clk++;
989 }
990 switch (t_rcd_clk) {
991 case 0:
992 case 1:
993 case 2:
994 tr0 |= SDRAM_TR0_SDRD_2_CLK;
995 break;
996 case 3:
997 tr0 |= SDRAM_TR0_SDRD_3_CLK;
998 break;
999 default:
1000 tr0 |= SDRAM_TR0_SDRD_4_CLK;
1001 break;
1002 }
wdenkfe8c2802002-11-03 00:38:21 +00001003
1004#if 0
Stefan Roese326c9712005-08-01 16:41:48 +02001005 printf("tr0: %x\n", tr0);
wdenkfe8c2802002-11-03 00:38:21 +00001006#endif
Stefan Roese326c9712005-08-01 16:41:48 +02001007 mtsdram(mem_tr0, tr0);
wdenkfe8c2802002-11-03 00:38:21 +00001008}
1009
1010void program_tr1 (void)
1011{
Stefan Roese326c9712005-08-01 16:41:48 +02001012 unsigned long tr0;
1013 unsigned long tr1;
1014 unsigned long cfg0;
1015 unsigned long ecc_temp;
1016 unsigned long dlycal;
1017 unsigned long dly_val;
1018 unsigned long i, j, k;
1019 unsigned long bxcr_num;
1020 unsigned long max_pass_length;
1021 unsigned long current_pass_length;
1022 unsigned long current_fail_length;
1023 unsigned long current_start;
1024 unsigned long rdclt;
1025 unsigned long rdclt_offset;
1026 long max_start;
1027 long max_end;
1028 long rdclt_average;
1029 unsigned char window_found;
1030 unsigned char fail_found;
1031 unsigned char pass_found;
1032 unsigned long * membase;
1033 PPC440_SYS_INFO sys_info;
wdenkfe8c2802002-11-03 00:38:21 +00001034
Stefan Roese326c9712005-08-01 16:41:48 +02001035 /*
1036 * get the board info
1037 */
1038 get_sys_info(&sys_info);
wdenkfe8c2802002-11-03 00:38:21 +00001039
Stefan Roese326c9712005-08-01 16:41:48 +02001040 /*
1041 * get SDRAM Timing Register 0 (SDRAM_TR0) and clear bits
1042 */
1043 mfsdram(mem_tr1, tr1);
1044 tr1 &= ~(SDRAM_TR1_RDSS_MASK | SDRAM_TR1_RDSL_MASK |
1045 SDRAM_TR1_RDCD_MASK | SDRAM_TR1_RDCT_MASK);
wdenkfe8c2802002-11-03 00:38:21 +00001046
Stefan Roese326c9712005-08-01 16:41:48 +02001047 mfsdram(mem_tr0, tr0);
1048 if (((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) &&
1049 (sys_info.freqPLB > 100000000)) {
1050 tr1 |= SDRAM_TR1_RDSS_TR2;
1051 tr1 |= SDRAM_TR1_RDSL_STAGE3;
1052 tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
1053 } else {
1054 tr1 |= SDRAM_TR1_RDSS_TR1;
1055 tr1 |= SDRAM_TR1_RDSL_STAGE2;
1056 tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
1057 }
wdenkfe8c2802002-11-03 00:38:21 +00001058
Stefan Roese326c9712005-08-01 16:41:48 +02001059 /*
1060 * save CFG0 ECC setting to a temporary variable and turn ECC off
1061 */
1062 mfsdram(mem_cfg0, cfg0);
1063 ecc_temp = cfg0 & SDRAM_CFG0_MCHK_MASK;
1064 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | SDRAM_CFG0_MCHK_NON);
wdenkfe8c2802002-11-03 00:38:21 +00001065
Stefan Roese326c9712005-08-01 16:41:48 +02001066 /*
1067 * get the delay line calibration register value
1068 */
1069 mfsdram(mem_dlycal, dlycal);
1070 dly_val = SDRAM_DLYCAL_DLCV_DECODE(dlycal) << 2;
wdenkfe8c2802002-11-03 00:38:21 +00001071
Stefan Roese326c9712005-08-01 16:41:48 +02001072 max_pass_length = 0;
1073 max_start = 0;
1074 max_end = 0;
1075 current_pass_length = 0;
1076 current_fail_length = 0;
1077 current_start = 0;
1078 rdclt_offset = 0;
1079 window_found = FALSE;
1080 fail_found = FALSE;
1081 pass_found = FALSE;
wdenkfe8c2802002-11-03 00:38:21 +00001082#ifdef DEBUG
Stefan Roese326c9712005-08-01 16:41:48 +02001083 printf("Starting memory test ");
wdenkfe8c2802002-11-03 00:38:21 +00001084#endif
Stefan Roese326c9712005-08-01 16:41:48 +02001085 for (k = 0; k < NUMHALFCYCLES; k++) {
1086 for (rdclt = 0; rdclt < dly_val; rdclt++) {
1087 /*
1088 * Set the timing reg for the test.
1089 */
1090 mtsdram(mem_tr1, (tr1 | SDRAM_TR1_RDCT_ENCODE(rdclt)));
wdenkfe8c2802002-11-03 00:38:21 +00001091
Stefan Roese326c9712005-08-01 16:41:48 +02001092 for (bxcr_num = 0; bxcr_num < MAXBXCR; bxcr_num++) {
1093 mtdcr(memcfga, mem_b0cr + (bxcr_num<<2));
1094 if ((mfdcr(memcfgd) & SDRAM_BXCR_SDBE) == SDRAM_BXCR_SDBE) {
1095 /* Bank is enabled */
1096 membase = (unsigned long*)
1097 (mfdcr(memcfgd) & SDRAM_BXCR_SDBA_MASK);
wdenkfe8c2802002-11-03 00:38:21 +00001098
Stefan Roese326c9712005-08-01 16:41:48 +02001099 /*
1100 * Run the short memory test
1101 */
1102 for (i = 0; i < NUMMEMTESTS; i++) {
1103 for (j = 0; j < NUMMEMWORDS; j++) {
1104 membase[j] = test[i][j];
1105 ppcDcbf((unsigned long)&(membase[j]));
1106 }
wdenkfe8c2802002-11-03 00:38:21 +00001107
Stefan Roese326c9712005-08-01 16:41:48 +02001108 for (j = 0; j < NUMMEMWORDS; j++) {
1109 if (membase[j] != test[i][j]) {
1110 ppcDcbf((unsigned long)&(membase[j]));
1111 break;
1112 }
1113 ppcDcbf((unsigned long)&(membase[j]));
1114 }
wdenkfe8c2802002-11-03 00:38:21 +00001115
Stefan Roese326c9712005-08-01 16:41:48 +02001116 if (j < NUMMEMWORDS) {
1117 break;
1118 }
1119 }
wdenkfe8c2802002-11-03 00:38:21 +00001120
Stefan Roese326c9712005-08-01 16:41:48 +02001121 /*
1122 * see if the rdclt value passed
1123 */
1124 if (i < NUMMEMTESTS) {
1125 break;
1126 }
1127 }
1128 }
wdenkfe8c2802002-11-03 00:38:21 +00001129
Stefan Roese326c9712005-08-01 16:41:48 +02001130 if (bxcr_num == MAXBXCR) {
1131 if (fail_found == TRUE) {
1132 pass_found = TRUE;
1133 if (current_pass_length == 0) {
1134 current_start = rdclt_offset + rdclt;
1135 }
wdenkfe8c2802002-11-03 00:38:21 +00001136
Stefan Roese326c9712005-08-01 16:41:48 +02001137 current_fail_length = 0;
1138 current_pass_length++;
wdenkfe8c2802002-11-03 00:38:21 +00001139
Stefan Roese326c9712005-08-01 16:41:48 +02001140 if (current_pass_length > max_pass_length) {
1141 max_pass_length = current_pass_length;
1142 max_start = current_start;
1143 max_end = rdclt_offset + rdclt;
1144 }
1145 }
1146 } else {
1147 current_pass_length = 0;
1148 current_fail_length++;
wdenkfe8c2802002-11-03 00:38:21 +00001149
Stefan Roese326c9712005-08-01 16:41:48 +02001150 if (current_fail_length >= (dly_val>>2)) {
1151 if (fail_found == FALSE) {
1152 fail_found = TRUE;
1153 } else if (pass_found == TRUE) {
1154 window_found = TRUE;
1155 break;
1156 }
1157 }
1158 }
wdenk57b2d802003-06-27 21:31:46 +00001159 }
wdenkfe8c2802002-11-03 00:38:21 +00001160#ifdef DEBUG
Stefan Roese326c9712005-08-01 16:41:48 +02001161 printf(".");
wdenkfe8c2802002-11-03 00:38:21 +00001162#endif
Stefan Roese326c9712005-08-01 16:41:48 +02001163 if (window_found == TRUE) {
1164 break;
1165 }
wdenkfe8c2802002-11-03 00:38:21 +00001166
Stefan Roese326c9712005-08-01 16:41:48 +02001167 tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1168 rdclt_offset += dly_val;
1169 }
wdenkfe8c2802002-11-03 00:38:21 +00001170#ifdef DEBUG
Stefan Roese326c9712005-08-01 16:41:48 +02001171 printf("\n");
wdenkfe8c2802002-11-03 00:38:21 +00001172#endif
1173
Stefan Roese326c9712005-08-01 16:41:48 +02001174 /*
1175 * make sure we find the window
1176 */
1177 if (window_found == FALSE) {
1178 printf("ERROR: Cannot determine a common read delay.\n");
1179 hang();
1180 }
wdenkfe8c2802002-11-03 00:38:21 +00001181
Stefan Roese326c9712005-08-01 16:41:48 +02001182 /*
1183 * restore the orignal ECC setting
1184 */
1185 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) | ecc_temp);
wdenkfe8c2802002-11-03 00:38:21 +00001186
Stefan Roese326c9712005-08-01 16:41:48 +02001187 /*
1188 * set the SDRAM TR1 RDCD value
1189 */
1190 tr1 &= ~SDRAM_TR1_RDCD_MASK;
1191 if ((tr0 & SDRAM_TR0_SDCL_MASK) == SDRAM_TR0_SDCL_2_5_CLK) {
1192 tr1 |= SDRAM_TR1_RDCD_RCD_1_2;
1193 } else {
1194 tr1 |= SDRAM_TR1_RDCD_RCD_0_0;
1195 }
wdenkfe8c2802002-11-03 00:38:21 +00001196
Stefan Roese326c9712005-08-01 16:41:48 +02001197 /*
1198 * set the SDRAM TR1 RDCLT value
1199 */
1200 tr1 &= ~SDRAM_TR1_RDCT_MASK;
1201 while (max_end >= (dly_val << 1)) {
1202 max_end -= (dly_val << 1);
1203 max_start -= (dly_val << 1);
1204 }
wdenkfe8c2802002-11-03 00:38:21 +00001205
Stefan Roese326c9712005-08-01 16:41:48 +02001206 rdclt_average = ((max_start + max_end) >> 1);
1207 if (rdclt_average >= 0x60)
1208 while (1)
1209 ;
wdenkfe8c2802002-11-03 00:38:21 +00001210
Stefan Roese326c9712005-08-01 16:41:48 +02001211 if (rdclt_average < 0) {
1212 rdclt_average = 0;
1213 }
wdenkfe8c2802002-11-03 00:38:21 +00001214
Stefan Roese326c9712005-08-01 16:41:48 +02001215 if (rdclt_average >= dly_val) {
1216 rdclt_average -= dly_val;
1217 tr1 = tr1 ^ SDRAM_TR1_RDCD_MASK;
1218 }
1219 tr1 |= SDRAM_TR1_RDCT_ENCODE(rdclt_average);
wdenkfe8c2802002-11-03 00:38:21 +00001220
1221#if 0
Stefan Roese326c9712005-08-01 16:41:48 +02001222 printf("tr1: %x\n", tr1);
wdenkfe8c2802002-11-03 00:38:21 +00001223#endif
Stefan Roese326c9712005-08-01 16:41:48 +02001224 /*
1225 * program SDRAM Timing Register 1 TR1
1226 */
1227 mtsdram(mem_tr1, tr1);
wdenkfe8c2802002-11-03 00:38:21 +00001228}
1229
1230unsigned long program_bxcr(unsigned long* dimm_populated,
wdenk57b2d802003-06-27 21:31:46 +00001231 unsigned char* iic0_dimm_addr,
1232 unsigned long num_dimm_banks)
wdenkfe8c2802002-11-03 00:38:21 +00001233{
Stefan Roese326c9712005-08-01 16:41:48 +02001234 unsigned long dimm_num;
Stefan Roese326c9712005-08-01 16:41:48 +02001235 unsigned long bank_base_addr;
Stefan Roese326c9712005-08-01 16:41:48 +02001236 unsigned long cr;
1237 unsigned long i;
Stefan Roesec45d1e32005-11-15 16:04:58 +01001238 unsigned long j;
Stefan Roese326c9712005-08-01 16:41:48 +02001239 unsigned long temp;
1240 unsigned char num_row_addr;
1241 unsigned char num_col_addr;
1242 unsigned char num_banks;
1243 unsigned char bank_size_id;
Stefan Roesec45d1e32005-11-15 16:04:58 +01001244 unsigned long ctrl_bank_num[MAXBANKS];
1245 unsigned long bx_cr_num;
1246 unsigned long largest_size_index;
Wolfgang Denkf6a692b2005-12-04 00:40:34 +01001247 unsigned long largest_size;
1248 unsigned long current_size_index;
Stefan Roesec45d1e32005-11-15 16:04:58 +01001249 BANKPARMS bank_parms[MAXBXCR];
1250 unsigned long sorted_bank_num[MAXBXCR]; /* DDR Controller bank number table (sorted by size) */
1251 unsigned long sorted_bank_size[MAXBXCR]; /* DDR Controller bank size table (sorted by size)*/
wdenkfe8c2802002-11-03 00:38:21 +00001252
Stefan Roese326c9712005-08-01 16:41:48 +02001253 /*
1254 * Set the BxCR regs. First, wipe out the bank config registers.
1255 */
Stefan Roesec45d1e32005-11-15 16:04:58 +01001256 for (bx_cr_num = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1257 mtdcr(memcfga, mem_b0cr + (bx_cr_num << 2));
Stefan Roese326c9712005-08-01 16:41:48 +02001258 mtdcr(memcfgd, 0x00000000);
Stefan Roesec45d1e32005-11-15 16:04:58 +01001259 bank_parms[bx_cr_num].bank_size_bytes = 0;
Stefan Roese326c9712005-08-01 16:41:48 +02001260 }
Stefan Roesec45d1e32005-11-15 16:04:58 +01001261
1262#ifdef CONFIG_BAMBOO
1263 /*
1264 * This next section is hardware dependent and must be programmed
1265 * to match the hardware. For bammboo, the following holds...
1266 * 1. SDRAM0_B0CR: Bank 0 of dimm 0 ctrl_bank_num : 0
1267 * 2. SDRAM0_B1CR: Bank 0 of dimm 1 ctrl_bank_num : 1
1268 * 3. SDRAM0_B2CR: Bank 1 of dimm 1 ctrl_bank_num : 1
1269 * 4. SDRAM0_B3CR: Bank 0 of dimm 2 ctrl_bank_num : 3
1270 * ctrl_bank_num corresponds to the first usable DDR controller bank number by DIMM
1271 */
1272 ctrl_bank_num[0] = 0;
1273 ctrl_bank_num[1] = 1;
1274 ctrl_bank_num[2] = 3;
1275#else
1276 ctrl_bank_num[0] = 0;
1277 ctrl_bank_num[1] = 1;
1278 ctrl_bank_num[2] = 2;
1279 ctrl_bank_num[3] = 3;
Stefan Roese363330b2005-08-04 17:09:16 +02001280#endif
wdenkfe8c2802002-11-03 00:38:21 +00001281
Stefan Roese326c9712005-08-01 16:41:48 +02001282 /*
1283 * reset the bank_base address
1284 */
1285 bank_base_addr = CFG_SDRAM_BASE;
wdenkfe8c2802002-11-03 00:38:21 +00001286
Stefan Roese326c9712005-08-01 16:41:48 +02001287 for (dimm_num = 0; dimm_num < num_dimm_banks; dimm_num++) {
1288 if (dimm_populated[dimm_num] == TRUE) {
1289 num_row_addr = spd_read(iic0_dimm_addr[dimm_num], 3);
1290 num_col_addr = spd_read(iic0_dimm_addr[dimm_num], 4);
1291 num_banks = spd_read(iic0_dimm_addr[dimm_num], 5);
1292 bank_size_id = spd_read(iic0_dimm_addr[dimm_num], 31);
wdenkfe8c2802002-11-03 00:38:21 +00001293
Stefan Roese326c9712005-08-01 16:41:48 +02001294 /*
1295 * Set the SDRAM0_BxCR regs
1296 */
1297 cr = 0;
Stefan Roese326c9712005-08-01 16:41:48 +02001298 switch (bank_size_id) {
1299 case 0x02:
1300 cr |= SDRAM_BXCR_SDSZ_8;
1301 break;
1302 case 0x04:
1303 cr |= SDRAM_BXCR_SDSZ_16;
1304 break;
1305 case 0x08:
1306 cr |= SDRAM_BXCR_SDSZ_32;
1307 break;
1308 case 0x10:
1309 cr |= SDRAM_BXCR_SDSZ_64;
1310 break;
1311 case 0x20:
1312 cr |= SDRAM_BXCR_SDSZ_128;
1313 break;
1314 case 0x40:
1315 cr |= SDRAM_BXCR_SDSZ_256;
1316 break;
1317 case 0x80:
1318 cr |= SDRAM_BXCR_SDSZ_512;
1319 break;
1320 default:
1321 printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1322 dimm_num);
1323 printf("ERROR: Unsupported value for the banksize: %d.\n",
1324 bank_size_id);
1325 printf("Replace the DIMM module with a supported DIMM.\n\n");
1326 hang();
1327 }
wdenkfe8c2802002-11-03 00:38:21 +00001328
Stefan Roese326c9712005-08-01 16:41:48 +02001329 switch (num_col_addr) {
1330 case 0x08:
1331 cr |= SDRAM_BXCR_SDAM_1;
1332 break;
1333 case 0x09:
1334 cr |= SDRAM_BXCR_SDAM_2;
1335 break;
1336 case 0x0A:
1337 cr |= SDRAM_BXCR_SDAM_3;
1338 break;
1339 case 0x0B:
1340 cr |= SDRAM_BXCR_SDAM_4;
1341 break;
1342 default:
1343 printf("DDR-SDRAM: DIMM %lu BxCR configuration.\n",
1344 dimm_num);
1345 printf("ERROR: Unsupported value for number of "
1346 "column addresses: %d.\n", num_col_addr);
1347 printf("Replace the DIMM module with a supported DIMM.\n\n");
1348 hang();
1349 }
wdenkfe8c2802002-11-03 00:38:21 +00001350
Stefan Roese326c9712005-08-01 16:41:48 +02001351 /*
1352 * enable the bank
1353 */
1354 cr |= SDRAM_BXCR_SDBE;
wdenkfe8c2802002-11-03 00:38:21 +00001355
Stefan Roese5b89fc12007-03-07 16:39:36 +01001356 for (i = 0; i < num_banks; i++) {
1357 bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].bank_size_bytes =
Stefan Roesec45d1e32005-11-15 16:04:58 +01001358 (4 * 1024 * 1024) * bank_size_id;
Stefan Roese5b89fc12007-03-07 16:39:36 +01001359 bank_parms[ctrl_bank_num[dimm_num]+i+dimm_num].cr = cr;
1360 }
Stefan Roesec45d1e32005-11-15 16:04:58 +01001361 }
1362 }
1363
1364 /* Initialize sort tables */
1365 for (i = 0; i < MAXBXCR; i++) {
1366 sorted_bank_num[i] = i;
1367 sorted_bank_size[i] = bank_parms[i].bank_size_bytes;
1368 }
1369
1370 for (i = 0; i < MAXBXCR-1; i++) {
1371 largest_size = sorted_bank_size[i];
1372 largest_size_index = 255;
1373
1374 /* Find the largest remaining value */
1375 for (j = i + 1; j < MAXBXCR; j++) {
1376 if (sorted_bank_size[j] > largest_size) {
1377 /* Save largest remaining value and its index */
1378 largest_size = sorted_bank_size[j];
1379 largest_size_index = j;
Stefan Roese326c9712005-08-01 16:41:48 +02001380 }
wdenk57b2d802003-06-27 21:31:46 +00001381 }
Stefan Roesec45d1e32005-11-15 16:04:58 +01001382
1383 if (largest_size_index != 255) {
1384 /* Swap the current and largest values */
1385 current_size_index = sorted_bank_num[largest_size_index];
1386 sorted_bank_size[largest_size_index] = sorted_bank_size[i];
1387 sorted_bank_size[i] = largest_size;
1388 sorted_bank_num[largest_size_index] = sorted_bank_num[i];
1389 sorted_bank_num[i] = current_size_index;
1390 }
1391 }
1392
1393 /* Set the SDRAM0_BxCR regs thanks to sort tables */
1394 for (bx_cr_num = 0, bank_base_addr = 0; bx_cr_num < MAXBXCR; bx_cr_num++) {
1395 if (bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes) {
1396 mtdcr(memcfga, mem_b0cr + (sorted_bank_num[bx_cr_num] << 2));
1397 temp = mfdcr(memcfgd) & ~(SDRAM_BXCR_SDBA_MASK | SDRAM_BXCR_SDSZ_MASK |
1398 SDRAM_BXCR_SDAM_MASK | SDRAM_BXCR_SDBE);
1399 temp = temp | (bank_base_addr & SDRAM_BXCR_SDBA_MASK) |
1400 bank_parms[sorted_bank_num[bx_cr_num]].cr;
1401 mtdcr(memcfgd, temp);
1402 bank_base_addr += bank_parms[sorted_bank_num[bx_cr_num]].bank_size_bytes;
1403 }
wdenk57b2d802003-06-27 21:31:46 +00001404 }
wdenkfe8c2802002-11-03 00:38:21 +00001405
Stefan Roese326c9712005-08-01 16:41:48 +02001406 return(bank_base_addr);
wdenkfe8c2802002-11-03 00:38:21 +00001407}
1408
Wolfgang Denkf6a692b2005-12-04 00:40:34 +01001409void program_ecc (unsigned long num_bytes)
wdenkfe8c2802002-11-03 00:38:21 +00001410{
Stefan Roese326c9712005-08-01 16:41:48 +02001411 unsigned long bank_base_addr;
1412 unsigned long current_address;
1413 unsigned long end_address;
1414 unsigned long address_increment;
1415 unsigned long cfg0;
wdenkfe8c2802002-11-03 00:38:21 +00001416
Stefan Roese326c9712005-08-01 16:41:48 +02001417 /*
1418 * get Memory Controller Options 0 data
1419 */
1420 mfsdram(mem_cfg0, cfg0);
wdenkfe8c2802002-11-03 00:38:21 +00001421
Stefan Roese326c9712005-08-01 16:41:48 +02001422 /*
1423 * reset the bank_base address
1424 */
1425 bank_base_addr = CFG_SDRAM_BASE;
wdenkfe8c2802002-11-03 00:38:21 +00001426
Stefan Roese326c9712005-08-01 16:41:48 +02001427 if ((cfg0 & SDRAM_CFG0_MCHK_MASK) != SDRAM_CFG0_MCHK_NON) {
1428 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
1429 SDRAM_CFG0_MCHK_GEN);
wdenkfe8c2802002-11-03 00:38:21 +00001430
Stefan Roese326c9712005-08-01 16:41:48 +02001431 if ((cfg0 & SDRAM_CFG0_DMWD_MASK) == SDRAM_CFG0_DMWD_32) {
1432 address_increment = 4;
1433 } else {
1434 address_increment = 8;
1435 }
wdenkfe8c2802002-11-03 00:38:21 +00001436
Stefan Roese326c9712005-08-01 16:41:48 +02001437 current_address = (unsigned long)(bank_base_addr);
1438 end_address = (unsigned long)(bank_base_addr) + num_bytes;
wdenkfe8c2802002-11-03 00:38:21 +00001439
Stefan Roese326c9712005-08-01 16:41:48 +02001440 while (current_address < end_address) {
1441 *((unsigned long*)current_address) = 0x00000000;
1442 current_address += address_increment;
1443 }
wdenkfe8c2802002-11-03 00:38:21 +00001444
Stefan Roese326c9712005-08-01 16:41:48 +02001445 mtsdram(mem_cfg0, (cfg0 & ~SDRAM_CFG0_MCHK_MASK) |
1446 SDRAM_CFG0_MCHK_CHK);
1447 }
wdenkfe8c2802002-11-03 00:38:21 +00001448}
wdenkfe8c2802002-11-03 00:38:21 +00001449#endif /* CONFIG_SPD_EEPROM */