Keith Hui has uploaded this change for review. ( https://review.coreboot.org/22687
Change subject: intel/i440bx: Correct RAM init programming ......................................................................
intel/i440bx: Correct RAM init programming
Corrects MBSC/MBFS programming when initializing DRAM on boards with both 3 and 4 DIMM slots.
Reformats comments to current coreboot standards.
Drops some romcc "optimizations" no longer necessary.
Boot tested on asus/p2b-ls, where it fixes a memory related hang after SeaBIOS resets the board with nothing to boot from.
Change-Id: Ib8c21489338643e13f69bd58008d14733796d4d0 Signed-off-by: Keith Hui buurin@gmail.com --- M src/northbridge/intel/i440bx/raminit.c 1 file changed, 149 insertions(+), 79 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/87/22687/1
diff --git a/src/northbridge/intel/i440bx/raminit.c b/src/northbridge/intel/i440bx/raminit.c index 84008e7..439fb14 100644 --- a/src/northbridge/intel/i440bx/raminit.c +++ b/src/northbridge/intel/i440bx/raminit.c @@ -431,40 +431,43 @@
static void set_dram_buffer_strength(void) { - /* To give some breathing room for romcc, - * mbsc0 doubles as drb - * mbsc1 doubles as drb1 - * mbfs0 doubles as i and reg + /* + * Program MBSC[39:0] and MBFS[23:0]. + * + * The 440BX datasheet says buffer frequency is independent from bus + * frequency and mismatch both ways are possible. + * + * MBSC[47:40] and MBFS[23] are reserved. */ - uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
- /* Tally how many rows between rows 0-3 and rows 4-7 are populated. + unsigned int i, reg, drb; + uint8_t mbsc0, mbsc1, mbsc2, mbsc3, mbsc4, mbfs0, mbfs1, mbfs2; + + /* + * Tally how many rows between rows 0-3 and rows 4-7 are populated. * This determines how to program MBFS and MBSC. */ uint8_t dimm03 = 0; uint8_t dimm47 = 0;
- mbsc0 = 0; - for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) { - mbsc1 = pci_read_config8(NB, mbfs0); - if (mbsc0 != mbsc1) { - if (mbfs0 <= DRB3) { + for (drb = 0, i = DRB0; i <= DRB7; i++) { + reg = pci_read_config8(NB, i); + if (drb != reg) { + if (i <= DRB3) dimm03++; - } else { + else dimm47++; - } - mbsc0 = mbsc1; + + drb = reg; } }
- /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0]. + #if IS_ENABLED(CONFIG_SDRAMPWR_4DIMM) + /* + * For a 4 DIMM board, based on ASUS P2B-LS mainboard. * - * The 440BX datasheet says buffer frequency is independent from bus - * frequency and mismatch both ways are possible. This is how it is - * programmed in the ASUS P2B-LS mainboard. - * - * There are four main conditions to check when programming DRAM buffer - * frequency and strength: + * There are four main conditions to check when programming + * DRAM buffer frequency and strength: * * a: >2 rows populated across DIMM0,1 * b: >2 rows populated across DIMM2,3 @@ -474,62 +477,56 @@ * 6: NBXCFG[13] strapped as 66MHz * * CKE0/FENA ----------------------------------------------------------+ - * CKE1/GCKE -------------------[ MBFS ]------------------------+| - * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+|| - * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+||| - * DQMB5/CASB5# ---------------------------------------------------+|||| - * DQMA1/CASA1# --------------------------------------------------+||||| - * DQMA5/CASA5# -------------------------------------------------+|||||| - * CSA0-5#,CSB0-5# ----------------------------------------++++++||||||| - * CSA6#/CKE2# -------------------------------------------+||||||||||||| - * CSB6#/CKE4# ------------------------------------------+|||||||||||||| - * CSA7#/CKE3# -----------------------------------------+||||||||||||||| - * CSB7#/CKE5# ----------------------------------------+|||||||||||||||| - * MECC[7:0] #2/#1 (100MHz) -------------------------++||||||||||||||||| - * MD[63:0] #2/#1 (100MHz) ------------------------++||||||||||||||||||| + * CKE1/GCKE ----------------------[ MBFS ]---------------------+| + * DQMA/CASA[764320]# -------------[ 0 = 66MHz ]--------------------+|| + * DQMB1/CASB1# (Fixed for 66MHz) -[ 1 = 100MHz ]-------------------+||| + * DQMB5/CASB5# (Fixed for 66MHz) ---------------------------------+|||| + * DQMA1/CASA1# (Fixed for 66MHz) --------------------------------+||||| + * DQMA5/CASA5# (Fixed for 66MHz) -------------------------------+|||||| + * CSA[5:0]#,CSB[5:0]# ------------------------------------++++++||||||| + * CS[B7,A7,B6,A6]#/CKE[5342] -------------------------++++||||||||||||| + * MECC[7:0] #2/#1 ----------------------------------++||||||||||||||||| + * MD[63:0] #2/#1 ---------------------------------++||||||||||||||||||| * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+||||||||||||||||||||| * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+|||||||||||||||||||||| * Reserved ------------------------------------+||||||||||||||||||||||| * |||||||||||||||||||||||| - * 3 32 21 10 0 * 2 21 10 0 - * 9876543210987654321098765432109876543210 * 321098765432109876543210 - * a 10------------------------1010---------- * -1---------------11----- a - *!a 11------------------------1111---------- * -0---------------00----- !a - * b --10--------------------------1010------ * --1----------------11--- b - *!b --11--------------------------1111------ * --0----------------00--- !b - * c ----------------------------------1100-- * ----------------------1- c - *!c ----------------------------------1011-- * ----------------------0- !c - * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1 - * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6 - * | | | | | | | | | | ||||||| | | | | | | - * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA - * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE - * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]# - * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1# - * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5# - * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1# - * | | | | | | | | | | ||||||+------------- DQMA5/CASA5# - * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ] - * | | | | | | | | | +--------------------- CSA6#/CKE2# - * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4# - * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3# - * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5# - * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x) - * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x) - * | | | +--------------------------------- MD[63:0] #1 (2x) - * | | +----------------------------------- MD[63:0] #2 (2x) - * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# - * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA# - * MBSC[47:40] and MBFS[23] are reserved. - * - * This algorithm is checked against the ASUS P2B-LS (which has - * 4 DIMM slots) factory BIOS. - * Therefore it assumes a board with 4 slots, and will need testing - * on boards with 3 DIMM slots. + * 3 32 21 10 0 * 2 21 10 0 + * 9876543210987654321098765432109876543210 * 321098765432109876543210 + * 10------------------------1010---------- a -1---------------11----- + * 11------------------------1111---------- !a -0---------------00----- + * --10--------------------------1010------ b --1----------------11--- + * --11--------------------------1111------ !b --0----------------00--- + * ----------------------------------1100-- c ----------------------1- + * ----------------------------------1011-- !c ----------------------0- + * ----1010101000000000000000------------00 1 ---11111111111111----1-0 + * ----000000000000000000000010101010----00 6 ---1111111111111100000-0 + * | | | | | | | | | | ||||||| | | | | | | + * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA + * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE + * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]# + * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1# (66MHz: 2x) + * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5# (66MHz: 2x) + * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1# (66MHz: 2x) + * | | | | | | | | | | ||||||+------------- DQMA5/CASA5# (66MHz: 2x) + * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# (1x) + * | | | | | | | | | +--------------------- CSA6#/CKE2 + * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4 + * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3 + * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5 + * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 + * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 + * | | | +--------------------------------- MD[63:0] #1 + * | | +----------------------------------- MD[63:0] #2 + * | +------------------ MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# + * +------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA# */ + unsigned int fsb;
mbsc0 = 0x80; mbsc1 = 0x2a; + mbsc2 = 0; + mbfs1 = 0xff; mbfs2 = 0x1f; if (pci_read_config8(NB, NBXCFG + 1) & 0x30) { fsb = 66; @@ -542,24 +539,21 @@ mbsc4 = 0x0a; mbfs0 = 0x84; } - if (dimm03 > 2) { mbsc4 = mbsc4 | 0x80; - mbsc1 = mbsc1 | 0x28; mbfs2 = mbfs2 | 0x40; - mbfs0 = mbfs0 | 0x60; + if (fsb == 100) + mbfs0 |= 0x60; } else { mbsc4 = mbsc4 | 0xc0; - if (fsb == 100) { + if (fsb == 100) mbsc1 = mbsc1 | 0x3c; - } } if (dimm47 > 2) { mbsc4 = mbsc4 | 0x20; - mbsc1 = mbsc1 | 0x02; - mbsc0 = mbsc0 | 0x80; mbfs2 = mbfs2 | 0x20; - mbfs0 = mbfs0 | 0x18; + if (fsb == 100) + mbfs0 |= 0x18; } else { mbsc4 = mbsc4 | 0x30; if (fsb == 100) { @@ -573,14 +567,90 @@ } else { mbsc0 = mbsc0 | 0x2c; } + #else + /* + * For a 3 DIMM board, based on ASUS P2B mainboard. + * + * There are two main conditions to check when programming DRAM buffer + * frequency and strength: + * + * a: >2 rows populated across DIMM0,1 + * c: >4 rows populated across all DIMM slots + * + * CKE0 ---------------------------------------------------------------+ + * CKE1 ------------------------[ MBFS ]------------------------+| + * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+|| + * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+||| + * DQMB5/CASB5# ---------------------------------------------------+|||| + * DQMA1/CASA1# --------------------------------------------------+||||| + * DQMA5/CASA5# -------------------------------------------------+|||||| + * CSA0-5#,CSB0-5# ----------------------------------------++++++||||||| + * CSA6#/CKE2 --------------------------------------------+||||||||||||| + * CSB6#/CKE4 -------------------------------------------+|||||||||||||| + * CSA7#/CKE3 ------------------------------------------+||||||||||||||| + * CSB7#/CKE5 -----------------------------------------+|||||||||||||||| + * MECC[7:0] #2/#1 (100MHz) -------------------------++||||||||||||||||| + * MD[63:0] #2/#1 (100MHz) ------------------------++||||||||||||||||||| + * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+||||||||||||||||||||| + * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+|||||||||||||||||||||| + * Reserved ------------------------------------+||||||||||||||||||||||| + * |||||||||||||||||||||||| + * 3 32 21 10 0 * 2 21 10 0 + * 9876543210987654321098765432109876543210 * 321098765432109876543210 + * 10------------------------1111---------- a -1---------------------- + * 11------------------------1010---------- !a -0---------------------- + * --110000000010101010111111----1010--1010 * --01111000000000000000-0 + * ----------------------------------11---- c ----------------------1- + * ----------------------------------10---- !c ----------------------0- + * | | | | | | | | | | ||||||| | | | | | | + * | | | | | | | | | | ||||||| | | | | | +- CKE0 + * | | | | | | | | | | ||||||| | | | | +--- CKE1 + * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]# + * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1# + * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5# + * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1# + * | | | | | | | | | | ||||||+------------- DQMA5/CASA5# + * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# (2x) + * | | | | | | | | | +--------------------- CSA6#/CKE2 + * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4 + * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3 + * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5 + * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (1x) + * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (1x) + * | | | +--------------------------------- MD[63:0] #1 (1x) + * | | +----------------------------------- MD[63:0] #2 (1x) + * | +------------------ MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# + * +------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA# + */ + + mbsc0 = 0xaa; + mbsc1 = 0xea; + mbsc2 = 0xaf; + mbsc3 = 0x0a; + mbsc4 = 0xb0; + mbfs0 = 0x00; + mbfs1 = 0x00; + mbfs2 = 0x1e; + + if (dimm03 > 2) { + mbfs2 |= 0x40; + } else { + mbsc4 |= 0xc0; + mbsc1 |= 0x3c; + } + if ((dimm03 + dimm47) > 4) { + mbsc0 |= 0x30; + mbfs0 |= 0x02; + } + #endif
pci_write_config8(NB, MBSC + 0, mbsc0); pci_write_config8(NB, MBSC + 1, mbsc1); - pci_write_config8(NB, MBSC + 2, 0x00); + pci_write_config8(NB, MBSC + 2, mbsc2); pci_write_config8(NB, MBSC + 3, mbsc3); pci_write_config8(NB, MBSC + 4, mbsc4); pci_write_config8(NB, MBFS + 0, mbfs0); - pci_write_config8(NB, MBFS + 1, 0xff); + pci_write_config8(NB, MBFS + 1, mbfs1); pci_write_config8(NB, MBFS + 2, mbfs2); }