Remove VIA VX800 northbridge support

Change-Id: Id6026e9d7ff064d54b0dd93e80dabdcc4efd2b8e
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/26679
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
Kyösti Mälkki 2018-05-24 02:02:42 +03:00
parent e99f0390b9
commit f99fa1058d
31 changed files with 0 additions and 6153 deletions

View File

@ -1,11 +0,0 @@
config NORTHBRIDGE_VIA_VX800
bool
select NO_MMCONF_SUPPORT
select HAVE_DEBUG_RAM_SETUP
select HAVE_DEBUG_SMBUS
select LATE_CBMEM_INIT
config VIDEO_MB
int
default 0 # FIXME
depends on NORTHBRIDGE_VIA_VX800

View File

@ -1,27 +0,0 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
##
## 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.
##
ifeq ($(CONFIG_NORTHBRIDGE_VIA_VX800),y)
ramstage-y += northbridge.c
ramstage-y += vga.c
ramstage-y += lpc.c
ramstage-y += ide.c
bootblock-y += romstrap.ld
bootblock-y += romstrap.S
endif

View File

@ -1,277 +0,0 @@
/*
* 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.
*/
void DutyCycleCtrl(DRAM_SYS_ATTR *DramAttr)
{
u8 Data, FreqId, i;
if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 3;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 4;
else if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 5;
else
FreqId = 5;
if (DramAttr->RankNumChA > 0) { /* 1 rank */
for (i = 0; i < DUTY_CYCLE_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
ChA_Duty_Control_DDR2[i][0]);
Data &= ChA_Duty_Control_DDR2[i][1]; /* mask */
Data |= ChA_Duty_Control_DDR2[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
ChA_Duty_Control_DDR2[i][0], Data);
}
}
if (1 == ENABLE_CHC) { /* 1 rank */
for (i = 0; i < DUTY_CYCLE_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
ChB_Duty_Control_DDR2[i][0]);
Data &= ChB_Duty_Control_DDR2[i][1]; /* mask */
Data |= ChB_Duty_Control_DDR2[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
ChB_Duty_Control_DDR2[i][0], Data);
}
}
}
/*
* DRAM clock phase and delay control
*/
/* Subroutine list */
void ClkPhsCtrlFBMDDR2(DRAM_SYS_ATTR *DramAttr);
void WrtDataPhsCtrl(DRAM_SYS_ATTR *DramAttr);
void DQDQSOutputDlyCtrl(DRAM_SYS_ATTR *DramAttr);
void DQSInputCaptureCtrl(DRAM_SYS_ATTR *DramAttr);
void DCLKPhsCtrl(DRAM_SYS_ATTR *DramAttr);
void DRAMClkCtrl(DRAM_SYS_ATTR *DramAttr)
{
/* Write data clock phase control. */
WrtDataPhsCtrl(DramAttr);
/* Clock phase control */
ClkPhsCtrlFBMDDR2(DramAttr);
/**/ DQDQSOutputDlyCtrl(DramAttr);
/**/ DQSInputCaptureCtrl(DramAttr);
DCLKPhsCtrl(DramAttr);
}
void ClkPhsCtrlFBMDDR2(DRAM_SYS_ATTR *DramAttr)
{
u8 Data, FreqId, i;
if (DramAttr->DramFreq == DIMMFREQ_800)
FreqId = 2;
else if (DramAttr->DramFreq == DIMMFREQ_667)
FreqId = 3;
else if (DramAttr->DramFreq == DIMMFREQ_533)
FreqId = 4;
else if (DramAttr->DramFreq == DIMMFREQ_400)
FreqId = 5;
else
FreqId = 5;
/* Channel A */
// 2~4 Rank
if (DramAttr->RankNumChA == 1) { /* 1 rank */
for (i = 0; i < 3; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChA_Clk_Phase_Table_1R[i][0]);
Data &= DDR2_ChA_Clk_Phase_Table_1R[i][1]; /* mask */
Data |= DDR2_ChA_Clk_Phase_Table_1R[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChA_Clk_Phase_Table_1R[i][0], Data);
}
} else if (DramAttr->RankNumChA > 1) { /* 2~4 Rank */
for (i = 0; i < 3; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChA_Clk_Phase_Table_2R[i][0]);
Data &= DDR2_ChA_Clk_Phase_Table_2R[i][1]; /* mask */
Data |= DDR2_ChA_Clk_Phase_Table_2R[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChA_Clk_Phase_Table_2R[i][0], Data);
}
}
#if ENABLE_CHB
if (DramAttr->RankNumChB > 0) { /* 1 rank */
for (i = 0; i < 3; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChB_Clk_Phase_Table_1R[i][0]);
Data &= DDR2_ChB_Clk_Phase_Table_1R[i][1]; /* mask */
Data |= DDR2_ChB_Clk_Phase_Table_1R[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChB_Clk_Phase_Table_1R[i][0], Data);
}
}
#endif
}
void WrtDataPhsCtrl(DRAM_SYS_ATTR *DramAttr)
{
u8 Data, FreqId, i;
if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 3;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 4;
else if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 5;
else
FreqId = 5;
if (DramAttr->RankNumChA > 0) { /* 1 rank */
for (i = 0; i < WrtData_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChA_WrtData_Phase_Table[i][0]);
Data &= DDR2_ChA_WrtData_Phase_Table[i][1]; /* mask */
Data |= DDR2_ChA_WrtData_Phase_Table[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChA_WrtData_Phase_Table[i][0], Data);
}
}
#if ENABLE_CHB
if (DramAttr->RankNumChB > 0) { /* 1 rank */
for (i = 0; i < WrtData_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChB_WrtData_Phase_Table[i][0]);
Data &= DDR2_ChB_WrtData_Phase_Table[i][1]; /* mask */
Data |= DDR2_ChB_WrtData_Phase_Table[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChB_WrtData_Phase_Table[i][0], Data);
}
}
#endif
Data = pci_read_config8(MEMCTRL, 0x8C);
Data &= 0xFC;
Data |= 0x03;
pci_write_config8(MEMCTRL, 0x8C, Data);
}
void DQDQSOutputDlyCtrl(DRAM_SYS_ATTR *DramAttr)
{
u8 Data, FreqId;
if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 0;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 1;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 2;
else
FreqId = 0;
if (DramAttr->RankNumChA > 0) {
Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][0];
pci_write_config8(MEMCTRL, 0xf0, Data);
Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][1];
pci_write_config8(MEMCTRL, 0xf1, Data);
Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][2];
pci_write_config8(MEMCTRL, 0xf2, Data);
Data = DDR2_CHA_DQ_DQS_Delay_Table[FreqId][3];
pci_write_config8(MEMCTRL, 0xf3, Data);
}
#if ENABLE_CHB
if (DramAttr->RankNumChB > 0) {
Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][0];
pci_write_config8(MEMCTRL, 0xf4, Data);
Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][1];
pci_write_config8(MEMCTRL, 0xf5, Data);
Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][2];
pci_write_config8(MEMCTRL, 0xf6, Data);
Data = DDR2_CHB_DQ_DQS_Delay_Table[FreqId][3];
pci_write_config8(MEMCTRL, 0xf7, Data);
}
#endif
}
void DQSInputCaptureCtrl(DRAM_SYS_ATTR *DramAttr)
{
u8 Data, FreqId, i;
if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 3;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 4;
else if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 5;
else
FreqId = 2;
Data = 0x8A;
pci_write_config8(MEMCTRL, 0x77, Data);
if (DramAttr->RankNumChA > 0) { /* 1 rank */
for (i = 0; i < DQS_INPUT_CAPTURE_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChA_DQS_Input_Capture_Tbl[i][0]);
Data &= DDR2_ChA_DQS_Input_Capture_Tbl[i][1]; /* mask */
Data |= DDR2_ChA_DQS_Input_Capture_Tbl[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChA_DQS_Input_Capture_Tbl[i][0], Data);
}
}
#if ENABLE_CHB
if (DramAttr->RankNumChB > 0) { /* 1 rank */
for (i = 0; i < DQS_INPUT_CAPTURE_REG_NUM; i++) {
Data = pci_read_config8(MEMCTRL,
DDR2_ChB_DQS_Input_Capture_Tbl[i][0]);
Data &= DDR2_ChB_DQS_Input_Capture_Tbl[i][1]; /* mask */
Data |= DDR2_ChB_DQS_Input_Capture_Tbl[i][FreqId]; /* set val */
pci_write_config8(MEMCTRL,
DDR2_ChB_DQS_Input_Capture_Tbl[i][0], Data);
}
}
#endif
}
/*
* This is very important, if you don't set it correctly, DRAM will be
* unreliable,
*
* Set DCLK Phase control(Reg99H[6:1]) according the DDRII in the DIMM.
*/
void DCLKPhsCtrl(DRAM_SYS_ATTR *DramAttr)
{
u8 Data;
Data = 0; /* TODO: Can be dropped? */
Data = pci_read_config8(MEMCTRL, 0x99);
Data &= 0xE1;
/* DDR in Dimm1, MCLKOA[4,3,0] will output MCLK */
if (DramAttr->RankPresentMap & 0x03)
Data |= 0x09 << 1;
/* DDR in Dimm2, MCLKOA[5,2,1] will output MCLK */
if (DramAttr->RankPresentMap & 0x0C)
Data |= 0x06 << 1;
pci_write_config8(MEMCTRL, 0x99, Data);
}

View File

@ -1,193 +0,0 @@
/*
* 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.
*/
/* FIXME this should go away */
static const struct mem_controller ctrl = {
.channel0 = {DIMM0, DIMM1},
};
/* read data */
CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 *Buf);
void DRAMCmdRate(DRAM_SYS_ATTR *DramAttr);
CB_STATUS GetInfoFromSPD(DRAM_SYS_ATTR *DramAttr);
CB_STATUS GetSPDData(u8 Slot, u8 Length, u8 *Buf)
{
// CB_STATUS Status = CB_NOT_READY;
u8 Val, i;
if (1 > Length || NULL == Buf)
return CB_INVALID_PARAMETER;
for (i = 0; i < Length; i++) {
Val = get_spd_data(ctrl.channel0[Slot], i);
*(Buf + i) = Val;
}
return CB_SUCCESS;
}
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;
}
/*
* Determine 1T or 2T command rate.
*
* To enable 1T command rate, the system will satisfy the following
* three conditions:
*
* 1. Each DRAM channel may have 1 or 2 ranks of DIMM. 3/4 ranks can not
* support 1T command rate. It's for loading issue. 1T can supports
* (a) only one socket with two ranks, OR
* (b) two sockets each with 1 rank.
* 2. User wishes to enable 1T command rate mode and turn on by setup menu.
* 3. If 1T command rate can be enabled, just set EBP bit here.
*/
void DRAMCmdRate(DRAM_SYS_ATTR *DramAttr)
{
u8 Data;
// 5.1t/2t command rate, use the stable set
//offset50
DramAttr->CmdRate = 2;
Data = pci_read_config8(MEMCTRL, 0x50);
Data = (u8) (Data & 0xEE);
pci_write_config8(MEMCTRL, 0x50, Data);
}
/*
* 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;
}

View File

@ -1,942 +0,0 @@
/*
* 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.
*/
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(void);
/*===================================================================
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] = {
/* Reg 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.
*/
{0x85, 0x00, 0x00},
{0x40, 0x00, 0x00},
{0, 0, 0}
};
void DRAMRegInitValue(DRAM_SYS_ATTR *DramAttr)
{
u8 Idx, CL, 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 controller 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);
// 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]
// 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
static BOOLEAN ChkForExistLowBank(void)
{
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 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, 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 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, Reg6BVal, Idx, CL, BL, Twr, DimmNum;
u32 AccessAddr;
/* Step 2 */
/* 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);
/* Step 4 */
/* 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);
/* Step 12. 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];
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 : 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, Idx, CL, Twr;
u32 AccessAddr;
CB_STATUS Status;
/* Step 3. 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);
/* Step 10. MRS enable. */
Data = pci_read_config8(MEMCTRL, 0xdb);
Data &= 0xE3;
Data |= 0x1C;
pci_write_config8(MEMCTRL, 0xdb, Data);
/* Step 11. EMRS DLL enable and Disable DQS. */
Data = 0x40;
pci_write_config8(MEMCTRL, 0xf8, Data);
Data = 0x24;
pci_write_config8(MEMCTRL, 0xf9, Data);
/* Step 12. 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 13. 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);
/* Step 15. 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 16. 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);
/* Step 17. 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);
/* Step 18. 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(void)
{
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;
}

View File

@ -1,93 +0,0 @@
/*
* 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.
*/
void SetDQSOutputCHA(DRAM_SYS_ATTR * DramAttr);
void SetDQSOutputCHB(DRAM_SYS_ATTR * DramAttr);
/*===================================================================
Function : DRAMDQSOutputSearchCHA()
Precondition :
Input :
DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
in MotherBoard
Output : Void
Purpose : set DQS output delay register reg70 and DQ output delay register reg71
===================================================================*/
#define CH_A 0
#define CH_B 1
void DRAMDQSOutputSearch(DRAM_SYS_ATTR * DramAttr)
{
if (DramAttr->RankNumChA > 0)
SetDQSOutputCHA(DramAttr);
}
/*===================================================================
Function : SetDQSOutputCHA()
Precondition :
Input :
DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
in MotherBoard
Output : Void
Purpose : according the frequence set CHA DQS output
===================================================================*/
void SetDQSOutputCHA(DRAM_SYS_ATTR * DramAttr)
{
u8 Reg70, Reg71;
u8 Index;
if (DramAttr->DramFreq == DIMMFREQ_400)
Index = 3;
else if (DramAttr->DramFreq == DIMMFREQ_533)
Index = 2;
else if (DramAttr->DramFreq == DIMMFREQ_667)
Index = 1;
else if (DramAttr->DramFreq == DIMMFREQ_800)
Index = 0;
else
Index = 3;
if (DramAttr->RankNumChA > 2) {
Reg70 = Fixed_DQSA_3_4_Rank_Table[Index][0];
Reg71 = Fixed_DQSA_3_4_Rank_Table[Index][1];
} else {
Reg70 = Fixed_DQSA_1_2_Rank_Table[Index][0];
Reg71 = Fixed_DQSA_1_2_Rank_Table[Index][1];
}
pci_write_config8(MEMCTRL, 0x70, Reg70);
pci_write_config8(MEMCTRL, 0x71, Reg71);
}
//################
// STEP 12 #
//################
/*===================================================================
Function : DRAMDQSInputSearch()
Precondition :
Input :
DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
in MotherBoard
Output : Void
Purpose : search DQS input delay for CHA/CHB
===================================================================*/
void DRAMDQSInputSearch(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
//auto mode
Data = 0x0;
pci_write_config8(MEMCTRL, 0x77, Data);
}

View File

@ -1,79 +0,0 @@
/*
* 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.
*/
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;
}

View File

@ -1,241 +0,0 @@
/*
* 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.
*/
#ifndef __DRAMINIT_H_
#define __DRAMINIT_H_
//Dram Size
#define M (1024*1024)
#define M1 (1*M)
#define M64 (64*M)
#define M128 (128*M)
#define M256 (256*M)
#define M384 (384*M)
#define M512 (512*M)
// UMA size
#define UMASIZE M64
#define ENABLE_CHC 0 //CHC enable, how ever, this CHC,used some reg define in CHB
#define ENABLE_CHB 0 //CHB enable , CHB is VX800's, VX855 no this CHB.
//Dram Freq
#define DIMMFREQ_800 400
#define DIMMFREQ_667 333
#define DIMMFREQ_533 266
#define DIMMFREQ_400 200
#define DIMMFREQ_333 166
#define DIMMFREQ_266 133
#define DIMMFREQ_200 100
//Dram Type
#define RAMTYPE_FPMDRAM 1
#define RAMTYPE_EDO 2
#define RAMTYPE_PipelinedNibble 3
#define RAMTYPE_SDRAM 4
#define RAMTYPE_ROM 5
#define RAMTYPE_SGRAMDDR 6
#define RAMTYPE_SDRAMDDR 7
#define RAMTYPE_SDRAMDDR2 8
/* CAS latency constant */
#define CASLAN_15 15
#define CASLAN_2 20
#define CASLAN_25 25
#define CASLAN_3 30
#define CASLAN_35 35
#define CASLAN_4 40
#define CASLAN_45 45
#define CASLAN_5 50
#define CASLAN_NULL 00
//Burst length
#define BURSTLENGTH8 8
#define BURSTLENGTH4 4
//Data Width
#define SPD_MEMORY_TYPE 2 /*Memory type FPM,EDO,SDRAM,DDR,DDR2 */
#define SPD_SDRAM_ROW_ADDR 3 /*Number of row addresses on this assembly */
#define SPD_SDRAM_COL_ADDR 4 /*Number of column addresses on this assembly */
#define SPD_SDRAM_DIMM_RANKS 5 /*Number of RANKS on this assembly */
#define SPD_SDRAM_MOD_DATA_WIDTH 6 /*Data width of this assembly */
#define SPD_SDRAM_TCLK_X 9 /*Cycle time at Maximum supported CAS latency (CL = X) */
#define SPD_SDRAM_TAC_X 10 /*Access time for highest CL */
#define SPD_SDRAM_CONFIG_TYPE 11 /*Non-parity , Parity or ECC */
#define SPD_SDRAM_REFRESH 12 /*Refresh rate/type */
#define SPD_SDRAM_WIDTH 13 /*Primary sdram width */
#define SPD_SDRAM_MIN_CLK_DLY 15 /*Minimum clock delay */
#define SPD_SDRAM_BURSTLENGTH 16 /*Burst Lengths supported */
#define SPD_SDRAM_NO_OF_BANKS 17 /*Number of banks on this assembly */
#define SPD_SDRAM_CAS_LATENCY 18 /*CAS latency */
#define SPD_SDRAM_DIMM_TYPE_DDR2 20 /*DIMM type information; identifies the DDR2 memory module type */
#define SPD_SDRAM_DEV_ATTR_DDR1 20 /*WE latency */
#define SPD_SDRAM_MODULES_ATTR 21 /*This byte depicts various aspects of the modules; DDR DDR2 have different aspects */
#define SPD_SDRAM_DEV_ATTR_GEN 22 /*General device attributes */
#define SPD_SDRAM_TCLK_X_1 23 /*Minimum clock cycle time at Reduced CL, DDR: X-0.5 DDR2: X-1 */
#define SPD_SDRAM_TAC_X_1 24 /*Maximum Data Access time from Clock at reduced CL,DDR: X-0.5 DDR2: X-1 */
#define SPD_SDRAM_TCLK_X_2 25 /*Minimum clock cycle time at reduced CL, DDR: X-1 DDR2: X-2 */
#define SPD_SDRAM_TAC_X_2 26 /*Maximum Data Access time from Clock at reduced CL, DDR: X-1 DDR2: X-2 */
#define SPD_SDRAM_TRP 27 /*minimum row precharge time */
#define SPD_SDRAM_TRRD 28 /*minimum row active to row active delay */
#define SPD_SDRAM_TRCD 29 /*minimum RAS to CAS delay */
#define SPD_SDRAM_TRAS 30 /*minimum active to precharge time */
#define SPD_SDRAM_TWR 36 /*write recovery time, only DDR2 use it */
#define SPD_SDRAM_TWTR 37 /*internal write to read command delay, only DDR2 use it */
#define SPD_SDRAM_TRTP 38 /*internal read to prechange command delay, only DDR2 use it */
#define SPD_SDRAM_TRFC2 40 /*extension of byte 41 tRC and byte 42 tRFC, only DDR2 use it */
#define SPC_SDRAM_TRC 41 /*minimum active to active/refresh time */
#define SPD_SDRAM_TRFC 42 /*minimum refresh to active / refresh command period */
#define SPD_DATA_SIZE 44
//Dram cofig are
/*the most number of socket*/
#define MAX_RAM_SLOTS 2
#define MAX_SOCKETS MAX_RAM_SLOTS
#define MAX_DIMMS MAX_SOCKETS /*every sockets can plug one DIMM */
/*the most number of RANKs on a DIMM*/
#define MAX_RANKS MAX_SOCKETS*2
struct mem_controller {
u8 channel0[MAX_DIMMS];
};
typedef struct _DRAM_CONFIG_DATA {
u8 DramClk;
u8 DramTiming;
u8 CasLatency;
u8 BankIntlv;
u8 Trp;
u8 Tras;
u8 Trcd;
u8 Trfc;
u8 Trrd;
u8 Trtp;
u8 Twtr;
u8 Twr;
u8 CmdRate;
u8 DualEn;
u8 BaScmb;
u8 DrdyTiming;
u16 UMASize;
} DRAM_CONFIG_DATA;
/*DIMM(assembly) information*/
typedef struct _DIMM_INFO_tag {
u8 bPresence;
u8 SPDDataBuf[SPD_DATA_SIZE]; /*get all information from spd data */
} DIMM_INFO;
typedef struct _DRAM_SYS_ATTR_tag {
DIMM_INFO DimmInfo[MAX_DIMMS];
u8 RankPresentMap; /*bit0,1 Rank0,1 on DIMM0, bit2,3 Rank2,3 on DIMM1,
bit4,5 Rank4,5 on DIMM2, bit6,7 Rank6,7 on DIMM3 */
u8 DimmNumChA; /*Dimm number */
u8 DimmNumChB;
u8 RankNumChA; /*the number of Ranks on the mortherbaord */
u8 RankNumChB;
u8 LoadNumChA; /*the number of chips on all DIMM */
u8 LoadNumChB;
u8 DramType; /*DDR1 or DDR2 */
u16 DramFreq;
u16 DramCyc; /*10ns, 7.5ns, 6ns, 5ns, 3.75ns, 3ns, 2.5ns =1/SysFreq, unit: 100*ns. */
//u16 HFreq; /*100, 133, 166, 200, 266, 333, 400*/
u8 CL; /* CAS lantency */
u8 CmdRate; /*1T or 2T */
u32 RankSize[MAX_RANKS];
u8 Dual_Channel;
DRAM_CONFIG_DATA ConfigData;
u8 reserved[4];
} DRAM_SYS_ATTR;
typedef struct _DRAM_SIZE_INFO {
u32 RankLength[MAX_RANKS];
} DRAM_SIZE_INFO;
//detection.c
/*Step1 detect DRAM type, Read SPD data,command rate*/
CB_STATUS DRAMDetect(DRAM_SYS_ATTR * DramAttr);
//freq_setting.c
/*Step2 set Frequency, calculate CAL*/
void DRAMFreqSetting(DRAM_SYS_ATTR * DramAttr);
//timing_setting.c
/*Step3 Set DRAM Timing*/
void DRAMTimingSetting(DRAM_SYS_ATTR * DramAttr);
//drdy_bl.c
/*Step4 DRDY*/
void DRAMDRDYSetting(DRAM_SYS_ATTR * DramAttr);
//drdy_bl.c
/*Step5 Burst Length*/
void DRAMBurstLength(DRAM_SYS_ATTR * DramAttr);
//driving_setting.c
/*Step6 DRAM Driving Adjustment*/
void DRAMDriving(DRAM_SYS_ATTR * DramAttr);
//clk_ctrl.c
/*Step7 duty cycle control*/
void DutyCycleCtrl(DRAM_SYS_ATTR * DramAttr);
//clk_ctrl.c
/*Step8 DRAM clock phase and delay control*/
void DRAMClkCtrl(DRAM_SYS_ATTR * DramAttr);
//dev_init.c
/*Step9 set register before init DRAM device*/
void DRAMRegInitValue(DRAM_SYS_ATTR * DramAttr);
//dev_init.c
/*Step10 DDR and DDR2 initialize process*/
void DRAMInitializeProc(DRAM_SYS_ATTR * DramAttr);
//dqs_search.c
/*Step11 Search DQS and DQ output delay*/
void DRAMDQSOutputSearch(DRAM_SYS_ATTR * DramAttr);
//dqs_search.c
/*Step12 Search DQS input delay*/
void DRAMDQSInputSearch(DRAM_SYS_ATTR * DramAttr);
//rank_map.c
/*Step13 Interleav function in rankmap.c*/
void DRAMBankInterleave(DRAM_SYS_ATTR * DramAttr);
//rank_map.c
/*Step14 Sizing*/
void DRAMSizingMATypeM(DRAM_SYS_ATTR * DramAttr);
//final_setting.c
/*Step15 DDR fresh counter setting*/
void DRAMRefreshCounter(DRAM_SYS_ATTR * DramAttr);
//final_setting.c
/*Step16 Final register setting for improve performance*/
void DRAMRegFinalValue(DRAM_SYS_ATTR * DramAttr);
/*set UMA*/
void SetUMARam(void);
CB_STATUS InstallMemory(DRAM_SYS_ATTR * DramAttr, u32 RamSize);
CB_STATUS DDR2_DRAM_INIT(void);
#endif

View File

@ -1,231 +0,0 @@
/*
* 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.
*/
void WaitMicroSec(UINTN MicroSeconds)
{
u32 i;
for (i = 0; i < 1024 * MicroSeconds; i++) {
__asm__ volatile ("nop\n\t");
}
return;
}
/*===================================================================
Function : via_write_phys()
Precondition :
Input : addr
value
Output : void
Purpose :
Reference : None
===================================================================*/
void via_write_phys(volatile u32 addr, volatile u32 value)
{
volatile u32 *ptr;
ptr = (volatile u32 *)addr;
*ptr = (volatile u32)value;
}
/*===================================================================
Function : via_read_phys()
Precondition :
Input : addr
Output : u32
Purpose :
Reference : None
===================================================================*/
u32 via_read_phys(volatile u32 addr)
{
volatile u32 y;
y = *(volatile u32 *)addr;
return y;
}
/*===================================================================
Function : DimmRead()
Precondition :
Input : x
Output : u32
Purpose :
Reference : None
===================================================================*/
u32 DimmRead(volatile u32 x)
{ // volatile u32 z;
volatile u32 y;
y = *(volatile u32 *)x;
return y;
}
/*===================================================================
Function : DramBaseTest()
Precondition : this function used to verify memory
Input :
BaseAdd,
length,
mode
Output : u32
Purpose :write into and read out to verify if dram is correct
Reference : None
===================================================================*/
BOOLEAN DramBaseTest(u32 BaseAdd, u32 Length,
DRAM_TEST_MODE Mode, BOOLEAN PrintFlag)
{
u32 TestSpan;
u32 Data, Address, Address2;
u8 i, TestCount;
//decide the test mode is continous or step
if (Mode == EXTENSIVE) {
//the test mode is continuos and must test each unit
TestSpan = 4;
TestCount = 1;
} else if (Mode == SPARE) {
// the test mode is step and test some unit
TestSpan = STEPSPAN;
TestCount = TESTCOUNT;
} else {
PRINT_DEBUG_MEM("the test mode is error\r");
return FALSE;
}
//write each test unit the value with TEST_PATTERN
for (Address = BaseAdd; Address < BaseAdd + Length; Address += TestSpan) {
for (i = 0; i < TestCount; i++)
via_write_phys(Address + i * 4, TEST_PATTERN);
if (PrintFlag) {
if ((u32) Address % 0x10000000 == 0) {
PRINT_DEBUG_MEM("Write in Addr =");
PRINT_DEBUG_MEM_HEX32(Address);
PRINT_DEBUG_MEM("\r");
}
}
}
//compare each test unit with the value of TEST_PATTERN
//and write it with compliment of TEST_PATTERN
for (Address = BaseAdd; Address < BaseAdd + Length; Address += TestSpan) {
for (i = 0; i < TestCount; i++) {
Data = via_read_phys(Address + i * 4);
via_write_phys(Address + i * 4, (u32) (~TEST_PATTERN));
if (Data != TEST_PATTERN) {
PRINT_DEBUG_MEM("TEST_PATTERN ERROR !!!!! ");
Address2 = Address + i * 4;
PRINT_DEBUG_MEM_HEX32(Address2);
PRINT_DEBUG_MEM(" : ");
PRINT_DEBUG_MEM_HEX32(Data);
PRINT_DEBUG_MEM(" \r");
return FALSE;
}
}
if (PrintFlag) {
if ((u32) Address % 0x10000000 == 0) {
PRINT_DEBUG_MEM("Write in Addr =");
PRINT_DEBUG_MEM_HEX32(Address);
PRINT_DEBUG_MEM("\r");
}
}
}
//compare each test unit with the value of ~TEST_PATTERN
for (Address = BaseAdd; Address < BaseAdd + Length; Address += TestSpan) {
for (i = (u8) (TestCount); i > 0; i--) {
Data = via_read_phys(Address + (i - 1) * 4);
if (Data != ~TEST_PATTERN) {
PRINT_DEBUG_MEM("~TEST_PATTERN ERROR !!!!! ");
Address2 = Address + (i - 1) * 4;
PRINT_DEBUG_MEM_HEX32(Address2);
PRINT_DEBUG_MEM(" : ");
PRINT_DEBUG_MEM_HEX32(Data);
PRINT_DEBUG_MEM(" \r");
return FALSE;
}
}
}
return TRUE;
}
/*===================================================================
Function : DumpRegisters()
Precondition :
Input :
pPCIPPI,
DevNum,
FuncNum
Output : Void
Purpose :
Reference : None
===================================================================*/
void DumpRegisters(INTN DevNum, INTN FuncNum)
{
INTN i, j;
u8 ByteVal;
ByteVal = 0;
PRINT_DEBUG_MEM("\rDev %02x Fun %02x\r");
PRINT_DEBUG_MEM
("\r 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\r");
PRINT_DEBUG_MEM
("---------------------------------------------------\r");
for (i = 0; i < 0x10; i++) {
PRINT_DEBUG_MEM_HEX32((u32)i);
for (j = 0; j < 0x10; j++) {
ByteVal =
pci_read_config8(PCI_DEV(0, DevNum, FuncNum),
i * 0x10 + j);
PRINT_DEBUG_MEM_HEX8(ByteVal);
PRINT_DEBUG_MEM(" ");
}
PRINT_DEBUG_MEM("\r");
}
return;
}
/*===================================================================
Function : dumpnorth()
Precondition :
Input :
pPCIPPI,
Func
Output : Void
Purpose :
Reference : None
===================================================================*/
void dumpnorth(u8 Func)
{
u16 r, c;
u8 ByteVal;
PRINT_DEBUG_MEM("Dump North!!!\r");
for (r = 0; r < 32; r++) {
for (c = (u16) (r << 3); c < (r << 3) + 8; c++) {
ByteVal = 0;
ByteVal = pci_read_config8(PCI_DEV(0, 0, Func), c);
PRINT_DEBUG_MEM_HEX16(c);
PRINT_DEBUG_MEM("= ");
PRINT_DEBUG_MEM_HEX8(ByteVal);
}
PRINT_DEBUG_MEM("\r");
}
}

View File

@ -1,43 +0,0 @@
/*
* 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.
*/
#ifndef __DRAM_UTIL_H__
#define __DRAM_UTIL_H__
#define STEPSPAN 0x1000 //the span when test memory in spare mode
#define TESTCOUNT 0x4 // the test count in each range when test memory in spare mode
#define TEST_PATTERN 0x5A5A5A5A //the test pattern
typedef enum __DRAM_TEST_MODE {
EXTENSIVE,
SPARE,
MAXMODE
} DRAM_TEST_MODE;
void WaitMicroSec(UINTN MicroSeconds);
void via_write_phys(u32 addr, u32 value);
u32 via_read_phys(u32 addr);
u32 DimmRead(u32 x);
BOOLEAN DramBaseTest(u32 BaseAdd, u32 Length,
DRAM_TEST_MODE mode, BOOLEAN PrintFlag);
void DumpRegisters(INTN DevNum, INTN FuncNum);
void dumpnorth(u8 Func);
#endif

View File

@ -1,505 +0,0 @@
/*
* 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.
*/
// Set P6IF DRDY Timing
// Because there are 1.5T & 2.5T CAS latency in DDR1 mode, we need to use RDELAYMD-0
//
// Entry:
// EBP[29:25] = DRAM Speed, Dual_Channel
// VIA_NB2HOST_REG54[7:5] Host Frequency
// VIA_NB3DRAM_REG62[2:0] CAS Latency
//
// Modify NB_Reg:
// VIA_NB2HOST_REG54[3,1]
// VIA_NB2HOST_REG55[1]
// VIA_NB2HOST_REG60
// VIA_NB2HOST_REG61
// VIA_NB2HOST_REG62[3:0]
// VIA_NB2HOST_REG63
// VIA_NB2HOST_REG64
// VIA_NB2HOST_REG65[3:0]
// VIA_NB2HOST_REG66
// VIA_NB2HOST_REG67[5:4]
//
// Processing:
//--------------------------------------------------------------------------
// P6IF DRDY Timing Control:
// *Following algorithm to set DRDY timing
// Set P6IF DRDY Timing by the following 3 conditions:
// 1. RDELAYMD
// a.RDRPH(MD input internal timing control)
// b.CAS Latency
// RDELAYMD(1bit) = bit0 of (CL + RDRPH)
// for example: RDRPH = 10b, CL3 -> F3_Rx56[5:4]=11b, 10b + 11b = 101b, RDELAYMD = 1 (bit0)
// RDRPH = 00b, CL2.5 -> F3_Rx56[5:4]=10b, 00b + 10b = 010b, RDELAYMD = 0 (bit0)
// 2. CPU Frequency
// 3. DRAM Frequency
//
// According to above conditions, we create different tables:
// 1. RDELAYMD = 0 : for integer CAS latency(ex. CL = 3)
// 2. RDELAYMD = 1 : for non-integer CAS latency(ex. CL = 2.5)
// 3. Normal performance
// 4. Top performance :
// Using phase0 to a case has better performance.
//
// Note: The setting are related to performance and maybe affect DRAM initialize.
// Turn OFF(F2_Rx51[7]=0) this feature at csDRAMRegInitValueJ procedure.
// Turn ON(F2_Rx51[7]=1) this feature at csDRAMRegFinalValueJ procedure.
//
// If F2_Rx51[7]=0, then CPU always wait 8QW, a slower but most stable way
// If F2_Rx51[7]=1, then the timing will refer to F2_Rx60 ~ F2_Rx67,
// a fast way but may cause the system to be unstable.
//
// Coding:
// 1. RDELAYMD and user's option for performance can determine which table
// 2. CPU Frequency can get block offset of table
// 3. DRAM Frequency can get row offset of block
// 4. Set value
//
// PS: Fun2 Rx62, Rx65, Rx67 are don't care bits in 3296, CPU 266MHz doesn't be supported by 3296,
// but I still keep these bits in table to avoid the usage in future
// and do the fewest modification for code.
//
// Early 3T
// Early 3T
#define P6IF_Misc_RFASTH 0x08
#define P6IF_Misc2_RRRDYH3E 0x10
#define P6IF_Misc2_RHTSEL 0x02
#define Rx54E3T P6IF_Misc_RFASTH
#define Rx55E3T P6IF_Misc2_RRRDYH3E
// Early 2T
#define Rx54E2T 0x00
#define Rx55E2T P6IF_Misc2_RRRDYH3E
// Early 1T
#define Rx54E1T 0x00
#define Rx55E1T 0x00
// Early 0T
#define Rx54E0T P6IF_Misc_RFASTH
#define Rx55E0T P6IF_Misc2_RRRDYH3E + P6IF_Misc2_RHTSEL
// Latter 1T
#define Rx54L1T P6IF_Misc_RFASTH
#define Rx55L1T P6IF_Misc2_RHTSEL
#define PH0_0_0_0 0x00
#define PH0_0_0_1 0x01
#define PH0_0_0_2 0x02
#define PH0_0_0_3 0x03
#define PH0_0_1_0 0x04
#define PH0_0_1_1 0x05
#define PH0_0_1_2 0x06
#define PH0_0_2_1 0x09
#define PH0_0_2_2 0x0a
#define PH0_0_2_3 0x0b
#define PH0_0_3_2 0x0e
#define PH0_0_3_3 0x0f
#define PH0_1_1_0 0x14
#define PH0_1_1_1 0x15
#define PH0_2_1_2 0x26
#define PH0_2_2_1 0x29
#define PH0_2_2_2 0x2a
#define PH0_2_2_3 0x2b
#define PH0_2_3_2 0x2e
#define PH0_2_3_3 0x2f
#define PH0_3_2_2 0x3a
#define PH0_3_3_3 0x3f
#define PH1_0_0_0 0x40
#define PH1_0_0_1 0x41
#define PH1_0_1_1 0x45
#define PH1_1_1_1 0x55
#define PH1_2_1_1 0x65
#define PH1_2_2_1 0x69
#define PH2_1_1_1 0x95
#define PH2_1_2_1 0x99
#define PH2_1_2_2 0x9a
#define PH2_2_1_2 0xa6
#define PH2_2_2_1 0xa9
#define PH2_2_2_2 0xaa
#define PH2_2_3_2 0xae
#define PH2_2_3_3 0xaf
#define PH2_3_2_2 0xba
#define PH2_3_2_3 0xbb
#define PH2_3_3_2 0xbe
#define PH3_2_2_3 0xeb
#define PH3_2_3_2 0xee
#define PH3_2_3_3 0xef
#define PH3_3_3_3 0xff
#define PT894_RDRDY_TBL_Width 10
#define PT894_RDRDY_TBL_Block 60
static const u8 PT894_128bit_DELAYMD0_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
// -----------------------------------------------------------------------------------------------------------------
// RX60 RX61 RX62 RX63 RX64 RX65 RX66 RX67 RX54[3,1] RX55[3,1] CPU/DRAM
// LN4:1 LN8:5 LN10:9 QW4:1 QW8:5 QW10:9 WS8:1 WS10:9 RFASTH RRRDYH3E
// RCONV RHTSEL
// -----------------------------------------------------------------------------------------------------------------
{
// cpu100
{
{PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/100
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/133
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 100/333
},
// cpu133
{
{PH0_2_2_1, PH0_0_0_0, PH0_0_0_0, PH0_2_2_1, PH0_0_0_0, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T}, // 133/100
{PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/133
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 133/333
},
// cpu200
{
{PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T}, // 200/100
{PH2_3_2_3, PH0_0_0_0, PH0_0_0_0, PH2_3_2_3, PH0_0_0_0, PH0_0_0_0, 0x0a, 0x00, Rx54E3T, Rx55E3T}, // 200/133
{PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T}, // 200/166
{PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 200/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 200/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 200/333
},
// cpu166
{
{PH0_2_3_3, PH0_0_0_0, PH0_0_0_0, PH0_2_2_3, PH0_0_0_0, PH0_0_0_0, 0x05, 0x00, Rx54E3T, Rx55E3T}, // 166/100
{PH1_2_2_1, PH0_0_0_0, PH0_0_0_0, PH1_2_2_1, PH0_0_0_0, PH0_0_0_0, 0x01, 0x00, Rx54E3T, Rx55E3T}, // 166/133
{PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 166/333
},
// cpu266
{
{PH0_2_2_3, PH0_0_0_0, PH0_0_0_0, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T}, // 266/100
{PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T}, // 266/133
{PH3_2_3_3, PH0_0_0_3, PH0_0_0_0, PH3_2_3_3, PH0_0_0_2, PH0_0_0_0, 0x0d, 0x00, Rx54E3T, Rx55E3T}, // 266/166
{PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH2_1_2_2, PH0_0_1_2, PH0_0_0_0, 0x12, 0x00, Rx54E3T, Rx55E3T}, // 266/200
{PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 266/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 266/333
},
// cpu333
{
{PH0_1_1_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T}, // 333/100
{PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T}, // 333/133
{PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, 0x1f, 0x00, Rx54E2T, Rx55E2T}, // 333/166
{PH2_2_1_2, PH0_0_2_1, PH0_0_0_0, PH1_2_1_1, PH0_0_2_1, PH0_0_0_0, 0x36, 0x00, Rx54E2T, Rx55E2T}, // 333/200
{PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, 0x44, 0x00, Rx54E3T, Rx55E3T}, // 333/266
{PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0x00, 0x00, Rx54E3T, Rx55E3T} // 333/333
}
};
static const u8 PT894_128bit_DELAYMD1_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
// -----------------------------------------------------------------------------------------------------------------
// RX60 RX61 RX62 RX63 RX64 RX65 RX66 RX67 RX54[3,1] RX55[3,1] CPU/DRAM
// LN4:1 LN8:5 LN10:9 QW4:1 QW8:5 QW10:9 WS8:1 WS10:9 RFASTH RRRDYH3E
// RCONV RHTSEL
// -----------------------------------------------------------------------------------------------------------------
{
// cpu100
{
{PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/100
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/133
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 100/333
},
// cpu133
{
{PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, 0x02, 0x00, Rx54E3T, Rx55E3T}, // 133/100
{PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/133
{PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 133/333
},
// cpu200
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T}, // 200/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH2_1_2_1, PH0_0_0_0, PH0_0_0_0, 0x0a, 0x00, Rx54E2T, Rx55E2T}, // 200/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x04, 0x00, Rx54E3T, Rx55E3T}, // 200/166
{PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 200/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 200/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 200/333
},
// cpu166
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_2_1_2, PH0_0_0_0, PH0_0_0_0, 0x05, 0x00, Rx54E2T, Rx55E2T}, // 166/100
{PH2_3_2_2, PH0_0_0_0, PH0_0_0_0, PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, 0x02, 0x00, Rx54E3T, Rx55E3T}, // 166/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/166
{PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 166/333
},
// cpu266
{
{PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T}, // 266/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T}, // 266/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_1_2, PH0_0_0_2, PH0_0_0_0, 0x15, 0x00, Rx54E2T, Rx55E2T}, // 266/166
{PH3_2_3_3, PH0_0_2_3, PH0_0_0_0, PH2_2_3_2, PH0_0_2_3, PH0_0_0_0, 0x24, 0x00, Rx54E3T, Rx55E3T}, // 266/200
{PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 266/266
{PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 266/333
},
// cpu333
{
{PH0_3_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T}, // 333/100
{PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E0T, Rx55E0T}, // 333/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x1f, 0x00, Rx54E1T, Rx55E1T}, // 333/166
{PH2_3_2_2, PH0_0_3_2, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x1b, 0x00, Rx54E2T, Rx55E2T}, // 333/200
{PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH2_2_2_1, PH2_2_2_1, PH0_0_0_0, 0x88, 0x00, Rx54E3T, Rx55E3T}, // 333/266
{PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0x00, 0x00, Rx54E3T, Rx55E3T} // 333/333
}
};
static const u8 PT894_64bit_DELAYMD0_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
// -----------------------------------------------------------------------------------------------------------------
// RX60 RX61 RX62 RX63 RX64 RX65 RX66 RX67 RX54[3,1] RX55[3,1] CPU/DRAM
// LN4:1 LN8:5 LN10:9 QW4:1 QW8:5 QW10:9 WS8:1 WS10:9 RFASTH RRRDYH3E
// RCONV RHTSEL
// -----------------------------------------------------------------------------------------------------------------
{
// cpu100
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T}, // 100/100
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x09, 0x00, Rx54E3T, Rx55E3T}, // 100/133
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 100/333
},
// cpu133
{
{PH0_2_3_2, PH0_0_0_0, PH0_0_0_0, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T}, // 133/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E3T, Rx55E3T}, // 133/133
{PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T}, // 133/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 133/333
},
// cpu200
{
{PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E0T, Rx55E0T}, // 200/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T}, // 200/133
{PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH1_2_2_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T}, // 200/166
{PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x3f, 0x00, Rx54E3T, Rx55E3T}, // 200/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E1T, Rx55E1T}, // 200/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 200/333
// DDR2 Both E3T and E2T Fail, need set to E1T, db PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 00110011b, 00000000b, Rx54E3T, Rx55E3T; 200/266
},
// cpu166
{
{PH0_2_3_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T}, // 166/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T}, // 166/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH1_1_1_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T}, // 166/166
{PH1_0_0_1, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1e, 0x00, Rx54E3T, Rx55E3T}, // 166/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 166/333
},
// cpu266
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54L1T, Rx55L1T}, // 266/100
{PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T}, // 266/133
{PH3_2_3_2, PH0_0_0_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E1T, Rx55E1T}, // 266/166
{PH3_2_2_3, PH0_0_2_2, PH0_0_0_0, PH1_0_0_1, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E2T, Rx55E2T}, // 266/200
{PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, PH1_1_1_1, PH1_1_1_1, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T}, // 266/266
{PH0_0_1_1, PH0_1_1_1, PH0_0_1_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x9c, 0x03, Rx54E3T, Rx55E3T} // 266/333
},
// cpu333
{
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T}, // 333/100; DO NOT Support
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T}, // 333/133
{PH3_3_3_3, PH0_0_0_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E0T, Rx55E0T}, // 333/166
{PH2_3_3_2, PH0_0_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E1T, Rx55E1T}, // 333/200
{PH3_3_3_3, PH3_3_3_3, PH0_0_0_0, PH2_1_1_1, PH2_1_1_1, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T}, // 333/266
{PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0xff, 0x03, Rx54E3T, Rx55E3T} // 333/333
}
};
static const u8 PT894_64bit_DELAYMD1_RCONV0[6][6][PT894_RDRDY_TBL_Width] =
// -----------------------------------------------------------------------------------------------------------------
// RX60 RX61 RX62 RX63 RX64 RX65 RX66 RX67 RX54[3,1] RX55[3,1] CPU/DRAM
// LN4:1 LN8:5 LN10:9 QW4:1 QW8:5 QW10:9 WS8:1 WS10:9 RFASTH RRRDYH3E
// RCONV RHTSEL
// -----------------------------------------------------------------------------------------------------------------
{
// cpu100
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E3T, Rx55E3T}, // 100/100
{PH1_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x06, 0x00, Rx54E3T, Rx55E3T}, // 100/133
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 100/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 100/333
},
// cpu133
{
{PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E2T, Rx55E2T}, // 133/100
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH1_1_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E3T, Rx55E3T}, // 133/133
{PH1_0_1_1, PH0_0_0_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1c, 0x00, Rx54E3T, Rx55E3T}, // 133/166
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x09, 0x00, Rx54E3T, Rx55E3T}, // 133/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 133/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 133/333
},
// cpu200
{
{PH0_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54L1T, Rx55L1T}, // 200/100
{PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E1T, Rx55E1T}, // 200/133
{PH2_2_3_3, PH0_0_0_2, PH0_0_0_0, PH1_0_1_1, PH0_0_0_1, PH0_0_0_0, 0x1f, 0x00, Rx54E2T, Rx55E2T}, // 200/166
{PH3_3_3_3, PH0_0_3_3, PH0_0_0_0, PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, 0x3f, 0x00, Rx54E3T, Rx55E3T}, // 200/200
{PH0_0_1_1, PH0_0_1_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0xcc, 0x00, Rx54E3T, Rx55E3T}, // 200/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 200/333
},
// cpu166
{
{PH0_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x07, 0x00, Rx54E1T, Rx55E1T}, // 166/100
{PH2_2_3_3, PH0_0_0_0, PH0_0_0_0, PH1_0_1_1, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54E2T, Rx55E2T}, // 166/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, 0x1f, 0x00, Rx54E3T, Rx55E3T}, // 166/166
{PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, PH1_0_0_0, PH0_0_0_1, PH0_0_0_0, 0x39, 0x00, Rx54E3T, Rx55E3T}, // 166/200
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T}, // 166/266
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54E3T, Rx55E3T} // 166/333
},
// cpu266
{
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T}, // 266/100; DO NOT Support
{PH2_2_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T}, // 266/133
{PH2_2_1_2, PH0_0_0_1, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54E0T, Rx55E0T}, // 266/166
{PH3_3_3_3, PH0_0_3_3, PH0_0_0_0, PH1_1_1_1, PH0_0_1_1, PH0_0_0_0, 0x3f, 0x00, Rx54E2T, Rx55E2T}, // 266/200
{PH3_3_3_3, PH3_3_3_3, PH0_0_0_0, PH2_2_2_2, PH2_2_2_2, PH0_0_0_0, 0xff, 0x00, Rx54E3T, Rx55E3T}, // 266/266
{PH1_1_1_1, PH1_1_1_1, PH0_0_1_1, PH0_0_0_1, PH0_0_1_1, PH0_0_1_0, 0x73, 0x02, Rx54E3T, Rx55E3T} // 266/333
},
// cpu333
{
{PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x00, 0x00, Rx54L1T, Rx55L1T}, // 333/100; DO NOT Support
{PH3_3_3_3, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x0f, 0x00, Rx54L1T, Rx55L1T}, // 333/133
{PH2_2_2_2, PH0_0_0_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x1f, 0x00, Rx54L1T, Rx55L1T}, // 333/166
{PH2_2_2_2, PH0_0_2_2, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, PH0_0_0_0, 0x3f, 0x00, Rx54E1T, Rx55E1T}, // 333/200
{PH2_3_2_2, PH2_3_2_2, PH0_0_0_0, PH0_1_1_0, PH0_1_1_0, PH0_0_0_0, 0xff, 0x00, Rx54E2T, Rx55E2T}, // 333/266
{PH3_3_3_3, PH3_3_3_3, PH0_0_3_3, PH2_2_2_2, PH2_2_2_2, PH0_0_2_2, 0xff, 0x03, Rx54E3T, Rx55E3T} // 333/333
}
};
void DRAMDRDYSetting(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
/*
this function has 3 switchs, correspond to 3 level of Drdy setting.
0:Slowest, 1:Default, 2:Optimize
you can only open one switch
*/
#if 1 //this is slowest
// 0 -> Slowest
//Write slowest value to register
Data = 0xAA;
pci_write_config8(PCI_DEV(0, 0, 2), 0x60, Data);
Data = 0x0A;
pci_write_config8(PCI_DEV(0, 0, 2), 0x61, Data);
Data = 0x00;
pci_write_config8(PCI_DEV(0, 0, 2), 0x62, Data);
Data = 0xAA;
pci_write_config8(PCI_DEV(0, 0, 2), 0x63, Data);
Data = 0x0A;
pci_write_config8(PCI_DEV(0, 0, 2), 0x64, Data);
Data = 0x00;
pci_write_config8(PCI_DEV(0, 0, 2), 0x65, Data);
Data = 0x00;
pci_write_config8(PCI_DEV(0, 0, 2), 0x66, Data);
Data = 0x00;
pci_write_config8(PCI_DEV(0, 0, 2), 0x67, Data);
Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x54);
Data = Data & 0xF5;
Data |= 0x08;
pci_write_config8(PCI_DEV(0, 0, 2), 0x54, Data);
//enable drdy timing
Data = pci_read_config8(PCI_DEV(0, 0, 2), 0x51);
Data = Data | 0x80;
pci_write_config8(PCI_DEV(0, 0, 2), 0x51, Data);
#endif
}
/*This routine process the ability for North Bridge side burst functionality
There are 3 variances that are valid:
1. DIMM BL = 8, chipset BL = 8
2. DIMM BL = 4, chipset BL = 4
3. DIMM BL = 4, chipset BL = 8 (only happened on Dual channel)
Device 0 function 2 HOST:REG54[4] must be 1 when 128-bit mode.
Since DIMM will be initialized in each rank individually,
1.If all DIMM BL = 4, DIMM will initialize BL = 4 first,
then check dual_channel flag to enable VIA_NB2HOST_REG54[4].
2.If all DIMM BL = 8, DIMM will initialize BL = 8 first,
then check dual_channel flag for re-initialize DIMM BL = 4.
also VIA_NB2HOST_REG54[4] need to be enabled.
Chipset_BL8==>chipset side can set burst length = 8
two register need to set
1. Device 0 function 2 HOST:REG54[4]
2. Device 0 function 3 DRAM:REG6C[3]
*/
void DRAMBurstLength(DRAM_SYS_ATTR * DramAttr)
{
u8 Data, BL;
u8 Sockets;
/*SPD byte16 bit3,2 describes the burst length supported. bit3 = 1 support BL = 8 bit2 = 1 support BL = 4 */
BL = 0x0c;
for (Sockets = 0; Sockets < 2; Sockets++) {
if (DramAttr->DimmInfo[Sockets].bPresence) {
BL &=
(DramAttr->
DimmInfo[Sockets].SPDDataBuf
[SPD_SDRAM_BURSTLENGTH]);
}
}
/*D0F3Rx6c bit3 CHA SDRAM effective burst length, for 64bit mode ranks =0 BL = 4; =1 BL = 8 */
if (BL & 0x08) /*All Assembly support BL = 8 */
BL = 0x8; /*set bit3 */
else
BL = 0x00; /*clear bit3 */
Data = pci_read_config8(MEMCTRL, 0x6c);
Data = (u8) ((Data & 0xf7) | BL);
#if ENABLE_CHB
if (DramAttr->RankNumChB > 0) {
BL = DramAttr->DimmInfo[2].SPDDataBuf[SPD_SDRAM_BURSTLENGTH];
//Rx6c[1], CHB burst length
if (BL & 0x08) /*CHB support BL = 8 */
BL = 0x2; /*set bit1 */
else
BL = 0x00; /*clear bit1 */
Data = (Data & 0xFD) | BL;
}
#endif
pci_write_config8(MEMCTRL, 0x6c, Data);
}

View File

@ -1,34 +0,0 @@
/*
* 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.
*/
#ifndef DRIVINGCLKPHASEDATA_H
#define DRIVINGCLKPHASEDATA_H
#define MA_Table 3
#define DUTY_CYCLE_FREQ_NUM 6
#define DUTY_CYCLE_REG_NUM 3
#define Clk_Phase_Table_DDR2_Width 6
#define WrtData_REG_NUM 4
#define WrtData_FREQ_NUM 6
#define DQ_DQS_Delay_Table_Width 4
#define DQS_INPUT_CAPTURE_REG_NUM 3
#define DQS_INPUT_CAPTURE_FREQ_NUM 6
#endif /* DRIVINGCLKPHASEDATA_H */

View File

@ -1,382 +0,0 @@
/*
* 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.
*/
/*
Driving setting: ODT/DQS/DQ/CS/MAA/MAB/DCLK
*/
void DrivingODT(DRAM_SYS_ATTR * DramAttr);
void DrivingDQS(DRAM_SYS_ATTR * DramAttr);
void DrivingDQ(DRAM_SYS_ATTR * DramAttr);
void DrivingCS(DRAM_SYS_ATTR * DramAttr);
void DrivingMA(DRAM_SYS_ATTR * DramAttr);
void DrivingDCLK(DRAM_SYS_ATTR * DramAttr);
/* DRAM Driving Adjustment*/
void DRAMDriving(DRAM_SYS_ATTR * DramAttr)
{
PRINT_DEBUG_MEM("set ODT!\r");
DrivingODT(DramAttr);
PRINT_DEBUG_MEM("set DQS!\r");
DrivingDQS(DramAttr);
PRINT_DEBUG_MEM(("set DQ!\r"));
DrivingDQ(DramAttr);
PRINT_DEBUG_MEM("set CS!\r");
DrivingCS(DramAttr);
PRINT_DEBUG_MEM("set MAA!\r");
DrivingMA(DramAttr);
PRINT_DEBUG_MEM("set DCLK!\r");
DrivingDCLK(DramAttr);
}
/*
ODT Control for DQ/DQS/CKE/SCMD/DCLKO in ChA & ChB
which include driving enable/range and strong/weak selection
Processing: According to DRAM frequency to ODT control bits.
Because function enable bit must be the last one to be set.
So the register VIA_NB3DRAM_REGD4 and VIA_NB3DRAM_REGD3 should be
the last register to be programmed.
*/
//-------------------------------------------------------------------------------
// ODT Lookup Table
//-------------------------------------------------------------------------------
#define Rank0_ODT 0
#define Rank1_ODT 1
#define Rank2_ODT 2
#define Rank3_ODT 3
#define NA_ODT 0
#define NB_ODT_75ohm 0
#define NB_ODT_150ohm 1
#define DDR2_ODT_75ohm 0x20
#define DDR2_ODT_150ohm 0x40
// Setting of ODT Lookup TBL
// RankMAP , Rank 3 Rank 2 Rank 1 Rank 0 , DRAM & NB ODT setting
// db 0000b , Reserved
#define ODTLookup_Tbl_count 8
static const u8 ODTLookup_TBL[ODTLookup_Tbl_count][3] = {
// 0001b
{0x01,
(Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
// 0010b , Reserved
// 0011b
{0x03,
(Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank0_ODT << 2) +
Rank1_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
// 0100b
{0x04,
(Rank3_ODT << 6) + (Rank2_ODT << 4) + (Rank1_ODT << 2) +
Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
// 0101b
{0x05,
(Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
// 0110b , Reserved
// 0111b
{0x07,
(Rank3_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
// 1000b , Reserved
// 1001b , Reserved
// 1010b , Reserved
// 1011b , Reserved
// 1100b
{0x0c,
(Rank2_ODT << 6) + (Rank3_ODT << 4) + (Rank1_ODT << 2) +
Rank0_ODT, DDR2_ODT_150ohm + NB_ODT_75ohm},
// 1101b
{0x0d,
(Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank1_ODT << 2) +
Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm},
// 1110b , Reserved
// 1111b
{0x0f,
(Rank0_ODT << 6) + (Rank0_ODT << 4) + (Rank2_ODT << 2) +
Rank2_ODT, DDR2_ODT_75ohm + NB_ODT_150ohm}
};
#define ODT_Table_Width_DDR2 4
// RxD6 RxD3
static const u8 ODT_Control_DDR2[ODT_Table_Width_DDR2] = { 0xFC, 0x01 };
void DrivingODT(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u8 i;
BOOLEAN bFound;
pci_write_config8(MEMCTRL, 0xD0, 0x88);
Data = ODT_Control_DDR2[0];
pci_write_config8(MEMCTRL, 0xd6, Data);
Data = ODT_Control_DDR2[1];
pci_write_config8(MEMCTRL, 0xd3, Data);
Data = pci_read_config8(MEMCTRL, 0x9e);
//set MD turn_around wait state
Data &= 0xCF; /*clear bit4,5 */
if (DIMMFREQ_400 == DramAttr->DramFreq)
Data |= 0x0;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
Data |= 0x10;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
Data |= 0x20;
else if (DIMMFREQ_800 == DramAttr->DramFreq)
Data |= 0x20;
else
Data |= 0;
pci_write_config8(MEMCTRL, 0x9e, Data);
if (DIMMFREQ_400 == DramAttr->DramFreq)
Data = 0x0;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
Data = 0x11;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
Data = 0x11;
else if (DIMMFREQ_800 == DramAttr->DramFreq)
Data = 0x11;
else
Data = 0;
pci_write_config8(MEMCTRL, 0x9f, Data);
/*channel A ODT select */
if (DramAttr->DimmNumChA > 0) {
Data = pci_read_config8(MEMCTRL, 0xd5);
Data &= 0x5F; /*clear bit7,5 */
if (DramAttr->RankNumChA > 2)
Data |= 0xA0; /*if rank number > 2 (3or4), set bit7,5 */
else
Data |= 0x00; /*if rank number is 1or2, clear bit5 */
pci_write_config8(MEMCTRL, 0xd5, Data);
Data = pci_read_config8(MEMCTRL, 0xd7);
Data &= 0xEF; /*clear bit7 */
if (DramAttr->RankNumChA > 2)
Data |= 0x80; /*if rank number > 2 (3or4), set bit7 */
else
Data |= 0x00; /*if rank number is 1or2, clear bit7 */
pci_write_config8(MEMCTRL, 0xd7, Data);
/*channel A */
Data = pci_read_config8(MEMCTRL, 0xd5);
Data &= 0xF3; //bit2,3
if (DramAttr->DimmNumChA == 2) /*2 Dimm, 3or4 Ranks */
Data |= 0x00;
else if (DramAttr->DimmNumChA == 1)
Data |= 0x04;
pci_write_config8(MEMCTRL, 0xd5, Data);
if ((DramAttr->RankPresentMap & 0x0F) != 0) { /*channel A */
// MAA ODT Lookup Table
bFound = FALSE;
for (i = 0; i < ODTLookup_Tbl_count; i++) {
if ((DramAttr->RankPresentMap & 0x0F) ==
ODTLookup_TBL[i][0]) {
Data = ODTLookup_TBL[i][1];
bFound = TRUE;
}
}
if (!bFound) { /*set default value */
Data =
ODTLookup_TBL[ODTLookup_Tbl_count - 1][1];
}
pci_write_config8(MEMCTRL, 0x9c, Data);
//set CHA MD ODT control State Dynamic-on
Data = pci_read_config8(MEMCTRL, 0xD4);
Data &= 0xC9;
Data |= 0x30;
pci_write_config8(MEMCTRL, 0xD4, Data);
Data = pci_read_config8(MEMCTRL, 0x9e);
Data |= 0x01;
pci_write_config8(MEMCTRL, 0x9e, Data);
}
}
/*channel B */
if (1 == ENABLE_CHC) {
//CHB has not auto compensation mode ,so must set it manual,or else CHB initialization will not successful
Data = pci_read_config8(MEMCTRL, 0xd5);
Data &= 0xAF;
if (DramAttr->RankNumChB > 2) /*rank number 3 or 4 */
Data |= 0x50;
else
Data |= 0x00;
pci_write_config8(MEMCTRL, 0xd5, Data);
Data = pci_read_config8(MEMCTRL, 0xd7);
Data &= 0xBF; /*clear bit6 */
if (DramAttr->RankNumChB > 2)
Data |= 0x40; /*if rank number > 2 (3or4), set bit7 */
else
Data |= 0x00; /*if rank number is 1or2, clear bit7 */
pci_write_config8(MEMCTRL, 0xd7, Data);
Data = pci_read_config8(MEMCTRL, 0xd5);
Data &= 0xFC;
if (DramAttr->DimmNumChB == 2) /*2 Dimm, 3or4 Ranks */
Data |= 0x00; // 2 dimm RxD5[2,0]=0,0b
else if (DramAttr->DimmNumChB == 1)
Data |= 0x01; // 1 dimm RxD5[2,0]=1,1b
pci_write_config8(MEMCTRL, 0xd5, Data);
//set CHB MD ODT control State Dynamic-on
Data = pci_read_config8(MEMCTRL, 0xD4);
Data &= 0xF6;
Data |= 0x08;
pci_write_config8(MEMCTRL, 0xD4, Data);
//enable CHB differential DQS input
Data = pci_read_config8(MEMCTRL, 0x9E);
Data |= 0x02;
pci_write_config8(MEMCTRL, 0x9E, Data);
}
//enable ODT Control
Data = pci_read_config8(MEMCTRL, 0x9e);
Data |= 0x80;
pci_write_config8(MEMCTRL, 0x9e, Data);
}
void DrivingDQS(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
/*channel A */
if (DramAttr->RankNumChA > 0) {
Data = DDR2_DQSA_Driving_Table[DramAttr->RankNumChA - 1];
pci_write_config8(MEMCTRL, 0xe0, Data);
}
/*channel B */
if (1 == ENABLE_CHC) {
Data = DDR2_DQSB_Driving_Table[DramAttr->RankNumChB - 1];
pci_write_config8(MEMCTRL, 0xe1, Data);
}
}
void DrivingDQ(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
/*channel A */
if (DramAttr->RankNumChA > 0) {
Data = DDR2_DQA_Driving_Table[DramAttr->RankNumChA - 1];
pci_write_config8(MEMCTRL, 0xe2, Data);
}
/*channel B */
if (1 == ENABLE_CHC) {
Data = DDR2_DQB_Driving_Table[DramAttr->RankNumChB - 1];
pci_write_config8(MEMCTRL, 0xe3, Data);
}
}
void DrivingCS(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
/*Channel A */
if (DramAttr->RankNumChA > 0) {
Data = DDR2_CSA_Driving_Table_x8[DramAttr->RankNumChA - 1];
pci_write_config8(MEMCTRL, 0xe4, Data);
}
/*channel B */
if (1 == ENABLE_CHC) {
Data = DDR2_CSB_Driving_Table_x8[DramAttr->RankNumChB - 1];
pci_write_config8(MEMCTRL, 0xe5, Data);
}
}
void DrivingMA(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u8 i, FreqId;
if (DramAttr->RankNumChA > 0) {
if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 1;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 3;
else if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 4;
else
FreqId = 1;
for (i = 0; i < MA_Table; i++) {
if (DramAttr->LoadNumChA <=
DDR2_MAA_Driving_Table[i][0]) {
Data = DDR2_MAA_Driving_Table[i][FreqId];
break;
}
}
pci_write_config8(MEMCTRL, 0xe8, Data);
}
if (1 == ENABLE_CHC) {
for (i = 0; i < MA_Table; i++) {
if (DramAttr->LoadNumChA <=
DDR2_MAB_Driving_Table[i][0]) {
Data = DDR2_MAB_Driving_Table[i][1];
break;
}
}
pci_write_config8(MEMCTRL, 0xe9, Data);
}
}
void DrivingDCLK(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u8 FreqId;
if (DIMMFREQ_400 == DramAttr->DramFreq)
FreqId = 0;
else if (DIMMFREQ_533 == DramAttr->DramFreq)
FreqId = 1;
else if (DIMMFREQ_667 == DramAttr->DramFreq)
FreqId = 2;
else if (DIMMFREQ_800 == DramAttr->DramFreq)
FreqId = 3;
else
FreqId = 0;
/*channel A */
if (DramAttr->RankNumChA > 0) {
Data = DDR2_DCLKA_Driving_Table[FreqId];
pci_write_config8(MEMCTRL, 0xe6, Data);
}
/*channel B */
if (1 == ENABLE_CHC) {
Data = DDR2_DCLKB_Driving_Table[FreqId];
pci_write_config8(MEMCTRL, 0xe7, Data);
}
}

View File

@ -1,94 +0,0 @@
/*
* 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.
*/
/*
* Enable the serial devices on the VIA
*/
#include <arch/io.h>
/* The base address is 0x15c, 0x2e, depending on config bytes */
#define SIO_BASE 0x3f0
#define SIO_DATA SIO_BASE+1
static void vx800_writepnpaddr(uint8_t val)
{
outb(val, 0x2e);
outb(val, 0xeb);
}
static void vx800_writepnpdata(uint8_t val)
{
outb(val, 0x2f);
outb(val, 0xeb);
}
static void vx800_writesiobyte(uint16_t reg, uint8_t val)
{
outb(val, reg);
}
static void vx800_writesioword(uint16_t reg, uint16_t val)
{
outw(val, reg);
}
/* regs we use: 85, and the southbridge devfn is defined by the
mainboard
*/
void enable_vx800_serial(void)
{
post_code(0x06);
outb(0x03, 0x22);
// turn on pnp
vx800_writepnpaddr(0x87);
vx800_writepnpaddr(0x87);
// now go ahead and set up com1.
// set address
vx800_writepnpaddr(0x7);
vx800_writepnpdata(0x2);
// enable serial out
vx800_writepnpaddr(0x30);
vx800_writepnpdata(0x1);
// serial port 1 base address (FEh)
vx800_writepnpaddr(0x60);
vx800_writepnpdata(0xfe);
// serial port 1 IRQ (04h)
vx800_writepnpaddr(0x70);
vx800_writepnpdata(0x4);
// serial port 1 control
vx800_writepnpaddr(0xf0);
vx800_writepnpdata(0x2);
// turn of pnp
vx800_writepnpaddr(0xaa);
// set up reg to set baud rate.
vx800_writesiobyte(0x3fb, 0x80);
// Set 115 kb
vx800_writesioword(0x3f8, 1);
// Set 9.6 kb
// WRITESIOWORD(0x3f8, 12)
// now set no parity, one stop, 8 bits
vx800_writesiobyte(0x3fb, 3);
// now turn on RTS, DRT
vx800_writesiobyte(0x3fc, 3);
// Enable interrupts
vx800_writesiobyte(0x3f9, 0xf);
// should be done. Dump a char for fun.
vx800_writesiobyte(0x3f8, 48);
post_code(0x07);
}

View File

@ -1,236 +0,0 @@
/*
* 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.
*/
#include <device/pci_ids.h>
#include "vx800.h"
#define SMBUS_IO_BASE 0x0500 //from award bios
#define PMIO_BASE VX800_ACPI_IO_BASE //might as well set this while we're here
#define SMBHSTSTAT SMBUS_IO_BASE + 0x0
#define SMBSLVSTAT SMBUS_IO_BASE + 0x1
#define SMBHSTCTL SMBUS_IO_BASE + 0x2
#define SMBHSTCMD SMBUS_IO_BASE + 0x3
#define SMBXMITADD SMBUS_IO_BASE + 0x4
#define SMBHSTDAT0 SMBUS_IO_BASE + 0x5
#define SMBHSTDAT1 SMBUS_IO_BASE + 0x6
/* Rest of these aren't currently used... */
#define SMBBLKDAT SMBUS_IO_BASE + 0x7
#define SMBSLVCTL SMBUS_IO_BASE + 0x8
#define SMBTRNSADD SMBUS_IO_BASE + 0x9
#define SMBSLVDATA SMBUS_IO_BASE + 0xa
#define SMLINK_PIN_CTL SMBUS_IO_BASE + 0xe
#define SMBUS_PIN_CTL SMBUS_IO_BASE + 0xf
/* Define register settings */
#define HOST_RESET 0xff
#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
#define SMBUS_TIMEOUT (100*1000*10)
#define I2C_TRANS_CMD 0x40
#define CLOCK_SLAVE_ADDRESS 0x69
#define SMBUS_DELAY() outb(0x80, 0x80)
#if IS_ENABLED(CONFIG_DEBUG_SMBUS)
#define DEBUG(x...) printk(BIOS_DEBUG, x)
#else
#define DEBUG(x...) while (0) { }
#endif
/* Internal functions */
static void smbus_print_error(unsigned char host_status_register, int loops)
{
/* Check if there actually was an error */
if (host_status_register == 0x00 || host_status_register == 0x40 ||
host_status_register == 0x42)
return;
printk(BIOS_ERR, "smbus_error: %02x\n", host_status_register);
if (loops >= SMBUS_TIMEOUT) {
printk(BIOS_ERR, "SMBus Timout\n");
}
if (host_status_register & (1 << 4)) {
printk(BIOS_ERR, "Interrup/SMI# was Failed Bus Transaction\n");
}
if (host_status_register & (1 << 3)) {
printk(BIOS_ERR, "Bus Error\n");
}
if (host_status_register & (1 << 2)) {
printk(BIOS_ERR, "Device Error\n");
}
if (host_status_register & (1 << 1)) {
/* This isn't a real error... */
printk(BIOS_DEBUG, "Interrupt/SMI# was Successful Completion\n");
}
if (host_status_register & (1 << 0)) {
printk(BIOS_ERR, "Host Busy\n");
}
}
static void smbus_wait_until_ready(void)
{
int loops;
loops = 0;
/* Yes, this is a mess, but it's the easiest way to do it */
while (((inb(SMBHSTSTAT) & 1) == 1) && (loops <= SMBUS_TIMEOUT)) {
SMBUS_DELAY();
++loops;
}
smbus_print_error(inb(SMBHSTSTAT), loops);
}
static void smbus_reset(void)
{
outb(HOST_RESET, SMBHSTSTAT);
}
/* Public functions */
static unsigned int get_spd_data(unsigned int dimm, unsigned int offset)
{
unsigned int val;
smbus_reset();
/* clear host data port */
outb(0x00, SMBHSTDAT0);
SMBUS_DELAY();
smbus_wait_until_ready();
/* Do some mathmatic magic */
dimm = (DIMM0 + dimm) << 1;
outb(dimm | 0x1, SMBXMITADD);
outb(offset, SMBHSTCMD);
outb(0x48, SMBHSTCTL);
SMBUS_DELAY();
smbus_wait_until_ready();
val = inb(SMBHSTDAT0);
smbus_reset();
return val;
}
void enable_smbus(void)
{
pci_devfn_t dev;
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855_LPC), 0);
if (dev == PCI_DEV_INVALID) {
/* This won't display text if enable_smbus() is before serial init */
die("Power Managment Controller not found\n");
}
/* Set clock source */
pci_write_config8(dev, 0x94, 0x20);
/* Write SMBus IO base to 0xd0, and enable SMBus */
pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1);
/* Set to Award value */
pci_write_config8(dev, 0xd2, 0x05);
/* Make it work for I/O ... */
pci_write_config16(dev, 0x04, 0x0003);
smbus_reset();
/* clear host data port */
outb(0x00, SMBHSTDAT0);
SMBUS_DELAY();
smbus_wait_until_ready();
}
/**
* A fixup for some systems that need time for the SMBus to "warm up". This is
* needed on some VT823x based systems, where the SMBus spurts out bad data for
* a short time after power on. This has been seen on the VIA Epia series and
* Jetway J7F2-series. It reads the ID byte from SMBus, looking for
* known-good data from a slot/address. Exits on either good data or a timeout.
*
* TODO: This should probably go into some global file, but one would need to
* be created just for it. If some other chip needs/wants it, we can
* worry about it then.
*
* @param mem_ctrl The memory controller and SMBus addresses.
*/
void smbus_fixup(const struct mem_controller *mem_ctrl)
{
int i, ram_slots, current_slot = 0;
u8 result = 0;
ram_slots = ARRAY_SIZE(mem_ctrl->channel0);
if (!ram_slots) {
printk(BIOS_ERR, "smbus_fixup() thinks there are no RAM slots!\n");
return;
}
DEBUG("Waiting for SMBus to warm up");
/*
* Bad SPD data should be either 0 or 0xff, but YMMV. So we look for
* the ID bytes of SDRAM, DDR, DDR2, and DDR3 (and anything in between).
* VT8237R has only been seen on DDR and DDR2 based systems, so far.
*/
for (i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) ||
(result >
SPD_MEMORY_TYPE_SDRAM_DDR3)));
i++) {
if (current_slot > ram_slots)
current_slot = 0;
result = get_spd_data(mem_ctrl->channel0[current_slot],
SPD_MEMORY_TYPE);
current_slot++;
DEBUG(".");
}
if (i >= SMBUS_TIMEOUT)
printk(BIOS_ERR, "SMBus timed out while warming up\n");
else
DEBUG("Done\n");
}
/* Debugging Function */
#if IS_ENABLED(CONFIG_DEBUG_SMBUS)
static void dump_spd_data(void)
{
int dimm, offset, regs;
unsigned int val;
for (dimm = 0; dimm < 8; dimm++) {
printk(BIOS_DEBUG, "SPD Data for DIMM %02x\n", dimm);
val = get_spd_data(dimm, 0);
if (val == 0xff) {
regs = 256;
} else if (val == 0x80) {
regs = 128;
} else {
printk(BIOS_DEBUG, "No DIMM present\n");
regs = 0;
}
for (offset = 0; offset < regs; offset++)
printk(BIOS_DEBUG, " Offset %02x = 0x%02x\n",
offset, get_spd_data(dimm, offset));
}
}
#else
#define dump_spd_data()
#endif

View File

@ -1,123 +0,0 @@
/*
* 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.
*/
static const u8 RefreshCounter[7][2] = {
//Non_256Mbit, 256Mbit
{0xCA, 0xA8}, // DRAM400
{0xCA, 0xA8}, // DRAM333
{0xCA, 0x86}, // DRAM266
{0xCA, 0x65}, // DRAM200
{0xA8, 0x54}, // DRAM166
{0x86, 0x43}, // DRAM133
{0x65, 0x32} // DRAM100
};
void DRAMRefreshCounter(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u8 Freq = 5, i, Dram_256_Mb;
if (DramAttr->DramFreq == DIMMFREQ_800)
Freq = 0;
else if (DramAttr->DramFreq == DIMMFREQ_667)
Freq = 1;
else if (DramAttr->DramFreq == DIMMFREQ_533)
Freq = 2;
else if (DramAttr->DramFreq == DIMMFREQ_400)
Freq = 3;
else if (DramAttr->DramFreq == DIMMFREQ_333)
Freq = 4;
else if (DramAttr->DramFreq == DIMMFREQ_266)
Freq = 5;
else if (DramAttr->DramFreq == DIMMFREQ_200)
Freq = 6;
else
Freq = 6;
Dram_256_Mb = 0;
for (i = 0; i < MAX_SOCKETS; i++) {
if (DramAttr->DimmInfo[i].SPDDataBuf[SPD_SDRAM_ROW_ADDR] == 13) {
Dram_256_Mb = 1;
break;
}
}
Data = RefreshCounter[Freq][Dram_256_Mb];
pci_write_config8(MEMCTRL, 0x6a, Data);
}
/*===================================================================
Function : DRAMRegFinalValue()
Precondition :
Input :
DramAttr: pointer point to DRAM_SYS_ATTR which consist the DDR and Dimm information
in MotherBoard
Output : Void
Purpose : Chipset Performance UP and other setting after DRAM Sizing
Turn on register directly to promote performance
===================================================================*/
//--------------------------------------------------------------------------
// register AND OR
//--------------------------------------------------------------------------
#define DRAM_table_item 9
static const u8 DRAM_table[DRAM_table_item][3] = {
{0x60, 0xff, 0xD0},
{0x66, 0xcf, 0x80}, // DRAMC queue > 2
{0x69, 0xff, 0x07}, // Enable multiple page
{0x95, 0x00, 0x0D},
{0x96, 0x0F, 0xA0},
{0xFB, 0x00, 0x3E},
{0xFD, 0x00, 0xA9},
{0xFE, 0x00, 0x0f},
{0xFF, 0x00, 0x3D}
};
#define PM_table_item 5
static const u8 PM_table[PM_table_item][3] = {
{0xA0, 0x0F, 0xF0},
{0xA1, 0x1F, 0xE0},
{0xA2, 0x00, 0xFE},
{0xA3, 0x7F, 0x80},
{0xA5, 0x7E, 0x81},
};
void DRAMRegFinalValue(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u8 i;
for (i = 0; i < DRAM_table_item; i++) {
Data = pci_read_config8(MEMCTRL, DRAM_table[i][0]);
Data = (u8) ((Data & DRAM_table[i][1]) | DRAM_table[i][2]);
pci_write_config8(MEMCTRL, DRAM_table[i][0], Data);
}
//enable dram By-Rank self refresh
Data = pci_read_config8(MEMCTRL, 0x96);
Data &= 0xF0;
for (i = 0x01; i < 0x10; i = i << 1) {
if ((DramAttr->RankPresentMap & i) != 0x00)
Data |= i;
}
pci_write_config8(MEMCTRL, 0x96, Data);
for (i = 0; i < PM_table_item; i++) {
Data = pci_read_config8(PCI_DEV(0, 0, 4), PM_table[i][0]);
Data = (u8) ((Data & PM_table[i][1]) | PM_table[i][2]);
pci_write_config8(PCI_DEV(0, 0, 4), PM_table[i][0], Data);
}
}

View File

@ -1,233 +0,0 @@
/*
* 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.
*/
void CalcCLAndFreq(DRAM_SYS_ATTR * DramAttr);
/*
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);
}
/*
calculate CL and dram freq
DDR1
+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+
|TBD| 4 |3.5| 3 |2.5| 2 |1.5| 1 |
+---+---+---+---+---+---+---+---+
DDR2
+---+---+---+---+---+---+---+---+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---+---+---+---+---+---+---+---+
|TBD| 6 | 5 | 4 | 3 | 2 |TBD|TBD|
+---+---+---+---+---+---+---+---+
*/
static const u8 CL_DDR1[7] = { 10, 15, 20, 25, 30, 35, 40 };
static const u8 CL_DDR2[7] = { 0, 0, 20, 30, 40, 50, 60 };
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 */
die("SPD Data Error, Can not get CL !!!! \r");
}
/*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;
}
}
if (CycTime <= 0) {
//error!
die("Error, cycle time <= 0\n");
}
/* cycle time value
0x25-->2.5ns Freq = 400 DDR800
0x30-->3.0ns Freq = 333 DDR667
0x3D-->3.75ns Freq = 266 DDR533
0x50-->5.0ns Freq = 200 DDR400
0x60-->6.0ns Freq = 166 DDR333
0x75-->7.5ns Freq = 133 DDR266
0xA0-->10.0ns Freq = 100 DDR200
*/
if (CycTime <= 0x25) {
DramAttr->DramFreq = DIMMFREQ_800;
DramAttr->DramCyc = 250;
} else if (CycTime <= 0x30) {
DramAttr->DramFreq = DIMMFREQ_667;
DramAttr->DramCyc = 300;
} else if (CycTime <= 0x3d) {
DramAttr->DramFreq = DIMMFREQ_533;
DramAttr->DramCyc = 375;
} else if (CycTime <= 0x50) {
DramAttr->DramFreq = DIMMFREQ_400;
DramAttr->DramCyc = 500;
} else if (CycTime <= 0x60) {
DramAttr->DramFreq = DIMMFREQ_333;
DramAttr->DramCyc = 600;
} else if (CycTime <= 0x75) {
DramAttr->DramFreq = DIMMFREQ_266;
DramAttr->DramCyc = 750;
} else if (CycTime <= 0xA0) {
DramAttr->DramFreq = DIMMFREQ_200;
DramAttr->DramCyc = 1000;
}
//if set the frequence mannul
PRINT_DEBUG_MEM("Dram Frequency:");
PRINT_DEBUG_MEM_HEX16(DramAttr->DramFreq);
PRINT_DEBUG_MEM(" \r");
}

View File

@ -1,202 +0,0 @@
/*
* 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.
*/
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <console/console.h>
#include <arch/io.h>
#include "vx800.h"
static const u8 idedevicepcitable[16 * 12] = {
/*
0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
0x00, 0x00, 0xA8, 0xA8, 0xF0, 0x00, 0x00, 0xB6,
0x00, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
0x00, 0xC2, 0xF9, 0x01, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
*/
0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
0x00, 0x00, 0x99, 0x20, 0xf0, 0x00, 0x00, 0x20,
0x00, 0x00, 0x17, 0xF1, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
0x00, 0xc2, 0x09, 0x01, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* Legacy BIOS XP PCI value */
/*
0x02, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
0x00, 0x00, 0xa8, 0x20, 0x00, 0x00, 0x00, 0xb6,
0x00, 0x00, 0x16, 0xF1, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
0x00, 0x02, 0x09, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
*/
/* ROM legacy BIOS on cn_8562b */
/*
0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
0x00, 0x00, 0x99, 0x20, 0x60, 0x00, 0x00, 0x20,
0x00, 0x00, 0x1E, 0xF1, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
*/
/* From legacy BIOS on c7_8562b */
/*
0x03, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
0x00, 0x00, 0x5E, 0x20, 0x60, 0x00, 0x00, 0xB6,
0x00, 0x00, 0x1E, 0xF1, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x09, 0xC4, 0x06, 0x11, 0x09, 0xC4,
0x00, 0x02, 0x09, 0x01, 0x18, 0x0C, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x01, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
*/
};
static void ide_init(struct device *dev)
{
u8 i, data;
printk(BIOS_INFO, "ide_init\n");
/* these 3 lines help to keep interl back door for DID VID SUBID untouched */
u16 data16_1, data16_2;
data16_1 = pci_read_config16(dev, 0xba);
data16_2 = pci_read_config16(dev, 0xbe);
for (i = 0; i < (16 * 12); i++) {
pci_write_config8(dev, 0x40 + i, idedevicepcitable[i]);
}
data = pci_read_config8(dev, 0x0d);
data &= 0x0f;
data |= 0x40;
pci_write_config8(dev, 0x0d, data);
//these 2 lines help to keep interl back door for DID VID SUBID untouched
pci_write_config16(dev, 0xba, data16_1);
pci_write_config16(dev, 0xbe, data16_2);
/* Force interrupts to use compat mode. */
pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
}
static struct device_operations ide_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = ide_init,
.enable = 0,
.ops_pci = 0,
};
static const struct pci_driver via_ide_driver __pci_driver = {
.ops = &ide_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_VX855_IDE,
};

View File

@ -1,350 +0,0 @@
/*
* 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.
*/
#include <arch/io.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <pc80/mc146818rtc.h>
#include <pc80/keyboard.h>
#include <pc80/i8259.h>
#include "vx800.h"
static const unsigned char pciIrqs[4] = { 0xa, 0x9, 0xb, 0xa };
static const unsigned char vgaPins[4] = { 'A', 'B', 'C', 'D' }; //only INTA
static const unsigned char slotPins[4] = { 'A', 'A', 'A', 'A' }; //all 4
static const unsigned char usbdevicePins[4] = { 'A', 'B', 'C', 'D' }; //only INTA
static const unsigned char sdioPins[4] = { 'A', 'B', 'C', 'D' }; //only INTA
static const unsigned char sd_ms_ctrl_Pins[4] = { 'B', 'C', 'D', 'A' }; //only INTA
static const unsigned char ce_ata_nf_ctrl_Pins[4] = { 'C', 'C', 'D', 'A' }; //only INTA
static const unsigned char hdacaudioPins[4] = { 'B', 'C', 'D', 'A' }; //only INTA
static unsigned char *pin_to_irq(const unsigned char *pin)
{
static unsigned char Irqs[4];
int i;
for (i = 0; i < 4; i++)
Irqs[i] = pciIrqs[pin[i] - 'A'];
return Irqs;
}
static void pci_routing_fixup(struct device *dev)
{
printk(BIOS_INFO, "%s: dev is %p\n", __FUNCTION__, dev);
/* set up PCI IRQ routing */
pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4));
pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
/* VGA */
printk(BIOS_INFO, "setting vga\n");
pci_assign_irqs(0, 0x1, pin_to_irq(vgaPins));
/* PCI slot */
printk(BIOS_INFO, "setting pci slot\n");
pci_assign_irqs(0, 0x08, pin_to_irq(slotPins));
/* PCI slot */
printk(BIOS_INFO, "setting USB Device Controller\n");
pci_assign_irqs(0, 0x0b, pin_to_irq(usbdevicePins));
/* PCI slot */
printk(BIOS_INFO, "setting SDIO Controller\n");
pci_assign_irqs(0, 0x0c, pin_to_irq(sdioPins));
/* PCI slot */
printk(BIOS_INFO, "setting SD $ MS Controller\n");
pci_assign_irqs(0, 0x0d, pin_to_irq(sd_ms_ctrl_Pins));
/* PCI slot */
printk(BIOS_INFO, "setting CE-ATA NF Controller(Card Boot)\n");
pci_assign_irqs(0, 0x0e, pin_to_irq(ce_ata_nf_ctrl_Pins));
/* PCI slot */
printk(BIOS_INFO, "setting ide\n");
/* Standard usb components */
printk(BIOS_INFO, "setting usb1-2\n");
/* sound hardware */
printk(BIOS_INFO, "setting hdac audio\n");
pci_assign_irqs(0, 0x14, pin_to_irq(hdacaudioPins));
printk(BIOS_SPEW, "%s: DONE\n", __FUNCTION__);
}
static void setup_pm(struct device *dev)
{
u16 tmp;
/* Debounce LID and PWRBTN# Inputs for 16ms. */
pci_write_config8(dev, 0x80, 0x20);
/* Set ACPI base address to IO VX800_ACPI_IO_BASE */
pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 1);
/* set ACPI irq to 9 */
pci_write_config8(dev, 0x82, 0x49);
/* Primary interupt channel, define wake events 0 = IRQ0 15 = IRQ15 1 = en. */
pci_write_config16(dev, 0x84, 0x609a); // 0x609a??
/* SMI output level to low, 7.5us throttle clock */
pci_write_config8(dev, 0x8d, 0x18);
/* GP Timer Control 1s */
pci_write_config8(dev, 0x93, 0x88);
/* Power Well */
pci_write_config8(dev, 0x94, 0x20); // 0x20??
/* 7 = stp to sust delay 1msec
* 6 = SUSST# Deasserted Before PWRGD for STD
*/
pci_write_config8(dev, 0x95, 0xc0); // 0xc1??
/* Disable GP2 & GP3 Timer */
pci_write_config8(dev, 0x98, 0);
/* GP2 Timer Counter */
pci_write_config8(dev, 0x99, 0xfb);
/* Multi Function Select 1 */
pci_write_config8(dev, 0xe4, 0x00);
/* Multi Function Select 2 */
pci_write_config8(dev, 0xe5, 0x41); //??
/* Enable ACPI access (and setup like award) */
pci_write_config8(dev, 0x81, 0x84);
/* Clear status events. */
outw(0xffff, VX800_ACPI_IO_BASE + 0x00);
outw(0xffff, VX800_ACPI_IO_BASE + 0x20);
outw(0xffff, VX800_ACPI_IO_BASE + 0x28);
outl(0xffffffff, VX800_ACPI_IO_BASE + 0x30);
/* Disable SCI on GPIO. */
outw(0x0, VX800_ACPI_IO_BASE + 0x22);
/* Disable SMI on GPIO. */
outw(0x0, VX800_ACPI_IO_BASE + 0x24);
/* Disable all global enable SMIs. */
outw(0x0, VX800_ACPI_IO_BASE + 0x2a);
/* All SMI off, both IDE buses ON, PSON rising edge. */
outw(0x0, VX800_ACPI_IO_BASE + 0x2c);
/* Primary activity SMI disable. */
outl(0x0, VX800_ACPI_IO_BASE + 0x34);
/* GP timer reload on none. */
outl(0x0, VX800_ACPI_IO_BASE + 0x38);
/* Disable extended IO traps. */
outb(0x0, VX800_ACPI_IO_BASE + 0x42);
tmp = inw(VX800_ACPI_IO_BASE + 0x04);
/* SCI is generated for RTC/pwrBtn/slpBtn. */
tmp |= 1;
outw(tmp, VX800_ACPI_IO_BASE + 0x04);
/* Allow SLP# signal to assert LDTSTOP_L.
* Will work for C3 and for FID/VID change.
*/
outb(0x1, VX800_ACPI_IO_BASE + 0x11);
}
static void S3_ps2_kb_ms_wakeup(struct device *dev)
{
u8 enables;
enables = pci_read_config8(dev, 0x51);
enables |= 2;
pci_write_config8(dev, 0x51, enables);
outb(0xe0, 0x2e);
outb(0x0b, 0x2f); //if 09,then only support kb wakeup
outb(0xe1, 0x2e); //set any key scan code can wakeup
outb(0x00, 0x2f);
outb(0xe9, 0x2e); //set any mouse scan code can wakeup
outb(0x00, 0x2f);
enables &= 0xd;
pci_write_config8(dev, 0x51, enables);
outb(inb(VX800_ACPI_IO_BASE + 0x02) | 0x20, VX800_ACPI_IO_BASE + 0x02); //ACPI golabe enable for sci smi trigger
outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x204, VX800_ACPI_IO_BASE + 0x22); //ACPI SCI on Internal KBC PME and mouse PME
}
static void S3_usb_wakeup(struct device *dev)
{
outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x4000, VX800_ACPI_IO_BASE + 0x22); //SCI on USB PME
}
static void S3_lid_wakeup(struct device *dev)
{
outw(inw(VX800_ACPI_IO_BASE + 0x22) | 0x800, VX800_ACPI_IO_BASE + 0x22); //SCI on LID PME
}
/* This looks good enough to work, maybe */
static void vx800_sb_init(struct device *dev)
{
unsigned char enables;
// enable the internal I/O decode
enables = pci_read_config8(dev, 0x6C);
enables |= 0x80;
pci_write_config8(dev, 0x6C, enables);
// Map 4MB of FLASH into the address space
// Set bit 6 of 0x40, because Award does it (IO recovery time)
// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
// interrupts can be properly marked as level triggered.
enables = pci_read_config8(dev, 0x40);
enables |= 0x44;
pci_write_config8(dev, 0x40, enables);
/* DMA Line buffer control */
enables = pci_read_config8(dev, 0x42);
enables |= 0xf0;
pci_write_config8(dev, 0x42, enables);
/* I/O recovery time */
pci_write_config8(dev, 0x4c, 0x44);
/* ROM memory cycles go to LPC. */
pci_write_config8(dev, 0x59, 0x80);
/* Set 0x5b to 0x01 to match Award */
enables = pci_read_config8(dev, 0x5b);
enables |= 0x01;
pci_write_config8(dev, 0x5b, enables);
/* Set Read Pass Write Control Enable */
pci_write_config8(dev, 0x48, 0x0c);
/* Set 0x58 to 0x42 APIC and RTC. */
enables = pci_read_config8(dev, 0x58);
enables |= 0x41; //
pci_write_config8(dev, 0x58, enables);
/* Set bit 3 of 0x4f to match award (use INIT# as CPU reset) */
enables = pci_read_config8(dev, 0x4f);
enables |= 0x08;
pci_write_config8(dev, 0x4f, enables);
/* enable serial irq */
pci_write_config8(dev, 0x52, 0x9);
/* dma */
pci_write_config8(dev, 0x53, 0x00);
// Power management setup
setup_pm(dev);
/* set up isa bus -- i/o recovery time, ROM write enable, extend-ale */
pci_write_config8(dev, 0x40, 0x54);
// Start the rtc
cmos_init(0);
}
/* total kludge to get lxb to call our childrens set/enable functions - these are
not called unless this device has a resource to set - so set a dummy one */
static void vx800_read_resources(struct device *dev)
{
struct resource *resource;
pci_dev_read_resources(dev);
resource = new_resource(dev, 1);
resource->flags |=
IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO |
IORESOURCE_STORED;
resource->size = 2;
resource->base = 0x2e;
}
static void vx800_set_resources(struct device *dev)
{
struct resource *resource;
resource = find_resource(dev, 1);
resource->flags |= IORESOURCE_STORED;
pci_dev_set_resources(dev);
}
static void southbridge_init(struct device *dev)
{
printk(BIOS_DEBUG, "vx800 sb init\n");
vx800_sb_init(dev);
pci_routing_fixup(dev);
setup_i8259(); // make sure interupt controller is configured before keyboard init
/* turn on keyboard and RTC, no need to visit this reg twice */
pc_keyboard_init(NO_AUX_DEVICE);
printk(BIOS_DEBUG, "ps2 usb lid, you set who can wakeup system from s3 sleep\n");
S3_ps2_kb_ms_wakeup(dev);
S3_usb_wakeup(dev);
S3_lid_wakeup(dev);
/* enable acpi CPU c3 state. (c2 state need not do anything.)
#1
fadt->pm2_cnt_blk = 0x22;//to support cpu-c3
fadt->p_lvl2_lat = 0x50; //this is the coreboot source
fadt->p_lvl3_lat = 0x320;//
fadt->pm2_cnt_len = 1;//to support cpu-c3
#2
ssdt? ->every CPU has a P_BLK address. set it to 0x10 (so that "Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state"---VIA vx800 P SPEC )
#3 write 0x17 in to PMIO = VX800_ACPI_IO_BASE + 0x26, following the describtion in the P-spec.
1 enable SLP# asserts in C3 state PMIORx26<1> = 1
2 enable CPUSTP# asserts in C3 state; PMIORx26<2> = 1
3 CLKRUN# is always asserted PMIORx26<3> = 0
4 Disable PCISTP# When CLKRUN# is asserted
1: PCISTP# will not assert When CLKRUN# is asserted
PMIORx26<4> = 1
5 This bit controls whether the CPU voltage is lowered when in C3/S1 state.
VRDSLP will be active in either this bit set in C3 or LVL4 register read
PMIORx26<0> =0
6 Read Processor Level3 register(PMIORx15<7:0>) to enter C3 state PMIORx15
*/
outb(0x17, VX800_ACPI_IO_BASE + 0x26);
}
static struct device_operations vx800_lpc_ops = {
.read_resources = vx800_read_resources,
.set_resources = vx800_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = southbridge_init,
.scan_bus = scan_lpc_bus,
};
static const struct pci_driver lpc_driver __pci_driver = {
.ops = &vx800_lpc_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_VX855_LPC,
};

View File

@ -1,155 +0,0 @@
/*
* 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.
*/
/*
part of this file is from cx700 port, part of is from cn700 port,
*/
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <stdlib.h>
#include <string.h>
#include <cpu/cpu.h>
#include "vx800.h"
/* !!FIXME!! This was meant to be a CONFIG option */
#define VIACONFIG_TOP_SM_SIZE_MB 32 // Set frame buffer 32M for default
/* !!FIXME!! I declared this to fix the build. */
u8 acpi_sleep_type = 0;
static void memctrl_init(struct device *dev)
{
/*
set VGA in uma_ram_setting.c, not in this function.
*/
}
static const struct device_operations memctrl_operations = {
.read_resources = DEVICE_NOOP,
.init = memctrl_init,
};
static const struct pci_driver memctrl_driver __pci_driver = {
.ops = &memctrl_operations,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_VX855_MEMCTRL,
};
static void pci_domain_set_resources(struct device *dev)
{
/*
* the order is important to find the correct RAM size.
*/
u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
struct device *mc_dev;
u32 pci_tolm;
u8 reg;
printk(BIOS_SPEW, "Entering vx800 pci_domain_set_resources.\n");
pci_tolm = find_pci_tolm(dev->link_list);
mc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
if (mc_dev) {
unsigned long tomk, tolmk;
unsigned char rambits;
u8 i, idx;
/*
* once the register value is not zero, the ramsize is
* this register's value multiply 64 * 1024 * 1024
*/
for (rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
rambits = pci_read_config8(mc_dev, ramregs[i]);
if (rambits != 0)
break;
}
/*
Get memory size and frame buffer from northbridge's registers.
if register with invalid value we set frame buffer size to 32M for default, but it won't happen.
*/
reg = pci_read_config8(mc_dev, 0xa1);
reg &= 0x70;
reg = reg >> 4;
/* TOP 1M SM Memory */
if (reg == 0x0)
tomk = (((rambits << 6) - 32 - VIACONFIG_TOP_SM_SIZE_MB) * 1024); // Set frame buffer 32M for default
else
tomk =
(((rambits << 6) - (4 << reg) -
VIACONFIG_TOP_SM_SIZE_MB) * 1024);
printk(BIOS_SPEW, "tomk is 0x%lx\n", tomk);
/* Compute the Top Of Low Memory, in Kb */
tolmk = pci_tolm >> 10;
if (tolmk >= tomk) {
/* The PCI hole does does not overlap the memory. */
tolmk = tomk;
}
/* Report the memory regions */
idx = 10;
/* TODO: Hole needed? */
ram_resource(dev, idx++, 0, 640); /* first 640k */
/* Leave a hole for vga, 0xa0000 - 0xc0000 */
ram_resource(dev, idx++, 768, (tolmk - 768));
}
assign_resources(dev->link_list);
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
.write_acpi_tables = acpi_write_hpet,
#endif
.enable_resources = NULL,
.init = NULL,
.scan_bus = pci_domain_scan_bus,
};
static void cpu_bus_init(struct device *dev)
{
initialize_cpus(dev->link_list);
}
static struct device_operations cpu_bus_ops = {
.read_resources = DEVICE_NOOP,
.set_resources = DEVICE_NOOP,
.enable_resources = DEVICE_NOOP,
.init = cpu_bus_init,
.scan_bus = 0,
};
static void enable_dev(struct device *dev)
{
printk(BIOS_SPEW, "In VX800 enable_dev for device %s.\n", dev_path(dev));
/* Set the operations if it is a special bus type */
if (dev->path.type == DEVICE_PATH_DOMAIN) {
dev->ops = &pci_domain_ops;
} else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_via_vx800_ops = {
CHIP_NAME("VIA VX800 Chipset")
.enable_dev = enable_dev,
};

View File

@ -1,69 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2009 One Laptop per Child, Association, Inc.
* Copyright (C) 2010 coresystems GmbH
*
* 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.
*/
#ifndef NORTHBRIDGE_VIA_VX800_PCI_RAWOPS_H
#define NORTHBRIDGE_VIA_VX800_PCI_RAWOPS_H
#include <stdint.h>
#include <arch/io.h>
struct VIA_PCI_REG_INIT_TABLE {
u8 ChipRevisionStart;
u8 ChipRevisionEnd;
u8 Bus;
u8 Device;
u8 Function;
u32 Register;
u8 Mask;
u8 Value;
};
static void pci_modify_config8(pci_devfn_t dev, unsigned where, u8 orval,
u8 mask)
{
u8 data = pci_read_config8(dev, where);
data &= (~mask);
data |= orval;
pci_write_config8(dev, where, data);
}
static void via_pci_inittable(u8 chipversion,
const struct VIA_PCI_REG_INIT_TABLE *initdata)
{
u8 i = 0;
pci_devfn_t devbxdxfx;
for (i = 0;; i++) {
if ((initdata[i].Mask == 0) && (initdata[i].Value == 0)
&& (initdata[i].Bus == 0)
&& (initdata[i].ChipRevisionEnd == 0xff)
&& (initdata[i].ChipRevisionStart == 0)
&& (initdata[i].Device == 0)
&& (initdata[i].Function == 0)
&& (initdata[i].Register == 0))
break;
if ((chipversion >= initdata[i].ChipRevisionStart)
&& (chipversion <= initdata[i].ChipRevisionEnd)) {
devbxdxfx =
PCI_DEV(initdata[i].Bus, initdata[i].Device,
initdata[i].Function);
pci_modify_config8(devbxdxfx,
initdata[i].Register,
initdata[i].Value,
initdata[i].Mask);
}
}
}
#endif

View File

@ -1,72 +0,0 @@
/*
* 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.
*/
#include <spd.h>
#include <delay.h>
#ifdef __clang__
/* Silence clang warnings via pragmas to avoid the problems in this file
blocking analyzes for the rest of the tree. */
#pragma clang diagnostic ignored "-Wsometimes-uninitialized"
#pragma clang diagnostic ignored "-Wconstant-logical-operand"
#pragma clang diagnostic ignored "-Warray-bounds"
#endif
#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
#define PRINT_DEBUG_MEM(x) printk(BIOS_DEBUG, x)
#define PRINT_DEBUG_MEM_HEX8(x) printk(BIOS_DEBUG, "%02x", x)
#define PRINT_DEBUG_MEM_HEX16(x) printk(BIOS_DEBUG, "%04x", x)
#define PRINT_DEBUG_MEM_HEX32(x) printk(BIOS_DEBUG, "%08x", x)
#define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
#else
#define PRINT_DEBUG_MEM(x)
#define PRINT_DEBUG_MEM_HEX8(x)
#define PRINT_DEBUG_MEM_HEX16(x)
#define PRINT_DEBUG_MEM_HEX32(x)
#define DUMPNORTH()
#endif
#include "northbridge/via/vx800/translator_ddr2_init.c"
#include "northbridge/via/vx800/dram_init.h"
#include "northbridge/via/vx800/early_smbus.c"
#include "northbridge/via/vx800/early_serial.c"
#include "northbridge/via/vx800/dram_util.h"
#include "northbridge/via/vx800/dram_util.c"
#include "northbridge/via/vx800/detection.c"
#include "northbridge/via/vx800/freq_setting.c"
#include "northbridge/via/vx800/timing_setting.c"
#include "northbridge/via/vx800/drdy_bl.c"
#include "northbridge/via/vx800/driving_setting.c"
#include "northbridge/via/vx800/clk_ctrl.c"
#include "northbridge/via/vx800/dev_init.c"
#include "northbridge/via/vx800/rank_map.c"
#include "northbridge/via/vx800/dqs_search.c"
#include "northbridge/via/vx800/final_setting.c"
#include "northbridge/via/vx800/uma_ram_setting.c"
#include "northbridge/via/vx800/dram_init.c"
/*
* Support one dimm with up to 2 ranks
*/
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");
}
}

View File

@ -1,20 +0,0 @@
/*
* 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.
*/
#ifndef RAMINIT_H
#define RAMINIT_H
#define MEMCTRL PCI_DEV(0,0,3)
#endif /* RAMINIT_H */

View File

@ -1,345 +0,0 @@
/*
* 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.
*/
void DRAMClearEndingAddress(DRAM_SYS_ATTR * DramAttr);
void DRAMSizingEachRank(DRAM_SYS_ATTR * DramAttr);
BOOLEAN DoDynamicSizing1XM(DRAM_SYS_ATTR * DramAttr,
u8 * nRA, u8 * nCA, u8 * nBS, u8 PhyRank);
void DRAMSetRankMAType(DRAM_SYS_ATTR * DramAttr);
void DRAMSetEndingAddress(DRAM_SYS_ATTR * DramAttr);
void DRAMPRToVRMapping(DRAM_SYS_ATTR * DramAttr);
/*===================================================================
Function : DRAMBankInterleave()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : STEP 13 Set Bank Interleave VIANB3DRAMREG69[7:6] 00:No Interleave 01:2 Bank 10:4 Bank 11:8 Bank
Scan all DIMMs on board to find out the lowest Bank Interleave among these DIMMs and set register.
===================================================================*/
void DRAMBankInterleave(DRAM_SYS_ATTR * DramAttr)
{
u8 Data, SpdBAData;
DIMM_INFO *CurrentDimminfo;
u8 Bank = 3, Shift, RankNO, Count;
Shift = 1;
for (RankNO = 0; RankNO < 4; RankNO += 2) //all_even 0 RankNO 4 6
{
if ((DramAttr->RankPresentMap & Shift) != 0) {
CurrentDimminfo = &(DramAttr->DimmInfo[RankNO >> 1]); //this Rank in a dimm
SpdBAData =
(u8) (CurrentDimminfo->SPDDataBuf
[SPD_SDRAM_NO_OF_BANKS]);
if (SpdBAData == 4)
Count = 2;
else if (SpdBAData == 8)
Count = 3;
else
Count = 0;
if (Count < Bank)
Bank = Count;
}
Shift <<= 2;
}
Data = pci_read_config8(MEMCTRL, 0x69);
Data &= ~0xc0;
Data |= (Bank << 6);
pci_write_config8(MEMCTRL, 0x69, Data);
if (DramAttr->DimmNumChB > 0) {
CurrentDimminfo = &(DramAttr->DimmInfo[3]); //this Rank in a dimm
SpdBAData =
(u8) (CurrentDimminfo->SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]);
if (SpdBAData == 4)
Bank = 2;
else if (SpdBAData == 2)
Bank = 1;
else
Bank = 0;
pci_write_config8(MEMCTRL, 0x87, Bank);
}
}
/*===================================================================
Function : DRAMSizingMATypeM()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : STEP 14 1 DRAM Sizing 2 Fill MA type 3 Prank to vrankMapping
===================================================================*/
void DRAMSizingMATypeM(DRAM_SYS_ATTR * DramAttr)
{
DRAMClearEndingAddress(DramAttr);
DRAMSizingEachRank(DramAttr);
DRAMSetRankMAType(DramAttr);
DRAMSetEndingAddress(DramAttr);
DRAMPRToVRMapping(DramAttr);
}
/*===================================================================
Function : DRAMClearEndingAddress()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : clear Ending and Start adress from 0x40-4f to zero
===================================================================*/
void DRAMClearEndingAddress(DRAM_SYS_ATTR * DramAttr)
{
u8 Data, Reg;
Data = 0;
for (Reg = 0x40; Reg <= 0x4f; Reg++) {
pci_write_config8(MEMCTRL, Reg, Data);
}
}
/*===================================================================
Function : DRAMSizingEachRank()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : Sizing each Rank invidually, by number of rows column banks pins, be care about 128bit
===================================================================*/
void DRAMSizingEachRank(DRAM_SYS_ATTR * DramAttr)
{
u8 Slot, RankIndex, Rows, Columns, Banks;
u32 Size;
BOOLEAN HasThreeBitBA;
u8 Data;
HasThreeBitBA = FALSE;
for (Slot = 0; Slot < 2; Slot++) {
if (!DramAttr->DimmInfo[Slot].bPresence)
continue;
Rows = DramAttr->DimmInfo[Slot].SPDDataBuf[SPD_SDRAM_ROW_ADDR];
Columns =
DramAttr->DimmInfo[Slot].SPDDataBuf[SPD_SDRAM_COL_ADDR];
Banks = DramAttr->DimmInfo[Slot].SPDDataBuf[SPD_SDRAM_NO_OF_BANKS]; //this is Bank number not Bank address bit
if (Banks == 4)
Banks = 2;
else if (Banks == 8)
Banks = 3;
else
Banks = 0;
Size = (u32) (1 << (Rows + Columns + Banks + 3));
RankIndex = 2 * Slot;
DramAttr->RankSize[RankIndex] = Size;
//if this module have two ranks
if ((DramAttr->
DimmInfo[Slot].SPDDataBuf[SPD_SDRAM_DIMM_RANKS] & 0x07) ==
0x01) {
RankIndex++;
DramAttr->RankSize[RankIndex] = Size;
}
PRINT_DEBUG_MEM("rows: ");
PRINT_DEBUG_MEM_HEX8(Rows);
PRINT_DEBUG_MEM(", columns:");
PRINT_DEBUG_MEM_HEX8(Columns);
PRINT_DEBUG_MEM(", banks:");
PRINT_DEBUG_MEM_HEX8(Banks);
PRINT_DEBUG_MEM("\r");
if (Banks == 3)
HasThreeBitBA = TRUE;
}
//must set BA2 enable if any 8-bank device exists
if (HasThreeBitBA) {
Data = pci_read_config8(MEMCTRL, 0x53);
Data |= 0x80;
pci_write_config8(MEMCTRL, 0x53, Data);
}
#if 1
for (RankIndex = 0; DramAttr->RankSize[RankIndex] != 0; RankIndex++) {
PRINT_DEBUG_MEM("Rank:");
PRINT_DEBUG_MEM_HEX8(RankIndex);
PRINT_DEBUG_MEM(", Size:");
PRINT_DEBUG_MEM_HEX32(DramAttr->RankSize[RankIndex] >> 20);
PRINT_DEBUG_MEM("\r");
}
#endif
}
/*===================================================================
Function : DRAMSetRankMAType()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : set the matype Reg by MAMapTypeTbl, which the rule can be found in memoryinit
===================================================================*/
void DRAMSetRankMAType(DRAM_SYS_ATTR * DramAttr)
{
u8 SlotNum, Data, j, Reg, or, and;
u8 ShiftBits[] = { 5, 1, 5, 1 }; /* Rank 0/1 MA Map Type is 7:5, Rank 2/3 MA Map Type is 3:1. See Fun3Rx50. */
u8 MAMapTypeTbl[] = { /* Table 12 of P4M800 Pro DataSheet. */
2, 9, 0, /* Bank Address Bits, Column Address Bits, Rank MA Map Type */
2, 10, 1,
2, 11, 2,
2, 12, 3,
3, 10, 5,
3, 11, 6,
3, 12, 7,
0, 0, 0
};
Data = pci_read_config8(MEMCTRL, 0x50);
Data &= 0x1;
pci_write_config8(MEMCTRL, 0x50, Data);
// disable MA32/16 MA33/17 swap in memory init it has this Reg fill
Data = pci_read_config8(MEMCTRL, 0x6b);
Data &= ~0x08;
pci_write_config8(MEMCTRL, 0x6b, Data);
Data = 0x00;
for (SlotNum = 0; SlotNum < MAX_DIMMS; SlotNum++) {
if (DramAttr->DimmInfo[SlotNum].bPresence) {
for (j = 0; MAMapTypeTbl[j] != 0; j += 3) {
if ((1 << MAMapTypeTbl[j]) ==
DramAttr->
DimmInfo[SlotNum].SPDDataBuf
[SPD_SDRAM_NO_OF_BANKS]
&& MAMapTypeTbl[j + 1] ==
DramAttr->
DimmInfo[SlotNum].SPDDataBuf
[SPD_SDRAM_COL_ADDR]) {
break;
}
}
if (0 == MAMapTypeTbl[j]) {
PRINT_DEBUG_MEM
("UNSUPPORTED Bank, Row and Column Addr Bits!\r");
return;
}
or = MAMapTypeTbl[j + 2] << ShiftBits[SlotNum];
if (DramAttr->CmdRate == 1)
or |= 0x01 << (ShiftBits[SlotNum] - 1);
Reg = SlotNum / 2;
if ((SlotNum & 0x01) == 0x01) {
and = 0xf1; // BUGBUG: it should be 0xf0
} else {
and = 0x1f; // BUGBUG: it should be 0x0f
}
Data = pci_read_config8(MEMCTRL, 0x50 + Reg);
Data &= and;
Data |= or;
pci_write_config8(MEMCTRL, 0x50 + Reg, Data);
}
}
//may have some Reg filling at add 3-52 11 and 3-53 in his function
}
/*===================================================================
Function : DRAMSetEndingAddress()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : realize the Vrank 40...Reg (Start and Ending Regs). Vrank have same order with phy Rank, Size is actual Size
===================================================================*/
void DRAMSetEndingAddress(DRAM_SYS_ATTR * DramAttr)
{
u8 Shift = 1, Data, RankNO, Size, Start = 0, End = 0, Vrank;
for (RankNO = 0; RankNO < 4; RankNO++) {
if ((DramAttr->RankPresentMap & Shift) != 0) {
Size = (u8) (DramAttr->RankSize[RankNO] >> 26); // current Size in the unit of 64M
if (Size != 0) {
End = End + Size; // calculate current ending address, add the current Size to ending
Vrank = RankNO; // get virtual Rank
Data = End; // set begin/End address register to correspondig virtual Rank #
pci_write_config8(MEMCTRL, 0x40 + Vrank, Data);
Data = Start;
pci_write_config8(MEMCTRL, 0x48 + Vrank, Data);
PRINT_DEBUG_MEM("Rank: ");
PRINT_DEBUG_MEM_HEX8(Vrank);
PRINT_DEBUG_MEM(", Start:");
PRINT_DEBUG_MEM_HEX8(Start);
PRINT_DEBUG_MEM(", End:");
PRINT_DEBUG_MEM_HEX8(End);
PRINT_DEBUG_MEM("\r");
Start = End;
}
}
Shift <<= 1;
}
if (DramAttr->RankNumChB > 0) {
//this is a bug,fixed is to 2,so the max LL size is 128M
Data = 0x02;
pci_write_config8(MEMCTRL, 0x44, Data);
}
Data = End * 4;
pci_write_config8(PCI_DEV(0, 17, 7), 0x60, Data);
// We should directly write to south Bridge, not in north bridge
// program LOW TOP Address
Data = pci_read_config8(MEMCTRL, 0x88);
pci_write_config8(MEMCTRL, 0x85, Data);
// also program vlink mirror
// We should directly write to south Bridge, not in north bridge
pci_write_config8(PCI_DEV(0, 17, 7), 0xe5, Data);
}
/*===================================================================
Function : DRAMPRToVRMapping()
Precondition :
Input :
DramAttr: pointer point to DRAMSYSATTR which consist the DDR and Dimm information in MotherBoard
Output : Void
Purpose : set the Vrank-prank map with the same order
===================================================================*/
void DRAMPRToVRMapping(DRAM_SYS_ATTR * DramAttr)
{
u8 Shift, Data, and, or, DimmNO = 0, PhyRankNO, Reg;
for (Reg = 0x54; Reg <= 0x57; Reg++) //clear the map-reg
{
Data = 0;
pci_write_config8(MEMCTRL, Reg, Data);
}
Shift = 1;
for (PhyRankNO = 0; PhyRankNO < MAX_RANKS; PhyRankNO++) {
if ((DramAttr->RankPresentMap & Shift) != 0) {
or = PhyRankNO; // get virtual Rank ,same with PhyRank
or |= 0x08;
if ((PhyRankNO & 0x01) == 0x01) // get mask for register
and = 0xf0;
else {
and = 0x0f;
or <<= 4;
}
DimmNO = (PhyRankNO >> 1);
Data = pci_read_config8(MEMCTRL, 0x54 + DimmNO);
Data &= and;
Data |= or;
pci_write_config8(MEMCTRL, 0x54 + DimmNO, Data);
}
Shift <<= 1;
}
}

View File

@ -1,47 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2004 Tyan Computer
* (Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer)
* Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
* 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.
*/
/* This file constructs the ROM strap table for K8T890 and K8M890 */
.section ".romstrap", "a", @progbits
.globl __romstrap_start
__romstrap_start:
tblpointer:
.long 0x55aa66cc
.long 0x88012554
.long 0x77107777
.long 0x00770814
.long 0x00000000
.long 0x00000000
.long 0x00000000
.long 0x00000000
/*
* The pointer to above table should be at 0xffffffd0,
* the table itself MUST be aligned to 128B it seems!
*/
rspointers:
.long tblpointer // It will be 0xffffffd0
.globl __romstrap_end
__romstrap_end:
.previous

View File

@ -1,22 +0,0 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007 AMD
* (Written by Yinghai Lu <yinghai.lu@amd.com> for AMD)
*
* 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.
*/
SECTIONS {
. = (0xffffffff - 0x2c) - (__romstrap_end - __romstrap_start) + 1;
.romstrap (.): {
KEEP(*(.romstrap))
}
}

View File

@ -1,472 +0,0 @@
/*
* 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.
*/
/*
Set Dram Timing functions
*/
void SetCL(DRAM_SYS_ATTR * DramAttr);
void SetTrp(DRAM_SYS_ATTR * DramAttr);
void SetTrcd(DRAM_SYS_ATTR * DramAttr);
void SetTras(DRAM_SYS_ATTR * DramAttr);
void SetTrfc(DRAM_SYS_ATTR * DramAttr);
void SetTrrd(DRAM_SYS_ATTR * DramAttr);
void SetTwr(DRAM_SYS_ATTR * DramAttr);
void SetTwtr(DRAM_SYS_ATTR * DramAttr);
void SetTrtp(DRAM_SYS_ATTR * DramAttr);
/* 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);
}
/*
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);
}
/*
Minimum row precharge time, Trp for DDR1/DDR2
D0F3Rx64[3:2] for Trp 2T~5T
*/
#define MAX_TRP 6
#define MIN_TRP 2
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);
}
/*
Minimum RAS to CAS dely,Trcd for DDR1/DDR2
D0F3Rx64[7:6] for Trcd
*/
#define MAX_TRCD 6
#define MIN_TRCD 2
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);
}
/*
minimum active to precharge time,Tras for DDR1/DDR2
D0F3Rx62[7:4] Tras
*/
#define MAX_TRAS 20 //20T
#define MIN_TRAS 5 //5T
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);
}
/*
Minimum refresh to activate/refresh command period Trfc for DDR1/DDR2
D0F3Rx61[5:0] for Trfc
*/
#define MAX_TRFC 71 // Max supported,71T
#define MIN_TRFC 8 // Min supported,8T
void SetTrfc(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u32 Max, Tmp;
u8 Byte40;
u8 Socket;
/*get the max Trfc value from SPD data */
Max = 0;
for (Socket = 0; Socket < MAX_SOCKETS; Socket++) {
if (DramAttr->DimmInfo[Socket].bPresence) {
Tmp =
(u32) (DramAttr->
DimmInfo[Socket].SPDDataBuf[SPD_SDRAM_TRFC])
* 100;
/*only DDR2 need to add byte 40 bit[7:4] */
Byte40 =
(DramAttr->
DimmInfo[Socket].SPDDataBuf[SPD_SDRAM_TRFC2]);
/*if bit0 = 1, byte42(RFC)+256ns, SPD spec JEDEC standard No.21.c */
if (Byte40 & 0x01)
Tmp += (256 * 100);
/*bit1,2,3 000->0ns+byte42; 001->0.25ns+byte42; 010->0.33ns+byte42; 011->0.5ns+byte42;100-> 0.75ns+byte42 */
switch ((Byte40 >> 1) & 0x07) { /*bit1,2,3 */
case 1:
Tmp += 25;
break;
case 2:
Tmp += 33;
break;
case 3:
Tmp += 50;
break;
case 4:
Tmp += 66;
break;
case 5:
Tmp += 75;
break;
case 6: //what is FRU???
default:
break;
}
if (Tmp > Max)
Max = Tmp;
}
}
/*Calculate clock,value range 8T-71T */
Tmp = (u16) CEIL_DIV(Max, DramAttr->DramCyc);
PRINT_DEBUG_MEM("Trfc = ");
PRINT_DEBUG_MEM_HEX16(Tmp);
PRINT_DEBUG_MEM("\r");
if (Tmp > MAX_TRFC)
Tmp = MAX_TRFC;
else if (Tmp < MIN_TRFC) {
// return;
Tmp = 0x40;
}
/*D0F3Rx61 bit[0:5] 0->8T ... 63->71T */
Tmp -= 8;
Data = pci_read_config8(MEMCTRL, 0x61);
Data = (u8) ((Data & 0xc0) | ((u8) Tmp & 0x3f));
pci_write_config8(MEMCTRL, 0x61, Data);
}
/*
Minimum row active to row active delay: Trrd for DDR1/DDR2
D0F3Rx61[7:6]:Trrd 00->2T, 01->3T, 10->4T, 11->5T
*/
#define MAX_TRRD 5
#define MIN_TRRD 2
void SetTrrd(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u16 Max, Tmp;
u8 Socket;
/*get the max Trrd value from SPD data
SPD Byte28, 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_TRRD]);
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("Trrd =");
PRINT_DEBUG_MEM_HEX16(Tmp);
PRINT_DEBUG_MEM("\r");
if (Tmp > MAX_TRRD)
Tmp = MAX_TRRD;
else if (Tmp < MIN_TRRD)
Tmp = MIN_TRRD;
Tmp -= 2; //00->2T, 01->3T, 10->4T, 11->5T
Tmp <<= 6;
Data = pci_read_config8(MEMCTRL, 0x61);
Data = (u8) ((Data & 0x3f) | (u8) Tmp);
pci_write_config8(MEMCTRL, 0x61, Data);
}
/*
Write recovery time: Twr for DDR1/DDR2
Device 0 Function 3:REG63[7:5]:Twr 00->2T 01->3T 10->4T 11->5T
*/
#define MAX_TWR 6
#define MIN_TWR 2
void SetTwr(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u16 Max, Tmp;
u8 Socket;
/*get the max Trtp value from SPD data
SPD Byte36, 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_TWR]);
if (Tmp > Max)
Max = Tmp;
}
}
/*Calculate clock */
Tmp = (u16) CEIL_DIV((Max * 100), ((DramAttr->DramCyc) << 2)); //this value should be 2T,3T,4T,5T
PRINT_DEBUG_MEM("Twr = ");
PRINT_DEBUG_MEM_HEX16(Tmp);
PRINT_DEBUG_MEM("\r");
if (Tmp > MAX_TWR)
Tmp = MAX_TWR;
else if (Tmp < MIN_TWR)
Tmp = MIN_TWR;
Tmp -= 2; //00->2T, 01->3T, 10->4T, 11->5T
Tmp <<= 5;
Data = pci_read_config8(MEMCTRL, 0x63);
Data = (u8) ((Data & 0x1f) | (u8) Tmp);
pci_write_config8(MEMCTRL, 0x63, Data);
}
/*
Internal write to read command delay: Twtr for DDR1/DDR2
Device 0 Function 3:REG63[1,0]:Twtr DDR: 1T or 2T; DDR2 2T or 3T
*/
#define MAX_TWTR 5 //5T
#define MIN_TWTR 2 //2T
void SetTwtr(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u16 Max, Tmp;
u8 Socket;
/*get the max Trtp value from SPD data
SPD Byte37, 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_TWTR]);
if (Tmp > Max)
Max = Tmp;
}
}
/*Calculate clock */
Tmp = (u16) CEIL_DIV((Max * 100), ((DramAttr->DramCyc) << 2)); //this value should be 2T or 3T
PRINT_DEBUG_MEM("Twtr =");
PRINT_DEBUG_MEM_HEX16(Tmp);
PRINT_DEBUG_MEM("\r");
if (Tmp > MAX_TWR)
Tmp = MAX_TWTR;
else if (Tmp < MIN_TWR)
Tmp = MIN_TWTR;
Tmp -= 2; //00->2T, 01->3T, 10->4T, 11->5T
Data = pci_read_config8(MEMCTRL, 0x63);
Data = (u8) ((Data & 0xFC) | Tmp);
pci_write_config8(MEMCTRL, 0x63, Data);
}
/*
Internal read to precharge command delay, Trtp for DDR1/DDR2
Device 0 Function 3:REG63[3]:Trtp 2T or 3T
*/
#define MAX_TRTP 3 //3T
#define MIN_TRTP 2 //2T
void SetTrtp(DRAM_SYS_ATTR * DramAttr)
{
u8 Data;
u16 Max, Tmp;
u8 Socket;
/*get the max Trtp value from SPD data
SPD Byte38, 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_TRTP]);
if (Tmp > Max)
Max = Tmp;
}
}
/*Calculate clock */
Tmp = (u16) CEIL_DIV((Max * 100), ((DramAttr->DramCyc) << 2)); //this value should be 2T or 3T
PRINT_DEBUG_MEM("Trtp =");
PRINT_DEBUG_MEM_HEX16(Tmp);
PRINT_DEBUG_MEM("\r");
Data = pci_read_config8(MEMCTRL, 0x63);
if (Tmp > MIN_TRTP)
Data = (u8) (Data | 0x08); /*set bit3, set 3T */
else
Data = (u8) (Data & 0xf7); /*clear bit3, set 2T */
pci_write_config8(MEMCTRL, 0x63, Data);
}

View File

@ -1,29 +0,0 @@
/*
* 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.
*/
#define CB_SUCCESS 0x0
#define CB_INVALID_PARAMETER 0x2
#define CB_NOT_READY 0x6
#define CB_DEVICE_ERROR 0x7
#define TRUE 1
#define FALSE 0
typedef int8_t INT8;
typedef unsigned long uintn_t;
typedef uintn_t UINTN;
typedef long intn_t;
typedef intn_t INTN;
typedef UINTN CB_STATUS;
typedef uint8_t BOOLEAN;

View File

@ -1,317 +0,0 @@
/*
* 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.
*/
#include "pci_rawops.h"
typedef struct __UMA_RAM_tag {
u16 DramSize;
u8 D0F3Val;
u8 D1F0Val;
u8 VgaPortVal;
} UMARAM;
#define UMARAM_512M 7
#define UMARAM_256M 6
#define UMARAM_128M 5
#define UMARAM_64M 4
#define UMARAM_32M 3
#define UMARAM_16M 2
#define UMARAM_8M 1
#define UMARAM_0M 0
#define FB_512M 0
#define FB_256M 0x40
#define FB_128M 0x60
#define FB_64M 0x70
#define FB_32M 0x78
#define FB_16M 0x7c
#define FB_8M 0x7E
#define FB_4M 0x7F
#define VGA_PORT_512M 0x00
#define VGA_PORT_256M 0x80
#define VGA_PORT_128M 0xC0
#define VGA_PORT_64M 0xE0
#define VGA_PORT_32M 0xF0
#define VGA_PORT_16M 0xF8
#define VIACONFIG_VGA_PCI_10 0xf8000008
#define VIACONFIG_VGA_PCI_14 0xfc000000
static const UMARAM UMARamArr[] = {
{0, UMARAM_0M, FB_4M, 0xFE},
{8, UMARAM_8M, FB_8M, 0xFC},
{16, UMARAM_16M, FB_16M, VGA_PORT_16M},
{32, UMARAM_32M, FB_32M, VGA_PORT_32M},
{64, UMARAM_64M, FB_64M, VGA_PORT_64M},
{128, UMARAM_128M, FB_128M, VGA_PORT_128M},
{256, UMARAM_256M, FB_256M, VGA_PORT_256M},
{512, UMARAM_512M, FB_512M, VGA_PORT_512M},
{0xffff, 0xff, 0xff, 0xFF}
};
void SetUMARam(void)
{
#if 1
u8 ramregs[] = { 0x43, 0x42, 0x41, 0x40 };
pci_devfn_t vga_dev = PCI_DEV(0, 1, 0), d0f0_dev = PCI_DEV(0, 0, 0);
u8 ByteVal, temp;
const UMARAM *pUMARamTable;
u16 UmaSize;
u8 SLD0F3Val, SLD1F0Val, VgaPortVal;
u32 RamSize, SLBase, Tmp;
u8 i;
PRINT_DEBUG_MEM("Entering vx800 SetUMARam.\n");
SLD0F3Val = 0;
SLD1F0Val = 0;
VgaPortVal = 0;
ByteVal = pci_read_config8(MEMCTRL, 0xa1);
ByteVal |= 0x80;
pci_write_config8(MEMCTRL, 0xa1, ByteVal);
//set VGA Timer
pci_write_config8(MEMCTRL, 0xa2, 0xee);
//set agp misc
//GFX Data Delay to Sync with Clock
pci_write_config8(MEMCTRL, 0xa4, 0x01);
//page register life timer
pci_write_config8(MEMCTRL, 0xa6, 0x76);
//GMINT and GFX relatate
//note Bit 3 VGA Enable
pci_write_config8(MEMCTRL, 0xa7, 0x8c);
//GMINT Misc.1
//AGPCINT MISC
//GMINT MISC.2
//disable read pass write
pci_write_config8(MEMCTRL, 0xb3, 0x9A);
//EPLL Register
//enable CHA and CHB merge mode
pci_write_config8(MEMCTRL, 0xde, 0x06);
//if can get the value from setup interface, so get the value
//else use the default value
UmaSize = CONFIG_VIDEO_MB;
for (pUMARamTable = UMARamArr; pUMARamTable->DramSize != 0xffff;
pUMARamTable++) {
if (UmaSize == pUMARamTable->DramSize) {
SLD0F3Val = pUMARamTable->D0F3Val;
SLD1F0Val = pUMARamTable->D1F0Val;
VgaPortVal = pUMARamTable->VgaPortVal;
}
}
//set SL size
//Fill in Fun3_RXA1[6:4] with the Frame Buffer size for the Integrated Graphic Device.
ByteVal = pci_read_config8(MEMCTRL, 0xa1);
ByteVal = (ByteVal & 0x8f) | (SLD0F3Val << 4);
pci_write_config8(MEMCTRL, 0xa1, ByteVal);
//RxB2 may be for S.L. and RxB1 may be for L. L.
// It is different from Spec.
ByteVal = SLD1F0Val;
pci_write_config8(vga_dev, 0xb2, ByteVal);
//set M1 size
PRINT_DEBUG_MEM("UMA setting - 3\n");
//Enable p2p IO/mem
ByteVal = 0x07;
pci_write_config8(vga_dev, 0x04, ByteVal);
//must set SL and MMIO base, or else when enable GFX memory space, system will hang
//set S.L base
Tmp = pci_read_config32(vga_dev, 0x10);
Tmp = 0xfffffff8;
pci_write_config32(vga_dev, 0x10, Tmp);
Tmp = pci_read_config32(vga_dev, 0x10);
Tmp = VIACONFIG_VGA_PCI_10;
pci_write_config32(vga_dev, 0x10, Tmp);
//set MMIO base
Tmp = pci_read_config32(vga_dev, 0x14);
Tmp = 0xfffffffC;
pci_write_config32(vga_dev, 0x14, Tmp);
Tmp = pci_read_config32(vga_dev, 0x14);
Tmp = VIACONFIG_VGA_PCI_14;
pci_write_config32(vga_dev, 0x14, Tmp);
//enable direct CPU frame buffer access
i = pci_read_config8(PCI_DEV(0, 0, 3), 0xa1);
i = (i & 0xf0) | (VIACONFIG_VGA_PCI_10 >> 28);
pci_write_config8(PCI_DEV(0, 0, 3), 0xa1, i);
pci_write_config8(PCI_DEV(0, 0, 3), 0xa0, 0x01);
//enable GFx memory space access control for S.L and mmio
ByteVal = pci_read_config8(d0f0_dev, 0xD4);
ByteVal |= 0x03;
pci_write_config8(d0f0_dev, 0xD4, ByteVal);
//enable Base VGA 16 Bits Decode
ByteVal = pci_read_config8(d0f0_dev, 0xfe);
ByteVal |= 0x10;
pci_write_config8(d0f0_dev, 0xfe, ByteVal);
//disable CHB L.L
//set VGA memory selection
ByteVal = pci_read_config8(vga_dev, 0xb0);
ByteVal &= 0xF8;
ByteVal |= 0x03;
pci_write_config8(vga_dev, 0xb0, ByteVal);
//set LL size
//enable memory access to SL,MMIO,LL and IO to 3B0~3BB,3C0 ~3DF
//Turn on Graphic chip IO port port access
ByteVal = inb(0x03C3);
ByteVal |= 0x01;
outb(ByteVal, 0x03C3);
//Turn off Graphic chip Register protection
outb(0x10, 0x03C4);
ByteVal = inb(0x03C5);
ByteVal |= 0x01;
outb(ByteVal, 0x03C5);
//set VGA memory Frequence
//direct IO port 0x3DX to vga io space 0x3C2[0]
ByteVal = inb(0x03CC);
ByteVal |= 0x03;
outb(ByteVal, 0x03C2);
#if 1 //bios porting guide has no this two defination: 3d on 3d4/3d5 and 39 on 3c4/3c5
//set frequence 0x3D5.3d[7:4]
outb(0x3d, 0x03d4);
temp = pci_read_config8(MEMCTRL, 0x90);
temp = (u8) (temp & 0x07);
ByteVal = inb(0x03d5);
switch (temp) {
case 0: //DIMMFREQ_200:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x30);
break;
case 1: //DIMMFREQ_266:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x40);
break;
case 3: //DIMMFREQ_400:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x60);
break;
case 4: //DIMMFREQ_533:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
break;
case 5: //DIMMFREQ_667:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x80);
break;
case 6: //DIMMFREQ_800:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x90);
break;
default:
ByteVal = (u8) ((ByteVal & 0x0F) | 0x70);
break;
}
outb(ByteVal, 0x03d5);
// Set frame buffer size
outb(0x39, 0x03c4);
outb(1 << SLD0F3Val, 0x03c5);
#endif
// Set S.L. size in GFX's register
outb(0x68, 0x03c4);
outb(VgaPortVal, 0x03c5);
// ECLK Selection (00:166MHz, 01:185MHz, 10:250MHz, 11:275MHz)
// set 3C5.5A[0]=1, address maps to secondary resgiters
outb(0x5a, 0x03c4);
ByteVal = inb(0x03c5);
ByteVal |= 0x01;
outb(ByteVal, 0x03c5);
// Set 3D5.4C[7:6] (00:166MHz, 01:185MHz, 10:250MHz, 11:275MHz)
outb(0x4c, 0x03d4);
ByteVal = inb(0x03d5);
ByteVal = (ByteVal & 0x3F) | 0x80;
outb(ByteVal, 0x03d5);
// set 3C5.5A[0]=0, address maps to first resgiters
outb(0x5a, 0x03c4);
ByteVal = inb(0x03c5);
ByteVal &= 0xFE;
outb(ByteVal, 0x03c5);
// Set S.L. Address in System Memory
//calculate dram size
for (RamSize = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) {
RamSize = pci_read_config8(MEMCTRL, ramregs[i]);
if (RamSize != 0)
break;
}
//calculate SL Base Address
SLBase = (RamSize << 26) - (UmaSize << 20);
outb(0x6D, 0x03c4);
//SL Base[28:21]
outb((u8) ((SLBase >> 21) & 0xFF), 0x03c5);
outb(0x6e, 0x03c4);
//SL Base[36:29]
outb((u8) ((SLBase >> 29) & 0xFF), 0x03c5);
outb(0x6f, 0x03c4);
outb(0x00, 0x03c5);
// Set SVID high byte
outb(0x36, 0x03c4);
outb(0x11, 0x03c5);
// Set SVID Low byte
outb(0x35, 0x03c4);
outb(0x06, 0x03c5);
// Set SID high byte
outb(0x38, 0x03c4);
outb(0x51, 0x03c5);
// Set SID Low byte
outb(0x37, 0x03c4);
outb(0x22, 0x03c5);
//start : For enable snapshot mode control
// program 3C5 for SNAPSHOT Mode control, set RxF3h = 1Ah
outb(0xf3, 0x03c4);
ByteVal = inb(0x03c5);
ByteVal = (ByteVal & 0xE5) | 0x1A;
outb(ByteVal, 0x03c5);
outb(0xf3, 0x03d4);
ByteVal = inb(0x03d5);
ByteVal = (ByteVal & 0xE5) | 0x1A;
outb(ByteVal, 0x03d5);
// 3d4 3d freq
// IO Port / Index: 3X5.3D
// Scratch Pad Register 4
#endif
}

View File

@ -1,195 +0,0 @@
/*
* 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.
*/
/* Note: Some of the VGA control registers are located on the memory controller.
Registers are set both in raminit.c and northbridge.c */
#include <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <stdlib.h>
#include <string.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include <arch/interrupt.h>
#include <x86emu/regs.h>
#include <device/oprom/realmode/x86.h>
/* PCI Domain 1 Device 0 Function 0 */
#define SR_INDEX 0x3c4
#define SR_DATA 0x3c5
#define CRTM_INDEX 0x3b4
#define CRTM_DATA 0x3b5
#define CRTC_INDEX 0x3d4
#define CRTC_DATA 0x3d5
/* !!FIXME!! These were CONFIG_ options. Fix it in uma_ram_setting.c too. */
#define VIACONFIG_VGA_PCI_10 0xf8000008
#define VIACONFIG_VGA_PCI_14 0xfc000000
static int via_vx800_int15_handler(void)
{
int res = 0;
printk(BIOS_DEBUG, "via_vx800_int15_handler\n");
switch(X86_EAX & 0xffff) {
case 0x5f19:
X86_EAX = 0x5f;
X86_ECX = 0x03;
res = 1;
break;
case 0x5f18:
{
/*
* BL Bit[7:4]
* Memory Data Rate
* 0000: 66MHz
* 0001: 100MHz
* 0010: 133MHz
* 0011: 200MHz ( DDR200 )
* 0100: 266MHz ( DDR266 )
* 0101: 333MHz ( DDR333 )
* 0110: 400MHz ( DDR400 )
* 0111: 533MHz ( DDR I/II 533
* 1000: 667MHz ( DDR I/II 667)
* Bit[3:0]
* N: Frame Buffer Size 2^N MB
*/
u8 i;
struct device *dev;
dev = dev_find_slot(0, PCI_DEVFN(0, 3));
i = pci_read_config8(dev, 0xa1);
i = (i & 0x70);
i = i >> 4;
if (i == 0) {
X86_EAX = 0x00; //not support 5f18
break;
}
i = i + 2;
X86_EBX = (u32) i;
i = pci_read_config8(dev, 0x90);
i = (i & 0x07);
i = i + 3;
i = i << 4;
X86_EBX = X86_EBX + ((u32) i);
X86_EAX = 0x5f;
res = 1;
break;
}
case 0x5f00:
X86_EAX = 0x005f;
res = 1;
break;
case 0x5f01:
X86_EAX = 0x5f;
X86_ECX = (X86_ECX & 0xffffff00 ) | 2; // panel type = 2 = 1024 * 768
res = 1;
break;
case 0x5f02:
X86_EAX = 0x5f;
X86_EBX = (X86_EBX & 0xffff0000) | 2;
X86_ECX = (X86_ECX & 0xffff0000) | 0x401; // PAL + crt only
X86_EDX = (X86_EDX & 0xffff0000) | 0; // TV Layout - default
res = 1;
break;
case 0x5f0f:
X86_EAX = 0x005f;
res = 1;
break;
default:
printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
X86_EAX & 0xffff);
X86_EAX = 0;
break;
}
return res;
}
#ifdef UNUSED_CODE
static void write_protect_vgabios(void)
{
struct device *dev;
printk(BIOS_INFO, "write_protect_vgabios\n");
/* there are two possible devices. Just do both. */
dev = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_VX855_MEMCTRL, 0);
if (dev)
pci_write_config8(dev, 0x80, 0xff);
}
#endif
static void vga_enable_console(void)
{
#if IS_ENABLED(CONFIG_PCI_OPTION_ROM_RUN_REALMODE)
/* Call VGA BIOS int10 function 0x4f14 to enable main console
* Epia-M does not always autosense the main console so forcing
* it on is good.
*/
/* int#, EAX, EBX, ECX, EDX, ESI, EDI */
realmode_interrupt(0x10, 0x4f14, 0x8003, 0x0001, 0x0000, 0x0000, 0x0000);
#endif
}
extern u8 acpi_sleep_type;
static void vga_init(struct device *dev)
{
uint8_t reg8;
mainboard_interrupt_handlers(0x15, &via_vx800_int15_handler);
//A20 OPEN
reg8 = inb(0x92);
reg8 = reg8 | 2;
outb(reg8, 0x92);
printk(BIOS_DEBUG, "Initializing VGA...\n");
pci_dev_init(dev);
printk(BIOS_DEBUG, "Enable VGA console\n");
vga_enable_console();
if (acpi_sleep_type == 3/* || (PAYLOAD_IS_SEABIOS == 0)*/) {
/* It's not clear if these need to be programmed before or after
* the VGA bios runs. Try both, clean up later */
/* Set memory rate to 200MHz */
outb(0x3d, CRTM_INDEX);
reg8 = inb(CRTM_DATA);
reg8 &= 0x0f;
reg8 |= (0x3 << 4);
outb(0x3d, CRTM_INDEX);
outb(reg8, CRTM_DATA);
}
}
static struct device_operations vga_operations = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = vga_init,
.ops_pci = 0,
};
static const struct pci_driver vga_driver __pci_driver = {
.ops = &vga_operations,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_VX855_VGA,
};

View File

@ -1,114 +0,0 @@
/*
* 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.
*/
#ifndef VX800_H
#define VX800_H 1
#ifdef __PRE_RAM__
/* vx800_early_smbus.c */
struct mem_controller;
void enable_smbus(void);
void smbus_fixup(const struct mem_controller *mem_ctrl);
/* vx800_early_serial.c */
void enable_vx800_serial(void);
#endif
#define REV_B1 0x11
#define REV_B3 0x13
#define REV_B4 0x14
#define REV_B0 0x00
#define REV_B2 0x01
/* VGA stuff */
#define SR_INDEX 0x3c4
#define SR_DATA 0x3c5
#define CRTM_INDEX 0x3b4
#define CRTM_DATA 0x3b5
#define CRTC_INDEX 0x3d4
#define CRTC_DATA 0x3d5
/* Memory Controller Registers */
#define RANK0_END 0x40
#define RANK1_END 0x41
#define RANK2_END 0x42
#define RANK3_END 0x43
#define RANK0_START 0x48
#define RANK1_START 0x49
#define RANK2_START 0x4a
#define RANK3_START 0x4b
#define DDR_PAGE_CTL 0x69
#define DRAM_REFRESH_COUNTER 0x6a
#define DRAM_MISC_CTL 0x6b
#define CH_A_DQS_OUTPUT_DELAY 0x70
#define CH_A_MD_OUTPUT_DELAY 0x71
/* RAM Init Commands */
#define RAM_COMMAND_NORMAL 0x0
#define RAM_COMMAND_NOP 0x1
#define RAM_COMMAND_PRECHARGE 0x2
#define RAM_COMMAND_MRS 0x3
#define RAM_COMMAND_CBR 0x4
/* IDE specific bits */
#define IDE_MODE_REG 0x09
#define IDE0_NATIVE_MODE (1 << 0)
#define IDE1_NATIVE_MODE (1 << 2)
/* These are default addresses according to Via */
#define IDE0_DATA_ADDR 0x1f0
#define IDE0_CONTROL_ADDR 0x3f4
#define IDE1_DATA_ADDR 0x170
#define IDE1_CONTROL_ADDR 0x370
/* By Award default, Via default is 0xCC0 */
#define BUS_MASTER_ADDR 0xfe00
#define CHANNEL_ENABLE_REG 0x40
#define ENABLE_IDE0 (1 << 0)
#define ENABLE_IDE1 (1 << 1)
#define VX800_ACPI_IO_BASE 0x0400
#define NB_APIC_REG 0,0,5,
#define NB_PXPTRF_REG NB_APIC_REG
#define NB_MSGC_REG NB_APIC_REG
#define NB_HOST_REG 0,0,2,
#define NB_P6IF_REG NB_HOST_REG
#define NB_DRAMC_REG 0,0,3,
#define NB_PMU_REG 0,0,4,
#define NB_VLINK_REG 0,0,7,
#define NB_PEG_BRIDGE_REG 0,2, 0,
#define NB_D3F0_REG 0,3, 0,
#define NB_D3F1_REG 0,3, 1,
#define SB_LPC_REG 0,0x11,0,
#define SB_VLINK_REG 0,0x11,7,
#define SB_SATA_REG 0,0xf, 0,
#define SB_IDEC_REG 0,0xf, 0,
#define SB_P2PB_REG 0,0x13, 0,
#define SB_USB0_REG 0,0x10, 0,
#define SB_USB1_REG 0,0x10, 1,
#define SB_USB2_REG 0,0x10, 2,
#define SB_EHCI_REG 0,0x10, 4,
#define VX800SB_APIC_ID 0x4
#define VX800SB_APIC_DATA_OFFSET 0x10
#define VX800SB_APIC_ENTRY_NUMBER 0x40
#define VX800_D0F5_MMCONFIG_MBAR 0x61
#endif