From 901dc36e7a9eae6be1de24c7b61cfddee3bc80ef Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 13 Jul 2015 02:48:34 +0200 Subject: ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 3 Factor out common code from search_left_edge() and search_right_edge() which checks whether searching for the window edge should stop. The code is almost identical, so pull it into separate function and cater for the minor differences. Signed-off-by: Marek Vasut --- drivers/ddr/altera/sequencer.c | 126 ++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 66 deletions(-) (limited to 'drivers/ddr') diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c index 8f55e44..2ecf6b8 100644 --- a/drivers/ddr/altera/sequencer.c +++ b/drivers/ddr/altera/sequencer.c @@ -1781,6 +1781,60 @@ static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp) } /** + * search_stop_check() - Check if the detected edge is valid + * @write: Perform read (Stage 2) or write (Stage 3) calibration + * @d: DQS delay + * @rank_bgn: Rank number + * @write_group: Write Group + * @read_group: Read Group + * @bit_chk: Resulting bit mask after the test + * @sticky_bit_chk: Resulting sticky bit mask after the test + * @use_read_test: Perform read test + * + * Test if the found edge is valid. + */ +static u32 search_stop_check(const int write, const int d, const int rank_bgn, + const u32 write_group, const u32 read_group, + u32 *bit_chk, u32 *sticky_bit_chk, + const u32 use_read_test) +{ + const u32 ratio = RW_MGR_MEM_IF_READ_DQS_WIDTH / + RW_MGR_MEM_IF_WRITE_DQS_WIDTH; + const u32 correct_mask = write ? param->write_correct_mask : + param->read_correct_mask; + const u32 per_dqs = write ? RW_MGR_MEM_DQ_PER_WRITE_DQS : + RW_MGR_MEM_DQ_PER_READ_DQS; + u32 ret; + /* + * Stop searching when the read test doesn't pass AND when + * we've seen a passing read on every bit. + */ + if (write) { /* WRITE-ONLY */ + ret = !rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, + 0, PASS_ONE_BIT, + bit_chk, 0); + } else if (use_read_test) { /* READ-ONLY */ + ret = !rw_mgr_mem_calibrate_read_test(rank_bgn, read_group, + NUM_READ_PB_TESTS, + PASS_ONE_BIT, bit_chk, + 0, 0); + } else { /* READ-ONLY */ + rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 0, + PASS_ONE_BIT, bit_chk, 0); + *bit_chk = *bit_chk >> (per_dqs * + (read_group - (write_group * ratio))); + ret = (*bit_chk == 0); + } + *sticky_bit_chk = *sticky_bit_chk | *bit_chk; + ret = ret && (*sticky_bit_chk == correct_mask); + debug_cond(DLEVEL == 2, + "%s:%d center(left): dtap=%u => %u == %u && %u", + __func__, __LINE__, d, + *sticky_bit_chk, correct_mask, ret); + return ret; +} + +/** * search_left_edge() - Find left edge of DQ/DQS working phase * @write: Perform read (Stage 2) or write (Stage 3) calibration * @rank_bgn: Rank number @@ -1800,8 +1854,6 @@ static void search_left_edge(const int write, const int rank_bgn, u32 *bit_chk, u32 *sticky_bit_chk, int *left_edge, int *right_edge, const u32 use_read_test) { - const u32 correct_mask = write ? param->write_correct_mask : - param->read_correct_mask; const u32 delay_max = write ? IO_IO_OUT1_DELAY_MAX : IO_IO_IN_DELAY_MAX; const u32 dqs_max = write ? IO_IO_OUT1_DELAY_MAX : IO_DQS_IN_DELAY_MAX; const u32 per_dqs = write ? RW_MGR_MEM_DQ_PER_WRITE_DQS : @@ -1817,36 +1869,9 @@ static void search_left_edge(const int write, const int rank_bgn, writel(0, &sdr_scc_mgr->update); - /* - * Stop searching when the read test doesn't pass AND when - * we've seen a passing read on every bit. - */ - if (write) { /* WRITE-ONLY */ - stop = !rw_mgr_mem_calibrate_write_test(rank_bgn, - write_group, - 0, PASS_ONE_BIT, - bit_chk, 0); - } else if (use_read_test) { /* READ-ONLY */ - stop = !rw_mgr_mem_calibrate_read_test(rank_bgn, - read_group, NUM_READ_PB_TESTS, PASS_ONE_BIT, - bit_chk, 0, 0); - } else { /* READ-ONLY */ - rw_mgr_mem_calibrate_write_test(rank_bgn, - write_group, - 0, PASS_ONE_BIT, - bit_chk, 0); - *bit_chk = *bit_chk >> (per_dqs * - (read_group - (write_group * - RW_MGR_MEM_IF_READ_DQS_WIDTH / - RW_MGR_MEM_IF_WRITE_DQS_WIDTH))); - stop = (*bit_chk == 0); - } - *sticky_bit_chk = *sticky_bit_chk | *bit_chk; - stop = stop && (*sticky_bit_chk == correct_mask); - debug_cond(DLEVEL == 2, - "%s:%d center(left): dtap=%u => %u == %u && %u", __func__, __LINE__, d, - *sticky_bit_chk, correct_mask, stop); - + stop = search_stop_check(write, d, rank_bgn, write_group, + read_group, bit_chk, sticky_bit_chk, + use_read_test); if (stop == 1) break; @@ -1941,8 +1966,6 @@ static int search_right_edge(const int write, const int rank_bgn, u32 *bit_chk, u32 *sticky_bit_chk, int *left_edge, int *right_edge, const u32 use_read_test) { - const u32 correct_mask = write ? param->write_correct_mask : - param->read_correct_mask; const u32 delay_max = write ? IO_IO_OUT1_DELAY_MAX : IO_IO_IN_DELAY_MAX; const u32 dqs_max = write ? IO_IO_OUT1_DELAY_MAX : IO_DQS_IN_DELAY_MAX; const u32 per_dqs = write ? RW_MGR_MEM_DQ_PER_WRITE_DQS : @@ -1967,38 +1990,9 @@ static int search_right_edge(const int write, const int rank_bgn, writel(0, &sdr_scc_mgr->update); - /* - * Stop searching when the read test doesn't pass AND when - * we've seen a passing read on every bit. - */ - if (write) { /* WRITE-ONLY */ - stop = !rw_mgr_mem_calibrate_write_test(rank_bgn, - write_group, - 0, PASS_ONE_BIT, - bit_chk, 0); - - } else if (use_read_test) { /* READ-ONLY */ - stop = !rw_mgr_mem_calibrate_read_test(rank_bgn, - read_group, NUM_READ_PB_TESTS, PASS_ONE_BIT, - bit_chk, 0, 0); - } else { /* READ-ONLY */ - rw_mgr_mem_calibrate_write_test(rank_bgn, - write_group, - 0, PASS_ONE_BIT, - bit_chk, 0); - *bit_chk = *bit_chk >> (per_dqs * - (read_group - (write_group * - RW_MGR_MEM_IF_READ_DQS_WIDTH / - RW_MGR_MEM_IF_WRITE_DQS_WIDTH))); - stop = (*bit_chk == 0); - } - *sticky_bit_chk = *sticky_bit_chk | *bit_chk; - stop = stop && (*sticky_bit_chk == correct_mask); - - debug_cond(DLEVEL == 2, - "%s:%d center(right): dtap=%u => %u == %u && %u", __func__, __LINE__, d, - *sticky_bit_chk, correct_mask, stop); - + stop = search_stop_check(write, d, rank_bgn, write_group, + read_group, bit_chk, sticky_bit_chk, + use_read_test); if (stop == 1) { if (write && (d == 0)) { /* WRITE-ONLY */ for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) { -- cgit v1.1