示例#1
0
/* Set DRAM	Timing*/
void DRAMTimingSetting(DRAM_SYS_ATTR * DramAttr)
{
	PRINT_DEBUG_MEM("Set CAS latency value!");
	SetCL(DramAttr);

	PRINT_DEBUG_MEM("Set tRP value!");
	SetTrp(DramAttr);

	PRINT_DEBUG_MEM("Set tRCD value!");
	SetTrcd(DramAttr);

	PRINT_DEBUG_MEM("Set tRAS value!");
	SetTras(DramAttr);

	PRINT_DEBUG_MEM("Set tRFC value!");
	SetTrfc(DramAttr);

	PRINT_DEBUG_MEM("Set tRRD value!");
	SetTrrd(DramAttr);

	PRINT_DEBUG_MEM("Set tWR value!");
	SetTwr(DramAttr);

	PRINT_DEBUG_MEM("Set tWTR value!");
	SetTwtr(DramAttr);

	PRINT_DEBUG_MEM("Set tRTP value!");
	SetTrtp(DramAttr);
}
示例#2
0
static void ddr2_ram_setup(void)
{
	CB_STATUS Status;
	PRINT_DEBUG_MEM("In ddr2_ram_setup\r");

	Status = DDR2_DRAM_INIT();
	if (CB_SUCCESS != Status) {
		PRINT_DEBUG_MEM("Dram init error. Status = %x\r");
	}

}
示例#3
0
/*
Set DRAM Timing: CAS Latency for DDR1
D0F3RX62 bit[0:2] for CAS Latency;
*/
void SetCL(DRAM_SYS_ATTR * DramAttr)
{
	u8 Data;
	u8 CL;

	/*DDR2 CL Value: 20, 30, 40, 50 -> 2, 3, 4, 5 */
	CL = (u8) ((DramAttr->CL - 20) / 10);	//000,001,010,011

	PRINT_DEBUG_MEM("CAS = ");
	PRINT_DEBUG_MEM_HEX8(CL);
	PRINT_DEBUG_MEM("\n");
	Data = pci_read_config8(MEMCTRL, 0x62);
	Data = (u8) ((Data & 0xf8) | CL);
	pci_write_config8(MEMCTRL, 0x62, Data);
}
示例#4
0
void SetTrp(DRAM_SYS_ATTR * DramAttr)
{
	u8 Data;
	u16 Max, Tmp;
	u8 Socket;

	/*get the max Trp value from SPD data
	   SPD Byte27, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
	Max = 0;
	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
		if (DramAttr->DimmInfo[Socket].bPresence) {
			Tmp =
			    (u16) (DramAttr->
				   DimmInfo[Socket].SPDDataBuf[SPD_SDRAM_TRP]);
			if (Tmp > Max)
				Max = Tmp;
		}
		/*Calculate clock,this value should be 2T,3T,4T,5T */
	}
	Tmp =
	    (u16) CEIL_DIV(Max * 100, (DramAttr->DramCyc) << 2);
	PRINT_DEBUG_MEM("Trp = ");
	PRINT_DEBUG_MEM_HEX16(Tmp);
	PRINT_DEBUG_MEM("\r");

	if (Tmp > MAX_TRP)
		Tmp = MAX_TRP;
	else if (Tmp < MIN_TRP)
		Tmp = MIN_TRP;

	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
	Tmp <<= 1;		//bit1,2,3

	Data = pci_read_config8(MEMCTRL, 0x64);
	Data = (u8) ((Data & 0xf1) | (u8) Tmp);
	pci_write_config8(MEMCTRL, 0x64, Data);

	//enable DDR2 8-Bank Device Timing Constraint
	Data = pci_read_config8(MEMCTRL, 0x62);
	Data = (u8) ((Data & 0xf7) | 0x08);
	pci_write_config8(MEMCTRL, 0x62, Data);
}
示例#5
0
static void sdram_enable(device_t dev, u8 *rank_address)
{
	u8 i;

	/* 1. Apply NOP. */
	PRINT_DEBUG_MEM("RAM Enable 1: Apply NOP\n");
	do_ram_command(dev, RAM_COMMAND_NOP);
	udelay(100);
	read32(rank_address + 0x10);

	/* 2. Precharge all. */
	udelay(400);
	PRINT_DEBUG_MEM("RAM Enable 2: Precharge all\n");
	do_ram_command(dev, RAM_COMMAND_PRECHARGE);
	read32(rank_address + 0x10);

	/* 3. Mode register set. */
	PRINT_DEBUG_MEM("RAM Enable 3: Mode register set\n");
	do_ram_command(dev, RAM_COMMAND_MRS);
	read32(rank_address + 0x120000);	/* EMRS DLL Enable */
	read32(rank_address + 0x800);	/* MRS DLL Reset */

	/* 4. Precharge all again. */
	PRINT_DEBUG_MEM("RAM Enable 4: Precharge all\n");
	do_ram_command(dev, RAM_COMMAND_PRECHARGE);
	read32(rank_address + 0x0);

	/* 5. Perform 8 refresh cycles. Wait tRC each time. */
	PRINT_DEBUG_MEM("RAM Enable 5: CBR\n");
	do_ram_command(dev, RAM_COMMAND_CBR);
	for (i = 0; i < 8; i++) {
		read32(rank_address + 0x20);
		udelay(100);
	}

	/* 6. Mode register set. */
	PRINT_DEBUG_MEM("RAM Enable 6: Mode register set\n");
	/* Safe value for now, BL=8, WR=5, CAS=4 */
	/*
	 * (E)MRS values are from the BPG. No direct explanation is given, but
	 * they should somehow conform to the JEDEC DDR2 SDRAM Specification
	 * (JESD79-2C).
	 */
	do_ram_command(dev, RAM_COMMAND_MRS);
	read32(rank_address + 0x002258); /* MRS command */
	read32(rank_address + 0x121c20); /* EMRS OCD Default */
	read32(rank_address + 0x120020); /* EMRS OCD Calibration Mode Exit */

	/* 8. Normal operation */
	PRINT_DEBUG_MEM("RAM Enable 7: Normal operation\n");
	do_ram_command(dev, RAM_COMMAND_NORMAL);
	read32(rank_address + 0x30);
}
示例#6
0
void SetTrcd(DRAM_SYS_ATTR * DramAttr)
{
	u8 Data;
	u16 Max, Tmp;
	u8 Socket;

	/*get the max Trcd value from SPD data
	   SPD Byte29, Bit7:2->1ns~63ns, Bit1:0->0ns, 0.25ns, 0.50ns, 0.75ns */
	Max = 0;
	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
		if (DramAttr->DimmInfo[Socket].bPresence) {
			Tmp =
			    (u16) (DramAttr->
				   DimmInfo[Socket].SPDDataBuf[SPD_SDRAM_TRCD]);
			if (Tmp > Max)
				Max = Tmp;
		}
	}
	/*Calculate clock,this value should be 2T,3T,4T,5T */
	Tmp =
	    (u16) CEIL_DIV(Max * 100, (DramAttr->DramCyc) << 2);
	PRINT_DEBUG_MEM("Trcd =");
	PRINT_DEBUG_MEM_HEX16(Tmp);
	PRINT_DEBUG_MEM("\r");

	if (Tmp > MAX_TRCD)
		Tmp = MAX_TRCD;
	else if (Tmp < MIN_TRCD)
		Tmp = MIN_TRCD;
	Tmp -= 2;		//00->2T, 01->3T, 10->4T, 11->5T
	Tmp <<= 5;		//bit5,6,7

	Data = pci_read_config8(MEMCTRL, 0x64);
	Data = (u8) ((Data & 0x1f) | (u8) Tmp);
	pci_write_config8(MEMCTRL, 0x64, Data);

}
示例#7
0
void SetTras(DRAM_SYS_ATTR * DramAttr)
{
	u8 Data;
	u16 Max, Tmp;
	u8 Socket;

	/*get the max Tras value from SPD data
	   SPD byte30: bit0:7 1ns~255ns */
	Max = 0;
	for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
		if (DramAttr->DimmInfo[Socket].bPresence) {
			Tmp =
			    (u16) (DramAttr->
				   DimmInfo[Socket].SPDDataBuf[SPD_SDRAM_TRAS]);
			if (Tmp > Max)
				Max = Tmp;
		}
	}

	/*Calculate clock,value range 5T-20T */
	Tmp = (u16) CEIL_DIV((Max * 100), DramAttr->DramCyc);
	PRINT_DEBUG_MEM("Tras =");
	PRINT_DEBUG_MEM_HEX16(Tmp);
	PRINT_DEBUG_MEM("\r");

	if (Tmp > MAX_TRAS)
		Tmp = MAX_TRAS;
	else if (Tmp < MIN_TRAS)
		Tmp = MIN_TRAS;
	Tmp -= 5;		//0->5T  ... 1111->20T
	Tmp <<= 4;		//bit4:7

	Data = pci_read_config8(MEMCTRL, 0x62);
	Data = (u8) ((Data & 0x0f) | (u8) Tmp);
	pci_write_config8(MEMCTRL, 0x62, Data);
}
示例#8
0
CB_STATUS DRAMDetect(DRAM_SYS_ATTR *DramAttr)
{
	CB_STATUS Status = CB_SUCCESS;

	PRINT_DEBUG_MEM("DRAM detection \r");

	/* Read D0F3Rx6C, detect memory type DDR1 or DDR2. */
	/* 353 supports DDR2 only */
	DramAttr->DramType = RAMTYPE_SDRAMDDR2;
	/* Get information for SPD. */
	Status = GetInfoFromSPD(DramAttr);
	if (CB_SUCCESS == Status) {
		/* 64bit or 128Bit */

		/* Select command rate. */
		DRAMCmdRate(DramAttr);
	}
	return Status;
}
示例#9
0
CB_STATUS DDR2_DRAM_INIT(void)
{
    u8 i;
    u32 RamSize;
    DRAM_SYS_ATTR DramAttr;

    PRINT_DEBUG_MEM("DRAM_INIT \r");

    memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
    /*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T */
    DRAMDetect(&DramAttr);

    //Step2 set Frequency; calculate CL and Frequncy from SPD data; set the Frequency
    DRAMFreqSetting(&DramAttr);
    //Step3 Set DRAM Timing; CL, tRP, tRCD, tRAS, tRFC, tRRD, tWR, tWTR, tRTP
    DRAMTimingSetting(&DramAttr);
    //Step4 DRDY
    DRAMDRDYSetting(&DramAttr);
    //Step5 Burst length
    DRAMBurstLength(&DramAttr);
    //Step6 DRAM Driving Adjustment
    DRAMDriving(&DramAttr);
    //Step7 duty cycle control
    DutyCycleCtrl(&DramAttr);
    //Step8 DRAM clock phase and delay control
    DRAMClkCtrl(&DramAttr);
    //Step9 set register before init DRAM device
    DRAMRegInitValue(&DramAttr);
    //Step10 DDR and DDR2 initialize process
    DRAMInitializeProc(&DramAttr);

    //Step13 Interleave function in rankmap.c
    DRAMBankInterleave(&DramAttr);
    //Step14 Sizing
    DRAMSizingMATypeM(&DramAttr);

    //Step11 Search DQS and DQ output delay
    DRAMDQSOutputSearch(&DramAttr);
    //Step12 Search DQS  input delay
    DRAMDQSInputSearch(&DramAttr);

    //Step15 DDR fresh counter setting
    DRAMRefreshCounter(&DramAttr);
    //Step16 Final register setting for improve performance
    DRAMRegFinalValue(&DramAttr);

    RamSize = 0;
    for (i = 0; i < MAX_RANKS; i++) {
        if (DramAttr.RankSize[i] == 0) {
            continue;
        }
        RamSize += DramAttr.RankSize[i];
    }
    PRINT_DEBUG_MEM("RamSize=");
    PRINT_DEBUG_MEM_HEX32(RamSize);
    PRINT_DEBUG_MEM("\r");
    DumpRegisters(0, 3);
    //BOOLEAN bTest = DramBaseTest( M1, RamSize - M1 * 2,SPARE, FALSE);
    /* the memory can not correct work, this is because the user set the incorrect memory
       parameter from setup interface.so we must set the boot mode to recovery mode, let
       the system to reset and use the spd value to initialize the memory */
    SetUMARam();
    return CB_SUCCESS;
}
示例#10
0
/*
 Set DRAM Frequency
*/
void DRAMFreqSetting(DRAM_SYS_ATTR * DramAttr)
{

	u8 Data = 0;

	PRINT_DEBUG_MEM("Dram Frequency setting \r");

	//calculate dram frequency using SPD data
	CalcCLAndFreq(DramAttr);

	//init some Dramc control by Simon Chu slide
	//Must use "CPU delay" to make sure VLINK is dis-connect
	Data = pci_read_config8(PCI_DEV(0, 0, 7), 0x47);
	Data = (u8) (Data | 0x04);
	pci_write_config8(PCI_DEV(0, 0, 7), 0x47, Data);

	//in order to make sure NB command buffer don`t have pending request(C2P cycle)
	//CPU DELAY
	WaitMicroSec(20);

	//Before Set Dram Frequency, we must set 111 by Simon Chu slide.
	Data = pci_read_config8(MEMCTRL, 0x90);
	Data = (u8) ((Data & 0xf8) | 7);
	pci_write_config8(MEMCTRL, 0x90, Data);

	WaitMicroSec(20);

	//Set Dram Frequency.
	Data = pci_read_config8(MEMCTRL, 0x90);
	switch (DramAttr->DramFreq) {
	case DIMMFREQ_400:
		Data = (u8) ((Data & 0xf8) | 3);
		break;
	case DIMMFREQ_533:
		Data = (u8) ((Data & 0xf8) | 4);
		break;
	case DIMMFREQ_667:
		Data = (u8) ((Data & 0xf8) | 5);
		break;
	case DIMMFREQ_800:
		Data = (u8) ((Data & 0xf8) | 6);
		break;
	default:
		Data = (u8) ((Data & 0xf8) | 1);
	}
	pci_write_config8(MEMCTRL, 0x90, Data);

	//CPU Delay
	WaitMicroSec(20);

	// Manual       reset and adjust DLL when DRAM change frequency
	Data = pci_read_config8(MEMCTRL, 0x6B);
	Data = (u8) ((Data & 0x2f) | 0xC0);
	pci_write_config8(MEMCTRL, 0x6B, Data);

	//CPU Delay
	WaitMicroSec(20);

	Data = pci_read_config8(MEMCTRL, 0x6B);
	Data = (u8) (Data | 0x10);
	pci_write_config8(MEMCTRL, 0x6B, Data);

	//CPU Delay
	WaitMicroSec(20);

	Data = pci_read_config8(MEMCTRL, 0x6B);
	Data = (u8) (Data & 0x3f);
	pci_write_config8(MEMCTRL, 0x6B, Data);

	//disable V_LINK Auto-Disconnect, or else program may stopped at some place and
	//we cannot find the reason
	Data = pci_read_config8(PCI_DEV(0, 0, 7), 0x47);
	Data = (u8) (Data & 0xFB);
	pci_write_config8(PCI_DEV(0, 0, 7), 0x47, Data);

}
示例#11
0
/*
 * Get SPD data and set RANK presence map.
 *
 * Sockets0,1 is Channel A / Sockets2,3 is Channel B.
 *
 * Socket0 SPD device address 0x50 / socket1 SPD device address 0x51
 * Socket2 SPD device address 0x52 / socket3 SPD device address 0x53
 */
CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR *DramAttr)
{
	CB_STATUS Status;
	u8 *pSPDDataBuf;
	u8 ModuleDataWidth, ChipWidth, RankNum, LoadNum, Sockets, i;
	BOOLEAN bFind;  /* FIXME: We don't have/want BOOLEAN. */

	bFind = FALSE;  /* FIXME: We don't have/want FALSE. */
	Status = CB_DEVICE_ERROR;

	for (Sockets = 0; Sockets < MAX_SOCKETS; Sockets++) {
		pSPDDataBuf = DramAttr->DimmInfo[Sockets].SPDDataBuf;
		pSPDDataBuf[SPD_MEMORY_TYPE] =
		    get_spd_data(ctrl.channel0[Sockets], SPD_MEMORY_TYPE);
		if (pSPDDataBuf[SPD_MEMORY_TYPE] == 0) {
			Status = CB_NOT_READY;
		} else {
			Status =
			    GetSPDData(Sockets, SPD_DATA_SIZE, pSPDDataBuf);
			PRINT_DEBUG_MEM("SPD : \r");
			for (i = 0; i < SPD_DATA_SIZE; i++) {
				PRINT_DEBUG_MEM(" ");
				PRINT_DEBUG_MEM_HEX8(pSPDDataBuf[i]);
			}
		}
		if (CB_SUCCESS == Status) {
			/*
			 * If DRAM controller detected type not same as the
			 * type got from SPD, there are ERROR.
			 */
			if (pSPDDataBuf[SPD_MEMORY_TYPE] != DramAttr->DramType) {
				Status = CB_DEVICE_ERROR; /* memory int error */
				PRINT_DEBUG_MEM("Memory Device ERROR: DRAM "
                                                "controller detected type != "
                                                "type got from SPD\r");
				break;
			}
			DramAttr->DimmInfo[Sockets].bPresence = TRUE;

			/* Calculate load number (chips number). */
			ModuleDataWidth = (u8) (DramAttr->
				  DimmInfo[Sockets].SPDDataBuf
				  [SPD_SDRAM_MOD_DATA_WIDTH + 1]);
			ModuleDataWidth = (u8) (ModuleDataWidth << 8);
			ModuleDataWidth |= (u8) (DramAttr->
				  DimmInfo[Sockets].SPDDataBuf
				  [SPD_SDRAM_MOD_DATA_WIDTH]);
			ChipWidth = (u8) ((DramAttr->
				   DimmInfo[Sockets].SPDDataBuf
				   [SPD_SDRAM_WIDTH]) & 0x7F);
			LoadNum = (u8) (ModuleDataWidth / ChipWidth);

			/* Set the RANK map. */
                        /* Get bit0,1, the most number of supported RANK is 2. */
			RankNum = (u8) (pSPDDataBuf[SPD_SDRAM_DIMM_RANKS] & 0x3);
			if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
                                /*
                                 * For DDR bit[0,1]: 01->1 RANK, 10->2 RANK
                                 * For DDR2 bit[0,1]: 00->1 RANK, 01->2 RANK
                                 */
				RankNum++;

                        /* Every DIMM have 1 or 2 ranks. */
			if (RankNum != 2 && RankNum != 1) {
				Status = CB_DEVICE_ERROR;
				PRINT_DEBUG_MEM("Memory Device ERROR: Number "
                                                "of RANK not supported!\r");
				break;
			}

			if (Sockets < 2) { /* Sockets0,1 is channel A */
				DramAttr->RankNumChA =
				    (u8) (DramAttr->RankNumChA + RankNum);
				DramAttr->DimmNumChA++;
				DramAttr->LoadNumChA =
				    (u8) (DramAttr->LoadNumChA * LoadNum *
					  RankNum);
			} else { /* Sockets2,3 is channel B */
				DramAttr->RankNumChB =
				    (u8) (DramAttr->RankNumChB + RankNum);
				DramAttr->DimmNumChB++;
				DramAttr->LoadNumChB =
				    (u8) (DramAttr->LoadNumChB * LoadNum *
					  RankNum);;
			}
			RankNum |= 1; /* Set rank map. */
			DramAttr->RankPresentMap |= (RankNum << (Sockets * 2));
			bFind = TRUE;
		}
	}

	PRINT_DEBUG_MEM("Rank Present Map:");
	PRINT_DEBUG_MEM_HEX8(DramAttr->RankPresentMap);
	PRINT_DEBUG_MEM("\r");

	if (bFind)
		Status = CB_SUCCESS;

	return Status;
}
示例#12
0
void CalcCLAndFreq(DRAM_SYS_ATTR * DramAttr)
{
	u8 AllDimmSupportedCL, Tmp;
	u8 CLMask, tmpMask;
	u8 SckId, BitId, TmpId;
	u16 CycTime, TmpCycTime;

	/*1.list the CL value that all DIMM supported */
	AllDimmSupportedCL = 0xFF;
	if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
		AllDimmSupportedCL &= 0x7C;	/*bit2,3,4,5,6 */
	else			/*DDR1 */
		AllDimmSupportedCL &= 0x7F;	/*bit0,1,2,3,4,5,6 */
	for (SckId = 0; SckId < MAX_SOCKETS; SckId++) {
		if (DramAttr->DimmInfo[SckId].bPresence) {	/*all DIMM supported CL */
			AllDimmSupportedCL &=
			    (DramAttr->
			     DimmInfo[SckId].SPDDataBuf[SPD_SDRAM_CAS_LATENCY]);
		}
	}
	if (!AllDimmSupportedCL) {	/*if equal 0, no supported CL */
		PRINT_DEBUG_MEM("SPD Data Error, Can not get CL !!!! \r");
		for (;;) ;
	}

	/*Get CL Value */
	CLMask = 0x40;		/*from Bit6 */

	for (BitId = 7; BitId > 0; BitId--) {
		if ((AllDimmSupportedCL & CLMask) == CLMask) {	/*find the first bit */
			if (RAMTYPE_SDRAMDDR2 == DramAttr->DramType)
				DramAttr->CL = CL_DDR2[BitId - 1];
			else	/*DDR1 */
				DramAttr->CL = CL_DDR1[BitId - 1];
			break;
		}
		CLMask >>= 1;
	}

	/*according the CL value calculate the cycle time, for X or X-1 or X-2 */
	CycTime = 0;
	TmpCycTime = 0;

	for (SckId = 0; SckId < MAX_SOCKETS; SckId++) {
		if (DramAttr->DimmInfo[SckId].bPresence) {
			Tmp =
			    (DramAttr->
			     DimmInfo[SckId].SPDDataBuf[SPD_SDRAM_CAS_LATENCY]);
			tmpMask = 0x40;
			for (TmpId = 7; TmpId > 0; TmpId--) {
				if ((Tmp & tmpMask) == tmpMask)
					break;
				tmpMask >>= 1;
			}
			if (TmpId - BitId == 0) {	/*get Cycle time for X, SPD BYTE9 */
				TmpCycTime =
				    DramAttr->
				    DimmInfo[SckId].SPDDataBuf
				    [SPD_SDRAM_TCLK_X];
			} else if (TmpId - BitId == 1) {	/*get Cycle time for X-1, SPD BYTE23 */
				TmpCycTime =
				    DramAttr->
				    DimmInfo[SckId].SPDDataBuf
				    [SPD_SDRAM_TCLK_X_1];
			} else if (TmpId - BitId == 2) {	/*get cycle time for X-2, SPD BYTE25 */
				TmpCycTime =
				    DramAttr->
				    DimmInfo[SckId].SPDDataBuf
				    [SPD_SDRAM_TCLK_X_2];
			} else {
				//error!!!
			}
			if (TmpCycTime > CycTime)	/*get the most cycle time,there is some problem! */
				CycTime = TmpCycTime;
		}
	}