aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/via/vx800/dev_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge/via/vx800/dev_init.c')
-rw-r--r--src/northbridge/via/vx800/dev_init.c1318
1 files changed, 1318 insertions, 0 deletions
diff --git a/src/northbridge/via/vx800/dev_init.c b/src/northbridge/via/vx800/dev_init.c
new file mode 100644
index 0000000000..bb0232589d
--- /dev/null
+++ b/src/northbridge/via/vx800/dev_init.c
@@ -0,0 +1,1318 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 One Laptop per Child, Association, Inc.
+ *
+ * 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; version 2 of the License.
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+void DRAMSetVRNum(DRAM_SYS_ATTR * DramAttr, u8 PhyRank, // Physical Rank
+ u8 VirRank, // Virtual Rank
+ BOOLEAN Enable);
+
+void SetEndingAddr(DRAM_SYS_ATTR * DramAttr, u8 VirRank, // Ending address register number indicator (INDEX
+ INT8 Value // (value) add or subtract value to this and after banks
+ );
+
+void InitDDR2CHA(DRAM_SYS_ATTR * DramAttr);
+
+void InitDDR2CHB(DRAM_SYS_ATTR * DramAttr);
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr);
+
+CB_STATUS VerifyChc();
+/*===================================================================
+Function : DRAMRegInitValue()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+Output : Void
+Purpose : Set necessary register before DRAM initialize
+===================================================================*/
+
+static const u8 DramRegTbl[][3] = {
+ //Register AND OR
+ {0x50, 0x11, 0xEE}, // DDR default MA7 for DRAM init
+ {0x51, 0x11, 0x60}, // DDR default MA3 for CHB init
+ {0x52, 0x00, 0x33}, // DDR use BA0=M17, BA1=M18,
+ {0x53, 0x00, 0x3F}, // DDR BA2=M19
+
+ {0x54, 0x00, 0x00}, // default PR0=VR0; PR1=VR1
+ {0x55, 0x00, 0x00}, // default PR2=VR2; PR3=VR3
+ {0x56, 0x00, 0x00}, // default PR4=VR4; PR5=VR5
+ {0x57, 0x00, 0x00}, // default PR4=VR4; PR5=VR5
+
+ {0x60, 0x00, 0x00}, // disable fast turn-around
+ {0x65, 0x00, 0xD9}, // AGP timer = 0XD; Host timer = 8;
+ {0x66, 0x00, 0x88}, //DRAMC Queue Size = 4; park at the last bus owner,Priority promotion timer = 8
+ {0x68, 0x00, 0x0C},
+ {0x69, 0xF0, 0x04}, // set RX69[3:0]=0000b
+ {0x6A, 0x00, 0x00}, // refresh counter
+ {0x6E, 0xF8, 0x80}, //must set 6E[7],or else DDR2 probe test will fail
+ // In here, we not set RX70~RX74, because we just init DRAM but no need R/W DRAM,
+ // when we check DQS input/output delay, then we need R/W DRAM.
+
+ //{0x79, 0x00, 0x8F },
+ {0x85, 0x00, 0x00},
+ // {0x90, 0x87, 0x78 },
+ // {0x91, 0x00, 0x46 },
+ {0x40, 0x00, 0x00},
+ {0, 0, 0}
+};
+
+void DRAMRegInitValue(DRAM_SYS_ATTR * DramAttr)
+{
+ u8 Idx, CL;
+ u8 Data;
+
+ for (Idx = 0; DramRegTbl[Idx][0] != 0; Idx++) {
+ Data = pci_read_config8(MEMCTRL, DramRegTbl[Idx][0]);
+ Data &= DramRegTbl[Idx][1];
+ Data |= DramRegTbl[Idx][2];
+ pci_write_config8(MEMCTRL, DramRegTbl[Idx][0], Data);
+ }
+
+ Data = 0x80;
+ pci_write_config8(PCI_DEV(0, 0, 4), 0xa3, Data);
+
+ //set Dram Controllor mode
+ Data = pci_read_config8(MEMCTRL, 0x6c);
+ Data &= 0xFB;
+ if (ENABLE_CHC == 0) {
+ Data |= 0x4; //only CHA 64 bit mode
+ pci_write_config8(MEMCTRL, 0x6c, Data);
+ } else {
+ Data |= 0x0; //CHA + CHC
+ pci_write_config8(MEMCTRL, 0x6c, Data);
+
+ //Data = 0xAA;
+ //pci_write_config8(MEMCTRL, 0xb1, Data);
+
+ //set CHB DQSB input delay, or else will meet error which is some byte is right
+ //but another bit is error
+ Data = pci_read_config8(MEMCTRL, 0xff);
+ Data = (Data & 0x03) | 0x3D;
+ pci_write_config8(MEMCTRL, 0xff, Data);
+
+ //enable CHC RXDB[7]
+ //Data=pci_read_config8(MEMCTRL, 0xdb);
+ // Data = (Data & 0x7F) | 0x80;
+ //pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //rx62[2:0],CHA and CHB CL
+ Data = pci_read_config8(MEMCTRL, 0x62);
+ CL = Data & 0x07;
+
+ //if CL = 6 , so I set CHB CL = 5 default
+ if (CL >= 4)
+ CL = 3;
+
+ // set CHC Read CL rxDC[6:7]
+ Data = pci_read_config8(MEMCTRL, 0xdc);
+ Data = (Data & 0x3F) | (CL << 6);
+ pci_write_config8(MEMCTRL, 0xdc, Data);
+ // set CHC write CL rxDF[6:7]
+ Data = pci_read_config8(MEMCTRL, 0xdf);
+ Data = (Data & 0x3F) | (CL << 6);
+ pci_write_config8(MEMCTRL, 0xdf, Data);
+ // set CHC ODT RxDC[5:0]
+ Data = pci_read_config8(MEMCTRL, 0xdc);
+ Data = (Data & 0xC0) | 0x03;
+ pci_write_config8(MEMCTRL, 0xdc, Data);
+
+ //set column type RXDD[6] and enable ODT PAD RXDD[7]
+ Data = pci_read_config8(MEMCTRL, 0xdd);
+ Data |= 0x80;
+ Idx = DramAttr->DimmInfo[2].SPDDataBuf[SPD_SDRAM_COL_ADDR];
+ if ((Idx & 0x0F) == 10)
+ Data |= 0x40; //MA9~MA0
+ else
+ Data &= 0xBF; //MA8~MA0
+ pci_write_config8(MEMCTRL, 0xdd, Data);
+ }
+
+ // Disable read DRAM fast ready ;Rx51[7]
+ // Disable Read Around Write ;Rx51[6]
+
+ // Disable Consecutive Read ;RX52[1:0]
+ // disable speculative read
+
+}
+
+/*===================================================================
+Function : DRAMInitializeProc()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+Output : Void
+Purpose : DRAM initialize according to the bios porting guid
+===================================================================*/
+
+#define EXIST_TEST_PATTERN 0x55555555
+#define NOT_EXIST_TEST_PATTERN 0xAAAAAAAA
+BOOLEAN ChkForExistLowBank()
+{
+ u32 *Address, data32;
+
+ // Check Pattern
+
+ Address = (u32 *) 8;
+ *Address = EXIST_TEST_PATTERN;
+ Address = (u32 *) 4;
+ *Address = EXIST_TEST_PATTERN;
+
+// _asm {WBINVD}
+ WaitMicroSec(100);
+ Address = (u32 *) 8;
+ data32 = *Address;
+ if (data32 != EXIST_TEST_PATTERN)
+ return FALSE;
+ Address = (u32 *) 4;
+ data32 = *Address;
+ if (data32 != EXIST_TEST_PATTERN)
+ return FALSE;
+
+ // Check not Pattern
+ Address = (u32 *) 8;
+ *Address = NOT_EXIST_TEST_PATTERN;
+ Address = (u32 *) 4;
+ *Address = NOT_EXIST_TEST_PATTERN;
+ //_asm {WBINVD}
+ WaitMicroSec(100);
+
+
+ Address = (u32 *) 8;
+ data32 = *Address;
+ if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
+ return FALSE;
+ Address = (u32 *) 4;
+ data32 = *Address;
+ if (data32 != (u32) (NOT_EXIST_TEST_PATTERN))
+ return FALSE;
+
+ return TRUE;
+}
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr);
+void InitDDR2CHB(DRAM_SYS_ATTR * DramAttr);
+void DRAMInitializeProc(DRAM_SYS_ATTR * DramAttr)
+{
+ u8 shift, idx;
+ BOOLEAN Status;
+
+ shift = 1;
+ for (idx = 0; idx < MAX_RANKS; idx++) {
+ if ((DramAttr->RankPresentMap & shift) != 0) {
+ // Set VR# to physical rank indicated = PR + physical rank enable bit
+ DRAMSetVRNum(DramAttr, idx, idx, TRUE);
+ SetEndingAddr(DramAttr, idx, 0x10); // assume 1G size
+ if (idx < 4) //CHA init
+ InitDDR2CHA(DramAttr); //temp wjb 2007/1 only for compiling
+ // in the function InitDDR2,the parameter is no need
+ Status = ChkForExistLowBank();
+ if (Status == TRUE) {
+ PRINT_DEBUG_MEM(" S\r");
+ } else {
+ PRINT_DEBUG_MEM(" F\r");
+ }
+ // Set VR# to physical rank indicated = 00h + physical rank enable bit
+ DRAMSetVRNum(DramAttr, idx, 0, FALSE);
+ SetEndingAddr(DramAttr, idx, -16);
+ }
+ shift <<= 1;
+ }
+ if (ENABLE_CHC)
+ InitDDR2CHC(DramAttr);
+
+}
+
+
+/*===================================================================
+Function : DRAMSetVRNUM()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+ PhyRank: Physical Rank number
+ VirRank: Virtual Rank number
+ Enable: Enable/Disable Physical Rank
+Output : Void
+Purpose : Set virtual rank number for physical rank
+ Program the specific physical rank with specific virtual rank number
+ Program when necessary, otherwise don't touch the pr-vr-mapping registers
+===================================================================*/
+
+void DRAMSetVRNum(DRAM_SYS_ATTR * DramAttr, u8 PhyRank, // Physical Rank
+ u8 VirRank, // Virtual Rank
+ BOOLEAN Enable)
+{
+ u8 Data;
+ u8 AndData, OrData;
+ Data = pci_read_config8(MEMCTRL, (0x54 + (PhyRank >> 1)));
+
+ OrData = 0;
+ if (Enable)
+ OrData |= 0x08;
+ OrData |= VirRank;
+ if ((PhyRank & 0x01) == 0x00) {
+ AndData = 0x0F; // keep the value of odd rank on PR # is even(keep 1,3,5,7)
+ OrData <<= 4; // VR #, value to be set
+ } else {
+ AndData = 0xF0; // keep the value of even rank on PR # is odd(keep 0,2,4,6)
+ }
+ Data &= AndData;
+ Data |= OrData;
+ pci_write_config8(MEMCTRL, (0x54 + (PhyRank >> 1)), Data);
+}
+
+
+/*===================================================================
+Function : SetEndingAddr()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+ VirRank: Virtual Rank number
+ Value: (value) add or subtract value to this and after banks
+Output : Void
+Purpose : Set ending address of virtual rank specified by VirRank
+===================================================================*/
+
+void SetEndingAddr(DRAM_SYS_ATTR * DramAttr, u8 VirRank, // Ending address register number indicator (INDEX
+ INT8 Value // (value) add or subtract value to this and after banks
+ ) {
+ u8 Data;
+
+ // Read register,Rx40-Rx47(0,1,2,3,4,5,6,7) and set the ending address
+ Data = pci_read_config8(MEMCTRL, 0x40 + VirRank);
+ Data = (u8) (Data + Value);
+ pci_write_config8(MEMCTRL, 0x40 + VirRank, Data);
+
+ //program the virank's begining address to zero
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0x48 + VirRank, Data);
+}
+
+/*===================================================================
+Function : InitDDR2()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+Output : Void
+Purpose : Initialize DDR2 by standard sequence
+===================================================================*/
+
+// DLL: Enable Reset
+static const u32 CHA_MRS_DLL_150[2] = { 0x00020200, 0x00000800 }; // with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
+static const u32 CHA_MRS_DLL_75[2] = { 0x00020020, 0x00000800 }; // with 75 ohm (A17=1, A5=1), (A11=1)(cpu address)
+
+// CPU(DRAM)
+// { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
+// { DLL: reset. A11(MA8)=1 }
+//
+// DDR2 CL=2 CL=3 CL=4 CL=5 CL=6(Burst type=interleave)(WR fine tune in code)
+static const u16 CHA_DDR2_MRS_table[5] = { 0x0150, 0x01D0, 0x0250, 0x02D0, 0x350 }; // BL=4 ;Use 1X-bandwidth MA table to init DRAM
+
+// MA11 MA10(AP) MA9
+#define CHA_MRS_DDR2_TWR2 (0 << 13) + (0 << 20) + (1 << 12) // Value = 001000h
+#define CHA_MRS_DDR2_TWR3 (0 << 13) + (1 << 20) + (0 << 12) // Value = 100000h
+#define CHA_MRS_DDR2_TWR4 (0 << 13) + (1 << 20) + (1 << 12) // Value = 101000h
+#define CHA_MRS_DDR2_TWR5 (1 << 13) + (0 << 20) + (0 << 12) // Value = 002000h
+#define CHA_MRS_DDR2_TWR6 (1 << 13) + (0 << 20) + (1 << 12) // Value = 003000h
+
+// DDR2 Twr=2 Twr=3 Twr=4 Twr=5
+static const u32 CHA_DDR2_Twr_table[5] =
+ { CHA_MRS_DDR2_TWR2, CHA_MRS_DDR2_TWR3, CHA_MRS_DDR2_TWR4,
+CHA_MRS_DDR2_TWR5, CHA_MRS_DDR2_TWR6 };
+
+#define CHA_OCD_Exit_150ohm 0x20200 // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
+// A17=1, A12=A11=A10=0,A9=1 ,A5=0 (CPU address)
+#define CHA_OCD_Default_150ohm 0x21E00 // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
+// A17=1, A12=A11=A10=1,A9=1 ,A5=0 (CPU address)
+#define CHA_OCD_Exit_75ohm 0x20020 // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
+// A17=1, A12=A11=A10=0,A9=0 ,A5=1 (CPU address)
+#define CHA_OCD_Default_75ohm 0x21C20 // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
+// A17=1, A12=A11=A10=1,A9=0 ,A5=1 (CPU address)
+
+void InitDDR2CHA(DRAM_SYS_ATTR * DramAttr)
+{
+ u8 Data;
+ u8 Reg6BVal;
+ u8 Idx, CL, BL, Twr;
+ u32 AccessAddr;
+ u8 DimmNum;
+
+ // step2.
+ //disable bank paging and multi page
+ Data = pci_read_config8(MEMCTRL, 0x69);
+ Data &= ~0x03;
+ pci_write_config8(MEMCTRL, 0x69, Data);
+
+ Reg6BVal = pci_read_config8(MEMCTRL, 0x6b);
+ Reg6BVal &= ~0x07;
+ // Step 3.
+ // At least one NOP cycle will be issued after the 1m sec device deselect.
+ Data = Reg6BVal | 0x01;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ // step4.
+ //Read a double word from any address of the DIMM
+ DimmRead(0x0);
+
+ // Step 5.
+ // A minimum pause of 200u sec will be provided after the NOP.
+ // - <<< reduce BOOT UP time >>> -
+ // Loop 200us
+ for (Idx = 0; Idx < 0x10; Idx++)
+ WaitMicroSec(100);
+
+ // Step 6.
+ // Precharge all (PALL) will be issued to the DDR.
+ Data = Reg6BVal | 0x02;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ // Step7.
+ //Read a double word from any address of the DIMM
+ DimmRead(0x0);
+
+ // Step 8.
+ // MSR Eable will be issued to the DDR
+ Data = Reg6BVal | 0x03;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+
+ // Step 9,10. check ODT value for EMRS(1) command
+ // according to ODTLookUp_TBL in driving_setting.c if there is one dimm in MB's one channel , the DDR2's ODT is 150ohm
+ // if there is two dimm in MB's one channel, the DDR2's ODT is 75 ohm
+ DimmNum = DramAttr->DimmNumChA;
+
+ if (DimmNum == 1) //DDR's ODT is 150ohm
+ {
+ AccessAddr = (u32) CHA_MRS_DLL_150[0];
+ DimmRead(AccessAddr); //issue EMRS DLL Enable
+ PRINT_DEBUG_MEM("Step 9 Address ");
+ PRINT_DEBUG_MEM_HEX32(AccessAddr);
+ PRINT_DEBUG_MEM("\r");
+
+ AccessAddr = (u32) CHA_MRS_DLL_150[1];
+ DimmRead(AccessAddr); //issue MRS DLL Reset
+ PRINT_DEBUG_MEM("Step 10 Address ");
+ PRINT_DEBUG_MEM_HEX32(AccessAddr);
+ PRINT_DEBUG_MEM("\r");
+ } else if (DimmNum == 2) //DDR's ODT is 75ohm
+ {
+ AccessAddr = (u32) CHA_MRS_DLL_75[0];
+ DimmRead(AccessAddr); //issue EMRS DLL Enable
+ AccessAddr = (u32) CHA_MRS_DLL_75[1];
+ DimmRead(AccessAddr); //issue MRS DLL Reset
+ } else {
+ PRINT_DEBUG_MEM("Dimm NUM ERROR:");
+ PRINT_DEBUG_MEM_HEX8(DimmNum);
+ PRINT_DEBUG_MEM("\r");
+ }
+
+ // Step 11.
+ // Precharge all (PALL) will be issued to the DDR.
+ Data = Reg6BVal | 0x02;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ // Step12.
+ //Read a double word from any address of the DIMM
+ DimmRead(0x0);
+
+ // Step 13.
+ // Execute 8 CBR refresh
+ Data = Reg6BVal | 0x04;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ // issue 14,15 , 16
+ //reads and wait 100us between each read
+ for (Idx = 0; Idx < 8; Idx++) {
+ DimmRead(0x0);
+ WaitMicroSec(100);
+ }
+
+ // Step 17.
+ // enable MRS for MAA
+ Data = Reg6BVal | 0x03;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ //Step 18
+ //the SDRAM parameters.(Burst Length, CAS# Latency , Write recovery etc.)
+ //-------------------------------------------------------------
+ //Burst Length : really offset Rx6c[3]
+ Data = pci_read_config8(MEMCTRL, 0x6c);
+ BL = (Data & 0x08) >> 3;
+
+ // CL = really offset RX62[2:0]
+ Data = pci_read_config8(MEMCTRL, 0x62);
+ CL = Data & 0x03;
+
+ AccessAddr = (u32) (CHA_DDR2_MRS_table[CL]);
+ if (BL) {
+ AccessAddr += 8;
+ }
+ //Write recovery : really offset Rx63[7-5]
+ Data = pci_read_config8(MEMCTRL, 0x63);
+ Twr = (Data & 0xE0) >> 5;
+
+ AccessAddr += CHA_DDR2_Twr_table[Twr];
+ // AccessAddr = 0x1012D8;
+ DimmRead(AccessAddr); // Set MRS command
+ PRINT_DEBUG_MEM("Step 18 Address");
+ PRINT_DEBUG_MEM_HEX32(AccessAddr);
+ PRINT_DEBUG_MEM("\r");
+
+ //Step 19,20
+ if (DimmNum == 1) //DDR's ODT is 150ohm
+ {
+ AccessAddr = (u32) CHA_OCD_Default_150ohm;
+ DimmRead(AccessAddr); //issue EMRS OCD Default
+ PRINT_DEBUG_MEM("Step 19 Address ");
+ PRINT_DEBUG_MEM_HEX32(AccessAddr);
+ PRINT_DEBUG_MEM("\r");
+
+ AccessAddr = (u32) CHA_OCD_Exit_150ohm;
+ DimmRead(AccessAddr); //issue EMRS OCD Calibration Mode Exit
+ PRINT_DEBUG_MEM("Step 20 Address ");
+ PRINT_DEBUG_MEM_HEX32(AccessAddr);
+ PRINT_DEBUG_MEM("\r");
+ } else if (DimmNum == 2) //DDR's ODT is 75ohm
+ {
+ AccessAddr = (u32) CHA_OCD_Default_75ohm;
+ DimmRead(AccessAddr); //issue EMRS OCD Default
+ AccessAddr = (u32) CHA_OCD_Exit_75ohm;
+ DimmRead(AccessAddr); //issue EMRS OCD Calibration Mode Exit
+ } else {
+ PRINT_DEBUG_MEM("Dimm NUM ERROR: ");
+ PRINT_DEBUG_MEM_HEX8(DimmNum);
+ PRINT_DEBUG_MEM("\r");
+ }
+
+ //Step 21
+ //After MRS the device should be ready for full functionality within 3 clocks
+ // after Tmrd is met.
+ Data = Reg6BVal;
+ pci_write_config8(MEMCTRL, 0x6b, Data);
+
+ // Enable bank paging and multi page
+ Data = pci_read_config8(MEMCTRL, 0x69);
+ Data |= 0x03;
+ pci_write_config8(MEMCTRL, 0x69, Data);
+}
+
+/*===================================================================
+Function : InitDDR2_CHB()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+Output : Void
+Purpose : Initialize DDR2 of CHB by standard sequence
+Reference :
+===================================================================*/
+/*// DLL: Enable Reset
+static const u32 CHB_MRS_DLL_150[2] = { 0x00020200 | (1 << 20), 0x00000800 }; // with 150 ohm (A17=1, A9=1), (A11=1)(cpu address)
+//u32 CHB_MRS_DLL_75[2] = { 0x00020020 | (1 << 20), 0x00000800 }; // with 75 ohm (A17=1, A5=1), (A11=1)(cpu address)
+// CPU(DRAM)
+// { DLL: Enable. A17(BA0)=1 and A3(MA0)=0 }
+// { DLL: reset. A11(MA8)=1 }
+//
+// DDR2 CL=2 CL=3 CL=4 CL=5 (Burst type=interleave)(WR fine tune in code)
+static const u16 CHB_DDR2_MRS_table[4] ={ 0x0150, 0x01D0, 0x0250, 0x02D0 }; // BL=4 ;Use 1X-bandwidth MA table to init DRAM
+
+// MA11 MA10(AP) MA9
+#define CHB_MRS_DDR2_TWR2 (0 << 13) + (0 << 20) + (1 << 12) // Value = 001000h
+#define CHB_MRS_DDR2_TWR3 (0 << 13) + (1 << 20) + (0 << 12) // Value = 100000h
+#define CHB_MRS_DDR2_TWR4 (0 << 13) + (1 << 20) + (1 << 12) // Value = 101000h
+#define CHB_MRS_DDR2_TWR5 (1 << 13) + (0 << 20) + (0 << 12) // Value = 002000h
+#define CHB_MRS_DDR2_TWR6 (1 << 13) + (0 << 20) + (1 << 12) // Value = 003000h
+
+// DDR2 Twr=2 Twr=3 Twr=4 Twr=5
+static const u32 CHB_DDR2_Twr_table[5] = { CHB_MRS_DDR2_TWR2, CHB_MRS_DDR2_TWR3, CHB_MRS_DDR2_TWR4, CHB_MRS_DDR2_TWR5, CHB_MRS_DDR2_TWR6 };
+
+#define CHB_OCD_Exit_150ohm 0x20200 | (1 << 20) // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=1,MA2=0 (DRAM bus address)
+// A17=1, A12=A11=A10=0,A9=1 ,A5=0 (CPU address)
+#define CHB_OCD_Default_150ohm 0x21E00 | (1 << 20) // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=1,MA2=0 (DRAM bus address)
+// A17=1, A12=A11=A10=1,A9=1 ,A5=0 (CPU address)
+//#define CHB_OCD_Exit_75ohm 0x20020 | (1 << 20) // EMRS(1), BA0=1, MA9=MA8=MA7=0,MA6=0,MA2=1 (DRAM bus address)
+// A17=1, A12=A11=A10=0,A9=0 ,A5=1 (CPU address)
+//#define CHB_OCD_Default_75ohm 0x21C20 | (1 << 20) // EMRS(1), BA0=1, MA9=MA8=MA7=1,MA6=0,MA2=1 (DRAM bus address)
+// A17=1, A12=A11=A10=1,A9=0 ,A5=1 (CPU address)
+void InitDDR2CHB(
+ DRAM_SYS_ATTR *DramAttr
+ )
+
+{
+ u8 Data;
+ u8 Idx, CL, BL, Twr;
+ u32 AccessAddr;
+
+ Data = 0x80;
+ pci_write_config8(MEMCTRL, 0x54, Data);
+
+ // step3.
+ //disable bank paging and multi page
+ Data=pci_read_config8(MEMCTRL, 0x69);
+ Data &= ~0x03;
+ pci_write_config8(MEMCTRL, 0x69, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step 4. Initialize CHB begin
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data |= 0x40;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //Step 5. NOP command enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x08;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //Step 6. issue a nop cycle,RegD3[7] 0 -> 1
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+ // Step 7.
+ // A minimum pause of 200u sec will be provided after the NOP.
+ // - <<< reduce BOOT UP time >>> -
+ // Loop 200us
+ for (Idx = 0; Idx < 0x10; Idx++)
+ WaitMicroSec(10);
+
+ // Step 8.
+ // all banks precharge command enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x10;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step 9. issue a precharge all cycle,RegD3[7] 0 -> 1
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step10. EMRS enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x08;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step11. EMRS DLL Enable and Disable DQS
+ AccessAddr = CHB_MRS_DLL_150[0] >> 3;
+ Data =(u8) (AccessAddr & 0xff);
+ pci_write_config8(MEMCTRL, 0xd9, Data);
+
+ Data = (u8)((AccessAddr & 0xff00) >> 8);
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ Data |= (u8)((AccessAddr & 0x30000) >> 15);
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step12. issue EMRS cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step13. MSR enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x00;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+ //step 14. MSR DLL Reset
+ AccessAddr = CHB_MRS_DLL_150[1] >> 3;
+ Data =(u8) (AccessAddr & 0xff);
+ pci_write_config8(MEMCTRL, 0xd9, Data);
+
+ Data = (u8)((AccessAddr & 0xff00) >> 8);
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ Data |= (u8)((AccessAddr & 0x30000) >> 15);
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step15. issue MRS cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //clear the address
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ //step16. all banks precharge command enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x10;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+ // step17. issue precharge all cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step18. CBR cycle enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x20;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step 19.20.21
+ //repeat issue 8 CBR cycle, between each cycle stop 100us
+ for (Idx = 0; Idx < 8; Idx++)
+ {
+ // issue CBR cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ WaitMicroSec(200);
+ }
+
+ //step22. MSR enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x00;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+
+ //the SDRAM parameters.(Burst Length, CAS# Latency , Write recovery etc.)
+ //-------------------------------------------------------------
+ //Burst Length : really offset Rx6c[1]
+ Data=pci_read_config8(MEMCTRL, 0x6C);
+ BL = (Data & 0x02) >> 1;
+
+ // CL = really offset RX62[2:0]
+ Data=pci_read_config8(MEMCTRL, 0x62);
+ CL = Data & 0x03;
+
+
+ AccessAddr = (u32)(CHB_DDR2_MRS_table[CL]);
+ if (BL)
+ {
+ AccessAddr += 8;
+ }
+
+ //Write recovery : really offset Rx63[7:5]
+ Data=pci_read_config8(MEMCTRL, 0x63);
+ Twr = (Data & 0xE0) >> 5;
+
+ AccessAddr += CHB_DDR2_Twr_table[Twr];
+ //MSR Address use addr[20:3]
+ AccessAddr >>= 3;
+
+ //step 23. MSR command
+ Data = (u8)(AccessAddr & 0xFF);
+ pci_write_config8(MEMCTRL, 0xD9, Data);
+
+ Data = (u8)((AccessAddr & 0xFF00) >> 8);
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ Data |= (u8)(((AccessAddr & 0x30000)>>16) << 1);
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step 24. issue MRS cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step 25. EMRS enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x08;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+ //step 26. OCD default
+ AccessAddr = (CHB_OCD_Default_150ohm) >> 3;
+ Data =(u8) (AccessAddr & 0xff);
+ pci_write_config8(MEMCTRL, 0xd9, Data);
+
+ Data = (u8)((AccessAddr & 0xff00) >> 8);
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ Data |= (u8)((AccessAddr & 0x30000) >> 15);
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+ //step 27. issue EMRS cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step 25. EMRS enable
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x08;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step 28. OCD Exit
+ AccessAddr = (CHB_OCD_Exit_150ohm) >> 3;
+ Data =(u8) (AccessAddr & 0xff);
+ pci_write_config8(MEMCTRL, 0xd9, Data);
+
+ Data = (u8)((AccessAddr & 0xff00) >> 8);
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ Data |= (u8)((AccessAddr & 0x30000) >> 15);
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ //step 29. issue EMRS cycle
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0x7F;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+ Data |= 0x80;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //clear all the address
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xd9, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xda, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xF9;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+
+ //step 30. normal SDRAM Mode
+ Data=pci_read_config8(MEMCTRL, 0xd7);
+ Data &= 0xC7;
+ Data |= 0x00;
+ pci_write_config8(MEMCTRL, 0xd7, Data);
+
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xC7;
+ Data |= 0x00;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+ //step 31. exit the initialization mode
+ Data=pci_read_config8(MEMCTRL, 0xd3);
+ Data &= 0xBF;
+ pci_write_config8(MEMCTRL, 0xd3, Data);
+
+
+ //step 32. Enable bank paging and multi page
+ Data=pci_read_config8(MEMCTRL, 0x69);
+ Data |= 0x03;
+ pci_write_config8(MEMCTRL, 0x69, Data);
+}
+*/
+/*===================================================================
+Function : InitDDR2CHC()
+Precondition :
+Input :
+ DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
+ in MotherBoard
+Output : Void
+Purpose : Initialize DDR2 of CHC by standard sequence
+Reference :
+===================================================================*/
+// DDR2 CL=2 CL=3 CL=4 CL=5 (Burst type=interleave)(WR fine tune in code)
+static const u16 CHC_MRS_table[4] = { 0x22B, 0x23B, 0x24B, 0x25B }; // Use 1X-bandwidth MA table to init DRAM
+
+void InitDDR2CHC(DRAM_SYS_ATTR * DramAttr)
+{
+ u8 Data;
+ u8 Idx, CL, Twr;
+ u32 AccessAddr;
+ CB_STATUS Status;
+
+ // step3.
+ //clear RxDF[2] to disable Tri-state output
+ Data = pci_read_config8(MEMCTRL, 0xdf);
+ Data &= 0xFB;
+ pci_write_config8(MEMCTRL, 0xdf, Data);
+
+
+
+ //step 4. Enable the initialization mode of DRAM Controller C with NB's PLL clock
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x60;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //Step 5. NOP command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x00;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+ //Step 6. issue a nop cycle,RegDB[1] 0 -> 1
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+ // Step 7.
+ // A minimum pause of 200u sec will be provided after the NOP.
+ // - <<< reduce BOOT UP time >>> -
+ // Loop 200us
+ for (Idx = 0; Idx < 0x10; Idx++)
+ WaitMicroSec(100);
+
+ // Step 8.
+ // signal bank precharge command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x14;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //set MA10 =1, precharge all bank
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+
+ Data = 0x04;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step 9. issue a precharge all cycle,RegD3[7] 0 -> 1
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step10. MRS enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x1C;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+ //step11. EMRS DLL enable and Disable DQS
+ Data = 0x40;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x24;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step12. issue EMRS cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step13. MSR enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x1C;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step 14. MSR DLL Reset
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x01;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step15. issue MRS cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step16. signal banks precharge command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x14;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //set MA10 =1, precharge all bank
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x04;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // step17. issue precharge all cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step18. CBR cycle enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x18;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step 19.20.21
+ //repeat issue 8 CBR cycle, between each cycle stop 100us
+ for (Idx = 0; Idx < 8; Idx++) {
+ // issue CBR cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ WaitMicroSec(100);
+ }
+
+ //the SDRAM parameters.(, CAS# Latency , Write recovery etc.)
+ //------------------------------------------------------------
+
+ // CL = really offset RXDC[7:6]
+ Data = pci_read_config8(MEMCTRL, 0xdc);
+ CL = (Data & 0xC0) >> 6;
+
+ AccessAddr = (u32) (CHC_MRS_table[CL]);
+
+ //Write recovery : really offset Rx63[7:5]
+ Data = pci_read_config8(MEMCTRL, 0x63);
+ Twr = (Data & 0xE0) >> 5;
+
+ AccessAddr += Twr * 0x200;
+
+ //step22. MSR enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x1C;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step 23. MSR command
+ Data = (u8) (AccessAddr & 0xFF);
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = (u8) ((AccessAddr & 0xFF00) >> 8);
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step 24. issue MRS cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step 25. EMRS enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x1C;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+
+ //step 26. OCD default
+ Data = 0xC0;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x27;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ //step 27. issue EMRS cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //step 28. OCD Exit
+ Data = 0x40;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x24;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+
+ //step 29. issue EMRS cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Status = VerifyChc();
+ if (Status != CB_SUCCESS)
+ PRINT_DEBUG_MEM("Error!!!!CHC init error!\r");
+ //step 31. exit the initialization mode
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0x9F;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+}
+
+CB_STATUS VerifyChc()
+{
+ u8 Data, ByteVal, Index, pad;
+ u16 row;
+
+ //first write the pad to all the address
+
+ //the row bits is 13 and rank bit is 2, so the address bits is 15 and the value is 0x7fff
+ //verify each MA[0:12],BA[0:1]
+ pad = 1;
+ for (row = 0; row < 0x8000; row++) {
+ //set the write value;
+ //verify each MD[15:0]
+ for (Data = pad, Index = 0; Index < 16; Index++) {
+ Data <<= 1;
+ if (Data == 0)
+ Data = 1;
+ pci_write_config8(PCI_DEV(0, 0, 7), 0xC0 + Index,
+ Data);
+
+ }
+
+ //issue the bank active command
+ // bank active command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x10;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = (u8) (row && 0xFF);
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = (u8) ((row && 0xFF) >> 8);
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue active cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //issue ready/completion for read/write
+ // read/completion command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x04;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue read/completion cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //issue write command
+ // write command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x0C;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = (u8) ((row & 0x60) << 5);
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue write cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ ////issue ready/completion for read/write
+ // read/completion command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x04;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue read/completion cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //issue the bank active command
+ // bank active command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x10;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = (u8) (row && 0xFF);
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = (u8) ((row && 0xFF) >> 8);
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue active cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ ////issue ready/completion for read/write
+ // read/completion command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x04;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue read/completion cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ ////issue read command
+ // read/completion command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x08;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = (u8) ((row & 0x60) << 5);
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue read cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ ////issue ready/completion for read/write
+ // read/completion command enable
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data &= 0xE3;
+ Data |= 0x04;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf8, Data);
+
+ Data = 0x00;
+ pci_write_config8(MEMCTRL, 0xf9, Data);
+
+ // issue read/completion cycle
+ Data = pci_read_config8(MEMCTRL, 0xdb);
+ Data |= 0x2;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+ Data &= 0xFD;
+ pci_write_config8(MEMCTRL, 0xdb, Data);
+
+ //verify the value;
+ for (ByteVal = pad, Index = 0; Index < 16; Index++) {
+ Data =
+ pci_read_config8(PCI_DEV(0, 0, 7),
+ 0xD0 + Index);
+ if (ByteVal != Data) {
+ PRINT_DEBUG_MEM
+ ("error!!!! row = %x,Index =%x,Data = %x,ByteVal=%x\r");
+ }
+ ByteVal <<= 1;
+ if (ByteVal == 0)
+ ByteVal = 1;
+ }
+ pad <<= 1;
+ if (pad == 0)
+ pad = 1;
+ }
+
+ return CB_SUCCESS;
+}