nb/amd/mct_ddr3: Update drive strength configuration

The existing drive strength calibration code did not strictly
follow the BKDG-defined setup process.  Bring the calibration
code in line with the BKDG recommendations.

Change-Id: I122eeb93958d88de59d0c3b2979f607afa2c52c3
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: https://review.coreboot.org/13145
Tested-by: build bot (Jenkins)
Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com>
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Timothy Pearson 2015-11-24 14:11:50 -06:00 committed by Martin Roth
parent a2df081d44
commit 2d500ba598
1 changed files with 32 additions and 17 deletions

View File

@ -6828,7 +6828,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for data lanes (Stage 1) */ /* Program TxPreP/TxPreN for data lanes (Stage 1) */
for (index = 0; index < 0x9; index++) { for (index = 0; index < 0x9; index++) {
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8)); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8));
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0006 | (index << 8), dword);
} }
@ -6841,13 +6841,13 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for data lanes (Stage 2) */ /* Program TxPreP/TxPreN for data lanes (Stage 2) */
for (index = 0; index < 0x9; index++) { for (index = 0; index < 0x9; index++) {
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8)); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8));
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f000a | (index << 8), dword);
} }
for (index = 0; index < 0x9; index++) { for (index = 0; index < 0x9; index++) {
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8));
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8), dword);
} }
@ -6859,15 +6859,15 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for command/address lines (Stage 1) */ /* Program TxPreP/TxPreN for command/address lines (Stage 1) */
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8006, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f800a, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8002, dword);
@ -6878,31 +6878,31 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for command/address lines (Stage 2) */ /* Program TxPreP/TxPreN for command/address lines (Stage 2) */
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8106, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f810a, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc006, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00a, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc00e, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= tx_pre; dword |= tx_pre;
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc012, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f8102, dword);
@ -6913,7 +6913,7 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for command/address lines (Stage 3) */ /* Program TxPreP/TxPreN for command/address lines (Stage 3) */
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0fc002, dword);
@ -6924,17 +6924,32 @@ static void InitPhyCompensation(struct MCTStatStruc *pMCTstat,
/* Program TxPreP/TxPreN for clock lines */ /* Program TxPreP/TxPreN for clock lines */
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2002, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2102, dword);
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202);
dword &= ~(0xfff); dword &= ~(0xffff);
dword |= (0x8000 | tx_pre); dword |= (0x8000 | tx_pre);
Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword); Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f2202, dword);
/* Be extra safe and wait for the predriver calibration to be applied
* to the hardware. The BKDG does not require this, but it does take
* some time for the data to propagate, so it's probably a good idea.
*/
uint8_t predriver_cal_pending = 1;
printk(BIOS_DEBUG, "Waiting for predriver calibration to be applied...");
while (predriver_cal_pending) {
predriver_cal_pending = 0;
for (index = 0; index < 0x9; index++) {
if (Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x0d0f0002 | (index << 8)) & 0x8000)
predriver_cal_pending = 1;
}
}
printk(BIOS_DEBUG, "done!\n");
} else { } else {
dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00); dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x00);
dword = 0; dword = 0;