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

📄 spd_sdram.c

📁 from wangkj@yahoo.com 电路原理图和详细说明: amd.9966.org或者 arm.9966.org 都是原创,包括boot, loader,u-boot,linu
💻 C
📖 第 1 页 / 共 3 页
字号:
			    | (odt_cfg << 21)	/* ODT */			    | (d_init << 4)	/* D_INIT auto init DDR */			    );	debug("DDR: sdram_cfg_2  = 0x%08x\n", ddr->sdram_cfg_2);#ifdef MPC86xx_DDR_SDRAM_CLK_CNTL	/*	 * Setup the clock control.	 * SDRAM_CLK_CNTL[0] = Source synchronous enable == 1	 * SDRAM_CLK_CNTL[5-7] = Clock Adjust	 *	0110	3/4 cycle late	 *	0111	7/8 cycle late	 */	if (spd.mem_type == SPD_MEMTYPE_DDR)		clk_adjust = 0x6;	else		clk_adjust = 0x7;	ddr->sdram_clk_cntl = (0			       | 0x80000000			       | (clk_adjust << 23)			       );	debug("DDR: sdram_clk_cntl = 0x%08x\n", ddr->sdram_clk_cntl);#endif	/*	 * Figure out memory size in Megabytes.	 */	debug("# ranks = %d, rank_density = 0x%08lx\n", n_ranks, rank_density);	memsize = n_ranks * rank_density / 0x100000;	return memsize;}unsigned int enable_ddr(unsigned int ddr_num){	volatile immap_t *immap = (immap_t *)CFG_IMMR;	spd_eeprom_t spd1,spd2;	volatile ccsr_ddr_t *ddr;	unsigned sdram_cfg_1;	unsigned char sdram_type, mem_type, config, mod_attr;	unsigned char d_init;	unsigned int no_dimm1=0, no_dimm2=0;	/* Set up pointer to enable the current ddr controller */	if (ddr_num == 1)		ddr = &immap->im_ddr1;	else		ddr = &immap->im_ddr2;	/*	 * Read both dimm slots and decide whether	 * or not to enable this controller.	 */	memset((void *)&spd1,0,sizeof(spd1));	memset((void *)&spd2,0,sizeof(spd2));	if (ddr_num == 1) {		CFG_READ_SPD(SPD_EEPROM_ADDRESS1,			     0, 1, (uchar *) &spd1, sizeof(spd1));		CFG_READ_SPD(SPD_EEPROM_ADDRESS2,			     0, 1, (uchar *) &spd2, sizeof(spd2));	} else {		CFG_READ_SPD(SPD_EEPROM_ADDRESS3,			     0, 1, (uchar *) &spd1, sizeof(spd1));		CFG_READ_SPD(SPD_EEPROM_ADDRESS4,			     0, 1, (uchar *) &spd2, sizeof(spd2));	}	/*	 * Check for supported memory module types.	 */	if (spd1.mem_type != SPD_MEMTYPE_DDR	    && spd1.mem_type != SPD_MEMTYPE_DDR2) {		no_dimm1 = 1;	} else {		debug("\nFound memory of type 0x%02lx  ",spd1.mem_type );		if (spd1.mem_type == SPD_MEMTYPE_DDR)			debug("DDR I\n");		else			debug("DDR II\n");	}	if (spd2.mem_type != SPD_MEMTYPE_DDR &&	    spd2.mem_type != SPD_MEMTYPE_DDR2) {		no_dimm2 = 1;	} else {		debug("\nFound memory of type 0x%02lx  ",spd2.mem_type );		if (spd2.mem_type == SPD_MEMTYPE_DDR)			debug("DDR I\n");		else			debug("DDR II\n");	}#ifdef CONFIG_DDR_INTERLEAVE	if (no_dimm1) {		printf("For interleaved operation memory modules need to be present in CS0 DIMM slots of both DDR controllers!\n");		return 0;	}#endif	/*	 * Memory is not present in DIMM1 and DIMM2 - so do not enable DDRn	 */	if (no_dimm1  && no_dimm2) {		printf("No memory modules found for DDR controller %d!!\n", ddr_num);		return 0;	} else {		mem_type = no_dimm2 ? spd1.mem_type : spd2.mem_type;		/*		 * Figure out the settings for the sdram_cfg register.		 * Build up the entire register in 'sdram_cfg' before		 * writing since the write into the register will		 * actually enable the memory controller; all settings		 * must be done before enabling.		 *		 * sdram_cfg[0]   = 1 (ddr sdram logic enable)		 * sdram_cfg[1]   = 1 (self-refresh-enable)		 * sdram_cfg[5:7] = (SDRAM type = DDR SDRAM)		 *			010 DDR 1 SDRAM		 *			011 DDR 2 SDRAM		 */		sdram_type = (mem_type == SPD_MEMTYPE_DDR) ? 2 : 3;		sdram_cfg_1 = (0			       | (1 << 31)		/* Enable */			       | (1 << 30)		/* Self refresh */			       | (sdram_type << 24)	/* SDRAM type */			       );		/*		 * sdram_cfg[3] = RD_EN - registered DIMM enable		 *   A value of 0x26 indicates micron registered		 *   DIMMS (micron.com)		 */		mod_attr = no_dimm2 ? spd1.mod_attr : spd2.mod_attr;		if (mem_type == SPD_MEMTYPE_DDR && mod_attr == 0x26) {			sdram_cfg_1 |= 0x10000000;		/* RD_EN */		}#if defined(CONFIG_DDR_ECC)		config = no_dimm2 ? spd1.config : spd2.config;		/*		 * If the user wanted ECC (enabled via sdram_cfg[2])		 */		if (config == 0x02) {			ddr->err_disable = 0x00000000;			asm volatile("sync;isync;");			ddr->err_sbe = 0x00ff0000;			ddr->err_int_en = 0x0000000d;			sdram_cfg_1 |= 0x20000000;		/* ECC_EN */		}#endif		/*		 * Set 1T or 2T timing based on 1 or 2 modules		 */		{			if (!(no_dimm1 || no_dimm2)) {				/*				 * 2T timing,because both DIMMS are present.				 * Enable 2T timing by setting sdram_cfg[16].				 */				sdram_cfg_1 |= 0x8000;		/* 2T_EN */			}		}		/*		 * 200 painful micro-seconds must elapse between		 * the DDR clock setup and the DDR config enable.		 */		udelay(200);		/*		 * Go!		 */		ddr->sdram_cfg_1 = sdram_cfg_1;		asm volatile("sync;isync");		udelay(500);		debug("DDR: sdram_cfg   = 0x%08x\n", ddr->sdram_cfg_1);#if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)		d_init = 1;		debug("DDR: memory initializing\n");		/*		 * Poll until memory is initialized.		 * 512 Meg at 400 might hit this 200 times or so.		 */		while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0) {			udelay(1000);		}		debug("DDR: memory initialized\n\n");#endif		debug("Enabled DDR Controller %d\n", ddr_num);		return 1;	}}long intspd_sdram(void){	int memsize_ddr1_dimm1 = 0;	int memsize_ddr1_dimm2 = 0;	int memsize_ddr2_dimm1 = 0;	int memsize_ddr2_dimm2 = 0;	int memsize_total = 0;	int memsize_ddr1 = 0;	int memsize_ddr2 = 0;	unsigned int ddr1_enabled = 0;	unsigned int ddr2_enabled = 0;	unsigned int law_size_ddr1;	unsigned int law_size_ddr2;	volatile immap_t *immap = (immap_t *)CFG_IMMR;	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;#ifdef CONFIG_DDR_INTERLEAVE	unsigned int law_size_interleaved;	volatile ccsr_ddr_t *ddr1 = &immap->im_ddr1;	volatile ccsr_ddr_t *ddr2 = &immap->im_ddr2;	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,				      1, 1,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr1_dimm1;	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,				      2, 1,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr2_dimm1;	if (memsize_ddr1_dimm1 != memsize_ddr2_dimm1) {		if (memsize_ddr1_dimm1 <  memsize_ddr2_dimm1)			memsize_total -= memsize_ddr1_dimm1;		else			memsize_total -= memsize_ddr2_dimm1;		debug("Total memory available for interleaving 0x%08lx\n",		      memsize_total * 1024 * 1024);		debug("Adjusting CS0_BNDS to account for unequal DIMM sizes in interleaved memory\n");		ddr1->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;		ddr2->cs0_bnds = ((memsize_total * 1024 * 1024) - 1) >> 24;		debug("DDR1: cs0_bnds   = 0x%08x\n", ddr1->cs0_bnds);		debug("DDR2: cs0_bnds   = 0x%08x\n", ddr2->cs0_bnds);	}	ddr1_enabled = enable_ddr(1);	ddr2_enabled = enable_ddr(2);	/*	 * Both controllers need to be enabled for interleaving.	 */	if (ddr1_enabled && ddr2_enabled) {		law_size_interleaved = 19 + __ilog2(memsize_total);		/*		 * Set up LAWBAR for DDR 1 space.		 */		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);		mcm->lawar1 = (LAWAR_EN			       | LAWAR_TRGT_IF_DDR_INTERLEAVED			       | (LAWAR_SIZE & law_size_interleaved));		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);		debug("Interleaved memory size is 0x%08lx\n", memsize_total);#ifdef	CONFIG_DDR_INTERLEAVE#if (CFG_PAGE_INTERLEAVING == 1)		printf("Page ");#elif (CFG_BANK_INTERLEAVING == 1)		printf("Bank ");#elif (CFG_SUPER_BANK_INTERLEAVING == 1)		printf("Super-bank ");#else		printf("Cache-line ");#endif#endif		printf("Interleaved");		return memsize_total * 1024 * 1024;	}  else {		printf("Interleaved memory not enabled - check CS0 DIMM slots for both controllers.\n");		return 0;	}#else	/*	 * Call spd_sdram() routine to init ddr1 - pass I2c address,	 * controller number, dimm number, and starting address.	 */	memsize_ddr1_dimm1 = spd_init(SPD_EEPROM_ADDRESS1,				      1, 1,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr1_dimm1;	memsize_ddr1_dimm2 = spd_init(SPD_EEPROM_ADDRESS2,				      1, 2,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr1_dimm2;	/*	 * Enable the DDR controller - pass ddr controller number.	 */	ddr1_enabled = enable_ddr(1);	/* Keep track of memory to be addressed by DDR1 */	memsize_ddr1 = memsize_ddr1_dimm1 + memsize_ddr1_dimm2;	/*	 * First supported LAW size is 16M, at LAWAR_SIZE_16M == 23.  Fnord.	 */	if (ddr1_enabled) {		law_size_ddr1 = 19 + __ilog2(memsize_ddr1);		/*		 * Set up LAWBAR for DDR 1 space.		 */		mcm->lawbar1 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);		mcm->lawar1 = (LAWAR_EN			       | LAWAR_TRGT_IF_DDR1			       | (LAWAR_SIZE & law_size_ddr1));		debug("DDR: LAWBAR1=0x%08x\n", mcm->lawbar1);		debug("DDR: LAWAR1=0x%08x\n", mcm->lawar1);	}#if  (CONFIG_NUM_DDR_CONTROLLERS > 1)	memsize_ddr2_dimm1 = spd_init(SPD_EEPROM_ADDRESS3,				      2, 1,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr2_dimm1;	memsize_ddr2_dimm2 = spd_init(SPD_EEPROM_ADDRESS4,				      2, 2,				      (unsigned int)memsize_total * 1024*1024);	memsize_total += memsize_ddr2_dimm2;	ddr2_enabled = enable_ddr(2);	/* Keep track of memory to be addressed by DDR2 */	memsize_ddr2 = memsize_ddr2_dimm1 + memsize_ddr2_dimm2;	if (ddr2_enabled) {		law_size_ddr2 = 19 + __ilog2(memsize_ddr2);		/*		 * Set up LAWBAR for DDR 2 space.		 */		if (ddr1_enabled)			mcm->lawbar8 = (((memsize_ddr1 * 1024 * 1024) >> 12)					& 0xfffff);		else			mcm->lawbar8 = ((CFG_DDR_SDRAM_BASE >> 12) & 0xfffff);		mcm->lawar8 = (LAWAR_EN			       | LAWAR_TRGT_IF_DDR2			       | (LAWAR_SIZE & law_size_ddr2));		debug("\nDDR: LAWBAR8=0x%08x\n", mcm->lawbar8);		debug("DDR: LAWAR8=0x%08x\n", mcm->lawar8);	}#endif /* CONFIG_NUM_DDR_CONTROLLERS > 1 */	debug("\nMemory sizes are DDR1 = 0x%08lx, DDR2 = 0x%08lx\n",	      memsize_ddr1, memsize_ddr2);	/*	 * If neither DDR controller is enabled return 0.	 */	if (!ddr1_enabled && !ddr2_enabled)		return 0;	printf("Non-interleaved");	return memsize_total * 1024 * 1024;#endif /* CONFIG_DDR_INTERLEAVE */}#endif /* CONFIG_SPD_EEPROM */#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)/* * Initialize all of memory for ECC, then enable errors. */voidddr_enable_ecc(unsigned int dram_size){	uint *p = 0;	uint i = 0;	volatile immap_t *immap = (immap_t *)CFG_IMMR;	volatile ccsr_ddr_t *ddr1= &immap->im_ddr1;	dma_init();	for (*p = 0; p < (uint *)(8 * 1024); p++) {		if (((unsigned int)p & 0x1f) == 0) {			ppcDcbz((unsigned long) p);		}		*p = (unsigned int)CONFIG_MEM_INIT_VALUE;		if (((unsigned int)p & 0x1c) == 0x1c) {			ppcDcbf((unsigned long) p);		}	}	dma_xfer((uint *)0x002000, 0x002000, (uint *)0); /* 8K */	dma_xfer((uint *)0x004000, 0x004000, (uint *)0); /* 16K */	dma_xfer((uint *)0x008000, 0x008000, (uint *)0); /* 32K */	dma_xfer((uint *)0x010000, 0x010000, (uint *)0); /* 64K */	dma_xfer((uint *)0x020000, 0x020000, (uint *)0); /* 128k */	dma_xfer((uint *)0x040000, 0x040000, (uint *)0); /* 256k */	dma_xfer((uint *)0x080000, 0x080000, (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);	}	/*	 * Enable errors for ECC.	 */	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);	ddr1->err_disable = 0x00000000;	asm volatile("sync;isync");	debug("DMA DDR: err_disable = 0x%08x\n", ddr1->err_disable);}#endif	/* CONFIG_DDR_ECC  && ! CONFIG_ECC_INIT_VIA_DDRCONTROLLER */

⌨️ 快捷键说明

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