⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spd_sdram.c

📁 from wangkj@yahoo.com 电路原理图和详细说明: amd.9966.org或者 arm.9966.org 都是原创,包括boot, loader,u-boot,linu
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	} else if (max_data_rate >= 190) { /* it is DDR 200 */		if (ddrc_clk <= 350 && ddrc_clk > 230) {			/* DDR controller clk at 230~350 */			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) {			/* DDR controller clk at 90~230 */			effective_data_rate = 200; /* 10ns */			caslat = caslat;		}	}	debug("DDR:Effective data rate is: %dMhz\n", effective_data_rate);	debug("DDR:The MSB 1 of CAS Latency is: %d\n", caslat);	/*	 * Errata DDR6 work around: input enable 2 cycles earlier.	 * including MPC834x Rev1.0/1.1 and MPC8360 Rev1.1/1.2.	 */	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 */	__asm__ __volatile__ ("sync");	debug("Errata DDR6 (debug_reg=0x%08x)\n", ddr->debug_reg);	/*	 * note: caslat must also be programmed into ddr->sdram_mode	 * register.	 *	 * note: WRREC(Twr) and WRTORD(Twtr) are not in SPD,	 * use conservative value here.	 */	caslat_ctrl = (caslat + 1) & 0x07; /* see as above */	ddr->timing_cfg_1 =	    (((picos_to_clk(spd.trp * 250) & 0x07) << 28 ) |	     ((picos_to_clk(spd.tras * 1000) & 0x0f ) << 24 ) |	     ((picos_to_clk(spd.trcd * 250) & 0x07) << 20 ) |	     ((caslat_ctrl & 0x07) << 16 ) |	     (((picos_to_clk(spd.trfc * 1000) - 8) & 0x0f) << 12 ) |	     ( 0x300 ) |	     ((picos_to_clk(spd.trrd * 250) & 0x07) << 4) | 1);	ddr->timing_cfg_2 = 0x00000800;	debug("DDR:timing_cfg_1=0x%08x\n", ddr->timing_cfg_1);	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);	/* Setup init value, but not enable */	ddr->sdram_cfg = 0x42000000;	/* Check DIMM data bus width */	if (spd.dataw_lsb == 0x20) {		burstlen = 0x03; /* 32 bit data bus, burst len is 8 */		printf("\n   DDR DIMM: data bus width is 32 bit");	} else {		burstlen = 0x02; /* Others act as 64 bit bus, burst len is 4 */		printf("\n   DDR DIMM: data bus width is 64 bit");	}	/* Is this an ECC DDR chip? */	if (spd.config == 0x02)		printf(" with ECC\n");	else		printf(" without ECC\n");	/* Burst length is always 4 for 64 bit data bus, 8 for 32 bit data bus,	   Burst type is sequential	 */	switch (caslat) {		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;	}	debug("DDR:sdram_mode=0x%08x\n", ddr->sdram_mode);	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;	}	/*	 * Set BSTOPRE to 0x100 for page mode	 * If auto-charge is used, set BSTOPRE = 0	 */	ddr->sdram_interval = ((refresh_clk & 0x3fff) << 16) | 0x100;	debug("DDR:sdram_interval=0x%08x\n", ddr->sdram_interval);	/* SS_EN = 0, source synchronous disable	 * CLK_ADJST = 0, MCK/MCK# is launched aligned with addr/cmd	 */	ddr->sdram_clk_cntl = 0x00000000;	debug("DDR:sdram_clk_cntl=0x%08x\n", ddr->sdram_clk_cntl);	asm("sync;isync");	udelay(600);	/*	 * Figure out the settings for the sdram_cfg register. Build up	 * the value in 'sdram_cfg' before writing since the write into	 * 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)	 * sdram_cfg[6:7] = 2 (SDRAM type = DDR SDRAM)	 * sdram_cfg[12] = 0 (32_BE =0 , 64 bit bus mode)	 * sdram_cfg[13] = 0 (8_BE =0, 4-beat bursts)	 */	sdram_cfg = 0xC2000000;	/* sdram_cfg[3] = RD_EN - registered DIMM enable */	if (spd.mod_attr & 0x02)		sdram_cfg |= 0x10000000;	/* The DIMM is 32bit width */	if (spd.dataw_lsb == 0x20)		sdram_cfg |= 0x000C0000;	ddrc_ecc_enable = 0;#if defined(CONFIG_DDR_ECC)	/* Enable ECC with sdram_cfg[2] */	if (spd.config == 0x02) {		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) |				(0 << ECC_ERROR_MAN_SBEC_SHIFT);	}	debug("DDR:err_disable=0x%08x\n", ddr->err_disable);	debug("DDR:err_sbe=0x%08x\n", ddr->err_sbe);#endif	printf("   DDRC ECC mode: %s\n", ddrc_ecc_enable ? "ON":"OFF");#if defined(CONFIG_DDR_2T_TIMING)	/*	 * Enable 2T timing by setting sdram_cfg[16].	 */	sdram_cfg |= SDRAM_CFG_2T_EN;#endif	/* Enable controller, and GO! */	ddr->sdram_cfg = sdram_cfg;	asm("sync;isync");	udelay(500);	debug("DDR:sdram_cfg=0x%08x\n", ddr->sdram_cfg);	return memsize; /*in MBytes*/}#endif /* CONFIG_SPD_EEPROM */#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)/* * Use timebase counter, get_timer() is not availabe * at this point of initialization yet. */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;}/* * Initialize all of memory for ECC, then enable errors. *//* #define CONFIG_DDR_ECC_INIT_VIA_DMA */void ddr_enable_ecc(unsigned int dram_size){	volatile immap_t *immap = (immap_t *)CFG_IMMR;	volatile ddr83xx_t *ddr= &immap->ddr;	unsigned long t_start, t_end;	register u64 *p;	register uint size;	unsigned int pattern[2];#if defined(CONFIG_DDR_ECC_INIT_VIA_DMA)	uint i;#endif	icache_enable();	t_start = get_tbms();	pattern[0] = 0xdeadbeef;	pattern[1] = 0xdeadbeef;#if !defined(CONFIG_DDR_ECC_INIT_VIA_DMA)	debug("ddr init: CPU FP write method\n");	size = dram_size;	for (p = 0; p < (u64*)(size); p++) {		ppcDWstore((u32*)p, pattern);	}	__asm__ __volatile__ ("sync");#else	debug("ddr init: DMA method\n");	size = 0x2000;	for (p = 0; p < (u64*)(size); p++) {		ppcDWstore((u32*)p, pattern);	}	__asm__ __volatile__ ("sync");	/* Initialise DMA for direct transfer */	dma_init();	/* Start DMA to transfer */	dma_xfer((uint *)0x2000, 0x2000, (uint *)0); /* 8K */	dma_xfer((uint *)0x4000, 0x4000, (uint *)0); /* 16K */	dma_xfer((uint *)0x8000, 0x8000, (uint *)0); /* 32K */	dma_xfer((uint *)0x10000, 0x10000, (uint *)0); /* 64K */	dma_xfer((uint *)0x20000, 0x20000, (uint *)0); /* 128K */	dma_xfer((uint *)0x40000, 0x40000, (uint *)0); /* 256K */	dma_xfer((uint *)0x80000, 0x80000, (uint *)0); /* 512K */	dma_xfer((uint *)0x100000, 0x100000, (uint *)0); /* 1M */	dma_xfer((uint *)0x200000, 0x200000, (uint *)0); /* 2M */	dma_xfer((uint *)0x400000, 0x400000, (uint *)0); /* 4M */	for (i = 1; i < dram_size / 0x800000; i++) {		dma_xfer((uint *)(0x800000*i), 0x800000, (uint *)0);	}#endif	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");}#endif	/* CONFIG_DDR_ECC */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -