mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-14 08:57:58 +00:00
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 2
Factor out common code for searching best DM/DQS window. Signed-off-by: Marek Vasut <marex@denx.de>
This commit is contained in:
parent
3b44f55c3b
commit
c8570afa04
1 changed files with 88 additions and 79 deletions
|
@ -2883,6 +2883,89 @@ static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* search_window() - Search for the/part of the window with DM/DQS shift
|
||||||
|
* @search_dm: If 1, search for the DM shift, if 0, search for DQS shift
|
||||||
|
* @rank_bgn: Rank number
|
||||||
|
* @write_group: Write Group
|
||||||
|
* @bgn_curr: Current window begin
|
||||||
|
* @end_curr: Current window end
|
||||||
|
* @bgn_best: Current best window begin
|
||||||
|
* @end_best: Current best window end
|
||||||
|
* @win_best: Size of the best window
|
||||||
|
* @new_dqs: New DQS value (only applicable if search_dm = 0).
|
||||||
|
*
|
||||||
|
* Search for the/part of the window with DM/DQS shift.
|
||||||
|
*/
|
||||||
|
static void search_window(const int search_dm,
|
||||||
|
const u32 rank_bgn, const u32 write_group,
|
||||||
|
int *bgn_curr, int *end_curr, int *bgn_best,
|
||||||
|
int *end_best, int *win_best, int new_dqs)
|
||||||
|
{
|
||||||
|
u32 bit_chk;
|
||||||
|
const int max = IO_IO_OUT1_DELAY_MAX - new_dqs;
|
||||||
|
int d, di;
|
||||||
|
|
||||||
|
/* Search for the/part of the window with DM/DQS shift. */
|
||||||
|
for (di = max; di >= 0; di -= DELTA_D) {
|
||||||
|
if (search_dm) {
|
||||||
|
d = di;
|
||||||
|
scc_mgr_apply_group_dm_out1_delay(d);
|
||||||
|
} else {
|
||||||
|
/* For DQS, we go from 0...max */
|
||||||
|
d = max - di;
|
||||||
|
/*
|
||||||
|
* Note: This only shifts DQS, so are we limiting ourselve to
|
||||||
|
* width of DQ unnecessarily.
|
||||||
|
*/
|
||||||
|
scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
|
||||||
|
d + new_dqs);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(0, &sdr_scc_mgr->update);
|
||||||
|
|
||||||
|
if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
|
||||||
|
PASS_ALL_BITS, &bit_chk,
|
||||||
|
0)) {
|
||||||
|
/* Set current end of the window. */
|
||||||
|
*end_curr = search_dm ? -d : d;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If a starting edge of our window has not been seen
|
||||||
|
* this is our current start of the DM window.
|
||||||
|
*/
|
||||||
|
if (*bgn_curr == IO_IO_OUT1_DELAY_MAX + 1)
|
||||||
|
*bgn_curr = search_dm ? -d : d;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If current window is bigger than best seen.
|
||||||
|
* Set best seen to be current window.
|
||||||
|
*/
|
||||||
|
if ((*end_curr - *bgn_curr + 1) > *win_best) {
|
||||||
|
*win_best = *end_curr - *bgn_curr + 1;
|
||||||
|
*bgn_best = *bgn_curr;
|
||||||
|
*end_best = *end_curr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* We just saw a failing test. Reset temp edge. */
|
||||||
|
*bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
||||||
|
*end_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
||||||
|
|
||||||
|
/* Early exit is only applicable to DQS. */
|
||||||
|
if (search_dm)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Early exit optimization: if the remaining delay
|
||||||
|
* chain space is less than already seen largest
|
||||||
|
* window we can exit.
|
||||||
|
*/
|
||||||
|
if (*win_best - 1 > IO_IO_OUT1_DELAY_MAX - new_dqs - d)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* center all windows. do per-bit-deskew to possibly increase size of
|
* center all windows. do per-bit-deskew to possibly increase size of
|
||||||
* certain windows.
|
* certain windows.
|
||||||
|
@ -2891,8 +2974,7 @@ static int
|
||||||
rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
|
rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
|
||||||
const u32 test_bgn)
|
const u32 test_bgn)
|
||||||
{
|
{
|
||||||
int i, d;
|
int i;
|
||||||
u32 bit_chk;
|
|
||||||
u32 sticky_bit_chk;
|
u32 sticky_bit_chk;
|
||||||
u32 min_index;
|
u32 min_index;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
|
@ -2975,37 +3057,8 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
|
||||||
right_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
|
right_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
|
||||||
|
|
||||||
/* Search for the/part of the window with DM shift. */
|
/* Search for the/part of the window with DM shift. */
|
||||||
for (d = IO_IO_OUT1_DELAY_MAX; d >= 0; d -= DELTA_D) {
|
search_window(1, rank_bgn, write_group, &bgn_curr, &end_curr,
|
||||||
scc_mgr_apply_group_dm_out1_delay(d);
|
&bgn_best, &end_best, &win_best, 0);
|
||||||
writel(0, &sdr_scc_mgr->update);
|
|
||||||
|
|
||||||
if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
|
|
||||||
PASS_ALL_BITS, &bit_chk,
|
|
||||||
0)) {
|
|
||||||
/* Set current end of the window. */
|
|
||||||
end_curr = -d;
|
|
||||||
/*
|
|
||||||
* If a starting edge of our window has not been seen
|
|
||||||
* this is our current start of the DM window.
|
|
||||||
*/
|
|
||||||
if (bgn_curr == IO_IO_OUT1_DELAY_MAX + 1)
|
|
||||||
bgn_curr = -d;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If current window is bigger than best seen.
|
|
||||||
* Set best seen to be current window.
|
|
||||||
*/
|
|
||||||
if ((end_curr-bgn_curr+1) > win_best) {
|
|
||||||
win_best = end_curr-bgn_curr+1;
|
|
||||||
bgn_best = bgn_curr;
|
|
||||||
end_best = end_curr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* We just saw a failing test. Reset temp edge. */
|
|
||||||
bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
|
||||||
end_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset DM delay chains to 0. */
|
/* Reset DM delay chains to 0. */
|
||||||
scc_mgr_apply_group_dm_out1_delay(0);
|
scc_mgr_apply_group_dm_out1_delay(0);
|
||||||
|
@ -3021,52 +3074,8 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Search for the/part of the window with DQS shifts. */
|
/* Search for the/part of the window with DQS shifts. */
|
||||||
for (d = 0; d <= IO_IO_OUT1_DELAY_MAX - new_dqs; d += DELTA_D) {
|
search_window(0, rank_bgn, write_group, &bgn_curr, &end_curr,
|
||||||
/*
|
&bgn_best, &end_best, &win_best, new_dqs);
|
||||||
* Note: This only shifts DQS, so are we limiting ourselve to
|
|
||||||
* width of DQ unnecessarily.
|
|
||||||
*/
|
|
||||||
scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
|
|
||||||
d + new_dqs);
|
|
||||||
|
|
||||||
writel(0, &sdr_scc_mgr->update);
|
|
||||||
if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
|
|
||||||
PASS_ALL_BITS, &bit_chk,
|
|
||||||
0)) {
|
|
||||||
/* Set current end of the window. */
|
|
||||||
end_curr = d;
|
|
||||||
/*
|
|
||||||
* If a beginning edge of our window has not been seen
|
|
||||||
* this is our current begin of the DM window.
|
|
||||||
*/
|
|
||||||
if (bgn_curr == IO_IO_OUT1_DELAY_MAX + 1)
|
|
||||||
bgn_curr = d;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If current window is bigger than best seen. Set best
|
|
||||||
* seen to be current window.
|
|
||||||
*/
|
|
||||||
if ((end_curr-bgn_curr+1) > win_best) {
|
|
||||||
win_best = end_curr-bgn_curr+1;
|
|
||||||
bgn_best = bgn_curr;
|
|
||||||
end_best = end_curr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* We just saw a failing test. Reset temp edge. */
|
|
||||||
bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
|
||||||
end_curr = IO_IO_OUT1_DELAY_MAX + 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Early exit optimization: if the remaining delay
|
|
||||||
* chain space is less than already seen largest
|
|
||||||
* window we can exit.
|
|
||||||
*/
|
|
||||||
if ((win_best-1) >
|
|
||||||
(IO_IO_OUT1_DELAY_MAX - new_dqs - d)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assign left and right edge for cal and reporting. */
|
/* Assign left and right edge for cal and reporting. */
|
||||||
left_edge[0] = -1 * bgn_best;
|
left_edge[0] = -1 * bgn_best;
|
||||||
|
|
Loading…
Reference in a new issue