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

📄 dramsetup.c

📁 linux下的BOOT程序原码,有需要的可以来下,保证好用
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2004, Freescale, Inc * TsiChung Liew, Tsi-Chung.Liew@freescale.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 *//*DESCRIPTIONRead Dram spd and base on its information to calculate the memory size,characteristics to initialize the dram on MPC8220*/#include <common.h>#include <mpc8220.h>#include "i2cCore.h"#include "dramSetup.h"#define SPD_SIZE	CFG_SDRAM_SPD_SIZE#define DRAM_SPD	(CFG_SDRAM_SPD_I2C_ADDR)<<1	/* on Board SPD eeprom */#define TOTAL_BANK	CFG_SDRAM_TOTAL_BANKSint spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse){	int i;	for (i = 0; i < I2C_POLL_COUNT; i++) {		if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))			return (OK);	}	return (ERROR);}int spd_clear (volatile i2c8220_t * pi2c){	pi2c->adr = 0;	pi2c->fdr = 0;	pi2c->cr = 0;	pi2c->sr = 0;	return (OK);}int spd_stop (volatile i2c8220_t * pi2c){	pi2c->cr &= ~I2C_CTL_STA;	/* Generate stop signal         */	if (spd_status (pi2c, I2C_STA_BB, 0) != OK)		return ERROR;	return (OK);}int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index){	pi2c->sr &= ~I2C_STA_IF;	/* Clear Interrupt Bit          */	*readb = pi2c->dr;	/* Read a byte                  */	/*	   Set I2C_CTRL_TXAK will cause Transfer pending and	   set I2C_CTRL_STA will cause Interrupt pending	 */	if (*index != 2) {		if (spd_status (pi2c, I2C_STA_CF, 1) != OK)	/* Transfer not complete?       */			return ERROR;	}	if (*index != 1) {		if (spd_status (pi2c, I2C_STA_IF, 1) != OK)			return ERROR;	}	return (OK);}int readSpdData (u8 * spdData){	DECLARE_GLOBAL_DATA_PTR;	volatile i2c8220_t *pi2cReg;	volatile pcfg8220_t *pcfg;	u8 slvAdr = DRAM_SPD;	u8 Tmp;	int Length = SPD_SIZE;	int i = 0;	/* Enable Port Configuration for SDA and SDL signals */	pcfg = (volatile pcfg8220_t *) (MMAP_PCFG);	__asm__ ("sync");	pcfg->pcfg3 &= ~CFG_I2C_PORT3_CONFIG;	__asm__ ("sync");	/* Points the structure to I2c mbar memory offset */	pi2cReg = (volatile i2c8220_t *) (MMAP_I2C);	/* Clear FDR, ADR, SR and CR reg */	pi2cReg->adr = 0;	pi2cReg->fdr = 0;	pi2cReg->cr = 0;	pi2cReg->sr = 0;	/* Set for fix XLB Bus Frequency */	switch (gd->bus_clk) {	case 60000000:		pi2cReg->fdr = 0x15;		break;	case 70000000:		pi2cReg->fdr = 0x16;		break;	case 80000000:		pi2cReg->fdr = 0x3a;		break;	case 90000000:		pi2cReg->fdr = 0x17;		break;	case 100000000:		pi2cReg->fdr = 0x3b;		break;	case 110000000:		pi2cReg->fdr = 0x18;		break;	case 120000000:		pi2cReg->fdr = 0x19;		break;	case 130000000:		pi2cReg->fdr = 0x1a;		break;	}	pi2cReg->adr = CFG_I2C_SLAVE<<1;	pi2cReg->cr = I2C_CTL_EN;	/* Set Enable         */	/*	   The I2C bus should be in Idle state. If the bus is busy,	   clear the STA bit in control register	 */	if (spd_status (pi2cReg, I2C_STA_BB, 0) != OK) {		if ((pi2cReg->cr & I2C_CTL_STA) == I2C_CTL_STA)			pi2cReg->cr &= ~I2C_CTL_STA;		/* Check again if it is still busy, return error if found */		if (spd_status (pi2cReg, I2C_STA_BB, 1) == OK)			return ERROR;	}	pi2cReg->cr |= I2C_CTL_TX;	/* Enable the I2c for TX, Ack   */	pi2cReg->cr |= I2C_CTL_STA;	/* Generate start signal        */	if (spd_status (pi2cReg, I2C_STA_BB, 1) != OK)		return ERROR;	/* Write slave address */	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */	pi2cReg->dr = slvAdr;	/* Write a byte                 */	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */		spd_stop (pi2cReg);		return ERROR;	}	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {		spd_stop (pi2cReg);		return ERROR;	}	/* Issue the offset to start */	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */	pi2cReg->dr = 0;	/* Write a byte                 */	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */		spd_stop (pi2cReg);		return ERROR;	}	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {		spd_stop (pi2cReg);		return ERROR;	}	/* Set repeat start */	pi2cReg->cr |= I2C_CTL_RSTA;	/* Repeat Start                 */	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */	pi2cReg->dr = slvAdr | 1;	/* Write a byte                 */	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */		spd_stop (pi2cReg);		return ERROR;	}	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {		spd_stop (pi2cReg);		return ERROR;	}	if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))		return ERROR;	pi2cReg->cr &= ~I2C_CTL_TX;	/* Set receive mode             */	if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))		return ERROR;	/* Dummy Read */	if (spd_readbyte (pi2cReg, &Tmp, &i) != OK) {		spd_stop (pi2cReg);		return ERROR;	}	i = 0;	while (Length) {		if (Length == 2)			pi2cReg->cr |= I2C_CTL_TXAK;		if (Length == 1)			pi2cReg->cr &= ~I2C_CTL_STA;		if (spd_readbyte (pi2cReg, spdData, &Length) != OK) {			return spd_stop (pi2cReg);		}		i++;		Length--;		spdData++;	}	/* Stop the service */	spd_stop (pi2cReg);	return OK;}int getBankInfo (int bank, draminfo_t * pBank){	int status;	int checksum;	int count;	u8 spdData[SPD_SIZE];	if (bank > 2 || pBank == 0) {		/* illegal values */		return (-42);	}	status = readSpdData (&spdData[0]);	if (status < 0)		return (-1);	/* check the checksum */	for (count = 0, checksum = 0; count < LOC_CHECKSUM; count++)		checksum += spdData[count];	checksum = checksum - ((checksum / 256) * 256);	if (checksum != spdData[LOC_CHECKSUM])		return (-2);	/* Get the memory type */	if (!	    ((spdData[LOC_TYPE] == TYPE_DDR)	     || (spdData[LOC_TYPE] == TYPE_SDR)))		/* not one of the types we support */		return (-3);	pBank->type = spdData[LOC_TYPE];	/* Set logical banks */	pBank->banks = spdData[LOC_LOGICAL_BANKS];	/* Check that we have enough physical banks to cover the bank we are	 * figuring out.  Odd-numbered banks correspond to the second bank	 * on the device.	 */	if (bank & 1) {		/* Second bank of a "device" */		if (spdData[LOC_PHYS_BANKS] < 2)			/* this bank doesn't exist on the "device" */			return (-4);		if (spdData[LOC_ROWS] & 0xf0)			/* Two asymmetric banks */			pBank->rows = spdData[LOC_ROWS] >> 4;		else			pBank->rows = spdData[LOC_ROWS];		if (spdData[LOC_COLS] & 0xf0)			/* Two asymmetric banks */			pBank->cols = spdData[LOC_COLS] >> 4;		else			pBank->cols = spdData[LOC_COLS];	} else {		/* First bank of a "device" */		pBank->rows = spdData[LOC_ROWS];		pBank->cols = spdData[LOC_COLS];	}	pBank->width = spdData[LOC_WIDTH_HIGH] << 8 | spdData[LOC_WIDTH_LOW];	pBank->bursts = spdData[LOC_BURSTS];	pBank->CAS = spdData[LOC_CAS];	pBank->CS = spdData[LOC_CS];	pBank->WE = spdData[LOC_WE];	pBank->Trp = spdData[LOC_Trp];	pBank->Trcd = spdData[LOC_Trcd];	pBank->buffered = spdData[LOC_Buffered] & 1;	pBank->refresh = spdData[LOC_REFRESH];	return (0);}/* checkMuxSetting -- given a row/column device geometry, return a mask *                    of the valid DRAM controller addr_mux settings for *                    that geometry. * *  Arguments:        u8 rows:     number of row addresses in this device *                    u8 columns:  number of column addresses in this device * *  Returns:          a mask of the allowed addr_mux settings for this *                    geometry.  Each bit in the mask represents a *                    possible addr_mux settings (for example, the *                    (1<<2) bit in the mask represents the 0b10 setting)/ * */u8 checkMuxSetting (u8 rows, u8 columns){	muxdesc_t *pIdx, *pMux;	u8 mask;	int lrows, lcolumns;	u32 mux[4] = { 0x00080c04, 0x01080d03, 0x02080e02, 0xffffffff };	/* Setup MuxDescriptor in SRAM space */	/* MUXDESC AddressRuns [] = {	   { 0, 8, 12, 4 },         / setting, columns, rows, extra columns /	   { 1, 8, 13, 3 },         / setting, columns, rows, extra columns /	   { 2, 8, 14, 2 },         / setting, columns, rows, extra columns /	   { 0xff }                 / list terminator /	   }; */	pIdx = (muxdesc_t *) & mux[0];	/* Check rows x columns against each possible address mux setting */	for (pMux = pIdx, mask = 0;; pMux++) {		lrows = rows;		lcolumns = columns;		if (pMux->MuxValue == 0xff)			break;	/* end of list */		/* For a given mux setting, since we want all the memory in a		 * device to be contiguous, we want the device "use up" the		 * address lines such that there are no extra column or row		 * address lines on the device.		 */		lcolumns -= pMux->Columns;		if (lcolumns < 0)			/* Not enough columns to get to the rows */

⌨️ 快捷键说明

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