spd_sdram.c 24.8 KB
Newer Older
Eran Liberty's avatar
Eran Liberty committed
1
/*
2
 * (C) Copyright 2006-2007 Freescale Semiconductor, Inc.
3
 *
4 5
 * (C) Copyright 2006
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Wolfgang Denk's avatar
Wolfgang Denk committed
6
 *
7
 * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
Eran Liberty's avatar
Eran Liberty committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
 * (C) Copyright 2003 Motorola Inc.
 * Xianghua Xiao (X.Xiao@motorola.com)
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <asm/processor.h>
#include <i2c.h>
#include <spd.h>
#include <asm/mmu.h>
#include <spd_sdram.h>

37 38
DECLARE_GLOBAL_DATA_PTR;

39 40
void board_add_ram_info(int use_default)
{
41
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
42
	volatile ddr83xx_t *ddr = &immap->ddr;
43
	char buf[32];
44 45 46 47 48 49 50 51 52 53

	printf(" (DDR%d", ((ddr->sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK)
			   >> SDRAM_CFG_SDRAM_TYPE_SHIFT) - 1);

	if (ddr->sdram_cfg & SDRAM_CFG_32_BE)
		puts(", 32-bit");
	else
		puts(", 64-bit");

	if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
54
		puts(", ECC on");
55
	else
56 57 58
		puts(", ECC off");

	printf(", %s MHz)", strmhz(buf, gd->mem_clk));
59

60
#if defined(CONFIG_SYS_LB_SDRAM) && defined(CONFIG_SYS_LBC_SDRAM_SIZE)
61
	puts("\nSDRAM: ");
62
	print_size (CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024, " (local bus)");
63 64 65
#endif
}

Eran Liberty's avatar
Eran Liberty committed
66
#ifdef CONFIG_SPD_EEPROM
67 68
#ifndef	CONFIG_SYS_READ_SPD
#define CONFIG_SYS_READ_SPD	i2c_read
Eran Liberty's avatar
Eran Liberty committed
69 70 71 72 73 74 75 76
#endif

/*
 * Convert picoseconds into clock cycles (rounding up if needed).
 */
int
picos_to_clk(int picos)
{
Kim Phillips's avatar
Kim Phillips committed
77
	unsigned int mem_bus_clk;
Eran Liberty's avatar
Eran Liberty committed
78 79
	int clks;

Kim Phillips's avatar
Kim Phillips committed
80 81 82
	mem_bus_clk = gd->mem_clk >> 1;
	clks = picos / (1000000000 / (mem_bus_clk / 1000));
	if (picos % (1000000000 / (mem_bus_clk / 1000)) != 0)
83
		clks++;
Eran Liberty's avatar
Eran Liberty committed
84 85 86 87

	return clks;
}

88
unsigned int banksize(unsigned char row_dens)
Eran Liberty's avatar
Eran Liberty committed
89 90 91 92
{
	return ((row_dens >> 2) | ((row_dens & 3) << 6)) << 24;
}

93 94 95 96 97
int read_spd(uint addr)
{
	return ((int) addr);
}

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
#undef SPD_DEBUG
#ifdef SPD_DEBUG
static void spd_debug(spd_eeprom_t *spd)
{
	printf ("\nDIMM type:       %-18.18s\n", spd->mpart);
	printf ("SPD size:        %d\n", spd->info_size);
	printf ("EEPROM size:     %d\n", 1 << spd->chip_size);
	printf ("Memory type:     %d\n", spd->mem_type);
	printf ("Row addr:        %d\n", spd->nrow_addr);
	printf ("Column addr:     %d\n", spd->ncol_addr);
	printf ("# of rows:       %d\n", spd->nrows);
	printf ("Row density:     %d\n", spd->row_dens);
	printf ("# of banks:      %d\n", spd->nbanks);
	printf ("Data width:      %d\n",
			256 * spd->dataw_msb + spd->dataw_lsb);
	printf ("Chip width:      %d\n", spd->primw);
	printf ("Refresh rate:    %02X\n", spd->refresh);
	printf ("CAS latencies:   %02X\n", spd->cas_lat);
	printf ("Write latencies: %02X\n", spd->write_lat);
	printf ("tRP:             %d\n", spd->trp);
	printf ("tRCD:            %d\n", spd->trcd);
	printf ("\n");
}
#endif /* SPD_DEBUG */

long int spd_sdram()
Eran Liberty's avatar
Eran Liberty committed
124
{
125
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
126 127
	volatile ddr83xx_t *ddr = &immap->ddr;
	volatile law83xx_t *ecm = &immap->sysconf.ddrlaw[0];
Eran Liberty's avatar
Eran Liberty committed
128
	spd_eeprom_t spd;
129 130 131
	unsigned int n_ranks;
	unsigned int odt_rd_cfg, odt_wr_cfg;
	unsigned char twr_clk, twtr_clk;
132
	unsigned int sdram_type;
Eran Liberty's avatar
Eran Liberty committed
133 134
	unsigned int memsize;
	unsigned int law_size;
135
	unsigned char caslat, caslat_ctrl;
136 137 138 139 140 141 142
	unsigned int trfc, trfc_clk, trfc_low, trfc_high;
	unsigned int trcd_clk, trtp_clk;
	unsigned char cke_min_clk;
	unsigned char add_lat, wr_lat;
	unsigned char wr_data_delay;
	unsigned char four_act;
	unsigned char cpo;
143
	unsigned char burstlen;
144
	unsigned char odt_cfg, mode_odt_enable;
145 146 147 148
	unsigned int max_bus_clk;
	unsigned int max_data_rate, effective_data_rate;
	unsigned int ddrc_clk;
	unsigned int refresh_clk;
149
	unsigned int sdram_cfg;
150
	unsigned int ddrc_ecc_enable;
151
	unsigned int pvr = get_pvr();
152

Wolfgang Denk's avatar
Wolfgang Denk committed
153
	/* Read SPD parameters with I2C */
154
	CONFIG_SYS_READ_SPD(SPD_EEPROM_ADDRESS, 0, 1, (uchar *) & spd, sizeof (spd));
155 156 157
#ifdef SPD_DEBUG
	spd_debug(&spd);
#endif
158
	/* Check the memory type */
159
	if (spd.mem_type != SPD_MEMTYPE_DDR && spd.mem_type != SPD_MEMTYPE_DDR2) {
160
		debug("DDR: Module mem type is %02X\n", spd.mem_type);
161 162 163 164
		return 0;
	}

	/* Check the number of physical bank */
165 166 167 168 169 170 171 172
	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		n_ranks = spd.nrows;
	} else {
		n_ranks = (spd.nrows & 0x7) + 1;
	}

	if (n_ranks > 2) {
		printf("DDR: The number of physical bank is %02X\n", n_ranks);
Eran Liberty's avatar
Eran Liberty committed
173 174 175
		return 0;
	}

176
	/* Check if the number of row of the module is in the range of DDRC */
177
	if (spd.nrow_addr < 12 || spd.nrow_addr > 15) {
178 179
		printf("DDR: Row number is out of range of DDRC, row=%02X\n",
							 spd.nrow_addr);
Eran Liberty's avatar
Eran Liberty committed
180 181 182
		return 0;
	}

183 184 185 186 187 188
	/* Check if the number of col of the module is in the range of DDRC */
	if (spd.ncol_addr < 8 || spd.ncol_addr > 11) {
		printf("DDR: Col number is out of range of DDRC, col=%02X\n",
							 spd.ncol_addr);
		return 0;
	}
189

190
#ifdef CONFIG_SYS_DDRCDR_VALUE
191 192 193 194
	/*
	 * Adjust DDR II IO voltage biasing.  It just makes it work.
	 */
	if(spd.mem_type == SPD_MEMTYPE_DDR2) {
195
		immap->sysconf.ddrcdr = CONFIG_SYS_DDRCDR_VALUE;
196
	}
197
	udelay(50000);
198 199 200 201 202 203 204 205 206 207 208
#endif

	/*
	 * ODT configuration recommendation from DDR Controller Chapter.
	 */
	odt_rd_cfg = 0;			/* Never assert ODT */
	odt_wr_cfg = 0;			/* Never assert ODT */
	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
		odt_wr_cfg = 1;		/* Assert ODT on writes to CSn */
	}

Wolfgang Denk's avatar
Wolfgang Denk committed
209
	/* Setup DDR chip select register */
210
#ifdef CONFIG_SYS_83XX_DDR_USES_CS0
211 212
	ddr->csbnds[0].csbnds = (banksize(spd.row_dens) >> 24) - 1;
	ddr->cs_config[0] = ( 1 << 31
213 214
			    | (odt_rd_cfg << 20)
			    | (odt_wr_cfg << 16)
215 216
			    | ((spd.nbanks == 8 ? 1 : 0) << 14)
			    | ((spd.nrow_addr - 12) << 8)
217 218 219 220 221
			    | (spd.ncol_addr - 8) );
	debug("\n");
	debug("cs0_bnds = 0x%08x\n",ddr->csbnds[0].csbnds);
	debug("cs0_config = 0x%08x\n",ddr->cs_config[0]);

222
	if (n_ranks == 2) {
223 224 225
		ddr->csbnds[1].csbnds = ( (banksize(spd.row_dens) >> 8)
				  | ((banksize(spd.row_dens) >> 23) - 1) );
		ddr->cs_config[1] = ( 1<<31
226 227
				    | (odt_rd_cfg << 20)
				    | (odt_wr_cfg << 16)
228 229 230
				    | ((spd.nbanks == 8 ? 1 : 0) << 14)
				    | ((spd.nrow_addr - 12) << 8)
				    | (spd.ncol_addr - 8) );
231 232 233 234 235
		debug("cs1_bnds = 0x%08x\n",ddr->csbnds[1].csbnds);
		debug("cs1_config = 0x%08x\n",ddr->cs_config[1]);
	}

#else
Eran Liberty's avatar
Eran Liberty committed
236 237
	ddr->csbnds[2].csbnds = (banksize(spd.row_dens) >> 24) - 1;
	ddr->cs_config[2] = ( 1 << 31
238 239
			    | (odt_rd_cfg << 20)
			    | (odt_wr_cfg << 16)
240 241
			    | ((spd.nbanks == 8 ? 1 : 0) << 14)
			    | ((spd.nrow_addr - 12) << 8)
Eran Liberty's avatar
Eran Liberty committed
242 243 244 245
			    | (spd.ncol_addr - 8) );
	debug("\n");
	debug("cs2_bnds = 0x%08x\n",ddr->csbnds[2].csbnds);
	debug("cs2_config = 0x%08x\n",ddr->cs_config[2]);
246

247
	if (n_ranks == 2) {
Eran Liberty's avatar
Eran Liberty committed
248 249 250
		ddr->csbnds[3].csbnds = ( (banksize(spd.row_dens) >> 8)
				  | ((banksize(spd.row_dens) >> 23) - 1) );
		ddr->cs_config[3] = ( 1<<31
251 252
				    | (odt_rd_cfg << 20)
				    | (odt_wr_cfg << 16)
253 254 255
				    | ((spd.nbanks == 8 ? 1 : 0) << 14)
				    | ((spd.nrow_addr - 12) << 8)
				    | (spd.ncol_addr - 8) );
Eran Liberty's avatar
Eran Liberty committed
256 257 258
		debug("cs3_bnds = 0x%08x\n",ddr->csbnds[3].csbnds);
		debug("cs3_config = 0x%08x\n",ddr->cs_config[3]);
	}
259
#endif
Eran Liberty's avatar
Eran Liberty committed
260 261 262 263

	/*
	 * Figure out memory size in Megabytes.
	 */
264
	memsize = n_ranks * banksize(spd.row_dens) / 0x100000;
Eran Liberty's avatar
Eran Liberty committed
265 266 267 268 269 270 271 272 273

	/*
	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.
	 */
	law_size = 19 + __ilog2(memsize);

	/*
	 * Set up LAWBAR for all of DDR.
	 */
274
	ecm->bar = CONFIG_SYS_DDR_SDRAM_BASE & 0xfffff000;
Eran Liberty's avatar
Eran Liberty committed
275 276 277 278 279
	ecm->ar  = (LAWAR_EN | LAWAR_TRGT_IF_DDR | (LAWAR_SIZE & law_size));
	debug("DDR:bar=0x%08x\n", ecm->bar);
	debug("DDR:ar=0x%08x\n", ecm->ar);

	/*
280 281 282 283
	 * Find the largest CAS by locating the highest 1 bit
	 * in the spd.cas_lat field.  Translate it to a DDR
	 * controller field value:
	 *
284 285 286 287 288 289 290 291 292 293 294 295
	 *	CAS Lat	DDR I	DDR II	Ctrl
	 *	Clocks	SPD Bit	SPD Bit	Value
	 *	-------	-------	-------	-----
	 *	1.0	0		0001
	 *	1.5	1		0010
	 *	2.0	2	2	0011
	 *	2.5	3		0100
	 *	3.0	4	3	0101
	 *	3.5	5		0110
	 *	4.0	6	4	0111
	 *	4.5			1000
	 *	5.0		5	1001
Eran Liberty's avatar
Eran Liberty committed
296
	 */
297
	caslat = __ilog2(spd.cas_lat);
298 299 300 301 302 303 304 305
	if ((spd.mem_type == SPD_MEMTYPE_DDR)
	    && (caslat > 6)) {
		printf("DDR I: Invalid SPD CAS Latency: 0x%x.\n", spd.cas_lat);
		return 0;
	} else if (spd.mem_type == SPD_MEMTYPE_DDR2
		   && (caslat < 2 || caslat > 5)) {
		printf("DDR II: Invalid SPD CAS Latency: 0x%x.\n",
		       spd.cas_lat);
Eran Liberty's avatar
Eran Liberty committed
306 307
		return 0;
	}
308 309
	debug("DDR: caslat SPD bit is %d\n", caslat);

310 311 312 313
	max_bus_clk = 1000 *10 / (((spd.clk_cycle & 0xF0) >> 4) * 10
			+ (spd.clk_cycle & 0x0f));
	max_data_rate = max_bus_clk * 2;

Wolfgang Denk's avatar
Wolfgang Denk committed
314
	debug("DDR:Module maximum data rate is: %d MHz\n", max_data_rate);
315

Kim Phillips's avatar
Kim Phillips committed
316
	ddrc_clk = gd->mem_clk / 1000000;
317
	effective_data_rate = 0;
Eran Liberty's avatar
Eran Liberty committed
318

319 320 321 322 323 324 325 326 327 328 329 330 331 332
	if (max_data_rate >= 460) { /* it is DDR2-800, 667, 533 */
		if (spd.cas_lat & 0x08)
			caslat = 3;
		else
			caslat = 4;
		if (ddrc_clk <= 460 && ddrc_clk > 350)
			effective_data_rate = 400;
		else if (ddrc_clk <=350 && ddrc_clk > 280)
			effective_data_rate = 333;
		else if (ddrc_clk <= 280 && ddrc_clk > 230)
			effective_data_rate = 266;
		else
			effective_data_rate = 200;
	} else if (max_data_rate >= 390 && max_data_rate < 460) { /* it is DDR 400 */
333 334
		if (ddrc_clk <= 460 && ddrc_clk > 350) {
			/* DDR controller clk at 350~460 */
335 336 337 338 339
			effective_data_rate = 400; /* 5ns */
			caslat = caslat;
		} else if (ddrc_clk <= 350 && ddrc_clk > 280) {
			/* DDR controller clk at 280~350 */
			effective_data_rate = 333; /* 6ns */
340
			if (spd.clk_cycle2 == 0x60)
341
				caslat = caslat - 1;
342
			else
343 344 345 346
				caslat = caslat;
		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
			/* DDR controller clk at 230~280 */
			effective_data_rate = 266; /* 7.5ns */
347
			if (spd.clk_cycle3 == 0x75)
348
				caslat = caslat - 2;
349
			else if (spd.clk_cycle2 == 0x75)
350
				caslat = caslat - 1;
351
			else
352 353 354 355
				caslat = caslat;
		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
			/* DDR controller clk at 90~230 */
			effective_data_rate = 200; /* 10ns */
356
			if (spd.clk_cycle3 == 0xa0)
357
				caslat = caslat - 2;
358
			else if (spd.clk_cycle2 == 0xa0)
359
				caslat = caslat - 1;
360
			else
361 362
				caslat = caslat;
		}
363 364
	} else if (max_data_rate >= 323) { /* it is DDR 333 */
		if (ddrc_clk <= 350 && ddrc_clk > 280) {
365
			/* DDR controller clk at 280~350 */
366 367 368
			effective_data_rate = 333; /* 6ns */
			caslat = caslat;
		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
369 370
			/* DDR controller clk at 230~280 */
			effective_data_rate = 266; /* 7.5ns */
371
			if (spd.clk_cycle2 == 0x75)
372
				caslat = caslat - 1;
373
			else
374
				caslat = caslat;
375
		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
376 377
			/* DDR controller clk at 90~230 */
			effective_data_rate = 200; /* 10ns */
378
			if (spd.clk_cycle3 == 0xa0)
379
				caslat = caslat - 2;
380
			else if (spd.clk_cycle2 == 0xa0)
381
				caslat = caslat - 1;
382
			else
383
				caslat = caslat;
384 385 386
		}
	} else if (max_data_rate >= 256) { /* it is DDR 266 */
		if (ddrc_clk <= 350 && ddrc_clk > 280) {
387
			/* DDR controller clk at 280~350 */
388 389 390 391
			printf("DDR: DDR controller freq is more than "
				"max data rate of the module\n");
			return 0;
		} else if (ddrc_clk <= 280 && ddrc_clk > 230) {
392
			/* DDR controller clk at 230~280 */
393 394 395
			effective_data_rate = 266; /* 7.5ns */
			caslat = caslat;
		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
396 397
			/* DDR controller clk at 90~230 */
			effective_data_rate = 200; /* 10ns */
398
			if (spd.clk_cycle2 == 0xa0)
399 400 401 402
				caslat = caslat - 1;
		}
	} else if (max_data_rate >= 190) { /* it is DDR 200 */
		if (ddrc_clk <= 350 && ddrc_clk > 230) {
403
			/* DDR controller clk at 230~350 */
404 405 406 407
			printf("DDR: DDR controller freq is more than "
				"max data rate of the module\n");
			return 0;
		} else if (ddrc_clk <= 230 && ddrc_clk > 90) {
408
			/* DDR controller clk at 90~230 */
409 410 411
			effective_data_rate = 200; /* 10ns */
			caslat = caslat;
		}
Eran Liberty's avatar
Eran Liberty committed
412 413
	}

Wolfgang Denk's avatar
Wolfgang Denk committed
414
	debug("DDR:Effective data rate is: %dMHz\n", effective_data_rate);
415
	debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat);
416

417 418 419 420
	/*
	 * Errata DDR6 work around: input enable 2 cycles earlier.
	 * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.
	 */
421 422 423 424 425 426 427
	if(PVR_MAJ(pvr) <= 1 && spd.mem_type == SPD_MEMTYPE_DDR){
		if (caslat == 2)
			ddr->debug_reg = 0x201c0000; /* CL=2 */
		else if (caslat == 3)
			ddr->debug_reg = 0x202c0000; /* CL=2.5 */
		else if (caslat == 4)
			ddr->debug_reg = 0x202c0000; /* CL=3.0 */
428

429
		__asm__ __volatile__ ("sync");
430

431 432
		debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);
	}
433

Eran Liberty's avatar
Eran Liberty committed
434
	/*
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
	 * Convert caslat clocks to DDR controller value.
	 * Force caslat_ctrl to be DDR Controller field-sized.
	 */
	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		caslat_ctrl = (caslat + 1) & 0x07;
	} else {
		caslat_ctrl =  (2 * caslat - 1) & 0x0f;
	}

	debug("DDR: effective data rate is %d MHz\n", effective_data_rate);
	debug("DDR: caslat SPD bit is %d, controller field is 0x%x\n",
	      caslat, caslat_ctrl);

	/*
	 * Timing Config 0.
	 * Avoid writing for DDR I.
	 */
	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
		unsigned char taxpd_clk = 8;		/* By the book. */
		unsigned char tmrd_clk = 2;		/* By the book. */
		unsigned char act_pd_exit = 2;		/* Empirical? */
		unsigned char pre_pd_exit = 6;		/* Empirical? */

		ddr->timing_cfg_0 = (0
			| ((act_pd_exit & 0x7) << 20)	/* ACT_PD_EXIT */
			| ((pre_pd_exit & 0x7) << 16)	/* PRE_PD_EXIT */
			| ((taxpd_clk & 0xf) << 8)	/* ODT_PD_EXIT */
			| ((tmrd_clk & 0xf) << 0)	/* MRS_CYC */
			);
		debug("DDR: timing_cfg_0 = 0x%08x\n", ddr->timing_cfg_0);
	}

	/*
	 * For DDR I, WRREC(Twr) and WRTORD(Twtr) are not in SPD,
	 * use conservative value.
	 * For DDR II, they are bytes 36 and 37, in quarter nanos.
	 */

	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		twr_clk = 3;	/* Clocks */
		twtr_clk = 1;	/* Clocks */
	} else {
		twr_clk = picos_to_clk(spd.twr * 250);
		twtr_clk = picos_to_clk(spd.twtr * 250);
479 480
		if (twtr_clk < 2)
			twtr_clk = 2;
481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508
	}

	/*
	 * Calculate Trfc, in picos.
	 * DDR I:  Byte 42 straight up in ns.
	 * DDR II: Byte 40 and 42 swizzled some, in ns.
	 */
	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		trfc = spd.trfc * 1000;		/* up to ps */
	} else {
		unsigned int byte40_table_ps[8] = {
			0,
			250,
			330,
			500,
			660,
			750,
			0,
			0
		};

		trfc = (((spd.trctrfc_ext & 0x1) * 256) + spd.trfc) * 1000
			+ byte40_table_ps[(spd.trctrfc_ext >> 1) & 0x7];
	}
	trfc_clk = picos_to_clk(trfc);

	/*
	 * Trcd, Byte 29, from quarter nanos to ps and clocks.
Eran Liberty's avatar
Eran Liberty committed
509
	 */
510 511 512 513 514 515 516 517 518 519 520
	trcd_clk = picos_to_clk(spd.trcd * 250) & 0x7;

	/*
	 * Convert trfc_clk to DDR controller fields.  DDR I should
	 * fit in the REFREC field (16-19) of TIMING_CFG_1, but the
	 * 83xx controller has an extended REFREC field of three bits.
	 * The controller automatically adds 8 clocks to this value,
	 * so preadjust it down 8 first before splitting it up.
	 */
	trfc_low = (trfc_clk - 8) & 0xf;
	trfc_high = ((trfc_clk - 8) >> 4) & 0x3;
Eran Liberty's avatar
Eran Liberty committed
521 522

	ddr->timing_cfg_1 =
523 524
	    (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |	/* PRETOACT */
	     ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) | /* ACTTOPRE */
Wolfgang Denk's avatar
Wolfgang Denk committed
525
	     (trcd_clk << 20 ) |				/* ACTTORW */
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
	     (caslat_ctrl << 16 ) |				/* CASLAT */
	     (trfc_low << 12 ) |				/* REFEC */
	     ((twr_clk & 0x07) << 8) |				/* WRRREC */
	     ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) |	/* ACTTOACT */
	     ((twtr_clk & 0x07) << 0)				/* WRTORD */
	    );

	/*
	 * Additive Latency
	 * For DDR I, 0.
	 * For DDR II, with ODT enabled, use "a value" less than ACTTORW,
	 * which comes from Trcd, and also note that:
	 *	add_lat + caslat must be >= 4
	 */
	add_lat = 0;
	if (spd.mem_type == SPD_MEMTYPE_DDR2
	    && (odt_wr_cfg || odt_rd_cfg)
	    && (caslat < 4)) {
544
		add_lat = 4 - caslat;
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580
		if ((add_lat + caslat) < 4) {
			add_lat = 0;
		}
	}

	/*
	 * Write Data Delay
	 * Historically 0x2 == 4/8 clock delay.
	 * Empirically, 0x3 == 6/8 clock delay is suggested for DDR I 266.
	 */
	wr_data_delay = 2;

	/*
	 * Write Latency
	 * Read to Precharge
	 * Minimum CKE Pulse Width.
	 * Four Activate Window
	 */
	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		/*
		 * This is a lie.  It should really be 1, but if it is
		 * set to 1, bits overlap into the old controller's
		 * otherwise unused ACSM field.  If we leave it 0, then
		 * the HW will magically treat it as 1 for DDR 1.  Oh Yea.
		 */
		wr_lat = 0;

		trtp_clk = 2;		/* By the book. */
		cke_min_clk = 1;	/* By the book. */
		four_act = 1;		/* By the book. */

	} else {
		wr_lat = caslat - 1;

		/* Convert SPD value from quarter nanos to picos. */
		trtp_clk = picos_to_clk(spd.trtp * 250);
581 582 583
		if (trtp_clk < 2)
			trtp_clk = 2;
		trtp_clk += add_lat;
Eran Liberty's avatar
Eran Liberty committed
584

585 586 587 588 589 590 591 592 593 594
		cke_min_clk = 3;	/* By the book. */
		four_act = picos_to_clk(37500);	/* By the book. 1k pages? */
	}

	/*
	 * Empirically set ~MCAS-to-preamble override for DDR 2.
	 * Your milage will vary.
	 */
	cpo = 0;
	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
595 596
		if (effective_data_rate == 266) {
			cpo = 0x4;		/* READ_LAT + 1/2 */
597 598 599
		} else if (effective_data_rate == 333) {
			cpo = 0x6;		/* READ_LAT + 1 */
		} else if (effective_data_rate == 400) {
600
			cpo = 0x7;		/* READ_LAT + 5/4 */
601 602 603 604 605 606 607 608 609 610 611 612 613 614 615
		} else {
			/* Automatic calibration */
			cpo = 0x1f;
		}
	}

	ddr->timing_cfg_2 = (0
		| ((add_lat & 0x7) << 28)		/* ADD_LAT */
		| ((cpo & 0x1f) << 23)			/* CPO */
		| ((wr_lat & 0x7) << 19)		/* WR_LAT */
		| ((trtp_clk & 0x7) << 13)		/* RD_TO_PRE */
		| ((wr_data_delay & 0x7) << 10)		/* WR_DATA_DELAY */
		| ((cke_min_clk & 0x7) << 6)		/* CKE_PLS */
		| ((four_act & 0x1f) << 0)		/* FOUR_ACT */
		);
Eran Liberty's avatar
Eran Liberty committed
616 617 618

	debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1);
	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
619 620

	/* Check DIMM data bus width */
621
	if (spd.dataw_lsb < 64) {
622 623
		if (spd.mem_type == SPD_MEMTYPE_DDR)
			burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
624
		else
625
			burstlen = 0x02; /* 32 bit data bus, burst len is 4 */
626
		debug("\n   DDR DIMM: data bus width is 32 bit");
627
	} else {
628
		burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */
629
		debug("\n   DDR DIMM: data bus width is 64 bit");
630
	}
Eran Liberty's avatar
Eran Liberty committed
631

632
	/* Is this an ECC DDR chip? */
633
	if (spd.config == 0x02)
634
		debug(" with ECC\n");
635
	else
636
		debug(" without ECC\n");
637 638 639

	/* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus,
	   Burst type is sequential
Eran Liberty's avatar
Eran Liberty committed
640
	 */
641 642
	if (spd.mem_type == SPD_MEMTYPE_DDR) {
		switch (caslat) {
643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
		case 1:
			ddr->sdram_mode = 0x50 | burstlen; /* CL=1.5 */
			break;
		case 2:
			ddr->sdram_mode = 0x20 | burstlen; /* CL=2.0 */
			break;
		case 3:
			ddr->sdram_mode = 0x60 | burstlen; /* CL=2.5 */
			break;
		case 4:
			ddr->sdram_mode = 0x30 | burstlen; /* CL=3.0 */
			break;
		default:
			printf("DDR:only CL 1.5, 2.0, 2.5, 3.0 is supported\n");
			return 0;
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
		}
	} else {
		mode_odt_enable = 0x0;                  /* Default disabled */
		if (odt_wr_cfg || odt_rd_cfg) {
			/*
			 * Bits 6 and 2 in Extended MRS(1)
			 * Bit 2 == 0x04 == 75 Ohm, with 2 DIMM modules.
			 * Bit 6 == 0x40 == 150 Ohm, with 1 DIMM module.
			 */
			mode_odt_enable = 0x40;         /* 150 Ohm */
		}

		ddr->sdram_mode =
			(0
			 | (1 << (16 + 10))             /* DQS Differential disable */
			 | (add_lat << (16 + 3))        /* Additive Latency in EMRS1 */
			 | (mode_odt_enable << 16)      /* ODT Enable in EMRS1 */
675
			 | ((twr_clk - 1) << 9)         /* Write Recovery Autopre */
676 677 678
			 | (caslat << 4)                /* caslat */
			 | (burstlen << 0)              /* Burst length */
			);
Eran Liberty's avatar
Eran Liberty committed
679 680 681
	}
	debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);

682 683 684 685 686 687
	/*
	 * Clear EMRS2 and EMRS3.
	 */
	ddr->sdram_mode2 = 0;
	debug("DDR: sdram_mode2 = 0x%08x\n", ddr->sdram_mode2);

688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715
	switch (spd.refresh) {
		case 0x00:
		case 0x80:
			refresh_clk = picos_to_clk(15625000);
			break;
		case 0x01:
		case 0x81:
			refresh_clk = picos_to_clk(3900000);
			break;
		case 0x02:
		case 0x82:
			refresh_clk = picos_to_clk(7800000);
			break;
		case 0x03:
		case 0x83:
			refresh_clk = picos_to_clk(31300000);
			break;
		case 0x04:
		case 0x84:
			refresh_clk = picos_to_clk(62500000);
			break;
		case 0x05:
		case 0x85:
			refresh_clk = picos_to_clk(125000000);
			break;
		default:
			refresh_clk = 0x512;
			break;
Eran Liberty's avatar
Eran Liberty committed
716 717 718 719 720 721
	}

	/*
	 * Set BSTOPRE to 0x100 for page mode
	 * If auto-charge is used, set BSTOPRE = 0
	 */
722
	ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100;
Eran Liberty's avatar
Eran Liberty committed
723 724
	debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);

725 726 727 728
	/*
	 * SDRAM Cfg 2
	 */
	odt_cfg = 0;
729
#ifndef CONFIG_NEVER_ASSERT_ODT_TO_CPU
730 731 732
	if (odt_rd_cfg | odt_wr_cfg) {
		odt_cfg = 0x2;		/* ODT to IOs during reads */
	}
733
#endif
734 735 736 737 738 739 740 741 742 743
	if (spd.mem_type == SPD_MEMTYPE_DDR2) {
		ddr->sdram_cfg2 = (0
			    | (0 << 26)	/* True DQS */
			    | (odt_cfg << 21)	/* ODT only read */
			    | (1 << 12)	/* 1 refresh at a time */
			    );

		debug("DDR: sdram_cfg2  = 0x%08x\n", ddr->sdram_cfg2);
	}

744 745
#ifdef CONFIG_SYS_DDR_SDRAM_CLK_CNTL	/* Optional platform specific value */
	ddr->sdram_clk_cntl = CONFIG_SYS_DDR_SDRAM_CLK_CNTL;
746
#endif
747
	debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);
748

Eran Liberty's avatar
Eran Liberty committed
749 750
	asm("sync;isync");

751
	udelay(600);
Eran Liberty's avatar
Eran Liberty committed
752 753

	/*
754 755
	 * Figure out the settings for the sdram_cfg register. Build up
	 * the value in 'sdram_cfg' before writing since the write into
Eran Liberty's avatar
Eran Liberty committed
756 757 758 759 760
	 * the register will actually enable the memory controller, and all
	 * settings must be done before enabling.
	 *
	 * sdram_cfg[0]   = 1 (ddr sdram logic enable)
	 * sdram_cfg[1]   = 1 (self-refresh-enable)
761 762 763
	 * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)
	 *			010 DDR 1 SDRAM
	 *			011 DDR 2 SDRAM
764 765
	 * sdram_cfg[12] = 0 (32_BE =0 , 64 bit bus mode)
	 * sdram_cfg[13] = 0 (8_BE =0, 4-beat bursts)
Eran Liberty's avatar
Eran Liberty committed
766
	 */
767
	if (spd.mem_type == SPD_MEMTYPE_DDR)
768
		sdram_type = SDRAM_CFG_SDRAM_TYPE_DDR1;
769
	else
770
		sdram_type = SDRAM_CFG_SDRAM_TYPE_DDR2;
771 772

	sdram_cfg = (0
773 774 775
		     | SDRAM_CFG_MEM_EN		/* DDR enable */
		     | SDRAM_CFG_SREN		/* Self refresh */
		     | sdram_type		/* SDRAM type */
776
		     );
Eran Liberty's avatar
Eran Liberty committed
777

778
	/* sdram_cfg[3] = RD_EN - registered DIMM enable */
779
	if (spd.mod_attr & 0x02)
780
		sdram_cfg |= SDRAM_CFG_RD_EN;
Eran Liberty's avatar
Eran Liberty committed
781

782
	/* The DIMM is 32bit width */
783
	if (spd.dataw_lsb < 64) {
784
		if (spd.mem_type == SPD_MEMTYPE_DDR)
785
			sdram_cfg |= SDRAM_CFG_32_BE | SDRAM_CFG_8_BE;
786
		if (spd.mem_type == SPD_MEMTYPE_DDR2)
787
			sdram_cfg |= SDRAM_CFG_32_BE;
788
	}
789

790 791
	ddrc_ecc_enable = 0;

Eran Liberty's avatar
Eran Liberty committed
792
#if defined(CONFIG_DDR_ECC)
793
	/* Enable ECC with sdram_cfg[2] */
Eran Liberty's avatar
Eran Liberty committed
794
	if (spd.config == 0x02) {
795 796 797 798 799 800 801
		sdram_cfg |= 0x20000000;
		ddrc_ecc_enable = 1;
		/* disable error detection */
		ddr->err_disable = ~ECC_ERROR_ENABLE;
		/* set single bit error threshold to maximum value,
		 * reset counter to zero */
		ddr->err_sbe = (255 << ECC_ERROR_MAN_SBET_SHIFT) |
802
				(0 << ECC_ERROR_MAN_SBEC_SHIFT);
Eran Liberty's avatar
Eran Liberty committed
803
	}
804 805 806

	debug("DDR:err_disable=0x%08x\n", ddr->err_disable);
	debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);
Eran Liberty's avatar
Eran Liberty committed
807
#endif
808
	debug("   DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF");
Eran Liberty's avatar
Eran Liberty committed
809 810 811 812 813

#if defined(CONFIG_DDR_2T_TIMING)
	/*
	 * Enable 2T timing by setting sdram_cfg[16].
	 */
814
	sdram_cfg |= SDRAM_CFG_2T_EN;
Eran Liberty's avatar
Eran Liberty committed
815
#endif
816 817
	/* Enable controller, and GO! */
	ddr->sdram_cfg = sdram_cfg;
Eran Liberty's avatar
Eran Liberty committed
818 819 820 821
	asm("sync;isync");
	udelay(500);

	debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);
822
	return memsize; /*in MBytes*/
Eran Liberty's avatar
Eran Liberty committed
823 824 825
}
#endif /* CONFIG_SPD_EEPROM */

826
#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
Eran Liberty's avatar
Eran Liberty committed
827
/*
828 829
 * Use timebase counter, get_timer() is not availabe
 * at this point of initialization yet.
Eran Liberty's avatar
Eran Liberty committed
830
 */
831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
static __inline__ unsigned long get_tbms (void)
{
	unsigned long tbl;
	unsigned long tbu1, tbu2;
	unsigned long ms;
	unsigned long long tmp;

	ulong tbclk = get_tbclk();

	/* get the timebase ticks */
	do {
		asm volatile ("mftbu %0":"=r" (tbu1):);
		asm volatile ("mftb %0":"=r" (tbl):);
		asm volatile ("mftbu %0":"=r" (tbu2):);
	} while (tbu1 != tbu2);

	/* convert ticks to ms */
	tmp = (unsigned long long)(tbu1);
	tmp = (tmp << 32);
	tmp += (unsigned long long)(tbl);
	ms = tmp/(tbclk/1000);

	return ms;
}
Eran Liberty's avatar
Eran Liberty committed
855

856 857 858 859
/*
 * Initialize all of memory for ECC, then enable errors.
 */
void ddr_enable_ecc(unsigned int dram_size)
Eran Liberty's avatar
Eran Liberty committed
860
{
861
	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
862
	volatile ddr83xx_t *ddr= &immap->ddr;
863
	unsigned long t_start, t_end;
864 865 866
	register u64 *p;
	register uint size;
	unsigned int pattern[2];
867

868 869
	icache_enable();
	t_start = get_tbms();
870 871
	pattern[0] = 0xdeadbeef;
	pattern[1] = 0xdeadbeef;
872

873 874 875
#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)
	dma_meminit(pattern[0], dram_size);
#else
876 877 878 879
	debug("ddr init: CPU FP write method\n");
	size = dram_size;
	for (p = 0; p < (u64*)(size); p++) {
		ppcDWstore((u32*)p, pattern);
Eran Liberty's avatar
Eran Liberty committed
880
	}
881
	__asm__ __volatile__ ("sync");
882
#endif
Eran Liberty's avatar
Eran Liberty committed
883

884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
	t_end = get_tbms();
	icache_disable();

	debug("\nREADY!!\n");
	debug("ddr init duration: %ld ms\n", t_end - t_start);

	/* Clear All ECC Errors */
	if ((ddr->err_detect & ECC_ERROR_DETECT_MME) == ECC_ERROR_DETECT_MME)
		ddr->err_detect |= ECC_ERROR_DETECT_MME;
	if ((ddr->err_detect & ECC_ERROR_DETECT_MBE) == ECC_ERROR_DETECT_MBE)
		ddr->err_detect |= ECC_ERROR_DETECT_MBE;
	if ((ddr->err_detect & ECC_ERROR_DETECT_SBE) == ECC_ERROR_DETECT_SBE)
		ddr->err_detect |= ECC_ERROR_DETECT_SBE;
	if ((ddr->err_detect & ECC_ERROR_DETECT_MSE) == ECC_ERROR_DETECT_MSE)
		ddr->err_detect |= ECC_ERROR_DETECT_MSE;

	/* Disable ECC-Interrupts */
	ddr->err_int_en &= ECC_ERR_INT_DISABLE;

	/* Enable errors for ECC */
	ddr->err_disable &= ECC_ERROR_ENABLE;

	__asm__ __volatile__ ("sync");
	__asm__ __volatile__ ("isync");
}
Eran Liberty's avatar
Eran Liberty committed
909
#endif	/* CONFIG_DDR_ECC */