summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimothy Pearson <tpearson@raptorengineeringinc.com>2016-04-29 01:35:21 -0500
committerTimothy Pearson <tpearson@raptorengineeringinc.com>2016-05-01 00:50:05 +0200
commit29dd5da1dc577bf97cb85998b17b2e163a5ab86e (patch)
tree4eb734c3b96ced19c35a55cabc8a8116c5c0b947 /src
parent263c679075816a0db146ff5fa6b94689837ff696 (diff)
downloadcoreboot-29dd5da1dc577bf97cb85998b17b2e163a5ab86e.tar.xz
nb/amd/mct_ddr3: Do not constantly reset read data timing registers to 0
During DQS receiver enable cycle training on Family 15h platforms the read data timing registers were inadvertently set to zero on every lane training attempt. Ensure that the read data timing registers are correctly set after each lane is trained in receiver enable cycle training. This allows more than one RDIMM to function on a given DCT channel. Change-Id: I87d732f0383e9785a73b57e6f48855f3e872f1f9 Tested-On: ASUS KGPE-D16 Tested-With: 1x Opteron 6262HE Tested-With: 4x Crucial 36KSF1G72PZ-1G6M1 (slots A2 / A1 / B2 / B1) Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: https://review.coreboot.org/14543 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand <noreply@raptorengineeringinc.com> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
index 81e22a87c9..7ef2900de1 100644
--- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
+++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c
@@ -1687,6 +1687,11 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
/* 2.10.5.8.3 (2) */
read_dqs_receiver_enable_control_registers(initial_phy_phase_delay, dev, dct, dimm, index_reg);
+ /* Reset the read data timing registers to 1UI before calculating MaxRdLatency */
+ for (internal_lane = 0; internal_lane < MAX_BYTE_LANES; internal_lane++)
+ current_read_dqs_delay[internal_lane] = 0x20;
+ write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
+
for (lane = 0; lane < lane_count; lane++) {
/* Initialize variables */
memset(dqs_results_array, 0, sizeof(dqs_results_array));
@@ -1711,11 +1716,6 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
/* 2.10.5.8.3 (4 A) */
write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
- /* Reset the read data timing registers to 1UI before calculating MaxRdLatency */
- for (internal_lane = 0; internal_lane < MAX_BYTE_LANES; internal_lane++)
- current_read_dqs_delay[internal_lane] = 0x20;
- write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg);
-
/* Calculate and program MaxRdLatency */
Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, dct, 0);
@@ -1769,6 +1769,7 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
/* Update hardware registers with final values */
write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg);
+ TrainDQSRdWrPos_D_Fam15(pMCTstat, pDCTstat, dct, Receiver, Receiver + 2, lane, lane + 1);
break;
}
prev = dqs_results_array[current_phy_phase_delay[lane]];