diff options
Diffstat (limited to 'src/northbridge/via/vx800/dev_init.c')
-rw-r--r-- | src/northbridge/via/vx800/dev_init.c | 1318 |
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; +} |