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>
This commit is contained in:
Timothy Pearson 2016-04-29 01:35:21 -05:00
parent 263c679075
commit 29dd5da1dc
1 changed files with 6 additions and 5 deletions

View File

@ -1687,6 +1687,11 @@ static void TrainDQSReceiverEnCyc_D_Fam15(struct MCTStatStruc *pMCTstat,
/* 2.10.5.8.3 (2) */ /* 2.10.5.8.3 (2) */
read_dqs_receiver_enable_control_registers(initial_phy_phase_delay, dev, dct, dimm, index_reg); 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++) { for (lane = 0; lane < lane_count; lane++) {
/* Initialize variables */ /* Initialize variables */
memset(dqs_results_array, 0, sizeof(dqs_results_array)); 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) */ /* 2.10.5.8.3 (4 A) */
write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg); 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 */ /* Calculate and program MaxRdLatency */
Calc_SetMaxRdLatency_D_Fam15(pMCTstat, pDCTstat, dct, 0); 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 */ /* Update hardware registers with final values */
write_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg); 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; break;
} }
prev = dqs_results_array[current_phy_phase_delay[lane]]; prev = dqs_results_array[current_phy_phase_delay[lane]];