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>
diff --git a/drivers/ddr/altera/sequencer.c b/drivers/ddr/altera/sequencer.c
index e99ecb4..cc5db16 100644
--- a/drivers/ddr/altera/sequencer.c
+++ b/drivers/ddr/altera/sequencer.c
@@ -2883,6 +2883,89 @@
 	}
 }
 
+/**
+ * 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
  * certain windows.
@@ -2891,8 +2974,7 @@
 rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 				   const u32 test_bgn)
 {
-	int i, d;
-	u32 bit_chk;
+	int i;
 	u32 sticky_bit_chk;
 	u32 min_index;
 	u32 addr;
@@ -2975,37 +3057,8 @@
 	right_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
 
 	/* Search for the/part of the window with DM shift. */
-	for (d = IO_IO_OUT1_DELAY_MAX; d >= 0; d -= DELTA_D) {
-		scc_mgr_apply_group_dm_out1_delay(d);
-		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;
-		}
-	}
+	search_window(1, rank_bgn, write_group, &bgn_curr, &end_curr,
+		      &bgn_best, &end_best, &win_best, 0);
 
 	/* Reset DM delay chains to 0. */
 	scc_mgr_apply_group_dm_out1_delay(0);
@@ -3021,52 +3074,8 @@
 	}
 
 	/* Search for the/part of the window with DQS shifts. */
-	for (d = 0; d <= IO_IO_OUT1_DELAY_MAX - new_dqs; d += DELTA_D) {
-		/*
-		 * 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;
-			}
-		}
-	}
+	search_window(0, rank_bgn, write_group, &bgn_curr, &end_curr,
+		      &bgn_best, &end_best, &win_best, new_dqs);
 
 	/* Assign left and right edge for cal and reporting. */
 	left_edge[0] = -1 * bgn_best;