From 2d987fe0fbd2c5271e7b9c4a183558cb6f4dc35a Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Tue, 8 Mar 2016 18:25:15 -0600 Subject: nb/amd/mct_ddr3: Consolidate duplicated code read_dqs_read_data_timing_registers() and read_read_dqs_timing_control_registers() served essentially the same function but had slightly different semantics, causing confusion and needlessly complex Family15h code. Consolidate both into read_dqs_read_data_timing_registers() and adjust surrounding code to match new semantics. Change-Id: I3be808db5d15ceec4c36d17582756b01425df09a Signed-off-by: Timothy Pearson Reviewed-on: https://review.coreboot.org/13994 Tested-by: build bot (Jenkins) Tested-by: Raptor Engineering Automated Test Stand Reviewed-by: Martin Roth --- src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c | 97 ++++-------------------- src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c | 100 ++++++++++++++++++------- 2 files changed, 87 insertions(+), 110 deletions(-) (limited to 'src/northbridge') diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c index fc081549f3..182fab040e 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctdqs_d.c @@ -17,8 +17,11 @@ static void write_dqs_receiver_enable_control_registers(uint16_t* current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg); -static void read_read_dqs_timing_control_registers(uint16_t* current_total_delay, - uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg); +static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, + uint8_t dct, uint8_t dimm, uint32_t index_reg); + +static void write_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, + uint8_t dct, uint8_t dimm, uint32_t index_reg); static void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat); @@ -383,76 +386,6 @@ static void write_dqs_write_data_timing_registers(uint16_t* delay, uint32_t dev, Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x3 | (dimm << 8), dword); } -static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) -{ - uint32_t dword; - uint32_t mask; - - if (is_fam15h()) - mask = 0x3e; - else - mask = 0x3f; - - /* Lanes 0 - 3 */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8)); - delay[3] = (dword >> 24) & mask; - delay[2] = (dword >> 16) & mask; - delay[1] = (dword >> 8) & mask; - delay[0] = dword & mask; - - /* Lanes 4 - 7 */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8)); - delay[7] = (dword >> 24) & mask; - delay[6] = (dword >> 16) & mask; - delay[5] = (dword >> 8) & mask; - delay[4] = dword & mask; - - /* Lane 8 (ECC) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8)); - delay[8] = dword & mask; -} - -static void write_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) -{ - uint32_t dword; - uint32_t mask; - - if (is_fam15h()) - mask = 0x3e; - else - mask = 0x3f; - - /* Lanes 0 - 3 */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8)); - dword &= ~(mask << 24); - dword &= ~(mask << 16); - dword &= ~(mask << 8); - dword &= ~mask; - dword |= (delay[3] & mask) << 24; - dword |= (delay[2] & mask) << 16; - dword |= (delay[1] & mask) << 8; - dword |= delay[0] & mask; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8), dword); - - /* Lanes 4 - 7 */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8)); - dword &= ~(mask << 24); - dword &= ~(mask << 16); - dword &= ~(mask << 8); - dword &= ~mask; - dword |= (delay[7] & mask) << 24; - dword |= (delay[6] & mask) << 16; - dword |= (delay[5] & mask) << 8; - dword |= delay[4] & mask; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8), dword); - - /* Lane 8 (ECC) */ - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8)); - dword &= ~mask; - dword |= delay[8] & mask; - Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8), dword); -} - /* DQS Position Training * Algorithm detailed in the Fam10h BKDG Rev. 3.62 section 2.8.9.9.3 */ @@ -982,7 +915,7 @@ static void Calc_SetMaxRdLatency_D_Fam15(struct MCTStatStruc *pMCTstat, continue; read_dqs_receiver_enable_control_registers(current_phy_phase_delay, dev, dct, dimm, index_reg); - read_read_dqs_timing_control_registers(current_read_dqs_delay, dev, dct, dimm, index_reg); + read_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg); for (lane = 0; lane < MAX_BYTE_LANES; lane++) if ((current_phy_phase_delay[lane] + current_read_dqs_delay[lane]) > max_delay) max_delay = (current_phy_phase_delay[lane] + current_read_dqs_delay[lane]); @@ -1409,10 +1342,10 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, /* 2.10.5.8.4 (2 C) * For each Read DQS Delay value from 0 to 1 UI */ - for (current_read_dqs_delay[lane] = 0; current_read_dqs_delay[lane] < 0x40; current_read_dqs_delay[lane] += 2) { + for (current_read_dqs_delay[lane] = 0; current_read_dqs_delay[lane] < 0x20; current_read_dqs_delay[lane]++) { print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 161 current_read_dqs_delay[lane] ", current_read_dqs_delay[lane], 6); - if ((current_read_dqs_delay[lane] >> 1) >= (32 - 16)) { + if (current_read_dqs_delay[lane] >= (32 - 16)) { check_antiphase = 1; } else { check_antiphase = 0; @@ -1433,7 +1366,7 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, dword = Get_NB32_DCT(dev, dct, 0x264); if ((dword & 0x1ffffff) != 0) { print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 162 early abort: F2x264 ", dword, 6); - dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */ + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 0; /* Fail */ continue; } } @@ -1444,16 +1377,16 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, dword = Get_NB32_DCT(dev, dct, 0x268) & 0x3ffff; print_debug_dqs("\t\t\t\t\tTrainDQSRdWrPos: 163 read results: F2x268 ", dword, 6); if (dword & (0x3 << (lane * 2))) - dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 0; /* Fail */ + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 0; /* Fail */ else - dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][(current_read_dqs_delay[lane] >> 1) + 16] = 1; /* Pass */ + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][current_read_dqs_delay[lane] + 16] = 1; /* Pass */ if (check_antiphase == 1) { /* Check antiphase results */ dword = Get_NB32_DCT(dev, dct, 0x26c) & 0x3ffff; if (dword & (0x3 << (lane * 2))) - dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - (current_read_dqs_delay[lane] >> 1))] = 0; /* Fail */ + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - current_read_dqs_delay[lane])] = 0; /* Fail */ else - dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - (current_read_dqs_delay[lane] >> 1))] = 1; /* Pass */ + dqs_results_array[Receiver & 0x1][lane - lane_start][current_write_data_delay[lane] - initial_write_dqs_delay[lane]][16 - (32 - current_read_dqs_delay[lane])] = 1; /* Pass */ } } } @@ -1511,8 +1444,8 @@ static uint8_t TrainDQSRdWrPos_D_Fam15(struct MCTStatStruc *pMCTstat, memcpy(current_read_dqs_delay, initial_read_dqs_delay, sizeof(current_read_dqs_delay)); /* Program the Read DQS Timing Control register with the center of the passing window */ - current_read_dqs_delay[lane] = region_center << 1; - passing_read_dqs_delay_found = 1; + current_read_dqs_delay[lane] = region_center; + passing_dqs_delay_found[lane] = 1; /* Commit the current Read DQS Timing Control settings to the hardware registers */ write_dqs_read_data_timing_registers(current_read_dqs_delay, dev, dct, dimm, index_reg); diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c index f0e670b473..da71816d6f 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mctsrc.c @@ -475,40 +475,84 @@ static void write_dram_phase_recovery_control_registers(uint16_t* current_total_ } } -static void read_read_dqs_timing_control_registers(uint16_t* current_total_delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) +static void read_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) { - uint8_t lane; + uint8_t shift; uint32_t dword; + uint32_t mask; - for (lane = 0; lane < MAX_BYTE_LANES; lane++) { - uint32_t rdt_reg; + if (is_fam15h()) { + mask = 0x3e; + shift = 1; + } + else { + mask = 0x3f; + shift = 0; + } - /* Calculate DRAM Read DQS Timing register location */ - if ((lane == 0) || (lane == 1) || (lane == 2) || (lane == 3)) - rdt_reg = 0x5; - if ((lane == 4) || (lane == 5) || (lane == 6) || (lane == 7)) - rdt_reg = 0x6; - if (lane == 8) - rdt_reg = 0x7; - rdt_reg |= (dimm << 8); + /* Lanes 0 - 3 */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8)); + delay[3] = ((dword >> 24) & mask) >> shift; + delay[2] = ((dword >> 16) & mask) >> shift; + delay[1] = ((dword >> 8) & mask) >> shift; + delay[0] = (dword & mask) >> shift; + + /* Lanes 4 - 7 */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8)); + delay[7] = ((dword >> 24) & mask) >> shift; + delay[6] = ((dword >> 16) & mask) >> shift; + delay[5] = ((dword >> 8) & mask) >> shift; + delay[4] = (dword & mask) >> shift; + + /* Lane 8 (ECC) */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8)); + delay[8] = (dword & mask) >> shift; +} - dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, rdt_reg); - if ((lane == 7) || (lane == 3)) { - current_total_delay[lane] = (dword >> 24) & 0x3f; - } - if ((lane == 6) || (lane == 2)) { - current_total_delay[lane] = (dword >> 16) & 0x3f; - } - if ((lane == 5) || (lane == 1)) { - current_total_delay[lane] = (dword >> 8) & 0x3f; - } - if ((lane == 8) || (lane == 4) || (lane == 0)) { - current_total_delay[lane] = dword & 0x3f; - } +static void write_dqs_read_data_timing_registers(uint16_t* delay, uint32_t dev, uint8_t dct, uint8_t dimm, uint32_t index_reg) +{ + uint8_t shift; + uint32_t dword; + uint32_t mask; - if (is_fam15h()) - current_total_delay[lane] >>= 1; + if (is_fam15h()) { + mask = 0x3e; + shift = 1; + } + else { + mask = 0x3f; + shift = 0; } + + /* Lanes 0 - 3 */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8)); + dword &= ~(mask << 24); + dword &= ~(mask << 16); + dword &= ~(mask << 8); + dword &= ~mask; + dword |= ((delay[3] << shift) & mask) << 24; + dword |= ((delay[2] << shift) & mask) << 16; + dword |= ((delay[1] << shift) & mask) << 8; + dword |= (delay[0] << shift) & mask; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x5 | (dimm << 8), dword); + + /* Lanes 4 - 7 */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8)); + dword &= ~(mask << 24); + dword &= ~(mask << 16); + dword &= ~(mask << 8); + dword &= ~mask; + dword |= ((delay[7] << shift) & mask) << 24; + dword |= ((delay[6] << shift) & mask) << 16; + dword |= ((delay[5] << shift) & mask) << 8; + dword |= (delay[4] << shift) & mask; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x6 | (dimm << 8), dword); + + /* Lane 8 (ECC) */ + dword = Get_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8)); + dword &= ~mask; + dword |= (delay[8] << shift) & mask; + Set_NB32_index_wait_DCT(dev, dct, index_reg, 0x7 | (dimm << 8), dword); } static uint32_t convert_testaddr_and_channel_to_address(struct DCTStatStruc *pDCTstat, uint32_t testaddr, uint8_t channel) @@ -1596,7 +1640,7 @@ static void dqsTrainMaxRdLatency_SW_Fam15(struct MCTStatStruc *pMCTstat, /* Retrieve the total delay values from pass 1 of DQS receiver enable training */ read_dqs_receiver_enable_control_registers(current_total_delay, dev, Channel, dimm, index_reg); - read_read_dqs_timing_control_registers(current_rdqs_total_delay, dev, Channel, dimm, index_reg); + read_dqs_read_data_timing_registers(current_rdqs_total_delay, dev, Channel, dimm, index_reg); for (lane = 0; lane < 8; lane++) { current_total_delay[lane] += current_rdqs_total_delay[lane]; -- cgit v1.2.3