Skip to contentSkip to conversation

socfpga: SPL and DDR init

PATCH New Marek Vasut 3 participants 185 messages Jul 27, 2015 – Aug 3, 2015 Page 2 of 2

Subsystems (5)
lore
Share & tools
lore
#123 lore raw

PATCH 119/172 ddr: altera: Clean up sdr_*_phase() part 2

In reply to Marek Vasut

Fix the arguments passed to these functions. The grp argument does not have to be passed via reference, it's never modified within either of those functions, so make it into a value.

---
 drivers/ddr/altera/sequencer.c | 40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)
drivers/ddr/altera/sequencer.c +20 -20
index 61ddc2c..f4101b1 100644
@@ -1332,7 +1332,7 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
 	}
 }
 
-static int sdr_working_phase(uint32_t *grp, uint32_t *bit_chk,
+static int sdr_working_phase(uint32_t grp, uint32_t *bit_chk,
 			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
 			      uint32_t *v, uint32_t *d, uint32_t *p,
 			      uint32_t *i, uint32_t *max_working_cnt)
@@ -1344,16 +1344,16 @@ static int sdr_working_phase(uint32_t *grp, uint32_t *bit_chk,
 	for (*d = 0; *d <= dtaps_per_ptap; (*d)++, tmp_delay +=
 		IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
 		*work_bgn = tmp_delay;
-		scc_mgr_set_dqs_en_delay_all_ranks(*grp, *d);
+		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
 
 		for (*i = 0; *i < VFIFO_SIZE; (*i)++) {
 			for (*p = 0; *p <= IO_DQS_EN_PHASE_MAX; (*p)++, *work_bgn +=
 				IO_DELAY_PER_OPA_TAP) {
-				scc_mgr_set_dqs_en_phase_all_ranks(*grp, *p);
+				scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
 				test_status =
 				rw_mgr_mem_calibrate_read_test_all_ranks
-				(*grp, 1, PASS_ONE_BIT, bit_chk, 0);
+				(grp, 1, PASS_ONE_BIT, bit_chk, 0);
 
 				if (test_status) {
 					*max_working_cnt = 1;
@@ -1367,7 +1367,7 @@ static int sdr_working_phase(uint32_t *grp, uint32_t *bit_chk,
 
 			if (*p > IO_DQS_EN_PHASE_MAX)
 				/* fiddle with FIFO */
-				rw_mgr_incr_vfifo(*grp, v);
+				rw_mgr_incr_vfifo(grp, v);
 		}
 
 		if (found_begin)
@@ -1384,7 +1384,7 @@ static int sdr_working_phase(uint32_t *grp, uint32_t *bit_chk,
 	}
 }
 
-static void sdr_backup_phase(uint32_t *grp, uint32_t *bit_chk,
+static void sdr_backup_phase(uint32_t grp, uint32_t *bit_chk,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
 			     uint32_t *p, uint32_t *max_working_cnt)
 {
@@ -1394,18 +1394,18 @@ static void sdr_backup_phase(uint32_t *grp, uint32_t *bit_chk,
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
 		*p = IO_DQS_EN_PHASE_MAX;
-		rw_mgr_decr_vfifo(*grp, v);
+		rw_mgr_decr_vfifo(grp, v);
 	} else {
 		(*p)--;
 	}
 	tmp_delay = *work_bgn - IO_DELAY_PER_OPA_TAP;
-	scc_mgr_set_dqs_en_phase_all_ranks(*grp, *p);
+	scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
 	for (*d = 0; *d <= IO_DQS_EN_DELAY_MAX && tmp_delay < *work_bgn;
 		(*d)++, tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
-		scc_mgr_set_dqs_en_delay_all_ranks(*grp, *d);
+		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
 
-		if (rw_mgr_mem_calibrate_read_test_all_ranks(*grp, 1,
+		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
 							     bit_chk, 0)) {
 			found_begin = 1;
@@ -1425,13 +1425,13 @@ static void sdr_backup_phase(uint32_t *grp, uint32_t *bit_chk,
 	(*p)++;
 	if (*p > IO_DQS_EN_PHASE_MAX) {
 		*p = 0;
-		rw_mgr_incr_vfifo(*grp, v);
+		rw_mgr_incr_vfifo(grp, v);
 	}
 
-	scc_mgr_set_dqs_en_delay_all_ranks(*grp, 0);
+	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 }
 
-static int sdr_nonworking_phase(uint32_t *grp, uint32_t *bit_chk,
+static int sdr_nonworking_phase(uint32_t grp, uint32_t *bit_chk,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
 			     uint32_t *p, uint32_t *i, uint32_t *max_working_cnt,
 			     uint32_t *work_end)
@@ -1443,16 +1443,16 @@ static int sdr_nonworking_phase(uint32_t *grp, uint32_t *bit_chk,
 	if (*p > IO_DQS_EN_PHASE_MAX) {
 		/* fiddle with FIFO */
 		*p = 0;
-		rw_mgr_incr_vfifo(*grp, v);
+		rw_mgr_incr_vfifo(grp, v);
 	}
 
 	for (; *i < VFIFO_SIZE + 1; (*i)++) {
 		for (; *p <= IO_DQS_EN_PHASE_MAX; (*p)++, *work_end
 			+= IO_DELAY_PER_OPA_TAP) {
-			scc_mgr_set_dqs_en_phase_all_ranks(*grp, *p);
+			scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
 			if (!rw_mgr_mem_calibrate_read_test_all_ranks
-				(*grp, 1, PASS_ONE_BIT, bit_chk, 0)) {
+				(grp, 1, PASS_ONE_BIT, bit_chk, 0)) {
 				found_end = 1;
 				break;
 			} else {
@@ -1465,7 +1465,7 @@ static int sdr_nonworking_phase(uint32_t *grp, uint32_t *bit_chk,
 
 		if (*p > IO_DQS_EN_PHASE_MAX) {
 			/* fiddle with FIFO */
-			rw_mgr_incr_vfifo(*grp, v);
+			rw_mgr_incr_vfifo(grp, v);
 			*p = 0;
 		}
 	}
@@ -1579,7 +1579,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
-	if (sdr_working_phase(&grp, &bit_chk, dtaps_per_ptap, &work_bgn, &v, &d,
+	if (sdr_working_phase(grp, &bit_chk, dtaps_per_ptap, &work_bgn, &v, &d,
 			      &p, &i, &max_working_cnt) == 0)
 		return 0;
 
@@ -1595,13 +1595,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 3a: if we have room, back off by one and
 		increment in dtaps * */
 
-		sdr_backup_phase(&grp, &bit_chk, &work_bgn, &v, &d, &p,
+		sdr_backup_phase(grp, &bit_chk, &work_bgn, &v, &d, &p,
 				 &max_working_cnt);
 
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(&grp, &bit_chk, &work_bgn, &v, &d, &p,
+		if (sdr_nonworking_phase(grp, &bit_chk, &work_bgn, &v, &d, &p,
 					 &i, &max_working_cnt, &work_end) == 0)
 			return 0;
 
Signature · 1 line
2.1.4
#124 lore raw

PATCH 120/172 ddr: altera: Clean up sdr_*_phase() part 3

In reply to Marek Vasut

Fix the arguments passed to these functions. The bit_chk is overriden by rw_mgr_mem_calibrate_read_test_all_ranks() which is invoked by all three sdr_*_phase() functions, so just make this into local variable.

---
 drivers/ddr/altera/sequencer.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/ddr/altera/sequencer.c +12 -9
index f4101b1..c62bec5 100644
@@ -1332,7 +1332,7 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
 	}
 }
 
-static int sdr_working_phase(uint32_t grp, uint32_t *bit_chk,
+static int sdr_working_phase(uint32_t grp,
 			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
 			      uint32_t *v, uint32_t *d, uint32_t *p,
 			      uint32_t *i, uint32_t *max_working_cnt)
@@ -1340,6 +1340,7 @@ static int sdr_working_phase(uint32_t grp, uint32_t *bit_chk,
 	uint32_t found_begin = 0;
 	uint32_t tmp_delay = 0;
 	uint32_t test_status;
+	u32 bit_chk;
 
 	for (*d = 0; *d <= dtaps_per_ptap; (*d)++, tmp_delay +=
 		IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
@@ -1353,7 +1354,7 @@ static int sdr_working_phase(uint32_t grp, uint32_t *bit_chk,
 
 				test_status =
 				rw_mgr_mem_calibrate_read_test_all_ranks
-				(grp, 1, PASS_ONE_BIT, bit_chk, 0);
+				(grp, 1, PASS_ONE_BIT, &bit_chk, 0);
 
 				if (test_status) {
 					*max_working_cnt = 1;
@@ -1384,12 +1385,13 @@ static int sdr_working_phase(uint32_t grp, uint32_t *bit_chk,
 	}
 }
 
-static void sdr_backup_phase(uint32_t grp, uint32_t *bit_chk,
+static void sdr_backup_phase(uint32_t grp,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
 			     uint32_t *p, uint32_t *max_working_cnt)
 {
 	uint32_t found_begin = 0;
 	uint32_t tmp_delay;
+	u32 bit_chk;
 
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
@@ -1407,7 +1409,7 @@ static void sdr_backup_phase(uint32_t grp, uint32_t *bit_chk,
 
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
-							     bit_chk, 0)) {
+							     &bit_chk, 0)) {
 			found_begin = 1;
 			*work_bgn = tmp_delay;
 			break;
@@ -1431,12 +1433,13 @@ static void sdr_backup_phase(uint32_t grp, uint32_t *bit_chk,
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 }
 
-static int sdr_nonworking_phase(uint32_t grp, uint32_t *bit_chk,
+static int sdr_nonworking_phase(uint32_t grp,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
 			     uint32_t *p, uint32_t *i, uint32_t *max_working_cnt,
 			     uint32_t *work_end)
 {
 	uint32_t found_end = 0;
+	u32 bit_chk;
 
 	(*p)++;
 	*work_end += IO_DELAY_PER_OPA_TAP;
@@ -1452,7 +1455,7 @@ static int sdr_nonworking_phase(uint32_t grp, uint32_t *bit_chk,
 			scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
 			if (!rw_mgr_mem_calibrate_read_test_all_ranks
-				(grp, 1, PASS_ONE_BIT, bit_chk, 0)) {
+				(grp, 1, PASS_ONE_BIT, &bit_chk, 0)) {
 				found_end = 1;
 				break;
 			} else {
@@ -1579,7 +1582,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
-	if (sdr_working_phase(grp, &bit_chk, dtaps_per_ptap, &work_bgn, &v, &d,
+	if (sdr_working_phase(grp, dtaps_per_ptap, &work_bgn, &v, &d,
 			      &p, &i, &max_working_cnt) == 0)
 		return 0;
 
@@ -1595,13 +1598,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 3a: if we have room, back off by one and
 		increment in dtaps * */
 
-		sdr_backup_phase(grp, &bit_chk, &work_bgn, &v, &d, &p,
+		sdr_backup_phase(grp, &work_bgn, &v, &d, &p,
 				 &max_working_cnt);
 
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(grp, &bit_chk, &work_bgn, &v, &d, &p,
+		if (sdr_nonworking_phase(grp, &work_bgn, &v, &d, &p,
 					 &i, &max_working_cnt, &work_end) == 0)
 			return 0;
 
Signature · 1 line
2.1.4
#125 lore raw

PATCH 121/172 ddr: altera: Clean up sdr_*_phase() part 4

In reply to Marek Vasut

Get rid of found_{begin,end} variables. Instead of breaking out through all of the loops, just return when the begin/end of the window is found and be done with it. Also clean up the trailing conditional expression, which is now much easier.

---
 drivers/ddr/altera/sequencer.c | 41 ++++++++++-------------------------------
 1 file changed, 10 insertions(+), 31 deletions(-)
drivers/ddr/altera/sequencer.c +10 -31
index c62bec5..df261ae 100644
@@ -1337,7 +1337,6 @@ static int sdr_working_phase(uint32_t grp,
 			      uint32_t *v, uint32_t *d, uint32_t *p,
 			      uint32_t *i, uint32_t *max_working_cnt)
 {
-	uint32_t found_begin = 0;
 	uint32_t tmp_delay = 0;
 	uint32_t test_status;
 	u32 bit_chk;
@@ -1358,31 +1357,20 @@ static int sdr_working_phase(uint32_t grp,
 
 				if (test_status) {
 					*max_working_cnt = 1;
-					found_begin = 1;
-					break;
+					return 1;
 				}
 			}
 
-			if (found_begin)
-				break;
-
 			if (*p > IO_DQS_EN_PHASE_MAX)
 				/* fiddle with FIFO */
 				rw_mgr_incr_vfifo(grp, v);
 		}
-
-		if (found_begin)
-			break;
 	}
 
-	if (*i >= VFIFO_SIZE) {
-		/* cannot find working solution */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: no vfifo/\
-			   ptap/dtap\n", __func__, __LINE__);
-		return 0;
-	} else {
-		return 1;
-	}
+	/* Cannot find working solution */
+	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: no vfifo/\
+		   ptap/dtap\n", __func__, __LINE__);
+	return 0;
 }
 
 static void sdr_backup_phase(uint32_t grp,
@@ -1438,7 +1426,6 @@ static int sdr_nonworking_phase(uint32_t grp,
 			     uint32_t *p, uint32_t *i, uint32_t *max_working_cnt,
 			     uint32_t *work_end)
 {
-	uint32_t found_end = 0;
 	u32 bit_chk;
 
 	(*p)++;
@@ -1456,16 +1443,12 @@ static int sdr_nonworking_phase(uint32_t grp,
 
 			if (!rw_mgr_mem_calibrate_read_test_all_ranks
 				(grp, 1, PASS_ONE_BIT, &bit_chk, 0)) {
-				found_end = 1;
-				break;
+				return 1;
 			} else {
 				(*max_working_cnt)++;
 			}
 		}
 
-		if (found_end)
-			break;
-
 		if (*p > IO_DQS_EN_PHASE_MAX) {
 			/* fiddle with FIFO */
 			rw_mgr_incr_vfifo(grp, v);
@@ -1473,14 +1456,10 @@ static int sdr_nonworking_phase(uint32_t grp,
 		}
 	}
 
-	if (*i >= VFIFO_SIZE + 1) {
-		/* cannot see edge of failing read */
-		debug_cond(DLEVEL == 2, "%s:%d sdr_nonworking_phase: end:\
-			   failed\n", __func__, __LINE__);
-		return 0;
-	} else {
-		return 1;
-	}
+	/* Cannot see edge of failing read. */
+	debug_cond(DLEVEL == 2, "%s:%d sdr_nonworking_phase: end:\
+		   failed\n", __func__, __LINE__);
+	return 0;
 }
 
 /**
Signature · 1 line
2.1.4
#126 lore raw

PATCH 122/172 ddr: altera: Clean up sdr_*_phase() part 5

In reply to Marek Vasut

Pull out the loop for eaching working/non-working DQS enable phase into a separate function, as this is mostly common code between. Clean up sdr_working_phase() and sdr_nonworking_phase() while switching these two functions to the common sdr_find_phase().

---
 drivers/ddr/altera/sequencer.c | 127 +++++++++++++++++++++++------------------
 1 file changed, 72 insertions(+), 55 deletions(-)
drivers/ddr/altera/sequencer.c +72 -55
index df261ae..c90bb9a 100644
@@ -1332,45 +1332,78 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
 	}
 }
 
-static int sdr_working_phase(uint32_t grp,
-			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
-			      uint32_t *v, uint32_t *d, uint32_t *p,
-			      uint32_t *i, uint32_t *max_working_cnt)
+/**
+ * sdr_find_phase() - Find DQS enable phase
+ * @working:	If 1, look for working phase, if 0, look for non-working phase
+ * @grp:	Read/Write group
+ * @v:		VFIFO value
+ * @work:	Working window position
+ * @i:		Iterator
+ * @p:		DQS Phase Iterator
+ * @max_working_cnt:	Counter
+ *
+ * Find working or non-working DQS enable phase setting.
+ */
+static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
+			  u32 *i, u32 *p, u32 *max_working_cnt)
 {
-	uint32_t tmp_delay = 0;
-	uint32_t test_status;
-	u32 bit_chk;
+	u32 ret, bit_chk;
+	const u32 end = VFIFO_SIZE + (working ? 0 : 1);
 
-	for (*d = 0; *d <= dtaps_per_ptap; (*d)++, tmp_delay +=
-		IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
-		*work_bgn = tmp_delay;
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
+	for (; *i < end; (*i)++) {
+		if (working)
+			*p = 0;
 
-		for (*i = 0; *i < VFIFO_SIZE; (*i)++) {
-			for (*p = 0; *p <= IO_DQS_EN_PHASE_MAX; (*p)++, *work_bgn +=
-				IO_DELAY_PER_OPA_TAP) {
-				scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
+		for (; *p <= IO_DQS_EN_PHASE_MAX; (*p)++) {
+			scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
-				test_status =
-				rw_mgr_mem_calibrate_read_test_all_ranks
-				(grp, 1, PASS_ONE_BIT, &bit_chk, 0);
+			ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+						PASS_ONE_BIT, &bit_chk, 0);
+			if (ret)
+				(*max_working_cnt)++;
 
-				if (test_status) {
-					*max_working_cnt = 1;
-					return 1;
-				}
-			}
+			if (!working)
+				ret = !ret;
+
+			if (ret)
+				return 0;
 
-			if (*p > IO_DQS_EN_PHASE_MAX)
-				/* fiddle with FIFO */
-				rw_mgr_incr_vfifo(grp, v);
+			*work += IO_DELAY_PER_OPA_TAP;
+		}
+
+		if (*p > IO_DQS_EN_PHASE_MAX) {
+			/* Fiddle with FIFO. */
+			rw_mgr_incr_vfifo(grp, v);
+			if (!working)
+				*p = 0;
 		}
 	}
 
+	return -EINVAL;
+}
+
+static int sdr_working_phase(uint32_t grp,
+			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
+			      uint32_t *v, uint32_t *d, uint32_t *p,
+			      uint32_t *i, uint32_t *max_working_cnt)
+{
+	int ret;
+
+	*work_bgn = 0;
+
+	for (*d = 0; *d <= dtaps_per_ptap; (*d)++) {
+		*i = 0;
+		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
+		ret = sdr_find_phase(1, grp, v, work_bgn, i, p, max_working_cnt);
+		if (!ret)
+			return 0;
+		*work_bgn += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
+	}
+
 	/* Cannot find working solution */
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: no vfifo/\
-		   ptap/dtap\n", __func__, __LINE__);
-	return 0;
+	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: no vfifo/ptap/dtap\n",
+		   __func__, __LINE__);
+	return -EINVAL;
 }
 
 static void sdr_backup_phase(uint32_t grp,
@@ -1426,40 +1459,24 @@ static int sdr_nonworking_phase(uint32_t grp,
 			     uint32_t *p, uint32_t *i, uint32_t *max_working_cnt,
 			     uint32_t *work_end)
 {
-	u32 bit_chk;
+	int ret;
 
 	(*p)++;
 	*work_end += IO_DELAY_PER_OPA_TAP;
 	if (*p > IO_DQS_EN_PHASE_MAX) {
-		/* fiddle with FIFO */
+		/* Fiddle with FIFO. */
 		*p = 0;
 		rw_mgr_incr_vfifo(grp, v);
 	}
 
-	for (; *i < VFIFO_SIZE + 1; (*i)++) {
-		for (; *p <= IO_DQS_EN_PHASE_MAX; (*p)++, *work_end
-			+= IO_DELAY_PER_OPA_TAP) {
-			scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
-
-			if (!rw_mgr_mem_calibrate_read_test_all_ranks
-				(grp, 1, PASS_ONE_BIT, &bit_chk, 0)) {
-				return 1;
-			} else {
-				(*max_working_cnt)++;
-			}
-		}
-
-		if (*p > IO_DQS_EN_PHASE_MAX) {
-			/* fiddle with FIFO */
-			rw_mgr_incr_vfifo(grp, v);
-			*p = 0;
-		}
+	ret = sdr_find_phase(0, grp, v, work_end, i, p, max_working_cnt);
+	if (ret) {
+		/* Cannot see edge of failing read. */
+		debug_cond(DLEVEL == 2, "%s:%d: end: failed\n",
+			   __func__, __LINE__);
 	}
 
-	/* Cannot see edge of failing read. */
-	debug_cond(DLEVEL == 2, "%s:%d sdr_nonworking_phase: end:\
-		   failed\n", __func__, __LINE__);
-	return 0;
+	return ret;
 }
 
 /**
@@ -1562,7 +1579,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
 	if (sdr_working_phase(grp, dtaps_per_ptap, &work_bgn, &v, &d,
-			      &p, &i, &max_working_cnt) == 0)
+			      &p, &i, &max_working_cnt))
 		return 0;
 
 	work_end = work_bgn;
@@ -1584,7 +1601,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
 		if (sdr_nonworking_phase(grp, &work_bgn, &v, &d, &p,
-					 &i, &max_working_cnt, &work_end) == 0)
+					 &i, &max_working_cnt, &work_end))
 			return 0;
 
 		/* ********************************************************* */
Signature · 1 line
2.1.4
#127 lore raw

PATCH 123/172 ddr: altera: Clean up sdr_*_phase() part 6

In reply to Marek Vasut

It is now clear that the max_working_cnt variable is totally unused. Zap the variable and zap other variables which became unused due to this change too.

---
 drivers/ddr/altera/sequencer.c | 40 +++++++++-------------------------------
 1 file changed, 9 insertions(+), 31 deletions(-)
drivers/ddr/altera/sequencer.c +9 -31
index c90bb9a..75a0699 100644
@@ -1340,12 +1340,11 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
  * @work:	Working window position
  * @i:		Iterator
  * @p:		DQS Phase Iterator
- * @max_working_cnt:	Counter
  *
  * Find working or non-working DQS enable phase setting.
  */
 static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
-			  u32 *i, u32 *p, u32 *max_working_cnt)
+			  u32 *i, u32 *p)
 {
 	u32 ret, bit_chk;
 	const u32 end = VFIFO_SIZE + (working ? 0 : 1);
@@ -1359,9 +1358,6 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
 
 			ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 						PASS_ONE_BIT, &bit_chk, 0);
-			if (ret)
-				(*max_working_cnt)++;
-
 			if (!working)
 				ret = !ret;
 
@@ -1385,7 +1381,7 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
 static int sdr_working_phase(uint32_t grp,
 			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
 			      uint32_t *v, uint32_t *d, uint32_t *p,
-			      uint32_t *i, uint32_t *max_working_cnt)
+			      uint32_t *i)
 {
 	int ret;
 
@@ -1394,7 +1390,7 @@ static int sdr_working_phase(uint32_t grp,
 	for (*d = 0; *d <= dtaps_per_ptap; (*d)++) {
 		*i = 0;
 		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
-		ret = sdr_find_phase(1, grp, v, work_bgn, i, p, max_working_cnt);
+		ret = sdr_find_phase(1, grp, v, work_bgn, i, p);
 		if (!ret)
 			return 0;
 		*work_bgn += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
@@ -1408,9 +1404,8 @@ static int sdr_working_phase(uint32_t grp,
 
 static void sdr_backup_phase(uint32_t grp,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
-			     uint32_t *p, uint32_t *max_working_cnt)
+			     uint32_t *p)
 {
-	uint32_t found_begin = 0;
 	uint32_t tmp_delay;
 	u32 bit_chk;
 
@@ -1431,16 +1426,11 @@ static void sdr_backup_phase(uint32_t grp,
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
 							     &bit_chk, 0)) {
-			found_begin = 1;
 			*work_bgn = tmp_delay;
 			break;
 		}
 	}
 
-	/* We have found a working dtap before the ptap found above */
-	if (found_begin == 1)
-		(*max_working_cnt)++;
-
 	/*
 	 * Restore VFIFO to old state before we decremented it
 	 * (if needed).
@@ -1456,7 +1446,7 @@ static void sdr_backup_phase(uint32_t grp,
 
 static int sdr_nonworking_phase(uint32_t grp,
 			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
-			     uint32_t *p, uint32_t *i, uint32_t *max_working_cnt,
+			     uint32_t *p, uint32_t *i,
 			     uint32_t *work_end)
 {
 	int ret;
@@ -1469,7 +1459,7 @@ static int sdr_nonworking_phase(uint32_t grp,
 		rw_mgr_incr_vfifo(grp, v);
 	}
 
-	ret = sdr_find_phase(0, grp, v, work_end, i, p, max_working_cnt);
+	ret = sdr_find_phase(0, grp, v, work_end, i, p);
 	if (ret) {
 		/* Cannot see edge of failing read. */
 		debug_cond(DLEVEL == 2, "%s:%d: end: failed\n",
@@ -1552,7 +1542,6 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 {
 	uint32_t v, d, p, i;
-	uint32_t max_working_cnt;
 	uint32_t bit_chk;
 	uint32_t dtaps_per_ptap;
 	uint32_t work_bgn, work_end;
@@ -1573,13 +1562,10 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* * Step 1 : First push vfifo until we get a failing read * */
 	v = find_vfifo_read(grp, &bit_chk);
 
-	max_working_cnt = 0;
-
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
-	if (sdr_working_phase(grp, dtaps_per_ptap, &work_bgn, &v, &d,
-			      &p, &i, &max_working_cnt))
+	if (sdr_working_phase(grp, dtaps_per_ptap, &work_bgn, &v, &d, &p, &i))
 		return 0;
 
 	work_end = work_bgn;
@@ -1594,14 +1580,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 3a: if we have room, back off by one and
 		increment in dtaps * */
 
-		sdr_backup_phase(grp, &work_bgn, &v, &d, &p,
-				 &max_working_cnt);
+		sdr_backup_phase(grp, &work_bgn, &v, &d, &p);
 
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
 		if (sdr_nonworking_phase(grp, &work_bgn, &v, &d, &p,
-					 &i, &max_working_cnt, &work_end))
+					 &i, &work_end))
 			return 0;
 
 		/* ********************************************************* */
@@ -1634,13 +1619,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 			   v, p, d, work_bgn);
 
 		work_end = work_bgn;
-
-		/* * The actual increment of dtaps is done outside of the
-		if/else loop to share code */
-
-		/* Only here to counterbalance a subtract later on which is
-		not needed if this branch of the algorithm is taken */
-		max_working_cnt++;
 	}
 
 	/* The dtap increment to find the failing edge is done here */
Signature · 1 line
2.1.4
#128 lore raw

PATCH 124/172 ddr: altera: Clean up sdr_*_phase() part 7

In reply to Marek Vasut

Wrap dtaps_per_ptap into the sdr_working_phase() function to trim down the number of params. It's a constant too.

---
 drivers/ddr/altera/sequencer.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
drivers/ddr/altera/sequencer.c +6 -5
index 75a0699..d93b5fe 100644
@@ -1378,11 +1378,12 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
 	return -EINVAL;
 }
 
-static int sdr_working_phase(uint32_t grp,
-			      uint32_t dtaps_per_ptap, uint32_t *work_bgn,
-			      uint32_t *v, uint32_t *d, uint32_t *p,
-			      uint32_t *i)
+static int sdr_working_phase(uint32_t grp, uint32_t *work_bgn,
+			     uint32_t *v, uint32_t *d, uint32_t *p,
+			     uint32_t *i)
 {
+	const u32 dtaps_per_ptap = IO_DELAY_PER_OPA_TAP /
+				   IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 	int ret;
 
 	*work_bgn = 0;
@@ -1565,7 +1566,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
-	if (sdr_working_phase(grp, dtaps_per_ptap, &work_bgn, &v, &d, &p, &i))
+	if (sdr_working_phase(grp, &work_bgn, &v, &d, &p, &i))
 		return 0;
 
 	work_end = work_bgn;
Signature · 1 line
2.1.4
#129 lore raw

PATCH 125/172 ddr: altera: Clean up sdr_*_phase() part 8

In reply to Marek Vasut

The work_bgn parameter of sdr_nonworking_phase() is unused, zap it.

---
 drivers/ddr/altera/sequencer.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/ddr/altera/sequencer.c +3 -6
index d93b5fe..e6fb576 100644
@@ -1445,10 +1445,8 @@ static void sdr_backup_phase(uint32_t grp,
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 }
 
-static int sdr_nonworking_phase(uint32_t grp,
-			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
-			     uint32_t *p, uint32_t *i,
-			     uint32_t *work_end)
+static int sdr_nonworking_phase(uint32_t grp, uint32_t *v, uint32_t *d,
+				uint32_t *p, uint32_t *i, uint32_t *work_end)
 {
 	int ret;
 
@@ -1586,8 +1584,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(grp, &work_bgn, &v, &d, &p,
-					 &i, &work_end))
+		if (sdr_nonworking_phase(grp, &v, &d, &p, &i, &work_end))
 			return 0;
 
 		/* ********************************************************* */
Signature · 1 line
2.1.4
#130 lore raw

PATCH 126/172 ddr: altera: Clean up sdr_*_phase() part 9

In reply to Marek Vasut

The "d" variable is set to 0 in sdr_backup_phase() and is not used at all in sdr_nonworking_phase(). Make it local and zap it respectively.

---
 drivers/ddr/altera/sequencer.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/ddr/altera/sequencer.c +11 -11
index e6fb576..e5dd81b 100644
@@ -1403,12 +1403,11 @@ static int sdr_working_phase(uint32_t grp, uint32_t *work_bgn,
 	return -EINVAL;
 }
 
-static void sdr_backup_phase(uint32_t grp,
-			     uint32_t *work_bgn, uint32_t *v, uint32_t *d,
-			     uint32_t *p)
+static void sdr_backup_phase(uint32_t grp, uint32_t *work_bgn,
+			     uint32_t *v, uint32_t *p)
 {
-	uint32_t tmp_delay;
-	u32 bit_chk;
+	u32 tmp_delay;
+	u32 bit_chk, d;
 
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
@@ -1420,9 +1419,8 @@ static void sdr_backup_phase(uint32_t grp,
 	tmp_delay = *work_bgn - IO_DELAY_PER_OPA_TAP;
 	scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
-	for (*d = 0; *d <= IO_DQS_EN_DELAY_MAX && tmp_delay < *work_bgn;
-		(*d)++, tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
+	for (d = 0; d <= IO_DQS_EN_DELAY_MAX && tmp_delay < *work_bgn; d++) {
+		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
@@ -1430,6 +1428,8 @@ static void sdr_backup_phase(uint32_t grp,
 			*work_bgn = tmp_delay;
 			break;
 		}
+
+		tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 	}
 
 	/*
@@ -1445,7 +1445,7 @@ static void sdr_backup_phase(uint32_t grp,
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 }
 
-static int sdr_nonworking_phase(uint32_t grp, uint32_t *v, uint32_t *d,
+static int sdr_nonworking_phase(uint32_t grp, uint32_t *v,
 				uint32_t *p, uint32_t *i, uint32_t *work_end)
 {
 	int ret;
@@ -1579,12 +1579,12 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 3a: if we have room, back off by one and
 		increment in dtaps * */
 
-		sdr_backup_phase(grp, &work_bgn, &v, &d, &p);
+		sdr_backup_phase(grp, &work_bgn, &v, &p);
 
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(grp, &v, &d, &p, &i, &work_end))
+		if (sdr_nonworking_phase(grp, &v, &p, &i, &work_end))
 			return 0;
 
 		/* ********************************************************* */
Signature · 1 line
2.1.4
#131 lore raw

PATCH 127/172 ddr: altera: Clean up sdr_*_phase() part 10

In reply to Marek Vasut

Clean up data types, constify where applicable and document the functions with kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 59 ++++++++++++++++++++++++++++++------------
 1 file changed, 42 insertions(+), 17 deletions(-)
drivers/ddr/altera/sequencer.c +42 -17
index e5dd81b..ff11702 100644
@@ -1378,9 +1378,19 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
 	return -EINVAL;
 }
 
-static int sdr_working_phase(uint32_t grp, uint32_t *work_bgn,
-			     uint32_t *v, uint32_t *d, uint32_t *p,
-			     uint32_t *i)
+/**
+ * sdr_working_phase() - Find working DQS enable phase
+ * @grp:	Read/Write group
+ * @work_bgn:	Working window start position
+ * @v:		VFIFO value
+ * @d:		dtaps output value
+ * @p:		DQS Phase Iterator
+ * @i:		Iterator
+ *
+ * Find working DQS enable phase setting.
+ */
+static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *d,
+			     u32 *p, u32 *i)
 {
 	const u32 dtaps_per_ptap = IO_DELAY_PER_OPA_TAP /
 				   IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
@@ -1403,11 +1413,19 @@ static int sdr_working_phase(uint32_t grp, uint32_t *work_bgn,
 	return -EINVAL;
 }
 
-static void sdr_backup_phase(uint32_t grp, uint32_t *work_bgn,
-			     uint32_t *v, uint32_t *p)
+/**
+ * sdr_backup_phase() - Find DQS enable backup phase
+ * @grp:	Read/Write group
+ * @work_bgn:	Working window start position
+ * @v:		VFIFO value
+ * @p:		DQS Phase Iterator
+ *
+ * Find DQS enable backup phase setting.
+ */
+static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *p)
 {
-	u32 tmp_delay;
-	u32 bit_chk, d;
+	u32 tmp_delay, bit_chk, d;
+	int ret;
 
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
@@ -1422,9 +1440,9 @@ static void sdr_backup_phase(uint32_t grp, uint32_t *work_bgn,
 	for (d = 0; d <= IO_DQS_EN_DELAY_MAX && tmp_delay < *work_bgn; d++) {
 		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
-		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-							     PASS_ONE_BIT,
-							     &bit_chk, 0)) {
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+					PASS_ONE_BIT, &bit_chk, 0);
+		if (ret) {
 			*work_bgn = tmp_delay;
 			break;
 		}
@@ -1432,10 +1450,7 @@ static void sdr_backup_phase(uint32_t grp, uint32_t *work_bgn,
 		tmp_delay += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 	}
 
-	/*
-	 * Restore VFIFO to old state before we decremented it
-	 * (if needed).
-	 */
+	/* Restore VFIFO to old state before we decremented it (if needed). */
 	(*p)++;
 	if (*p > IO_DQS_EN_PHASE_MAX) {
 		*p = 0;
@@ -1445,8 +1460,18 @@ static void sdr_backup_phase(uint32_t grp, uint32_t *work_bgn,
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 }
 
-static int sdr_nonworking_phase(uint32_t grp, uint32_t *v,
-				uint32_t *p, uint32_t *i, uint32_t *work_end)
+/**
+ * sdr_nonworking_phase() - Find non-working DQS enable phase
+ * @grp:	Read/Write group
+ * @work_end:	Working window end position
+ * @v:		VFIFO value
+ * @p:		DQS Phase Iterator
+ * @i:		Iterator
+ *
+ * Find non-working DQS enable phase setting.
+ */
+static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *v,
+				u32 *p, u32 *i)
 {
 	int ret;
 
@@ -1584,7 +1609,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(grp, &v, &p, &i, &work_end))
+		if (sdr_nonworking_phase(grp, &work_end, &v, &p, &i))
 			return 0;
 
 		/* ********************************************************* */
Signature · 1 line
2.1.4
#132 lore raw

PATCH 128/172 ddr: altera: Clean up rw_mgr_*_vfifo() part 1

In reply to Marek Vasut

Perform minor cleanup, fix data types and constify where applicable. Add kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)
drivers/ddr/altera/sequencer.c +18 -4
index ff11702..3d0dc59 100644
@@ -1286,17 +1286,31 @@ static uint32_t rw_mgr_mem_calibrate_read_test_all_ranks(uint32_t group,
 					      bit_chk, all_groups, 1);
 }
 
-static void rw_mgr_incr_vfifo(uint32_t grp, uint32_t *v)
+/**
+ * rw_mgr_incr_vfifo() - Increase VFIFO value
+ * @grp:	Read/Write group
+ * @v:		VFIFO value
+ *
+ * Increase VFIFO value.
+ */
+static void rw_mgr_incr_vfifo(const u32 grp, u32 *v)
 {
 	writel(grp, &phy_mgr_cmd->inc_vfifo_hard_phy);
 	(*v)++;
 }
 
-static void rw_mgr_decr_vfifo(uint32_t grp, uint32_t *v)
+/**
+ * rw_mgr_decr_vfifo() - Decrease VFIFO value
+ * @grp:	Read/Write group
+ * @v:		VFIFO value
+ *
+ * Decrease VFIFO value.
+ */
+static void rw_mgr_decr_vfifo(const u32 grp, u32 *v)
 {
-	uint32_t i;
+	u32 i;
 
-	for (i = 0; i < VFIFO_SIZE-1; i++)
+	for (i = 0; i < VFIFO_SIZE - 1; i++)
 		rw_mgr_incr_vfifo(grp, v);
 }
 
Signature · 1 line
2.1.4
#133 lore raw

PATCH 129/172 ddr: altera: Clean up rw_mgr_*_vfifo() part 2

In reply to Marek Vasut

Pluck out all this VFIFO value counting, which turns out to be completely unused. Thus, remove it to simplify the code.

---
 drivers/ddr/altera/sequencer.c | 92 +++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 51 deletions(-)
drivers/ddr/altera/sequencer.c +41 -51
index 3d0dc59..50a5b8e 100644
@@ -1289,38 +1289,35 @@ static uint32_t rw_mgr_mem_calibrate_read_test_all_ranks(uint32_t group,
 /**
  * rw_mgr_incr_vfifo() - Increase VFIFO value
  * @grp:	Read/Write group
- * @v:		VFIFO value
  *
  * Increase VFIFO value.
  */
-static void rw_mgr_incr_vfifo(const u32 grp, u32 *v)
+static void rw_mgr_incr_vfifo(const u32 grp)
 {
 	writel(grp, &phy_mgr_cmd->inc_vfifo_hard_phy);
-	(*v)++;
 }
 
 /**
  * rw_mgr_decr_vfifo() - Decrease VFIFO value
  * @grp:	Read/Write group
- * @v:		VFIFO value
  *
  * Decrease VFIFO value.
  */
-static void rw_mgr_decr_vfifo(const u32 grp, u32 *v)
+static void rw_mgr_decr_vfifo(const u32 grp)
 {
 	u32 i;
 
 	for (i = 0; i < VFIFO_SIZE - 1; i++)
-		rw_mgr_incr_vfifo(grp, v);
+		rw_mgr_incr_vfifo(grp);
 }
 
 static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
 {
-	uint32_t  v;
+	uint32_t v;
 	uint32_t fail_cnt = 0;
 	uint32_t test_status;
 
-	for (v = 0; v < VFIFO_SIZE; ) {
+	for (v = 0; v < VFIFO_SIZE; v++) {
 		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: vfifo %u\n",
 			   __func__, __LINE__, v);
 		test_status = rw_mgr_mem_calibrate_read_test_all_ranks
@@ -1333,7 +1330,7 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
 		}
 
 		/* fiddle with FIFO */
-		rw_mgr_incr_vfifo(grp, &v);
+		rw_mgr_incr_vfifo(grp);
 	}
 
 	if (v >= VFIFO_SIZE) {
@@ -1350,14 +1347,13 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
  * sdr_find_phase() - Find DQS enable phase
  * @working:	If 1, look for working phase, if 0, look for non-working phase
  * @grp:	Read/Write group
- * @v:		VFIFO value
  * @work:	Working window position
  * @i:		Iterator
  * @p:		DQS Phase Iterator
  *
  * Find working or non-working DQS enable phase setting.
  */
-static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
+static int sdr_find_phase(int working, const u32 grp, u32 *work,
 			  u32 *i, u32 *p)
 {
 	u32 ret, bit_chk;
@@ -1383,7 +1379,7 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
 
 		if (*p > IO_DQS_EN_PHASE_MAX) {
 			/* Fiddle with FIFO. */
-			rw_mgr_incr_vfifo(grp, v);
+			rw_mgr_incr_vfifo(grp);
 			if (!working)
 				*p = 0;
 		}
@@ -1396,14 +1392,13 @@ static int sdr_find_phase(int working, const u32 grp, u32 *v, u32 *work,
  * sdr_working_phase() - Find working DQS enable phase
  * @grp:	Read/Write group
  * @work_bgn:	Working window start position
- * @v:		VFIFO value
  * @d:		dtaps output value
  * @p:		DQS Phase Iterator
  * @i:		Iterator
  *
  * Find working DQS enable phase setting.
  */
-static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *d,
+static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *d,
 			     u32 *p, u32 *i)
 {
 	const u32 dtaps_per_ptap = IO_DELAY_PER_OPA_TAP /
@@ -1415,7 +1410,7 @@ static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *d,
 	for (*d = 0; *d <= dtaps_per_ptap; (*d)++) {
 		*i = 0;
 		scc_mgr_set_dqs_en_delay_all_ranks(grp, *d);
-		ret = sdr_find_phase(1, grp, v, work_bgn, i, p);
+		ret = sdr_find_phase(1, grp, work_bgn, i, p);
 		if (!ret)
 			return 0;
 		*work_bgn += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
@@ -1431,12 +1426,11 @@ static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *d,
  * sdr_backup_phase() - Find DQS enable backup phase
  * @grp:	Read/Write group
  * @work_bgn:	Working window start position
- * @v:		VFIFO value
  * @p:		DQS Phase Iterator
  *
  * Find DQS enable backup phase setting.
  */
-static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *p)
+static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *p)
 {
 	u32 tmp_delay, bit_chk, d;
 	int ret;
@@ -1444,7 +1438,7 @@ static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *p)
 	/* Special case code for backing up a phase */
 	if (*p == 0) {
 		*p = IO_DQS_EN_PHASE_MAX;
-		rw_mgr_decr_vfifo(grp, v);
+		rw_mgr_decr_vfifo(grp);
 	} else {
 		(*p)--;
 	}
@@ -1468,7 +1462,7 @@ static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *p)
 	(*p)++;
 	if (*p > IO_DQS_EN_PHASE_MAX) {
 		*p = 0;
-		rw_mgr_incr_vfifo(grp, v);
+		rw_mgr_incr_vfifo(grp);
 	}
 
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
@@ -1478,14 +1472,12 @@ static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *v, u32 *p)
  * sdr_nonworking_phase() - Find non-working DQS enable phase
  * @grp:	Read/Write group
  * @work_end:	Working window end position
- * @v:		VFIFO value
  * @p:		DQS Phase Iterator
  * @i:		Iterator
  *
  * Find non-working DQS enable phase setting.
  */
-static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *v,
-				u32 *p, u32 *i)
+static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *p, u32 *i)
 {
 	int ret;
 
@@ -1494,10 +1486,10 @@ static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *v,
 	if (*p > IO_DQS_EN_PHASE_MAX) {
 		/* Fiddle with FIFO. */
 		*p = 0;
-		rw_mgr_incr_vfifo(grp, v);
+		rw_mgr_incr_vfifo(grp);
 	}
 
-	ret = sdr_find_phase(0, grp, v, work_end, i, p);
+	ret = sdr_find_phase(0, grp, work_end, i, p);
 	if (ret) {
 		/* Cannot see edge of failing read. */
 		debug_cond(DLEVEL == 2, "%s:%d: end: failed\n",
@@ -1512,14 +1504,13 @@ static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *v,
  * @grp:	Read/Write group
  * @work_bgn:	First working settings
  * @work_end:	Last working settings
- * @val:	VFIFO value
  *
  * Find center of the working DQS enable window.
  */
 static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
-				  const u32 work_end, const u32 val)
+				  const u32 work_end)
 {
-	u32 bit_chk, work_mid, v = val;
+	u32 bit_chk, work_mid;
 	int tmp_delay = 0;
 	int i, p, d;
 
@@ -1556,19 +1547,18 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 	 * because the largest possible margin in 1 VFIFO cycle.
 	 */
 	for (i = 0; i < VFIFO_SIZE; i++) {
-		debug_cond(DLEVEL == 2, "find_dqs_en_phase: center: vfifo=%u\n",
-			   v);
+		debug_cond(DLEVEL == 2, "find_dqs_en_phase: center\n");
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
 							     &bit_chk, 0)) {
 			debug_cond(DLEVEL == 2,
-				   "%s:%d center: found: vfifo=%u ptap=%u dtap=%u\n",
-				   __func__, __LINE__, v, p, d);
+				   "%s:%d center: found: ptap=%u dtap=%u\n",
+				   __func__, __LINE__, p, d);
 			return 0;
 		}
 
 		/* Fiddle with FIFO. */
-		rw_mgr_incr_vfifo(grp, &v);
+		rw_mgr_incr_vfifo(grp);
 	}
 
 	debug_cond(DLEVEL == 2, "%s:%d center: failed.\n",
@@ -1579,7 +1569,7 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 /* find a good dqs enable to use */
 static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 {
-	uint32_t v, d, p, i;
+	uint32_t d, p, i;
 	uint32_t bit_chk;
 	uint32_t dtaps_per_ptap;
 	uint32_t work_bgn, work_end;
@@ -1598,12 +1588,12 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 
 	/* ********************************************************* */
 	/* * Step 1 : First push vfifo until we get a failing read * */
-	v = find_vfifo_read(grp, &bit_chk);
+	find_vfifo_read(grp, &bit_chk);
 
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
 	work_bgn = 0;
-	if (sdr_working_phase(grp, &work_bgn, &v, &d, &p, &i))
+	if (sdr_working_phase(grp, &work_bgn, &d, &p, &i))
 		return 0;
 
 	work_end = work_bgn;
@@ -1618,12 +1608,12 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* * step 3a: if we have room, back off by one and
 		increment in dtaps * */
 
-		sdr_backup_phase(grp, &work_bgn, &v, &p);
+		sdr_backup_phase(grp, &work_bgn, &p);
 
 		/* ********************************************************* */
 		/* * step 4a: go forward from working phase to non working
 		phase, increment in ptaps * */
-		if (sdr_nonworking_phase(grp, &work_end, &v, &p, &i))
+		if (sdr_nonworking_phase(grp, &work_end, &p, &i))
 			return 0;
 
 		/* ********************************************************* */
@@ -1632,7 +1622,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		/* Special case code for backing up a phase */
 		if (p == 0) {
 			p = IO_DQS_EN_PHASE_MAX;
-			rw_mgr_decr_vfifo(grp, &v);
+			rw_mgr_decr_vfifo(grp);
 		} else {
 			p = p - 1;
 		}
@@ -1644,16 +1634,16 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		the if/else loop to share code */
 		d = 0;
 
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: v/p: \
-			   vfifo=%u ptap=%u\n", __func__, __LINE__,
-			   v, p);
+		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: p: \
+			   ptap=%u\n", __func__, __LINE__,
+			   p);
 	} else {
 		/* ******************************************************* */
 		/* * step 3-5b:  Find the right edge of the window using
 		delay taps   * */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase:vfifo=%u \
+		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: \
 			   ptap=%u dtap=%u bgn=%u\n", __func__, __LINE__,
-			   v, p, d, work_bgn);
+			   p, d, work_bgn);
 
 		work_end = work_bgn;
 	}
@@ -1676,9 +1666,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	if (d != 0)
 		work_end -= IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: v/p/d: vfifo=%u \
+	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: p/d: \
 		   ptap=%u dtap=%u end=%u\n", __func__, __LINE__,
-		   v, p, d-1, work_end);
+		   p, d-1, work_end);
 
 	if (work_end < work_bgn) {
 		/* nil range */
@@ -1703,15 +1693,15 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	/* Special case code for backing up a phase */
 	if (p == 0) {
 		p = IO_DQS_EN_PHASE_MAX;
-		rw_mgr_decr_vfifo(grp, &v);
+		rw_mgr_decr_vfifo(grp);
 		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: backedup \
-			   cycle/phase: v=%u p=%u\n", __func__, __LINE__,
-			   v, p);
+			   cycle/phase: p=%u\n", __func__, __LINE__,
+			   p);
 	} else {
 		p = p - 1;
 		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: backedup \
-			   phase only: v=%u p=%u", __func__, __LINE__,
-			   v, p);
+			   phase only: p=%u", __func__, __LINE__,
+			   p);
 	}
 
 	scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
@@ -1778,7 +1768,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 
 	/* ******************************************** */
 	/* * step 6:  Find the centre of the window   * */
-	if (sdr_find_window_centre(grp, work_bgn, work_end, v))
+	if (sdr_find_window_centre(grp, work_bgn, work_end))
 		return 0; /* FIXME: Old code, return 0 means failure :-( */
 
 	return 1;
Signature · 1 line
2.1.4
#134 lore raw

PATCH 130/172 ddr: altera: Clean up find_vfifo_read()

In reply to Marek Vasut

Fix data types, constify where applicable, fix comments and debug strings. In case enough failing reads are detected, just return right away instead of breaking from the loop. This lets us make the error handling at the end much simpler.

---
 drivers/ddr/altera/sequencer.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)
drivers/ddr/altera/sequencer.c +18 -19
index 50a5b8e..fbbf874 100644
@@ -1311,36 +1311,35 @@ static void rw_mgr_decr_vfifo(const u32 grp)
 		rw_mgr_incr_vfifo(grp);
 }
 
-static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
+/**
+ * find_vfifo_failing_read() - Push VFIFO to get a failing read
+ * @grp:	Read/Write group
+ *
+ * Push VFIFO until a failing read happens.
+ */
+static int find_vfifo_failing_read(const u32 grp)
 {
-	uint32_t v;
-	uint32_t fail_cnt = 0;
-	uint32_t test_status;
+	u32 v, ret, bit_chk, fail_cnt = 0;
 
 	for (v = 0; v < VFIFO_SIZE; v++) {
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: vfifo %u\n",
+		debug_cond(DLEVEL == 2, "%s:%d: vfifo %u\n",
 			   __func__, __LINE__, v);
-		test_status = rw_mgr_mem_calibrate_read_test_all_ranks
-			(grp, 1, PASS_ONE_BIT, bit_chk, 0);
-		if (!test_status) {
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+						PASS_ONE_BIT, &bit_chk, 0);
+		if (!ret) {
 			fail_cnt++;
 
 			if (fail_cnt == 2)
-				break;
+				return v;
 		}
 
-		/* fiddle with FIFO */
+		/* Fiddle with FIFO. */
 		rw_mgr_incr_vfifo(grp);
 	}
 
-	if (v >= VFIFO_SIZE) {
-		/* no failing read found!! Something must have gone wrong */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: vfifo failed\n",
-			   __func__, __LINE__);
-		return 0;
-	} else {
-		return v;
-	}
+	/* No failing read found! Something must have gone wrong. */
+	debug_cond(DLEVEL == 2, "%s:%d: vfifo failed\n", __func__, __LINE__);
+	return 0;
 }
 
 /**
@@ -1588,7 +1587,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 
 	/* ********************************************************* */
 	/* * Step 1 : First push vfifo until we get a failing read * */
-	find_vfifo_read(grp, &bit_chk);
+	find_vfifo_failing_read(grp);
 
 	/* ******************************************************** */
 	/* * step 2: find first working phase, increment in ptaps * */
Signature · 1 line
2.1.4
#135 lore raw

PATCH 131/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 1

In reply to Marek Vasut

Fix broken multiline debug strings, fix comments.
No functional change.

---
 drivers/ddr/altera/sequencer.c | 150 +++++++++++++++++++----------------------
 1 file changed, 70 insertions(+), 80 deletions(-)
drivers/ddr/altera/sequencer.c +70 -80
index fbbf874..a9f31d4 100644
@@ -1566,7 +1566,7 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 }
 
 /* find a good dqs enable to use */
-static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
+static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 {
 	uint32_t d, p, i;
 	uint32_t bit_chk;
@@ -1581,16 +1581,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	scc_mgr_set_dqs_en_delay_all_ranks(grp, 0);
 	scc_mgr_set_dqs_en_phase_all_ranks(grp, 0);
 
-	/* ************************************************************** */
-	/* * Step 0 : Determine number of delay taps for each phase tap * */
-	dtaps_per_ptap = IO_DELAY_PER_OPA_TAP/IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
+	/* Step 0: Determine number of delay taps for each phase tap. */
+	dtaps_per_ptap = IO_DELAY_PER_OPA_TAP / IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 
-	/* ********************************************************* */
-	/* * Step 1 : First push vfifo until we get a failing read * */
+	/* Step 1: First push vfifo until we get a failing read. */
 	find_vfifo_failing_read(grp);
 
-	/* ******************************************************** */
-	/* * step 2: find first working phase, increment in ptaps * */
+	/* Step 2: Find first working phase, increment in ptaps. */
 	work_bgn = 0;
 	if (sdr_working_phase(grp, &work_bgn, &d, &p, &i))
 		return 0;
@@ -1598,25 +1595,25 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	work_end = work_bgn;
 
 	/*
-	 * If d is 0 then the working window covers a phase tap and
-	 * we can follow the old procedure otherwise, we've found the beginning,
+	 * If d is 0 then the working window covers a phase tap and we can
+	 * follow the old procedure. Otherwise, we've found the beginning
 	 * and we need to increment the dtaps until we find the end.
 	 */
 	if (d == 0) {
-		/* ********************************************************* */
-		/* * step 3a: if we have room, back off by one and
-		increment in dtaps * */
-
+		/*
+		 * Step 3a: If we have room, back off by one and
+		 *          increment in dtaps.
+		 */
 		sdr_backup_phase(grp, &work_bgn, &p);
 
-		/* ********************************************************* */
-		/* * step 4a: go forward from working phase to non working
-		phase, increment in ptaps * */
+		/*
+		 * Step 4a: go forward from working phase to non working
+		 * phase, increment in ptaps.
+		 */
 		if (sdr_nonworking_phase(grp, &work_end, &p, &i))
 			return 0;
 
-		/* ********************************************************* */
-		/* * step 5a:  back off one from last, increment in dtaps  * */
+		/* Step 5a: Back off one from last, increment in dtaps. */
 
 		/* Special case code for backing up a phase */
 		if (p == 0) {
@@ -1629,97 +1626,92 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		work_end -= IO_DELAY_PER_OPA_TAP;
 		scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
 
-		/* * The actual increment of dtaps is done outside of
-		the if/else loop to share code */
 		d = 0;
 
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: p: \
-			   ptap=%u\n", __func__, __LINE__,
-			   p);
+		debug_cond(DLEVEL == 2, "%s:%d p: ptap=%u\n",
+			   __func__, __LINE__, p);
 	} else {
-		/* ******************************************************* */
-		/* * step 3-5b:  Find the right edge of the window using
-		delay taps   * */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: \
-			   ptap=%u dtap=%u bgn=%u\n", __func__, __LINE__,
-			   p, d, work_bgn);
+		/*
+		 * Step 3-5b: Find the right edge of the window
+		 *            using delay taps.
+		 */
+		debug_cond(DLEVEL == 2,
+			   "%s:%d ptap=%u dtap=%u bgn=%u\n",
+			   __func__, __LINE__, p, d, work_bgn);
 
 		work_end = work_bgn;
 	}
 
-	/* The dtap increment to find the failing edge is done here */
-	for (; d <= IO_DQS_EN_DELAY_MAX; d++, work_end +=
-		IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
-			debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: \
-				   end-2: dtap=%u\n", __func__, __LINE__, d);
-			scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
+	/* The dtap increment to find the failing edge is done here. */
+	for (; d <= IO_DQS_EN_DELAY_MAX;
+	     d++, work_end += IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
+		debug_cond(DLEVEL == 2, "%s:%d end-2: dtap=%u\n",
+			   __func__, __LINE__, d);
 
-			if (!rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-								      PASS_ONE_BIT,
-								      &bit_chk, 0)) {
-				break;
-			}
+		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
+
+		if (!rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+							      PASS_ONE_BIT,
+							      &bit_chk, 0)) {
+			break;
+		}
 	}
 
 	/* Go back to working dtap */
 	if (d != 0)
 		work_end -= IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: p/d: \
-		   ptap=%u dtap=%u end=%u\n", __func__, __LINE__,
-		   p, d-1, work_end);
+	debug_cond(DLEVEL == 2,
+		   "%s:%d p/d: ptap=%u dtap=%u end=%u\n",
+		   __func__, __LINE__, p, d - 1, work_end);
 
 	if (work_end < work_bgn) {
 		/* nil range */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: end-2: \
-			   failed\n", __func__, __LINE__);
+		debug_cond(DLEVEL == 2, "%s:%d end-2: failed\n",
+			   __func__, __LINE__);
 		return 0;
 	}
 
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: found range [%u,%u]\n",
+	debug_cond(DLEVEL == 2, "%s:%d found range [%u,%u]\n",
 		   __func__, __LINE__, work_bgn, work_end);
 
-	/* *************************************************************** */
 	/*
-	 * * We need to calculate the number of dtaps that equal a ptap
-	 * * To do that we'll back up a ptap and re-find the edge of the
-	 * * window using dtaps
+	 * We need to calculate the number of dtaps that equal a ptap.
+	 * To do that we'll back up a ptap and re-find the edge of the
+	 * window using dtaps
 	 */
-
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: calculate dtaps_per_ptap \
-		   for tracking\n", __func__, __LINE__);
+	debug_cond(DLEVEL == 2, "%s:%d calculate dtaps_per_ptap for tracking\n",
+		   __func__, __LINE__);
 
 	/* Special case code for backing up a phase */
 	if (p == 0) {
 		p = IO_DQS_EN_PHASE_MAX;
 		rw_mgr_decr_vfifo(grp);
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: backedup \
-			   cycle/phase: p=%u\n", __func__, __LINE__,
-			   p);
+		debug_cond(DLEVEL == 2, "%s:%d backedup cycle/phase: p=%u\n",
+			   __func__, __LINE__, p);
 	} else {
 		p = p - 1;
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: backedup \
-			   phase only: p=%u", __func__, __LINE__,
-			   p);
+		debug_cond(DLEVEL == 2, "%s:%d backedup phase only: p=%u",
+			   __func__, __LINE__, p);
 	}
 
 	scc_mgr_set_dqs_en_phase_all_ranks(grp, p);
 
 	/*
 	 * Increase dtap until we first see a passing read (in case the
-	 * window is smaller than a ptap),
-	 * and then a failing read to mark the edge of the window again
+	 * window is smaller than a ptap), and then a failing read to
+	 * mark the edge of the window again.
 	 */
 
-	/* Find a passing read */
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: find passing read\n",
+	/* Find a passing read. */
+	debug_cond(DLEVEL == 2, "%s:%d find passing read\n",
 		   __func__, __LINE__);
 	found_passing_read = 0;
 	found_failing_read = 0;
 	initial_failing_dtap = d;
 	for (; d <= IO_DQS_EN_DELAY_MAX; d++) {
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: testing \
-			   read d=%u\n", __func__, __LINE__, d);
+		debug_cond(DLEVEL == 2, "%s:%d testing read d=%u\n",
+			   __func__, __LINE__, d);
 		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
@@ -1731,12 +1723,12 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 	}
 
 	if (found_passing_read) {
-		/* Find a failing read */
-		debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: find failing \
-			   read\n", __func__, __LINE__);
+		/* Find a failing read. */
+		debug_cond(DLEVEL == 2, "%s:%d find failing read\n",
+			   __func__, __LINE__);
 		for (d = d + 1; d <= IO_DQS_EN_DELAY_MAX; d++) {
-			debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: \
-				   testing read d=%u\n", __func__, __LINE__, d);
+			debug_cond(DLEVEL == 2, "%s:%d testing read d=%u\n",
+				   __func__, __LINE__, d);
 			scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
 			if (!rw_mgr_mem_calibrate_read_test_all_ranks
@@ -1746,9 +1738,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 			}
 		}
 	} else {
-		debug_cond(DLEVEL == 1, "%s:%d find_dqs_en_phase: failed to \
-			   calculate dtaps", __func__, __LINE__);
-		debug_cond(DLEVEL == 1, "per ptap. Fall back on static value\n");
+		debug_cond(DLEVEL == 1,
+			   "%s:%d failed to calculate dtaps per ptap. Fall back on static value\n",
+			   __func__, __LINE__);
 	}
 
 	/*
@@ -1761,14 +1753,12 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(uint32_t grp)
 		dtaps_per_ptap = d - initial_failing_dtap;
 
 	writel(dtaps_per_ptap, &sdr_reg_file->dtaps_per_ptap);
-	debug_cond(DLEVEL == 2, "%s:%d find_dqs_en_phase: dtaps_per_ptap=%u \
-		   - %u = %u",  __func__, __LINE__, d,
-		   initial_failing_dtap, dtaps_per_ptap);
+	debug_cond(DLEVEL == 2, "%s:%d dtaps_per_ptap=%u - %u = %u",
+		   __func__, __LINE__, d, initial_failing_dtap, dtaps_per_ptap);
 
-	/* ******************************************** */
-	/* * step 6:  Find the centre of the window   * */
+	/* Step 6: Find the centre of the window. */
 	if (sdr_find_window_centre(grp, work_bgn, work_end))
-		return 0; /* FIXME: Old code, return 0 means failure :-( */
+		return 0;
 
 	return 1;
 }
Signature · 1 line
2.1.4
#136 lore raw

PATCH 132/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 2

In reply to Marek Vasut

If d != 0 after sdr_working_phase() finishes, the else branch of the condition has no impact on anything at all, since work_end was already set independently of the value of "d" . Zap this useless code.

---
 drivers/ddr/altera/sequencer.c | 10 ----------
 1 file changed, 10 deletions(-)
drivers/ddr/altera/sequencer.c +0 -10
index a9f31d4..16d09c1 100644
@@ -1630,16 +1630,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 
 		debug_cond(DLEVEL == 2, "%s:%d p: ptap=%u\n",
 			   __func__, __LINE__, p);
-	} else {
-		/*
-		 * Step 3-5b: Find the right edge of the window
-		 *            using delay taps.
-		 */
-		debug_cond(DLEVEL == 2,
-			   "%s:%d ptap=%u dtap=%u bgn=%u\n",
-			   __func__, __LINE__, p, d, work_bgn);
-
-		work_end = work_bgn;
 	}
 
 	/* The dtap increment to find the failing edge is done here. */
Signature · 1 line
2.1.4
#137 lore raw

PATCH 133/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 3

In reply to Marek Vasut

Clean up odd multiline loop, no functional change.

---
 drivers/ddr/altera/sequencer.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/ddr/altera/sequencer.c +3 -2
index 16d09c1..3d975f9 100644
@@ -1633,8 +1633,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 	}
 
 	/* The dtap increment to find the failing edge is done here. */
-	for (; d <= IO_DQS_EN_DELAY_MAX;
-	     d++, work_end += IO_DELAY_PER_DQS_EN_DCHAIN_TAP) {
+	for (; d <= IO_DQS_EN_DELAY_MAX; d++) {
 		debug_cond(DLEVEL == 2, "%s:%d end-2: dtap=%u\n",
 			   __func__, __LINE__, d);
 
@@ -1645,6 +1644,8 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 							      &bit_chk, 0)) {
 			break;
 		}
+
+		work_end += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
 	}
 
 	/* Go back to working dtap */
Signature · 1 line
2.1.4
#138 lore raw

PATCH 134/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 4

In reply to Marek Vasut

Implement common sdr_find_phase_delay() function and convert all places which use such code to this unified function. No functional change to the code.

---
 drivers/ddr/altera/sequencer.c | 103 ++++++++++++++++++++---------------------
 1 file changed, 49 insertions(+), 54 deletions(-)
drivers/ddr/altera/sequencer.c +49 -54
index 3d975f9..e575c21 100644
@@ -1343,6 +1343,43 @@ static int find_vfifo_failing_read(const u32 grp)
 }
 
 /**
+ * sdr_find_phase_delay() - Find DQS enable phase or delay
+ * @working:	If 1, look for working phase/delay, if 0, look for non-working
+ * @delay:	If 1, look for delay, if 0, look for phase
+ * @grp:	Read/Write group
+ * @work:	Working window position
+ * @work_inc:	Working window increment
+ * @pd:		DQS Phase/Delay Iterator
+ *
+ * Find working or non-working DQS enable phase setting.
+ */
+static int sdr_find_phase_delay(int working, int delay, const u32 grp,
+				u32 *work, const u32 work_inc, u32 *pd)
+{
+	const u32 max = delay ? IO_DQS_EN_DELAY_MAX : IO_DQS_EN_PHASE_MAX;
+	u32 ret, bit_chk;
+
+	for (; *pd <= max; (*pd)++) {
+		if (delay)
+			scc_mgr_set_dqs_en_delay_all_ranks(grp, *pd);
+		else
+			scc_mgr_set_dqs_en_phase_all_ranks(grp, *pd);
+
+		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+					PASS_ONE_BIT, &bit_chk, 0);
+		if (!working)
+			ret = !ret;
+
+		if (ret)
+			return 0;
+
+		if (work)
+			*work += work_inc;
+	}
+
+	return -EINVAL;
+}
+/**
  * sdr_find_phase() - Find DQS enable phase
  * @working:	If 1, look for working phase, if 0, look for non-working phase
  * @grp:	Read/Write group
@@ -1355,26 +1392,17 @@ static int find_vfifo_failing_read(const u32 grp)
 static int sdr_find_phase(int working, const u32 grp, u32 *work,
 			  u32 *i, u32 *p)
 {
-	u32 ret, bit_chk;
 	const u32 end = VFIFO_SIZE + (working ? 0 : 1);
+	int ret;
 
 	for (; *i < end; (*i)++) {
 		if (working)
 			*p = 0;
 
-		for (; *p <= IO_DQS_EN_PHASE_MAX; (*p)++) {
-			scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
-
-			ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-						PASS_ONE_BIT, &bit_chk, 0);
-			if (!working)
-				ret = !ret;
-
-			if (ret)
-				return 0;
-
-			*work += IO_DELAY_PER_OPA_TAP;
-		}
+		ret = sdr_find_phase_delay(working, 0, grp, work,
+					   IO_DELAY_PER_OPA_TAP, p);
+		if (!ret)
+			return 0;
 
 		if (*p > IO_DQS_EN_PHASE_MAX) {
 			/* Fiddle with FIFO. */
@@ -1569,7 +1597,6 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 {
 	uint32_t d, p, i;
-	uint32_t bit_chk;
 	uint32_t dtaps_per_ptap;
 	uint32_t work_bgn, work_end;
 	uint32_t found_passing_read, found_failing_read, initial_failing_dtap;
@@ -1633,20 +1660,8 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 	}
 
 	/* The dtap increment to find the failing edge is done here. */
-	for (; d <= IO_DQS_EN_DELAY_MAX; d++) {
-		debug_cond(DLEVEL == 2, "%s:%d end-2: dtap=%u\n",
-			   __func__, __LINE__, d);
-
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
-
-		if (!rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-							      PASS_ONE_BIT,
-							      &bit_chk, 0)) {
-			break;
-		}
-
-		work_end += IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
-	}
+	sdr_find_phase_delay(0, 1, grp, &work_end,
+			     IO_DELAY_PER_DQS_EN_DCHAIN_TAP, &d);
 
 	/* Go back to working dtap */
 	if (d != 0)
@@ -1697,37 +1712,17 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
 	/* Find a passing read. */
 	debug_cond(DLEVEL == 2, "%s:%d find passing read\n",
 		   __func__, __LINE__);
-	found_passing_read = 0;
-	found_failing_read = 0;
-	initial_failing_dtap = d;
-	for (; d <= IO_DQS_EN_DELAY_MAX; d++) {
-		debug_cond(DLEVEL == 2, "%s:%d testing read d=%u\n",
-			   __func__, __LINE__, d);
-		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
-		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-							     PASS_ONE_BIT,
-							     &bit_chk, 0)) {
-			found_passing_read = 1;
-			break;
-		}
-	}
+	initial_failing_dtap = d;
 
+	found_passing_read = !sdr_find_phase_delay(1, 1, grp, NULL, 0, &d);
 	if (found_passing_read) {
 		/* Find a failing read. */
 		debug_cond(DLEVEL == 2, "%s:%d find failing read\n",
 			   __func__, __LINE__);
-		for (d = d + 1; d <= IO_DQS_EN_DELAY_MAX; d++) {
-			debug_cond(DLEVEL == 2, "%s:%d testing read d=%u\n",
-				   __func__, __LINE__, d);
-			scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
-
-			if (!rw_mgr_mem_calibrate_read_test_all_ranks
-				(grp, 1, PASS_ONE_BIT, &bit_chk, 0)) {
-				found_failing_read = 1;
-				break;
-			}
-		}
+		d++;
+		found_failing_read = !sdr_find_phase_delay(0, 1, grp, NULL, 0,
+							   &d);
 	} else {
 		debug_cond(DLEVEL == 1,
 			   "%s:%d failed to calculate dtaps per ptap. Fall back on static value\n",
Signature · 1 line
2.1.4
#139 lore raw

PATCH 135/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 5

In reply to Marek Vasut

Fix the data types, constify where applicable.

---
 drivers/ddr/altera/sequencer.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/ddr/altera/sequencer.c +6 -6
index e575c21..b700116 100644
@@ -1593,13 +1593,13 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 	return -EINVAL;
 }
 
-/* find a good dqs enable to use */
-static uint32_t rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(u32 grp)
+static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 {
-	uint32_t d, p, i;
-	uint32_t dtaps_per_ptap;
-	uint32_t work_bgn, work_end;
-	uint32_t found_passing_read, found_failing_read, initial_failing_dtap;
+	u32 d, p, i;
+	u32 dtaps_per_ptap;
+	u32 work_bgn, work_end;
+	u32 found_passing_read, found_failing_read, initial_failing_dtap;
+	int ret;
 
 	debug("%s:%d %u\n", __func__, __LINE__, grp);
 
Signature · 1 line
2.1.4
#140 lore raw

PATCH 136/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 6

In reply to Marek Vasut

Fix the return value to match common conventions and propagate this change through the code.

---
 drivers/ddr/altera/sequencer.c | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)
drivers/ddr/altera/sequencer.c +14 -17
index b700116..5f23777 100644
@@ -1593,7 +1593,7 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 	return -EINVAL;
 }
 
-static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
+static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 {
 	u32 d, p, i;
 	u32 dtaps_per_ptap;
@@ -1616,8 +1616,9 @@ static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 
 	/* Step 2: Find first working phase, increment in ptaps. */
 	work_bgn = 0;
-	if (sdr_working_phase(grp, &work_bgn, &d, &p, &i))
-		return 0;
+	ret = sdr_working_phase(grp, &work_bgn, &d, &p, &i);
+	if (ret)
+		return ret;
 
 	work_end = work_bgn;
 
@@ -1637,8 +1638,9 @@ static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 		 * Step 4a: go forward from working phase to non working
 		 * phase, increment in ptaps.
 		 */
-		if (sdr_nonworking_phase(grp, &work_end, &p, &i))
-			return 0;
+		ret = sdr_nonworking_phase(grp, &work_end, &p, &i);
+		if (ret)
+			return ret;
 
 		/* Step 5a: Back off one from last, increment in dtaps. */
 
@@ -1675,7 +1677,7 @@ static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 		/* nil range */
 		debug_cond(DLEVEL == 2, "%s:%d end-2: failed\n",
 			   __func__, __LINE__);
-		return 0;
+		return -EINVAL;
 	}
 
 	debug_cond(DLEVEL == 2, "%s:%d found range [%u,%u]\n",
@@ -1743,10 +1745,9 @@ static u32 rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 		   __func__, __LINE__, d, initial_failing_dtap, dtaps_per_ptap);
 
 	/* Step 6: Find the centre of the window. */
-	if (sdr_find_window_centre(grp, work_bgn, work_end))
-		return 0;
+	ret = sdr_find_window_center(grp, work_bgn, work_end);
 
-	return 1;
+	return ret;
 }
 
 /* per-bit deskew DQ and center */
@@ -2184,7 +2185,7 @@ static int rw_mgr_mem_calibrate_dqs_enable_calibration(const u32 rw_group,
 	/* We start at zero, so have one less dq to devide among */
 	const u32 delay_step = IO_IO_IN_DELAY_MAX /
 			       (RW_MGR_MEM_DQ_PER_READ_DQS - 1);
-	int found;
+	int ret;
 	u32 i, p, d, r;
 
 	debug("%s:%d (%u,%u)\n", __func__, __LINE__, rw_group, test_bgn);
@@ -2210,11 +2211,11 @@ static int rw_mgr_mem_calibrate_dqs_enable_calibration(const u32 rw_group,
 	 * Try rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase across different
 	 * dq_in_delay values
 	 */
-	found = rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(rw_group);
+	ret = rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(rw_group);
 
 	debug_cond(DLEVEL == 1,
 		   "%s:%d: g=%u found=%u; Reseting delay chain to zero\n",
-		   __func__, __LINE__, rw_group, found);
+		   __func__, __LINE__, rw_group, !ret);
 
 	for (r = 0; r < RW_MGR_MEM_NUMBER_OF_RANKS;
 	     r += NUM_RANKS_PER_SHADOW_REG) {
@@ -2222,11 +2223,7 @@ static int rw_mgr_mem_calibrate_dqs_enable_calibration(const u32 rw_group,
 		writel(0, &sdr_scc_mgr->update);
 	}
 
-	if (!found)
-		return -EINVAL;
-
-	return 0;
-
+	return ret;
 }
 
 /**
Signature · 1 line
2.1.4
#141 lore raw

PATCH 137/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() part 7

In reply to Marek Vasut

Add kerneldoc, no functional change.

---
 drivers/ddr/altera/sequencer.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/ddr/altera/sequencer.c +6 -0
index 5f23777..6999504 100644
@@ -1593,6 +1593,12 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 	return -EINVAL;
 }
 
+/**
+ * rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase() - Find a good DQS enable to use
+ * @grp:	Read/Write Group
+ *
+ * Find a good DQS enable to use.
+ */
 static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 {
 	u32 d, p, i;
Signature · 1 line
2.1.4
#142 lore raw

PATCH 138/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test_all_ranks()

In reply to Marek Vasut
---
 drivers/ddr/altera/sequencer.c | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)
drivers/ddr/altera/sequencer.c +25 -15
index 6999504..f7e2e40 100644
@@ -1278,12 +1278,23 @@ static uint32_t rw_mgr_mem_calibrate_read_test(uint32_t rank_bgn, uint32_t group
 	}
 }
 
-static uint32_t rw_mgr_mem_calibrate_read_test_all_ranks(uint32_t group,
-	uint32_t num_tries, uint32_t all_correct, uint32_t *bit_chk,
-	uint32_t all_groups)
+/**
+ * rw_mgr_mem_calibrate_read_test_all_ranks() - Perform READ test on all ranks
+ * @grp:		Read/Write group
+ * @num_tries:		Number of retries of the test
+ * @all_correct:	All bits must be correct in the mask
+ * @all_groups:		Test all R/W groups
+ *
+ * Perform a READ test across all memory ranks.
+ */
+static int
+rw_mgr_mem_calibrate_read_test_all_ranks(const u32 grp, const u32 num_tries,
+					 const u32 all_correct,
+					 const u32 all_groups)
 {
-	return rw_mgr_mem_calibrate_read_test(0, group, num_tries, all_correct,
-					      bit_chk, all_groups, 1);
+	u32 bit_chk;
+	return rw_mgr_mem_calibrate_read_test(0, grp, num_tries, all_correct,
+					      &bit_chk, all_groups, 1);
 }
 
 /**
@@ -1319,13 +1330,13 @@ static void rw_mgr_decr_vfifo(const u32 grp)
  */
 static int find_vfifo_failing_read(const u32 grp)
 {
-	u32 v, ret, bit_chk, fail_cnt = 0;
+	u32 v, ret, fail_cnt = 0;
 
 	for (v = 0; v < VFIFO_SIZE; v++) {
 		debug_cond(DLEVEL == 2, "%s:%d: vfifo %u\n",
 			   __func__, __LINE__, v);
 		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-						PASS_ONE_BIT, &bit_chk, 0);
+						PASS_ONE_BIT, 0);
 		if (!ret) {
 			fail_cnt++;
 
@@ -1357,7 +1368,7 @@ static int sdr_find_phase_delay(int working, int delay, const u32 grp,
 				u32 *work, const u32 work_inc, u32 *pd)
 {
 	const u32 max = delay ? IO_DQS_EN_DELAY_MAX : IO_DQS_EN_PHASE_MAX;
-	u32 ret, bit_chk;
+	u32 ret;
 
 	for (; *pd <= max; (*pd)++) {
 		if (delay)
@@ -1366,7 +1377,7 @@ static int sdr_find_phase_delay(int working, int delay, const u32 grp,
 			scc_mgr_set_dqs_en_phase_all_ranks(grp, *pd);
 
 		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-					PASS_ONE_BIT, &bit_chk, 0);
+					PASS_ONE_BIT, 0);
 		if (!working)
 			ret = !ret;
 
@@ -1459,7 +1470,7 @@ static int sdr_working_phase(const u32 grp, u32 *work_bgn, u32 *d,
  */
 static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *p)
 {
-	u32 tmp_delay, bit_chk, d;
+	u32 tmp_delay, d;
 	int ret;
 
 	/* Special case code for backing up a phase */
@@ -1476,7 +1487,7 @@ static void sdr_backup_phase(const u32 grp, u32 *work_bgn, u32 *p)
 		scc_mgr_set_dqs_en_delay_all_ranks(grp, d);
 
 		ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
-					PASS_ONE_BIT, &bit_chk, 0);
+					PASS_ONE_BIT, 0);
 		if (ret) {
 			*work_bgn = tmp_delay;
 			break;
@@ -1537,7 +1548,7 @@ static int sdr_nonworking_phase(const u32 grp, u32 *work_end, u32 *p, u32 *i)
 static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 				  const u32 work_end)
 {
-	u32 bit_chk, work_mid;
+	u32 work_mid;
 	int tmp_delay = 0;
 	int i, p, d;
 
@@ -1577,7 +1588,7 @@ static int sdr_find_window_center(const u32 grp, const u32 work_bgn,
 		debug_cond(DLEVEL == 2, "find_dqs_en_phase: center\n");
 		if (rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
 							     PASS_ONE_BIT,
-							     &bit_chk, 0)) {
+							     0)) {
 			debug_cond(DLEVEL == 2,
 				   "%s:%d center: found: ptap=%u dtap=%u\n",
 				   __func__, __LINE__, p, d);
@@ -2427,7 +2438,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_end(uint32_t read_group,
 static uint32_t rw_mgr_mem_calibrate_lfifo(void)
 {
 	uint32_t found_one;
-	uint32_t bit_chk;
 
 	debug("%s:%d\n", __func__, __LINE__);
 
@@ -2447,7 +2457,7 @@ static uint32_t rw_mgr_mem_calibrate_lfifo(void)
 		if (!rw_mgr_mem_calibrate_read_test_all_ranks(0,
 							      NUM_READ_TESTS,
 							      PASS_ALL_BITS,
-							      &bit_chk, 1)) {
+							      1)) {
 			break;
 		}
 
Signature · 1 line
2.1.4
#143 lore raw

PATCH 139/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 1

In reply to Marek Vasut

Clean up the debug output handling at the end of the function and factor out common function call from the condition.

---
 drivers/ddr/altera/sequencer.c | 29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)
drivers/ddr/altera/sequencer.c +16 -13
index f7e2e40..c7ff863 100644
@@ -1189,6 +1189,8 @@ static uint32_t rw_mgr_mem_calibrate_read_test(uint32_t rank_bgn, uint32_t group
 	*bit_chk = param->read_correct_mask;
 	correct_mask_vg = param->read_correct_mask_vg;
 
+	int ret;
+
 	uint32_t quick_read_mode = (((STATIC_CALIB_STEPS) &
 		CALIB_SKIP_DELAY_SWEEPS) && ENABLE_SUPER_QUICK_CALIBRATION);
 
@@ -1260,22 +1262,23 @@ static uint32_t rw_mgr_mem_calibrate_read_test(uint32_t rank_bgn, uint32_t group
 	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
 	writel(RW_MGR_CLEAR_DQS_ENABLE, addr + (group << 2));
 
+	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+
 	if (all_correct) {
-		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "%s:%d read_test(%u,ALL,%u) =>\
-			   (%u == %u) => %lu", __func__, __LINE__, group,
-			   all_groups, *bit_chk, param->read_correct_mask,
-			   (long unsigned int)(*bit_chk ==
-			   param->read_correct_mask));
-		return *bit_chk == param->read_correct_mask;
+		ret = (*bit_chk == param->read_correct_mask);
+		debug_cond(DLEVEL == 2,
+			   "%s:%d read_test(%u,ALL,%u) => (%u == %u) => %i\n",
+			   __func__, __LINE__, group, all_groups, *bit_chk,
+			   param->read_correct_mask, ret);
 	} else	{
-		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "%s:%d read_test(%u,ONE,%u) =>\
-			   (%u != %lu) => %lu\n", __func__, __LINE__,
-			   group, all_groups, *bit_chk, (long unsigned int)0,
-			   (long unsigned int)(*bit_chk != 0x00));
-		return *bit_chk != 0x00;
+		ret = (*bit_chk != 0x00);
+		debug_cond(DLEVEL == 2,
+			   "%s:%d read_test(%u,ONE,%u) => (%u != %u) => %i\n",
+			   __func__, __LINE__, group, all_groups, *bit_chk,
+			   0, ret);
 	}
+
+	return ret;
 }
 
 /**
Signature · 1 line
2.1.4
#144 lore raw

PATCH 140/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 2

In reply to Marek Vasut

Clean up data types and constify where applicable. No function change.

---
 drivers/ddr/altera/sequencer.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)
drivers/ddr/altera/sequencer.c +15 -15
index c7ff863..76d141a 100644
@@ -1174,25 +1174,25 @@ static void rw_mgr_mem_calibrate_read_load_patterns(const u32 rank_bgn,
  * inserted into the mix used to align dqs enable. has more thorough checks
  * than the regular read test.
  */
-static uint32_t rw_mgr_mem_calibrate_read_test(uint32_t rank_bgn, uint32_t group,
-	uint32_t num_tries, uint32_t all_correct, uint32_t *bit_chk,
-	uint32_t all_groups, uint32_t all_ranks)
+static int
+rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
+			       const u32 num_tries, const u32 all_correct,
+			       u32 *bit_chk,
+			       const u32 all_groups, const u32 all_ranks)
 {
-	uint32_t r, vg;
-	uint32_t correct_mask_vg;
-	uint32_t tmp_bit_chk;
-	uint32_t rank_end = all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS :
+	const u32 rank_end = all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS :
 		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
-	uint32_t addr;
-	uint32_t base_rw_mgr;
+	const u32 quick_read_mode =
+		((STATIC_CALIB_STEPS & CALIB_SKIP_DELAY_SWEEPS) &&
+		 ENABLE_SUPER_QUICK_CALIBRATION);
+	u32 correct_mask_vg = param->read_correct_mask_vg;
+	u32 tmp_bit_chk;
+	u32 base_rw_mgr;
+	u32 addr;
 
-	*bit_chk = param->read_correct_mask;
-	correct_mask_vg = param->read_correct_mask_vg;
+	int r, vg, ret;
 
-	int ret;
-
-	uint32_t quick_read_mode = (((STATIC_CALIB_STEPS) &
-		CALIB_SKIP_DELAY_SWEEPS) && ENABLE_SUPER_QUICK_CALIBRATION);
+	*bit_chk = param->read_correct_mask;
 
 	for (r = rank_bgn; r < rank_end; r++) {
 		if (param->skip_ranks[r])
Signature · 1 line
2.1.4
#145 lore raw

PATCH 141/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 3

In reply to Marek Vasut

The C language has signed types, so make use of them. Fix this obscene loop, which tries to do away with unsigned type, but just makes the code more cryptic.

---
 drivers/ddr/altera/sequencer.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/ddr/altera/sequencer.c +3 -4
index 76d141a..c03fae1 100644
@@ -1232,7 +1232,8 @@ rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
 			&sdr_rw_load_jump_mgr_regs->load_jump_add3);
 
 		tmp_bit_chk = 0;
-		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS-1; ; vg--) {
+		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS - 1; vg >= 0;
+		     vg--) {
 			/* reset the fifos to get pointers to known state */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
@@ -1252,10 +1253,8 @@ rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
 
 			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
 			tmp_bit_chk = tmp_bit_chk | (correct_mask_vg & ~(base_rw_mgr));
-
-			if (vg == 0)
-				break;
 		}
+
 		*bit_chk &= tmp_bit_chk;
 	}
 
Signature · 1 line
2.1.4
#146 lore raw

PATCH 142/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 4

In reply to Marek Vasut

Clean up the inner loop a bit. No functional change.

---
 drivers/ddr/altera/sequencer.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/ddr/altera/sequencer.c +11 -9
index c03fae1..4585e37 100644
@@ -1234,25 +1234,27 @@ rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
 		tmp_bit_chk = 0;
 		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS - 1; vg >= 0;
 		     vg--) {
-			/* reset the fifos to get pointers to known state */
+			/* Reset the FIFOs to get pointers to known state. */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 			writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
 				  RW_MGR_RESET_READ_DATAPATH_OFFSET);
 
-			tmp_bit_chk = tmp_bit_chk << (RW_MGR_MEM_DQ_PER_READ_DQS
-				/ RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS);
-
-			if (all_groups)
-				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_ALL_GROUPS_OFFSET;
-			else
-				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
+			if (all_groups) {
+				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
+				       RW_MGR_RUN_ALL_GROUPS_OFFSET;
+			} else {
+				addr = SDR_PHYGRP_RWMGRGRP_ADDRESS |
+				       RW_MGR_RUN_SINGLE_GROUP_OFFSET;
+			}
 
 			writel(RW_MGR_READ_B2B, addr +
 			       ((group * RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS +
 			       vg) << 2));
 
 			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
-			tmp_bit_chk = tmp_bit_chk | (correct_mask_vg & ~(base_rw_mgr));
+			tmp_bit_chk <<= RW_MGR_MEM_DQ_PER_READ_DQS /
+					RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS;
+			tmp_bit_chk |= correct_mask_vg & ~(base_rw_mgr);
 		}
 
 		*bit_chk &= tmp_bit_chk;
Signature · 1 line
2.1.4
#147 lore raw

PATCH 143/172 ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 5

In reply to Marek Vasut

Make the function documentation into kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/ddr/altera/sequencer.c +13 -4
index 4585e37..0d1e6c8 100644
@@ -1169,10 +1169,19 @@ static void rw_mgr_mem_calibrate_read_load_patterns(const u32 rank_bgn,
 	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
 }
 
-/*
- * try a read and see if it returns correct data back. has dummy reads
- * inserted into the mix used to align dqs enable. has more thorough checks
- * than the regular read test.
+/**
+ * rw_mgr_mem_calibrate_read_test() - Perform READ test on single rank
+ * @rank_bgn:		Rank number
+ * @group:		Read/Write group
+ * @num_tries:		Number of retries of the test
+ * @all_correct:	All bits must be correct in the mask
+ * @bit_chk:		Resulting bit mask after the test
+ * @all_groups:		Test all R/W groups
+ * @all_ranks:		Test all ranks
+ *
+ * Try a read and see if it returns correct data back. Test has dummy reads
+ * inserted into the mix used to align DQS enable. Test has more thorough
+ * checks than the regular read test.
  */
 static int
 rw_mgr_mem_calibrate_read_test(const u32 rank_bgn, const u32 group,
Signature · 1 line
2.1.4
#148 lore raw

PATCH 144/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes()

In reply to Marek Vasut

Reorder the content of the function a little and fix the comments so they at least become full sentences. Constify function args. Fix the return value to match the common convention of 0 meaning success.

---
 drivers/ddr/altera/sequencer.c | 36 ++++++++++++++++++++++++------------
 1 file changed, 24 insertions(+), 12 deletions(-)
drivers/ddr/altera/sequencer.c +24 -12
index 0d1e6c8..714fdf0 100644
@@ -3160,25 +3160,37 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	return (dq_margin >= 0) && (dqs_margin >= 0) && (dm_margin >= 0);
 }
 
-/* calibrate the write operations */
-static uint32_t rw_mgr_mem_calibrate_writes(uint32_t rank_bgn, uint32_t g,
-	uint32_t test_bgn)
+/**
+ * rw_mgr_mem_calibrate_writes() - Write Calibration Part One
+ * @rank_bgn:		Rank number
+ * @group:		Read/Write Group
+ * @test_bgn:		Rank at which the test begins
+ *
+ * Stage 2: Write Calibration Part One.
+ *
+ * This function implements UniPHY calibration Stage 2, as explained in
+ * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
+ */
+static int rw_mgr_mem_calibrate_writes(const u32 rank_bgn, const u32 group,
+				       const u32 test_bgn)
 {
-	/* update info for sims */
-	debug("%s:%d %u %u\n", __func__, __LINE__, g, test_bgn);
+	int ret;
+
+	/* Update info for sims */
+	debug("%s:%d %u %u\n", __func__, __LINE__, group, test_bgn);
 
+	reg_file_set_group(group);
 	reg_file_set_stage(CAL_STAGE_WRITES);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_WRITES_CENTER);
 
-	reg_file_set_group(g);
-
-	if (!rw_mgr_mem_calibrate_writes_center(rank_bgn, g, test_bgn)) {
-		set_failing_group_stage(g, CAL_STAGE_WRITES,
+	ret = rw_mgr_mem_calibrate_writes_center(rank_bgn, group, test_bgn);
+	if (!ret) {
+		set_failing_group_stage(group, CAL_STAGE_WRITES,
 					CAL_SUBSTAGE_WRITES_CENTER);
-		return 0;
+		return -EIO;
 	}
 
-	return 1;
+	return 0;
 }
 
 /**
@@ -3472,7 +3484,7 @@ static uint32_t mem_calibrate(void)
 					continue;
 
 				/* Calibrate WRITEs */
-				if (rw_mgr_mem_calibrate_writes(rank_bgn,
+				if (!rw_mgr_mem_calibrate_writes(rank_bgn,
 						write_group, write_test_bgn))
 					continue;
 
Signature · 1 line
2.1.4
#149 lore raw

PATCH 145/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 1

In reply to Marek Vasut

Factor out common code from rw_mgr_mem_calibrate_writes_center() and rw_mgr_mem_calibrate_vfifo_center() for searching for the right edge of the window. The code is almost identical, so pull it into separate function and cater for the minor differences.

---
 drivers/ddr/altera/sequencer.c | 418 +++++++++++++++++++----------------------
 1 file changed, 197 insertions(+), 221 deletions(-)
drivers/ddr/altera/sequencer.c +197 -221
index 714fdf0..b175313 100644
@@ -1780,6 +1780,166 @@ static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 	return ret;
 }
 
+/**
+ * search_right_edge() - Find right edge of DQ/DQS working phase
+ * @write:		Perform read (Stage 2) or write (Stage 3) calibration
+ * @rank_bgn:		Rank number
+ * @write_group:	Write Group
+ * @read_group:		Read Group
+ * @start_dqs:		DQS start phase
+ * @start_dqs_en:	DQS enable start phase
+ * @bit_chk:		Resulting bit mask after the test
+ * @sticky_bit_chk:	Resulting sticky bit mask after the test
+ * @left_edge:		Left edge of the DQ/DQS phase
+ * @right_edge:		Right edge of the DQ/DQS phase
+ * @use_read_test:	Perform read test
+ *
+ * Find right edge of DQ/DQS working phase.
+ */
+static int search_right_edge(const int write, const int rank_bgn,
+	const u32 write_group, const u32 read_group,
+	const int start_dqs, const int start_dqs_en,
+	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 :
+				    RW_MGR_MEM_DQ_PER_READ_DQS;
+	u32 stop;
+	int i, d;
+
+	for (d = 0; d <= dqs_max - start_dqs; d++) {
+		if (write) {	/* WRITE-ONLY */
+			scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
+								d + start_dqs);
+		} else {	/* READ-ONLY */
+			scc_mgr_set_dqs_bus_in_delay(read_group, d + start_dqs);
+			if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
+				uint32_t delay = d + start_dqs_en;
+				if (delay > IO_DQS_EN_DELAY_MAX)
+					delay = IO_DQS_EN_DELAY_MAX;
+				scc_mgr_set_dqs_en_delay(read_group, delay);
+			}
+			scc_mgr_load_dqs(read_group);
+		}
+
+		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);
+
+		if (stop == 1) {
+			if (write && (d == 0)) {	/* WRITE-ONLY */
+				for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
+					/*
+					 * d = 0 failed, but it passed when
+					 * testing the left edge, so it must be
+					 * marginal, set it to -1
+					 */
+					if (right_edge[i] == delay_max + 1 &&
+					    left_edge[i] != delay_max + 1)
+						right_edge[i] = -1;
+				}
+			}
+			break;
+		}
+
+		/* stop != 1 */
+		for (i = 0; i < per_dqs; i++) {
+			if (*bit_chk & 1) {
+				/*
+				 * Remember a passing test as
+				 * the right_edge.
+				 */
+				right_edge[i] = d;
+			} else {
+				if (d != 0) {
+					/*
+					 * If a right edge has not
+					 * been seen yet, then a future
+					 * passing test will mark this
+					 * edge as the left edge.
+					 */
+					if (right_edge[i] == delay_max + 1)
+						left_edge[i] = -(d + 1);
+				} else {
+					/*
+					 * d = 0 failed, but it passed
+					 * when testing the left edge,
+					 * so it must be marginal, set
+					 * it to -1
+					 */
+					if (right_edge[i] == delay_max + 1 &&
+					    left_edge[i] != delay_max + 1)
+						right_edge[i] = -1;
+					/*
+					 * If a right edge has not been
+					 * seen yet, then a future
+					 * passing test will mark this
+					 * edge as the left edge.
+					 */
+					else if (right_edge[i] == delay_max + 1)
+						left_edge[i] = -(d + 1);
+				}
+			}
+
+			debug_cond(DLEVEL == 2, "%s:%d center[r,d=%u]: ",
+				   __func__, __LINE__, d);
+			debug_cond(DLEVEL == 2,
+				   "bit_chk_test=%i left_edge[%u]: %d ",
+				   *bit_chk & 1, i, left_edge[i]);
+			debug_cond(DLEVEL == 2, "right_edge[%u]: %d\n", i,
+				   right_edge[i]);
+			*bit_chk = *bit_chk >> 1;
+		}
+	}
+
+	/* Check that all bits have a window */
+	for (i = 0; i < per_dqs; i++) {
+		debug_cond(DLEVEL == 2,
+			   "%s:%d write_center: left_edge[%u]: %d right_edge[%u]: %d",
+			   __func__, __LINE__, i, left_edge[i],
+			   i, right_edge[i]);
+		if ((left_edge[i] == dqs_max + 1) ||
+		    (right_edge[i] == dqs_max + 1))
+			return i + 1;	/* FIXME: If we fail, retval > 0 */
+	}
+
+	return 0;
+}
+
 /* per-bit deskew DQ and center */
 static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
@@ -1803,6 +1963,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t stop;
 	uint32_t temp_dq_in_delay1, temp_dq_in_delay2;
 	uint32_t addr;
+	int ret;
 
 	debug("%s:%d: %u %u", __func__, __LINE__, read_group, test_bgn);
 
@@ -1909,132 +2070,38 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	}
 
 	/* Search for the right edge of the window for each bit */
-	for (d = 0; d <= IO_DQS_IN_DELAY_MAX - start_dqs; d++) {
-		scc_mgr_set_dqs_bus_in_delay(read_group, d + start_dqs);
-		if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
-			uint32_t delay = d + start_dqs_en;
-			if (delay > IO_DQS_EN_DELAY_MAX)
-				delay = IO_DQS_EN_DELAY_MAX;
-			scc_mgr_set_dqs_en_delay(read_group, delay);
-		}
-		scc_mgr_load_dqs(read_group);
-
-		writel(0, &sdr_scc_mgr->update);
-
+	ret = search_right_edge(0, rank_bgn, write_group, read_group,
+				start_dqs, start_dqs_en,
+				&bit_chk, &sticky_bit_chk,
+				left_edge, right_edge, use_read_test);
+	if (ret) {
 		/*
-		 * Stop searching when the read test doesn't pass AND when
-		 * we've seen a passing read on every bit.
+		 * Restore delay chain settings before letting the loop
+		 * in rw_mgr_mem_calibrate_vfifo to retry different
+		 * dqs/ck relationships.
 		 */
-		if (use_read_test) {
-			stop = !rw_mgr_mem_calibrate_read_test(rank_bgn,
-				read_group, NUM_READ_PB_TESTS, PASS_ONE_BIT,
-				&bit_chk, 0, 0);
-		} else {
-			rw_mgr_mem_calibrate_write_test(rank_bgn, write_group,
-							0, PASS_ONE_BIT,
-							&bit_chk, 0);
-			bit_chk = bit_chk >> (RW_MGR_MEM_DQ_PER_READ_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 == param->read_correct_mask);
+		scc_mgr_set_dqs_bus_in_delay(read_group, start_dqs);
+		if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
+			scc_mgr_set_dqs_en_delay(read_group, start_dqs_en);
 
-		debug_cond(DLEVEL == 2, "%s:%d vfifo_center(right): dtap=%u => %u == \
-			   %u && %u", __func__, __LINE__, d,
-			   sticky_bit_chk, param->read_correct_mask, stop);
+		scc_mgr_load_dqs(read_group);
+		writel(0, &sdr_scc_mgr->update);
 
-		if (stop == 1) {
-			break;
+		debug_cond(DLEVEL == 1,
+			   "%s:%d vfifo_center: failed to find edge [%u]: %d %d",
+			   __func__, __LINE__, i, left_edge[i], right_edge[i]);
+		if (use_read_test) {
+			set_failing_group_stage(read_group *
+				RW_MGR_MEM_DQ_PER_READ_DQS + i,
+				CAL_STAGE_VFIFO,
+				CAL_SUBSTAGE_VFIFO_CENTER);
 		} else {
-			for (i = 0; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++) {
-				if (bit_chk & 1) {
-					/* Remember a passing test as
-					the right_edge */
-					right_edge[i] = d;
-				} else {
-					if (d != 0) {
-						/* If a right edge has not been
-						seen yet, then a future passing
-						test will mark this edge as the
-						left edge */
-						if (right_edge[i] ==
-						IO_IO_IN_DELAY_MAX + 1) {
-							left_edge[i] = -(d + 1);
-						}
-					} else {
-						/* d = 0 failed, but it passed
-						when testing the left edge,
-						so it must be marginal,
-						set it to -1 */
-						if (right_edge[i] ==
-							IO_IO_IN_DELAY_MAX + 1 &&
-							left_edge[i] !=
-							IO_IO_IN_DELAY_MAX
-							+ 1) {
-							right_edge[i] = -1;
-						}
-						/* If a right edge has not been
-						seen yet, then a future passing
-						test will mark this edge as the
-						left edge */
-						else if (right_edge[i] ==
-							IO_IO_IN_DELAY_MAX +
-							1) {
-							left_edge[i] = -(d + 1);
-						}
-					}
-				}
-
-				debug_cond(DLEVEL == 2, "%s:%d vfifo_center[r,\
-					   d=%u]: ", __func__, __LINE__, d);
-				debug_cond(DLEVEL == 2, "bit_chk_test=%d left_edge[%u]: %d ",
-					   (int)(bit_chk & 1), i, left_edge[i]);
-				debug_cond(DLEVEL == 2, "right_edge[%u]: %d\n", i,
-					   right_edge[i]);
-				bit_chk = bit_chk >> 1;
-			}
-		}
-	}
-
-	/* Check that all bits have a window */
-	for (i = 0; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++) {
-		debug_cond(DLEVEL == 2, "%s:%d vfifo_center: left_edge[%u]: \
-			   %d right_edge[%u]: %d", __func__, __LINE__,
-			   i, left_edge[i], i, right_edge[i]);
-		if ((left_edge[i] == IO_IO_IN_DELAY_MAX + 1) || (right_edge[i]
-			== IO_IO_IN_DELAY_MAX + 1)) {
-			/*
-			 * Restore delay chain settings before letting the loop
-			 * in rw_mgr_mem_calibrate_vfifo to retry different
-			 * dqs/ck relationships.
-			 */
-			scc_mgr_set_dqs_bus_in_delay(read_group, start_dqs);
-			if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
-				scc_mgr_set_dqs_en_delay(read_group,
-							 start_dqs_en);
-			}
-			scc_mgr_load_dqs(read_group);
-			writel(0, &sdr_scc_mgr->update);
-
-			debug_cond(DLEVEL == 1, "%s:%d vfifo_center: failed to \
-				   find edge [%u]: %d %d", __func__, __LINE__,
-				   i, left_edge[i], right_edge[i]);
-			if (use_read_test) {
-				set_failing_group_stage(read_group *
-					RW_MGR_MEM_DQ_PER_READ_DQS + i,
-					CAL_STAGE_VFIFO,
-					CAL_SUBSTAGE_VFIFO_CENTER);
-			} else {
-				set_failing_group_stage(read_group *
-					RW_MGR_MEM_DQ_PER_READ_DQS + i,
-					CAL_STAGE_VFIFO_AFTER_WRITES,
-					CAL_SUBSTAGE_VFIFO_CENTER);
-			}
-			return 0;
+			set_failing_group_stage(read_group *
+				RW_MGR_MEM_DQ_PER_READ_DQS + i,
+				CAL_STAGE_VFIFO_AFTER_WRITES,
+				CAL_SUBSTAGE_VFIFO_CENTER);
 		}
+		return 0;
 	}
 
 	/* Find middle of window for each DQ bit */
@@ -2729,6 +2796,8 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	uint32_t temp_dq_out1_delay;
 	uint32_t addr;
 
+	int ret;
+
 	debug("%s:%d %u %u", __func__, __LINE__, write_group, test_bgn);
 
 	dm_margin = 0;
@@ -2833,107 +2902,14 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	}
 
 	/* Search for the right edge of the window for each bit */
-	for (d = 0; d <= IO_IO_OUT1_DELAY_MAX - start_dqs; d++) {
-		scc_mgr_apply_group_dqs_io_and_oct_out1(write_group,
-							d + start_dqs);
-
-		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.
-		 */
-		stop = !rw_mgr_mem_calibrate_write_test(rank_bgn, write_group,
-			0, PASS_ONE_BIT, &bit_chk, 0);
-
-		sticky_bit_chk = sticky_bit_chk | bit_chk;
-		stop = stop && (sticky_bit_chk == param->write_correct_mask);
-
-		debug_cond(DLEVEL == 2, "write_center (right): dtap=%u => %u == \
-			   %u && %u\n", d, sticky_bit_chk,
-			   param->write_correct_mask, stop);
-
-		if (stop == 1) {
-			if (d == 0) {
-				for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS;
-					i++) {
-					/* d = 0 failed, but it passed when
-					testing the left edge, so it must be
-					marginal, set it to -1 */
-					if (right_edge[i] ==
-						IO_IO_OUT1_DELAY_MAX + 1 &&
-						left_edge[i] !=
-						IO_IO_OUT1_DELAY_MAX + 1) {
-						right_edge[i] = -1;
-					}
-				}
-			}
-			break;
-		} else {
-			for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
-				if (bit_chk & 1) {
-					/*
-					 * Remember a passing test as
-					 * the right_edge.
-					 */
-					right_edge[i] = d;
-				} else {
-					if (d != 0) {
-						/*
-						 * If a right edge has not
-						 * been seen yet, then a future
-						 * passing test will mark this
-						 * edge as the left edge.
-						 */
-						if (right_edge[i] ==
-						    IO_IO_OUT1_DELAY_MAX + 1)
-							left_edge[i] = -(d + 1);
-					} else {
-						/*
-						 * d = 0 failed, but it passed
-						 * when testing the left edge,
-						 * so it must be marginal, set
-						 * it to -1.
-						 */
-						if (right_edge[i] ==
-						    IO_IO_OUT1_DELAY_MAX + 1 &&
-						    left_edge[i] !=
-						    IO_IO_OUT1_DELAY_MAX + 1)
-							right_edge[i] = -1;
-						/*
-						 * If a right edge has not been
-						 * seen yet, then a future
-						 * passing test will mark this
-						 * edge as the left edge.
-						 */
-						else if (right_edge[i] ==
-							IO_IO_OUT1_DELAY_MAX +
-							1)
-							left_edge[i] = -(d + 1);
-					}
-				}
-				debug_cond(DLEVEL == 2, "write_center[r,d=%d):", d);
-				debug_cond(DLEVEL == 2, "bit_chk_test=%d left_edge[%u]: %d",
-					   (int)(bit_chk & 1), i, left_edge[i]);
-				debug_cond(DLEVEL == 2, "right_edge[%u]: %d\n", i,
-					   right_edge[i]);
-				bit_chk = bit_chk >> 1;
-			}
-		}
-	}
-
-	/* Check that all bits have a window */
-	for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
-		debug_cond(DLEVEL == 2, "%s:%d write_center: left_edge[%u]: \
-			   %d right_edge[%u]: %d", __func__, __LINE__,
-			   i, left_edge[i], i, right_edge[i]);
-		if ((left_edge[i] == IO_IO_OUT1_DELAY_MAX + 1) ||
-		    (right_edge[i] == IO_IO_OUT1_DELAY_MAX + 1)) {
-			set_failing_group_stage(test_bgn + i,
-						CAL_STAGE_WRITES,
-						CAL_SUBSTAGE_WRITES_CENTER);
-			return 0;
-		}
+	ret = search_right_edge(1, rank_bgn, write_group, 0,
+				start_dqs, 0,
+				&bit_chk, &sticky_bit_chk,
+				left_edge, right_edge, 0);
+	if (ret) {
+		set_failing_group_stage(test_bgn + ret - 1, CAL_STAGE_WRITES,
+					CAL_SUBSTAGE_WRITES_CENTER);
+		return 0;
 	}
 
 	/* Find middle of window for each DQ bit */
Signature · 1 line
2.1.4
#150 lore raw

PATCH 146/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 2

In reply to Marek Vasut

Factor out common code from rw_mgr_mem_calibrate_writes_center() and rw_mgr_mem_calibrate_vfifo_center() for searching for the left edge of the window. The code is almost identical, so pull it into separate function and cater for the minor differences.

---
 drivers/ddr/altera/sequencer.c | 316 +++++++++++++++++++----------------------
 1 file changed, 146 insertions(+), 170 deletions(-)
drivers/ddr/altera/sequencer.c +146 -170
index b175313..8f55e44 100644
@@ -1781,6 +1781,145 @@ static int rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase(const u32 grp)
 }
 
 /**
+ * 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
+ * @write_group:	Write Group
+ * @read_group:		Read Group
+ * @test_bgn:		Rank number to begin the test
+ * @bit_chk:		Resulting bit mask after the test
+ * @sticky_bit_chk:	Resulting sticky bit mask after the test
+ * @left_edge:		Left edge of the DQ/DQS phase
+ * @right_edge:		Right edge of the DQ/DQS phase
+ * @use_read_test:	Perform read test
+ *
+ * Find left edge of DQ/DQS working phase.
+ */
+static void search_left_edge(const int write, const int rank_bgn,
+	const u32 write_group, const u32 read_group, const u32 test_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 :
+				    RW_MGR_MEM_DQ_PER_READ_DQS;
+	u32 stop;
+	int i, d;
+
+	for (d = 0; d <= dqs_max; d++) {
+		if (write)
+			scc_mgr_apply_group_dq_out1_delay(d);
+		else
+			scc_mgr_apply_group_dq_in_delay(test_bgn, d);
+
+		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);
+
+		if (stop == 1)
+			break;
+
+		/* stop != 1 */
+		for (i = 0; i < per_dqs; i++) {
+			if (*bit_chk & 1) {
+				/*
+				 * Remember a passing test as
+				 * the left_edge.
+				 */
+				left_edge[i] = d;
+			} else {
+				/*
+				 * If a left edge has not been seen
+				 * yet, then a future passing test
+				 * will mark this edge as the right
+				 * edge.
+				 */
+				if (left_edge[i] == delay_max + 1)
+					right_edge[i] = -(d + 1);
+			}
+			*bit_chk = *bit_chk >> 1;
+		}
+	}
+
+	/* Reset DQ delay chains to 0 */
+	if (write)
+		scc_mgr_apply_group_dq_out1_delay(0);
+	else
+		scc_mgr_apply_group_dq_in_delay(test_bgn, 0);
+
+	*sticky_bit_chk = 0;
+	for (i = per_dqs - 1; i >= 0; i--) {
+		debug_cond(DLEVEL == 2,
+			   "%s:%d vfifo_center: left_edge[%u]: %d right_edge[%u]: %d\n",
+			   __func__, __LINE__, i, left_edge[i],
+			   i, right_edge[i]);
+
+		/*
+		 * Check for cases where we haven't found the left edge,
+		 * which makes our assignment of the the right edge invalid.
+		 * Reset it to the illegal value.
+		 */
+		if ((left_edge[i] == delay_max + 1) &&
+		    (right_edge[i] != delay_max + 1)) {
+			right_edge[i] = delay_max + 1;
+			debug_cond(DLEVEL == 2,
+				   "%s:%d vfifo_center: reset right_edge[%u]: %d\n",
+				   __func__, __LINE__, i, right_edge[i]);
+		}
+
+		/*
+		 * Reset sticky bit
+		 * READ: except for bits where we have seen both
+		 *       the left and right edge.
+		 * WRITE: except for bits where we have seen the
+		 *        left edge.
+		 */
+		*sticky_bit_chk <<= 1;
+		if (write) {
+			if (left_edge[i] != delay_max + 1)
+				*sticky_bit_chk |= 1;
+		} else {
+			if ((left_edge[i] != delay_max + 1) &&
+			    (right_edge[i] != delay_max + 1))
+				*sticky_bit_chk |= 1;
+		}
+	}
+
+
+}
+
+/**
  * search_right_edge() - Find right edge of DQ/DQS working phase
  * @write:		Perform read (Stage 2) or write (Stage 3) calibration
  * @rank_bgn:		Rank number
@@ -1945,7 +2084,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
 	uint32_t use_read_test, uint32_t update_fom)
 {
-	uint32_t i, p, d, min_index;
+	uint32_t i, p, min_index;
 	/*
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
@@ -1960,7 +2099,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	int32_t new_dqs, start_dqs, start_dqs_en, shift_dq, final_dqs,
 		final_dqs_en;
 	int32_t dq_margin, dqs_margin;
-	uint32_t stop;
 	uint32_t temp_dq_in_delay1, temp_dq_in_delay2;
 	uint32_t addr;
 	int ret;
@@ -1982,92 +2120,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	}
 
 	/* Search for the left edge of the window for each bit */
-	for (d = 0; d <= IO_IO_IN_DELAY_MAX; d++) {
-		scc_mgr_apply_group_dq_in_delay(write_group, test_bgn, d);
-
-		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 (use_read_test) {
-			stop = !rw_mgr_mem_calibrate_read_test(rank_bgn,
-				read_group, NUM_READ_PB_TESTS, PASS_ONE_BIT,
-				&bit_chk, 0, 0);
-		} else {
-			rw_mgr_mem_calibrate_write_test(rank_bgn, write_group,
-							0, PASS_ONE_BIT,
-							&bit_chk, 0);
-			bit_chk = bit_chk >> (RW_MGR_MEM_DQ_PER_READ_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 == param->read_correct_mask);
-		debug_cond(DLEVEL == 2, "%s:%d vfifo_center(left): dtap=%u => %u == %u \
-			   && %u", __func__, __LINE__, d,
-			   sticky_bit_chk,
-			param->read_correct_mask, stop);
-
-		if (stop == 1) {
-			break;
-		} else {
-			for (i = 0; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++) {
-				if (bit_chk & 1) {
-					/* Remember a passing test as the
-					left_edge */
-					left_edge[i] = d;
-				} else {
-					/* If a left edge has not been seen yet,
-					then a future passing test will mark
-					this edge as the right edge */
-					if (left_edge[i] ==
-						IO_IO_IN_DELAY_MAX + 1) {
-						right_edge[i] = -(d + 1);
-					}
-				}
-				bit_chk = bit_chk >> 1;
-			}
-		}
-	}
-
-	/* Reset DQ delay chains to 0 */
-	scc_mgr_apply_group_dq_in_delay(test_bgn, 0);
-	sticky_bit_chk = 0;
-	for (i = RW_MGR_MEM_DQ_PER_READ_DQS - 1;; i--) {
-		debug_cond(DLEVEL == 2, "%s:%d vfifo_center: left_edge[%u]: \
-			   %d right_edge[%u]: %d\n", __func__, __LINE__,
-			   i, left_edge[i], i, right_edge[i]);
-
-		/*
-		 * Check for cases where we haven't found the left edge,
-		 * which makes our assignment of the the right edge invalid.
-		 * Reset it to the illegal value.
-		 */
-		if ((left_edge[i] == IO_IO_IN_DELAY_MAX + 1) && (
-			right_edge[i] != IO_IO_IN_DELAY_MAX + 1)) {
-			right_edge[i] = IO_IO_IN_DELAY_MAX + 1;
-			debug_cond(DLEVEL == 2, "%s:%d vfifo_center: reset \
-				   right_edge[%u]: %d\n", __func__, __LINE__,
-				   i, right_edge[i]);
-		}
-
-		/*
-		 * Reset sticky bit (except for bits where we have seen
-		 * both the left and right edge).
-		 */
-		sticky_bit_chk = sticky_bit_chk << 1;
-		if ((left_edge[i] != IO_IO_IN_DELAY_MAX + 1) &&
-		    (right_edge[i] != IO_IO_IN_DELAY_MAX + 1)) {
-			sticky_bit_chk = sticky_bit_chk | 1;
-		}
-
-		if (i == 0)
-			break;
-	}
+	search_left_edge(0, rank_bgn, write_group, read_group, test_bgn,
+			 &bit_chk, &sticky_bit_chk,
+			 left_edge, right_edge, use_read_test);
 
 	/* Search for the right edge of the window for each bit */
 	ret = search_right_edge(0, rank_bgn, write_group, read_group,
@@ -2792,7 +2847,6 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	int32_t mid_min, orig_mid_min;
 	int32_t new_dqs, start_dqs, shift_dq;
 	int32_t dq_margin, dqs_margin, dm_margin;
-	uint32_t stop;
 	uint32_t temp_dq_out1_delay;
 	uint32_t addr;
 
@@ -2819,87 +2873,9 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	}
 
 	/* Search for the left edge of the window for each bit */
-	for (d = 0; d <= IO_IO_OUT1_DELAY_MAX; d++) {
-		scc_mgr_apply_group_dq_out1_delay(write_group, d);
-
-		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.
-		 */
-		stop = !rw_mgr_mem_calibrate_write_test(rank_bgn, write_group,
-			0, PASS_ONE_BIT, &bit_chk, 0);
-		sticky_bit_chk = sticky_bit_chk | bit_chk;
-		stop = stop && (sticky_bit_chk == param->write_correct_mask);
-		debug_cond(DLEVEL == 2, "write_center(left): dtap=%d => %u \
-			   == %u && %u [bit_chk= %u ]\n",
-			d, sticky_bit_chk, param->write_correct_mask,
-			stop, bit_chk);
-
-		if (stop == 1) {
-			break;
-		} else {
-			for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
-				if (bit_chk & 1) {
-					/*
-					 * Remember a passing test as the
-					 * left_edge.
-					 */
-					left_edge[i] = d;
-				} else {
-					/*
-					 * If a left edge has not been seen
-					 * yet, then a future passing test will
-					 * mark this edge as the right edge.
-					 */
-					if (left_edge[i] ==
-						IO_IO_OUT1_DELAY_MAX + 1) {
-						right_edge[i] = -(d + 1);
-					}
-				}
-				debug_cond(DLEVEL == 2, "write_center[l,d=%d):", d);
-				debug_cond(DLEVEL == 2, "bit_chk_test=%d left_edge[%u]: %d",
-					   (int)(bit_chk & 1), i, left_edge[i]);
-				debug_cond(DLEVEL == 2, "right_edge[%u]: %d\n", i,
-				       right_edge[i]);
-				bit_chk = bit_chk >> 1;
-			}
-		}
-	}
-
-	/* Reset DQ delay chains to 0 */
-	scc_mgr_apply_group_dq_out1_delay(0);
-	sticky_bit_chk = 0;
-	for (i = RW_MGR_MEM_DQ_PER_WRITE_DQS - 1;; i--) {
-		debug_cond(DLEVEL == 2, "%s:%d write_center: left_edge[%u]: \
-			   %d right_edge[%u]: %d\n", __func__, __LINE__,
-			   i, left_edge[i], i, right_edge[i]);
-
-		/*
-		 * Check for cases where we haven't found the left edge,
-		 * which makes our assignment of the the right edge invalid.
-		 * Reset it to the illegal value.
-		 */
-		if ((left_edge[i] == IO_IO_OUT1_DELAY_MAX + 1) &&
-		    (right_edge[i] != IO_IO_OUT1_DELAY_MAX + 1)) {
-			right_edge[i] = IO_IO_OUT1_DELAY_MAX + 1;
-			debug_cond(DLEVEL == 2, "%s:%d write_center: reset \
-				   right_edge[%u]: %d\n", __func__, __LINE__,
-				   i, right_edge[i]);
-		}
-
-		/*
-		 * Reset sticky bit (except for bits where we have
-		 * seen the left edge).
-		 */
-		sticky_bit_chk = sticky_bit_chk << 1;
-		if ((left_edge[i] != IO_IO_OUT1_DELAY_MAX + 1))
-			sticky_bit_chk = sticky_bit_chk | 1;
-
-		if (i == 0)
-			break;
-	}
+	search_left_edge(1, rank_bgn, write_group, 0, test_bgn,
+			 &bit_chk, &sticky_bit_chk,
+			 left_edge, right_edge, 0);
 
 	/* Search for the right edge of the window for each bit */
 	ret = search_right_edge(1, rank_bgn, write_group, 0,
Signature · 1 line
2.1.4
#151 lore raw

PATCH 147/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 3

In reply to Marek Vasut

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.

---
 drivers/ddr/altera/sequencer.c | 126 ++++++++++++++++++++---------------------
 1 file changed, 60 insertions(+), 66 deletions(-)
drivers/ddr/altera/sequencer.c +60 -66
index 8f55e44..2ecf6b8 100644
@@ -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++) {
Signature · 1 line
2.1.4
#152 lore raw

PATCH 148/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 4

In reply to Marek Vasut

First of all, don't break strings in the debug_cond() calls across multiple lines. Next, zap a couple of really odd casts in the code. Finally, make i into a signed variable, so it is possible to avoid constructs of the form:

    for (i = FOO;; i--) { <code>; if (i == 0) break; }.
---
 drivers/ddr/altera/sequencer.c | 40 +++++++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 17 deletions(-)
drivers/ddr/altera/sequencer.c +23 -17
index 2ecf6b8..3db226d 100644
@@ -2078,7 +2078,8 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
 	uint32_t use_read_test, uint32_t update_fom)
 {
-	uint32_t i, p, min_index;
+	uint32_t p, min_index;
+	int i;
 	/*
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
@@ -2118,6 +2119,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 			 &bit_chk, &sticky_bit_chk,
 			 left_edge, right_edge, use_read_test);
 
+
 	/* Search for the right edge of the window for each bit */
 	ret = search_right_edge(0, rank_bgn, write_group, read_group,
 				start_dqs, start_dqs_en,
@@ -2198,8 +2200,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	}
 	new_dqs = start_dqs - mid_min;
 
-	debug_cond(DLEVEL == 1, "vfifo_center: start_dqs=%d start_dqs_en=%d \
-		   new_dqs=%d mid_min=%d\n", start_dqs,
+	debug_cond(DLEVEL == 1,
+		   "vfifo_center: start_dqs=%d start_dqs_en=%d new_dqs=%d mid_min=%d\n",
+		   start_dqs,
 		   IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS ? start_dqs_en : -1,
 		   new_dqs, mid_min);
 
@@ -2214,28 +2217,31 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 			(left_edge[min_index] - right_edge[min_index]))/2  +
 			(orig_mid_min - mid_min);
 
-		debug_cond(DLEVEL == 2, "vfifo_center: before: \
-			   shift_dq[%u]=%d\n", i, shift_dq);
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: before: shift_dq[%u]=%d\n",
+			   i, shift_dq);
 
 		addr = SDR_PHYGRP_SCCGRP_ADDRESS | SCC_MGR_IO_IN_DELAY_OFFSET;
 		temp_dq_in_delay1 = readl(addr + (p << 2));
 		temp_dq_in_delay2 = readl(addr + (i << 2));
 
-		if (shift_dq + (int32_t)temp_dq_in_delay1 >
-			(int32_t)IO_IO_IN_DELAY_MAX) {
-			shift_dq = (int32_t)IO_IO_IN_DELAY_MAX - temp_dq_in_delay2;
-		} else if (shift_dq + (int32_t)temp_dq_in_delay1 < 0) {
-			shift_dq = -(int32_t)temp_dq_in_delay1;
-		}
-		debug_cond(DLEVEL == 2, "vfifo_center: after: \
-			   shift_dq[%u]=%d\n", i, shift_dq);
+		if (shift_dq + temp_dq_in_delay1 > IO_IO_IN_DELAY_MAX)
+			shift_dq = IO_IO_IN_DELAY_MAX - temp_dq_in_delay2;
+		else if (shift_dq + temp_dq_in_delay1 < 0)
+			shift_dq = -temp_dq_in_delay1;
+
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: after: shift_dq[%u]=%d\n",
+			   i, shift_dq);
 		final_dq[i] = temp_dq_in_delay1 + shift_dq;
 		scc_mgr_set_dq_in_delay(p, final_dq[i]);
 		scc_mgr_load_dq(p);
 
-		debug_cond(DLEVEL == 2, "vfifo_center: margin[%u]=[%d,%d]\n", i,
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: margin[%u]=[%d,%d]\n", i,
 			   left_edge[i] - shift_dq + (-mid_min),
 			   right_edge[i] + shift_dq - (-mid_min));
+
 		/* To determine values for export structures */
 		if (left_edge[i] - shift_dq + (-mid_min) < dq_margin)
 			dq_margin = left_edge[i] - shift_dq + (-mid_min);
@@ -2257,9 +2263,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	/* Move DQS */
 	scc_mgr_set_dqs_bus_in_delay(read_group, final_dqs);
 	scc_mgr_load_dqs(read_group);
-	debug_cond(DLEVEL == 2, "%s:%d vfifo_center: dq_margin=%d \
-		   dqs_margin=%d", __func__, __LINE__,
-		   dq_margin, dqs_margin);
+	debug_cond(DLEVEL == 2,
+		   "%s:%d vfifo_center: dq_margin=%d dqs_margin=%d",
+		   __func__, __LINE__, dq_margin, dqs_margin);
 
 	/*
 	 * Do not remove this line as it makes sure all of our decisions
Signature · 1 line
2.1.4
#153 lore raw

PATCH 149/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 5

In reply to Marek Vasut

Factor out the get_window_mid_index() for finding the best DQ window centering. This is again code common to two stages, so pull it out.

---
 drivers/ddr/altera/sequencer.c | 90 +++++++++++++++++++++---------------------
 1 file changed, 44 insertions(+), 46 deletions(-)
drivers/ddr/altera/sequencer.c +44 -46
index 3db226d..d6b96f4 100644
@@ -2073,6 +2073,48 @@ static int search_right_edge(const int write, const int rank_bgn,
 	return 0;
 }
 
+/**
+ * get_window_mid_index() - Find the best middle setting of DQ/DQS phase
+ * @write:		Perform read (Stage 2) or write (Stage 3) calibration
+ * @left_edge:		Left edge of the DQ/DQS phase
+ * @right_edge:		Right edge of the DQ/DQS phase
+ * @mid_min:		Best DQ/DQS phase middle setting
+ *
+ * Find index and value of the middle of the DQ/DQS working phase.
+ */
+static int get_window_mid_index(const int write, int *left_edge,
+				int *right_edge, int *mid_min)
+{
+	const u32 per_dqs = write ? RW_MGR_MEM_DQ_PER_WRITE_DQS :
+				    RW_MGR_MEM_DQ_PER_READ_DQS;
+	int i, mid, min_index;
+
+	/* Find middle of window for each DQ bit */
+	*mid_min = left_edge[0] - right_edge[0];
+	min_index = 0;
+	for (i = 1; i < per_dqs; i++) {
+		mid = left_edge[i] - right_edge[i];
+		if (mid < *mid_min) {
+			*mid_min = mid;
+			min_index = i;
+		}
+	}
+
+	/*
+	 * -mid_min/2 represents the amount that we need to move DQS.
+	 * If mid_min is odd and positive we'll need to add one to make
+	 * sure the rounding in further calculations is correct (always
+	 * bias to the right), so just add 1 for all positive values.
+	 */
+	if (*mid_min > 0)
+		(*mid_min)++;
+	*mid_min = *mid_min / 2;
+
+	debug_cond(DLEVEL == 1, "%s:%d vfifo_center: *mid_min=%d (index=%u)\n",
+		   __func__, __LINE__, *mid_min, min_index);
+	return min_index;
+}
+
 /* per-bit deskew DQ and center */
 static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
@@ -2155,30 +2197,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 		return 0;
 	}
 
-	/* Find middle of window for each DQ bit */
-	mid_min = left_edge[0] - right_edge[0];
-	min_index = 0;
-	for (i = 1; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++) {
-		mid = left_edge[i] - right_edge[i];
-		if (mid < mid_min) {
-			mid_min = mid;
-			min_index = i;
-		}
-	}
-
-	/*
-	 * -mid_min/2 represents the amount that we need to move DQS.
-	 * If mid_min is odd and positive we'll need to add one to
-	 * make sure the rounding in further calculations is correct
-	 * (always bias to the right), so just add 1 for all positive values.
-	 */
-	if (mid_min > 0)
-		mid_min++;
-
-	mid_min = mid_min / 2;
-
-	debug_cond(DLEVEL == 1, "%s:%d vfifo_center: mid_min=%d (index=%u)\n",
-		   __func__, __LINE__, mid_min, min_index);
+	min_index = get_window_mid_index(0, left_edge, right_edge, &mid_min);
 
 	/* Determine the amount we can change DQS (which is -mid_min) */
 	orig_mid_min = mid_min;
@@ -2888,28 +2907,7 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 		return 0;
 	}
 
-	/* Find middle of window for each DQ bit */
-	mid_min = left_edge[0] - right_edge[0];
-	min_index = 0;
-	for (i = 1; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
-		mid = left_edge[i] - right_edge[i];
-		if (mid < mid_min) {
-			mid_min = mid;
-			min_index = i;
-		}
-	}
-
-	/*
-	 * -mid_min/2 represents the amount that we need to move DQS.
-	 * If mid_min is odd and positive we'll need to add one to
-	 * make sure the rounding in further calculations is correct
-	 * (always bias to the right), so just add 1 for all positive values.
-	 */
-	if (mid_min > 0)
-		mid_min++;
-	mid_min = mid_min / 2;
-	debug_cond(DLEVEL == 1, "%s:%d write_center: mid_min=%d\n", __func__,
-		   __LINE__, mid_min);
+	min_index = get_window_mid_index(1, left_edge, right_edge, &mid_min);
 
 	/* Determine the amount we can change DQS (which is -mid_min) */
 	orig_mid_min = mid_min;
Signature · 1 line
2.1.4
#154 lore raw

PATCH 150/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 6

In reply to Marek Vasut

Factor out center_dq_windows(), which is common code between stage 2 and stage 3 of the calibration again and cater for the minor differences.

---
 drivers/ddr/altera/sequencer.c | 177 ++++++++++++++++++++---------------------
 1 file changed, 88 insertions(+), 89 deletions(-)
drivers/ddr/altera/sequencer.c +88 -89
index d6b96f4..e3cd8a9 100644
@@ -2115,13 +2115,90 @@ static int get_window_mid_index(const int write, int *left_edge,
 	return min_index;
 }
 
+/**
+ * center_dq_windows() - Center the DQ/DQS windows
+ * @write:		Perform read (Stage 2) or write (Stage 3) calibration
+ * @left_edge:		Left edge of the DQ/DQS phase
+ * @right_edge:		Right edge of the DQ/DQS phase
+ * @mid_min:		Adjusted DQ/DQS phase middle setting
+ * @orig_mid_min:	Original DQ/DQS phase middle setting
+ * @min_index:		DQ/DQS phase middle setting index
+ * @test_bgn:		Rank number to begin the test
+ * @dq_margin:		Amount of shift for the DQ
+ * @dqs_margin:		Amount of shift for the DQS
+ *
+ * Align the DQ/DQS windows in each group.
+ */
+static void center_dq_windows(const int write, int *left_edge, int *right_edge,
+			      const int mid_min, const int orig_mid_min,
+			      const int min_index, const int test_bgn,
+			      int *dq_margin, int *dqs_margin)
+{
+	const u32 delay_max = write ? IO_IO_OUT1_DELAY_MAX : IO_IO_IN_DELAY_MAX;
+	const u32 per_dqs = write ? RW_MGR_MEM_DQ_PER_WRITE_DQS :
+				    RW_MGR_MEM_DQ_PER_READ_DQS;
+	const u32 delay_off = write ? SCC_MGR_IO_OUT1_DELAY_OFFSET :
+				      SCC_MGR_IO_IN_DELAY_OFFSET;
+	const u32 addr = SDR_PHYGRP_SCCGRP_ADDRESS | delay_off;
+
+	u32 temp_dq_io_delay1, temp_dq_io_delay2;
+	int shift_dq, i, p;
+
+	/* Initialize data for export structures */
+	*dqs_margin = delay_max + 1;
+	*dq_margin  = delay_max + 1;
+
+	/* add delay to bring centre of all DQ windows to the same "level" */
+	for (i = 0, p = test_bgn; i < per_dqs; i++, p++) {
+		/* Use values before divide by 2 to reduce round off error */
+		shift_dq = (left_edge[i] - right_edge[i] -
+			(left_edge[min_index] - right_edge[min_index]))/2  +
+			(orig_mid_min - mid_min);
+
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: before: shift_dq[%u]=%d\n",
+			   i, shift_dq);
+
+		temp_dq_io_delay1 = readl(addr + (p << 2));
+		temp_dq_io_delay2 = readl(addr + (i << 2));
+
+		if (shift_dq + temp_dq_io_delay1 > delay_max)
+			shift_dq = delay_max - temp_dq_io_delay2;
+		else if (shift_dq + temp_dq_io_delay1 < 0)
+			shift_dq = -temp_dq_io_delay1;
+
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: after: shift_dq[%u]=%d\n",
+			   i, shift_dq);
+
+		if (write)
+			scc_mgr_set_dq_out1_delay(i, temp_dq_io_delay1 + shift_dq);
+		else
+			scc_mgr_set_dq_in_delay(p, temp_dq_io_delay1 + shift_dq);
+
+		scc_mgr_load_dq(p);
+
+		debug_cond(DLEVEL == 2,
+			   "vfifo_center: margin[%u]=[%d,%d]\n", i,
+			   left_edge[i] - shift_dq + (-mid_min),
+			   right_edge[i] + shift_dq - (-mid_min));
+
+		/* To determine values for export structures */
+		if (left_edge[i] - shift_dq + (-mid_min) < *dq_margin)
+			*dq_margin = left_edge[i] - shift_dq + (-mid_min);
+
+		if (right_edge[i] + shift_dq - (-mid_min) < *dqs_margin)
+			*dqs_margin = right_edge[i] + shift_dq - (-mid_min);
+	}
+
+}
+
 /* per-bit deskew DQ and center */
 static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
 	uint32_t use_read_test, uint32_t update_fom)
 {
-	uint32_t p, min_index;
-	int i;
+	int i, min_index;
 	/*
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
@@ -2130,13 +2207,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t sticky_bit_chk;
 	int32_t left_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
 	int32_t right_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
-	int32_t final_dq[RW_MGR_MEM_DQ_PER_READ_DQS];
-	int32_t mid;
 	int32_t orig_mid_min, mid_min;
-	int32_t new_dqs, start_dqs, start_dqs_en, shift_dq, final_dqs,
-		final_dqs_en;
+	int32_t new_dqs, start_dqs, start_dqs_en, final_dqs, final_dqs_en;
 	int32_t dq_margin, dqs_margin;
-	uint32_t temp_dq_in_delay1, temp_dq_in_delay2;
 	uint32_t addr;
 	int ret;
 
@@ -2225,49 +2298,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 		   IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS ? start_dqs_en : -1,
 		   new_dqs, mid_min);
 
-	/* Initialize data for export structures */
-	dqs_margin = IO_IO_IN_DELAY_MAX + 1;
-	dq_margin  = IO_IO_IN_DELAY_MAX + 1;
-
-	/* add delay to bring centre of all DQ windows to the same "level" */
-	for (i = 0, p = test_bgn; i < RW_MGR_MEM_DQ_PER_READ_DQS; i++, p++) {
-		/* Use values before divide by 2 to reduce round off error */
-		shift_dq = (left_edge[i] - right_edge[i] -
-			(left_edge[min_index] - right_edge[min_index]))/2  +
-			(orig_mid_min - mid_min);
-
-		debug_cond(DLEVEL == 2,
-			   "vfifo_center: before: shift_dq[%u]=%d\n",
-			   i, shift_dq);
-
-		addr = SDR_PHYGRP_SCCGRP_ADDRESS | SCC_MGR_IO_IN_DELAY_OFFSET;
-		temp_dq_in_delay1 = readl(addr + (p << 2));
-		temp_dq_in_delay2 = readl(addr + (i << 2));
-
-		if (shift_dq + temp_dq_in_delay1 > IO_IO_IN_DELAY_MAX)
-			shift_dq = IO_IO_IN_DELAY_MAX - temp_dq_in_delay2;
-		else if (shift_dq + temp_dq_in_delay1 < 0)
-			shift_dq = -temp_dq_in_delay1;
-
-		debug_cond(DLEVEL == 2,
-			   "vfifo_center: after: shift_dq[%u]=%d\n",
-			   i, shift_dq);
-		final_dq[i] = temp_dq_in_delay1 + shift_dq;
-		scc_mgr_set_dq_in_delay(p, final_dq[i]);
-		scc_mgr_load_dq(p);
-
-		debug_cond(DLEVEL == 2,
-			   "vfifo_center: margin[%u]=[%d,%d]\n", i,
-			   left_edge[i] - shift_dq + (-mid_min),
-			   right_edge[i] + shift_dq - (-mid_min));
-
-		/* To determine values for export structures */
-		if (left_edge[i] - shift_dq + (-mid_min) < dq_margin)
-			dq_margin = left_edge[i] - shift_dq + (-mid_min);
-
-		if (right_edge[i] + shift_dq - (-mid_min) < dqs_margin)
-			dqs_margin = right_edge[i] + shift_dq - (-mid_min);
-	}
+	/* Add delay to bring centre of all DQ windows to the same "level". */
+	center_dq_windows(0, left_edge, right_edge, mid_min, orig_mid_min,
+			  min_index, test_bgn, &dq_margin, &dqs_margin);
 
 	final_dqs = new_dqs;
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
@@ -2852,7 +2885,7 @@ static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
 static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t test_bgn)
 {
-	uint32_t i, p, min_index;
+	uint32_t i, min_index;
 	int32_t d;
 	/*
 	 * Store these as signed since there are comparisons with
@@ -2864,9 +2897,8 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	int32_t right_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
 	int32_t mid;
 	int32_t mid_min, orig_mid_min;
-	int32_t new_dqs, start_dqs, shift_dq;
+	int32_t new_dqs, start_dqs;
 	int32_t dq_margin, dqs_margin, dm_margin;
-	uint32_t temp_dq_out1_delay;
 	uint32_t addr;
 
 	int ret;
@@ -2915,43 +2947,10 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	mid_min = 0;
 	debug_cond(DLEVEL == 1, "%s:%d write_center: start_dqs=%d new_dqs=%d \
 		   mid_min=%d\n", __func__, __LINE__, start_dqs, new_dqs, mid_min);
-	/* Initialize data for export structures */
-	dqs_margin = IO_IO_OUT1_DELAY_MAX + 1;
-	dq_margin  = IO_IO_OUT1_DELAY_MAX + 1;
-
-	/* add delay to bring centre of all DQ windows to the same "level" */
-	for (i = 0, p = test_bgn; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++, p++) {
-		/* Use values before divide by 2 to reduce round off error */
-		shift_dq = (left_edge[i] - right_edge[i] -
-			(left_edge[min_index] - right_edge[min_index]))/2  +
-		(orig_mid_min - mid_min);
-
-		debug_cond(DLEVEL == 2, "%s:%d write_center: before: shift_dq \
-			   [%u]=%d\n", __func__, __LINE__, i, shift_dq);
-
-		addr = SDR_PHYGRP_SCCGRP_ADDRESS | SCC_MGR_IO_OUT1_DELAY_OFFSET;
-		temp_dq_out1_delay = readl(addr + (i << 2));
-		if (shift_dq + (int32_t)temp_dq_out1_delay >
-			(int32_t)IO_IO_OUT1_DELAY_MAX) {
-			shift_dq = (int32_t)IO_IO_OUT1_DELAY_MAX - temp_dq_out1_delay;
-		} else if (shift_dq + (int32_t)temp_dq_out1_delay < 0) {
-			shift_dq = -(int32_t)temp_dq_out1_delay;
-		}
-		debug_cond(DLEVEL == 2, "write_center: after: shift_dq[%u]=%d\n",
-			   i, shift_dq);
-		scc_mgr_set_dq_out1_delay(i, temp_dq_out1_delay + shift_dq);
-		scc_mgr_load_dq(i);
 
-		debug_cond(DLEVEL == 2, "write_center: margin[%u]=[%d,%d]\n", i,
-			   left_edge[i] - shift_dq + (-mid_min),
-			   right_edge[i] + shift_dq - (-mid_min));
-		/* To determine values for export structures */
-		if (left_edge[i] - shift_dq + (-mid_min) < dq_margin)
-			dq_margin = left_edge[i] - shift_dq + (-mid_min);
-
-		if (right_edge[i] + shift_dq - (-mid_min) < dqs_margin)
-			dqs_margin = right_edge[i] + shift_dq - (-mid_min);
-	}
+	/* Add delay to bring centre of all DQ windows to the same "level". */
+	center_dq_windows(1, left_edge, right_edge, mid_min, orig_mid_min,
+			  min_index, 0, &dq_margin, &dqs_margin);
 
 	/* Move DQS */
 	scc_mgr_apply_group_dqs_io_and_oct_out1(write_group, new_dqs);
Signature · 1 line
2.1.4
#155 lore raw

PATCH 151/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 7

In reply to Marek Vasut

Perform minor reordering of the function to make the code more organised, no functional change.

---
 drivers/ddr/altera/sequencer.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)
drivers/ddr/altera/sequencer.c +9 -12
index e3cd8a9..eadf39b 100644
@@ -2198,7 +2198,9 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
 	uint32_t use_read_test, uint32_t update_fom)
 {
-	int i, min_index;
+	const u32 addr =
+		SDR_PHYGRP_SCCGRP_ADDRESS + SCC_MGR_DQS_IN_DELAY_OFFSET +
+		(read_group << 2);
 	/*
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
@@ -2208,18 +2210,16 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	int32_t left_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
 	int32_t right_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
 	int32_t orig_mid_min, mid_min;
-	int32_t new_dqs, start_dqs, start_dqs_en, final_dqs, final_dqs_en;
+	int32_t new_dqs, start_dqs, start_dqs_en, final_dqs_en;
 	int32_t dq_margin, dqs_margin;
-	uint32_t addr;
+	int i, min_index;
 	int ret;
 
 	debug("%s:%d: %u %u", __func__, __LINE__, read_group, test_bgn);
 
-	addr = SDR_PHYGRP_SCCGRP_ADDRESS | SCC_MGR_DQS_IN_DELAY_OFFSET;
-	start_dqs = readl(addr + (read_group << 2));
+	start_dqs = readl(addr);
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
-		start_dqs_en = readl(addr + ((read_group << 2)
-				     - IO_DQS_EN_DELAY_OFFSET));
+		start_dqs_en = readl(addr - IO_DQS_EN_DELAY_OFFSET);
 
 	/* set the left and right edge of each bit to an illegal value */
 	/* use (IO_IO_IN_DELAY_MAX + 1) as an illegal value */
@@ -2302,18 +2302,15 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	center_dq_windows(0, left_edge, right_edge, mid_min, orig_mid_min,
 			  min_index, test_bgn, &dq_margin, &dqs_margin);
 
-	final_dqs = new_dqs;
-	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
-		final_dqs_en = start_dqs_en - mid_min;
-
 	/* Move DQS-en */
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
+		final_dqs_en = start_dqs_en - mid_min;
 		scc_mgr_set_dqs_en_delay(read_group, final_dqs_en);
 		scc_mgr_load_dqs(read_group);
 	}
 
 	/* Move DQS */
-	scc_mgr_set_dqs_bus_in_delay(read_group, final_dqs);
+	scc_mgr_set_dqs_bus_in_delay(read_group, new_dqs);
 	scc_mgr_load_dqs(read_group);
 	debug_cond(DLEVEL == 2,
 		   "%s:%d vfifo_center: dq_margin=%d dqs_margin=%d",
Signature · 1 line
2.1.4
#156 lore raw

PATCH 152/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 8

In reply to Marek Vasut

The search_stop_check() always resets the bit_chk to a new value, so bit_chk will never survive between search_left_edge() and search_right_edge() invocation. There is thus no need to pass it into these functions, so make bit_chk local to them.

---
 drivers/ddr/altera/sequencer.c | 33 +++++++++++++++------------------
 1 file changed, 15 insertions(+), 18 deletions(-)
drivers/ddr/altera/sequencer.c +15 -18
index eadf39b..a01a2dc 100644
@@ -1841,7 +1841,6 @@ static u32 search_stop_check(const int write, const int d, const int rank_bgn,
  * @write_group:	Write Group
  * @read_group:		Read Group
  * @test_bgn:		Rank number to begin the test
- * @bit_chk:		Resulting bit mask after the test
  * @sticky_bit_chk:	Resulting sticky bit mask after the test
  * @left_edge:		Left edge of the DQ/DQS phase
  * @right_edge:		Right edge of the DQ/DQS phase
@@ -1851,14 +1850,14 @@ static u32 search_stop_check(const int write, const int d, const int rank_bgn,
  */
 static void search_left_edge(const int write, const int rank_bgn,
 	const u32 write_group, const u32 read_group, const u32 test_bgn,
-	u32 *bit_chk, u32 *sticky_bit_chk,
+	u32 *sticky_bit_chk,
 	int *left_edge, int *right_edge, const u32 use_read_test)
 {
 	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 :
 				    RW_MGR_MEM_DQ_PER_READ_DQS;
-	u32 stop;
+	u32 stop, bit_chk;
 	int i, d;
 
 	for (d = 0; d <= dqs_max; d++) {
@@ -1870,14 +1869,14 @@ static void search_left_edge(const int write, const int rank_bgn,
 		writel(0, &sdr_scc_mgr->update);
 
 		stop = search_stop_check(write, d, rank_bgn, write_group,
-					 read_group, bit_chk, sticky_bit_chk,
+					 read_group, &bit_chk, sticky_bit_chk,
 					 use_read_test);
 		if (stop == 1)
 			break;
 
 		/* stop != 1 */
 		for (i = 0; i < per_dqs; i++) {
-			if (*bit_chk & 1) {
+			if (bit_chk & 1) {
 				/*
 				 * Remember a passing test as
 				 * the left_edge.
@@ -1893,7 +1892,7 @@ static void search_left_edge(const int write, const int rank_bgn,
 				if (left_edge[i] == delay_max + 1)
 					right_edge[i] = -(d + 1);
 			}
-			*bit_chk = *bit_chk >> 1;
+			bit_chk >>= 1;
 		}
 	}
 
@@ -1952,7 +1951,6 @@ static void search_left_edge(const int write, const int rank_bgn,
  * @read_group:		Read Group
  * @start_dqs:		DQS start phase
  * @start_dqs_en:	DQS enable start phase
- * @bit_chk:		Resulting bit mask after the test
  * @sticky_bit_chk:	Resulting sticky bit mask after the test
  * @left_edge:		Left edge of the DQ/DQS phase
  * @right_edge:		Right edge of the DQ/DQS phase
@@ -1963,14 +1961,14 @@ static void search_left_edge(const int write, const int rank_bgn,
 static int search_right_edge(const int write, const int rank_bgn,
 	const u32 write_group, const u32 read_group,
 	const int start_dqs, const int start_dqs_en,
-	u32 *bit_chk, u32 *sticky_bit_chk,
+	u32 *sticky_bit_chk,
 	int *left_edge, int *right_edge, const u32 use_read_test)
 {
 	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 :
 				    RW_MGR_MEM_DQ_PER_READ_DQS;
-	u32 stop;
+	u32 stop, bit_chk;
 	int i, d;
 
 	for (d = 0; d <= dqs_max - start_dqs; d++) {
@@ -1991,7 +1989,7 @@ static int search_right_edge(const int write, const int rank_bgn,
 		writel(0, &sdr_scc_mgr->update);
 
 		stop = search_stop_check(write, d, rank_bgn, write_group,
-					 read_group, bit_chk, sticky_bit_chk,
+					 read_group, &bit_chk, sticky_bit_chk,
 					 use_read_test);
 		if (stop == 1) {
 			if (write && (d == 0)) {	/* WRITE-ONLY */
@@ -2011,7 +2009,7 @@ static int search_right_edge(const int write, const int rank_bgn,
 
 		/* stop != 1 */
 		for (i = 0; i < per_dqs; i++) {
-			if (*bit_chk & 1) {
+			if (bit_chk & 1) {
 				/*
 				 * Remember a passing test as
 				 * the right_edge.
@@ -2052,10 +2050,10 @@ static int search_right_edge(const int write, const int rank_bgn,
 				   __func__, __LINE__, d);
 			debug_cond(DLEVEL == 2,
 				   "bit_chk_test=%i left_edge[%u]: %d ",
-				   *bit_chk & 1, i, left_edge[i]);
+				   bit_chk & 1, i, left_edge[i]);
 			debug_cond(DLEVEL == 2, "right_edge[%u]: %d\n", i,
 				   right_edge[i]);
-			*bit_chk = *bit_chk >> 1;
+			bit_chk >>= 1;
 		}
 	}
 
@@ -2205,7 +2203,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
 	 */
-	uint32_t bit_chk;
 	uint32_t sticky_bit_chk;
 	int32_t left_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
 	int32_t right_edge[RW_MGR_MEM_DQ_PER_READ_DQS];
@@ -2231,14 +2228,14 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 
 	/* Search for the left edge of the window for each bit */
 	search_left_edge(0, rank_bgn, write_group, read_group, test_bgn,
-			 &bit_chk, &sticky_bit_chk,
+			 &sticky_bit_chk,
 			 left_edge, right_edge, use_read_test);
 
 
 	/* Search for the right edge of the window for each bit */
 	ret = search_right_edge(0, rank_bgn, write_group, read_group,
 				start_dqs, start_dqs_en,
-				&bit_chk, &sticky_bit_chk,
+				&sticky_bit_chk,
 				left_edge, right_edge, use_read_test);
 	if (ret) {
 		/*
@@ -2922,13 +2919,13 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 
 	/* Search for the left edge of the window for each bit */
 	search_left_edge(1, rank_bgn, write_group, 0, test_bgn,
-			 &bit_chk, &sticky_bit_chk,
+			 &sticky_bit_chk,
 			 left_edge, right_edge, 0);
 
 	/* Search for the right edge of the window for each bit */
 	ret = search_right_edge(1, rank_bgn, write_group, 0,
 				start_dqs, 0,
-				&bit_chk, &sticky_bit_chk,
+				&sticky_bit_chk,
 				left_edge, right_edge, 0);
 	if (ret) {
 		set_failing_group_stage(test_bgn + ret - 1, CAL_STAGE_WRITES,
Signature · 1 line
2.1.4
#157 lore raw

PATCH 153/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 9

In reply to Marek Vasut

The read_group and write_group arguments are the same in all cases when this function is invoked, just merge them into one rw_group argument. Also, clean up the function argument data types and constify them.

---
 drivers/ddr/altera/sequencer.c | 35 +++++++++++++++++------------------
 1 file changed, 17 insertions(+), 18 deletions(-)
drivers/ddr/altera/sequencer.c +17 -18
index a01a2dc..ee541ce 100644
@@ -2192,13 +2192,13 @@ static void center_dq_windows(const int write, int *left_edge, int *right_edge,
 }
 
 /* per-bit deskew DQ and center */
-static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
-	uint32_t write_group, uint32_t read_group, uint32_t test_bgn,
-	uint32_t use_read_test, uint32_t update_fom)
+static int rw_mgr_mem_calibrate_vfifo_center(const u32 rank_bgn,
+			const u32 rw_group, const u32 test_bgn,
+			const int use_read_test, const int update_fom)
 {
 	const u32 addr =
 		SDR_PHYGRP_SCCGRP_ADDRESS + SCC_MGR_DQS_IN_DELAY_OFFSET +
-		(read_group << 2);
+		(rw_group << 2);
 	/*
 	 * Store these as signed since there are comparisons with
 	 * signed numbers.
@@ -2212,7 +2212,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	int i, min_index;
 	int ret;
 
-	debug("%s:%d: %u %u", __func__, __LINE__, read_group, test_bgn);
+	debug("%s:%d: %u %u", __func__, __LINE__, rw_group, test_bgn);
 
 	start_dqs = readl(addr);
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
@@ -2227,13 +2227,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	}
 
 	/* Search for the left edge of the window for each bit */
-	search_left_edge(0, rank_bgn, write_group, read_group, test_bgn,
+	search_left_edge(0, rank_bgn, rw_group, rw_group, test_bgn,
 			 &sticky_bit_chk,
 			 left_edge, right_edge, use_read_test);
 
 
 	/* Search for the right edge of the window for each bit */
-	ret = search_right_edge(0, rank_bgn, write_group, read_group,
+	ret = search_right_edge(0, rank_bgn, rw_group, rw_group,
 				start_dqs, start_dqs_en,
 				&sticky_bit_chk,
 				left_edge, right_edge, use_read_test);
@@ -2243,23 +2243,23 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 		 * in rw_mgr_mem_calibrate_vfifo to retry different
 		 * dqs/ck relationships.
 		 */
-		scc_mgr_set_dqs_bus_in_delay(read_group, start_dqs);
+		scc_mgr_set_dqs_bus_in_delay(rw_group, start_dqs);
 		if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS)
-			scc_mgr_set_dqs_en_delay(read_group, start_dqs_en);
+			scc_mgr_set_dqs_en_delay(rw_group, start_dqs_en);
 
-		scc_mgr_load_dqs(read_group);
+		scc_mgr_load_dqs(rw_group);
 		writel(0, &sdr_scc_mgr->update);
 
 		debug_cond(DLEVEL == 1,
 			   "%s:%d vfifo_center: failed to find edge [%u]: %d %d",
 			   __func__, __LINE__, i, left_edge[i], right_edge[i]);
 		if (use_read_test) {
-			set_failing_group_stage(read_group *
+			set_failing_group_stage(rw_group *
 				RW_MGR_MEM_DQ_PER_READ_DQS + i,
 				CAL_STAGE_VFIFO,
 				CAL_SUBSTAGE_VFIFO_CENTER);
 		} else {
-			set_failing_group_stage(read_group *
+			set_failing_group_stage(rw_group *
 				RW_MGR_MEM_DQ_PER_READ_DQS + i,
 				CAL_STAGE_VFIFO_AFTER_WRITES,
 				CAL_SUBSTAGE_VFIFO_CENTER);
@@ -2302,13 +2302,13 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_center(uint32_t rank_bgn,
 	/* Move DQS-en */
 	if (IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS) {
 		final_dqs_en = start_dqs_en - mid_min;
-		scc_mgr_set_dqs_en_delay(read_group, final_dqs_en);
-		scc_mgr_load_dqs(read_group);
+		scc_mgr_set_dqs_en_delay(rw_group, final_dqs_en);
+		scc_mgr_load_dqs(rw_group);
 	}
 
 	/* Move DQS */
-	scc_mgr_set_dqs_bus_in_delay(read_group, new_dqs);
-	scc_mgr_load_dqs(read_group);
+	scc_mgr_set_dqs_bus_in_delay(rw_group, new_dqs);
+	scc_mgr_load_dqs(rw_group);
 	debug_cond(DLEVEL == 2,
 		   "%s:%d vfifo_center: dq_margin=%d dqs_margin=%d",
 		   __func__, __LINE__, dq_margin, dqs_margin);
@@ -2456,7 +2456,7 @@ rw_mgr_mem_calibrate_dq_dqs_centering(const u32 rw_group, const u32 test_bgn,
 			continue;
 
 		ret = rw_mgr_mem_calibrate_vfifo_center(rank_bgn, rw_group,
-							rw_group, test_bgn,
+							test_bgn,
 							use_read_test,
 							update_fom);
 		if (ret)
@@ -2595,7 +2595,6 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_end(uint32_t read_group,
 		if (!param->skip_shadow_regs[sr]) {
 		/* This is the last calibration round, update FOM here */
 			if (!rw_mgr_mem_calibrate_vfifo_center(rank_bgn,
-								write_group,
 								read_group,
 								test_bgn, 0,
 								1)) {
Signature · 1 line
2.1.4
#158 lore raw

PATCH 154/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 10

In reply to Marek Vasut

Fix the return value of the function to match common convention where 0 means success and negative means error. Fix the return values in case of an error to use errno.h codes.

---
 drivers/ddr/altera/sequencer.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/ddr/altera/sequencer.c +7 -4
index ee541ce..efcf283 100644
@@ -2264,7 +2264,7 @@ static int rw_mgr_mem_calibrate_vfifo_center(const u32 rank_bgn,
 				CAL_STAGE_VFIFO_AFTER_WRITES,
 				CAL_SUBSTAGE_VFIFO_CENTER);
 		}
-		return 0;
+		return -EIO;
 	}
 
 	min_index = get_window_mid_index(0, left_edge, right_edge, &mid_min);
@@ -2319,7 +2319,10 @@ static int rw_mgr_mem_calibrate_vfifo_center(const u32 rank_bgn,
 	 */
 	writel(0, &sdr_scc_mgr->update);
 
-	return (dq_margin >= 0) && (dqs_margin >= 0);
+	if ((dq_margin < 0) || (dqs_margin < 0))
+		return -EINVAL;
+
+	return 0;
 }
 
 /**
@@ -2459,7 +2462,7 @@ rw_mgr_mem_calibrate_dq_dqs_centering(const u32 rw_group, const u32 test_bgn,
 							test_bgn,
 							use_read_test,
 							update_fom);
-		if (ret)
+		if (!ret)
 			continue;
 
 		grp_calibrated = 0;
@@ -2594,7 +2597,7 @@ static uint32_t rw_mgr_mem_calibrate_vfifo_end(uint32_t read_group,
 		/* Determine if this set of ranks should be skipped entirely */
 		if (!param->skip_shadow_regs[sr]) {
 		/* This is the last calibration round, update FOM here */
-			if (!rw_mgr_mem_calibrate_vfifo_center(rank_bgn,
+			if (rw_mgr_mem_calibrate_vfifo_center(rank_bgn,
 								read_group,
 								test_bgn, 0,
 								1)) {
Signature · 1 line
2.1.4
#159 lore raw

PATCH 155/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 11

In reply to Marek Vasut

Add kerneldoc, no functional change.

---
 drivers/ddr/altera/sequencer.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/ddr/altera/sequencer.c +10 -1
index efcf283..b81fc8c 100644
@@ -2191,7 +2191,16 @@ static void center_dq_windows(const int write, int *left_edge, int *right_edge,
 
 }
 
-/* per-bit deskew DQ and center */
+/**
+ * rw_mgr_mem_calibrate_vfifo_center() - Per-bit deskew DQ and centering
+ * @rank_bgn:		Rank number
+ * @rw_group:		Read/Write Group
+ * @test_bgn:		Rank at which the test begins
+ * @use_read_test:	Perform a read test
+ * @update_fom:		Update FOM
+ *
+ * Per-bit deskew DQ and centering.
+ */
 static int rw_mgr_mem_calibrate_vfifo_center(const u32 rank_bgn,
 			const u32 rw_group, const u32 test_bgn,
 			const int use_read_test, const int update_fom)
Signature · 1 line
2.1.4
#160 lore raw

PATCH 156/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 1

In reply to Marek Vasut

Fix data types and constify where applicable, fix broken multiline debug strings and fix comments. No functional change.

---
 drivers/ddr/altera/sequencer.c | 124 +++++++++++++++++++++--------------------
 1 file changed, 63 insertions(+), 61 deletions(-)
drivers/ddr/altera/sequencer.c +63 -61
index b81fc8c..e99ecb4 100644
@@ -2887,24 +2887,26 @@ static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
  * center all windows. do per-bit-deskew to possibly increase size of
  * certain windows.
  */
-static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
-	uint32_t write_group, uint32_t test_bgn)
+static int
+rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
+				   const u32 test_bgn)
 {
-	uint32_t i, min_index;
-	int32_t d;
-	/*
-	 * Store these as signed since there are comparisons with
-	 * signed numbers.
-	 */
-	uint32_t bit_chk;
-	uint32_t sticky_bit_chk;
-	int32_t left_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
-	int32_t right_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
-	int32_t mid;
-	int32_t mid_min, orig_mid_min;
-	int32_t new_dqs, start_dqs;
-	int32_t dq_margin, dqs_margin, dm_margin;
-	uint32_t addr;
+	int i, d;
+	u32 bit_chk;
+	u32 sticky_bit_chk;
+	u32 min_index;
+	u32 addr;
+	int left_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
+	int right_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
+	int mid;
+	int mid_min, orig_mid_min;
+	int new_dqs, start_dqs;
+	int dq_margin, dqs_margin, dm_margin;
+	int bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
+	int end_curr = IO_IO_OUT1_DELAY_MAX + 1;
+	int bgn_best = IO_IO_OUT1_DELAY_MAX + 1;
+	int end_best = IO_IO_OUT1_DELAY_MAX + 1;
+	int win_best = 0;
 
 	int ret;
 
@@ -2916,11 +2918,11 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	start_dqs = readl(addr +
 			  (RW_MGR_MEM_DQ_PER_WRITE_DQS << 2));
 
-	/* per-bit deskew */
+	/* Per-bit deskew. */
 
 	/*
-	 * set the left and right edge of each bit to an illegal value
-	 * use (IO_IO_OUT1_DELAY_MAX + 1) as an illegal value.
+	 * Set the left and right edge of each bit to an illegal value.
+	 * Use (IO_IO_OUT1_DELAY_MAX + 1) as an illegal value.
 	 */
 	sticky_bit_chk = 0;
 	for (i = 0; i < RW_MGR_MEM_DQ_PER_WRITE_DQS; i++) {
@@ -2928,12 +2930,12 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 		right_edge[i] = IO_IO_OUT1_DELAY_MAX + 1;
 	}
 
-	/* Search for the left edge of the window for each bit */
+	/* Search for the left edge of the window for each bit. */
 	search_left_edge(1, rank_bgn, write_group, 0, test_bgn,
 			 &sticky_bit_chk,
 			 left_edge, right_edge, 0);
 
-	/* Search for the right edge of the window for each bit */
+	/* Search for the right edge of the window for each bit. */
 	ret = search_right_edge(1, rank_bgn, write_group, 0,
 				start_dqs, 0,
 				&sticky_bit_chk,
@@ -2946,12 +2948,13 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 
 	min_index = get_window_mid_index(1, left_edge, right_edge, &mid_min);
 
-	/* Determine the amount we can change DQS (which is -mid_min) */
+	/* Determine the amount we can change DQS (which is -mid_min). */
 	orig_mid_min = mid_min;
 	new_dqs = start_dqs;
 	mid_min = 0;
-	debug_cond(DLEVEL == 1, "%s:%d write_center: start_dqs=%d new_dqs=%d \
-		   mid_min=%d\n", __func__, __LINE__, start_dqs, new_dqs, mid_min);
+	debug_cond(DLEVEL == 1,
+		   "%s:%d write_center: start_dqs=%d new_dqs=%d mid_min=%d\n",
+		   __func__, __LINE__, start_dqs, new_dqs, mid_min);
 
 	/* Add delay to bring centre of all DQ windows to the same "level". */
 	center_dq_windows(1, left_edge, right_edge, mid_min, orig_mid_min,
@@ -2965,18 +2968,13 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	debug_cond(DLEVEL == 2, "%s:%d write_center: DM\n", __func__, __LINE__);
 
 	/*
-	 * set the left and right edge of each bit to an illegal value,
-	 * use (IO_IO_OUT1_DELAY_MAX + 1) as an illegal value,
+	 * Set the left and right edge of each bit to an illegal value.
+	 * Use (IO_IO_OUT1_DELAY_MAX + 1) as an illegal value.
 	 */
 	left_edge[0]  = IO_IO_OUT1_DELAY_MAX + 1;
 	right_edge[0] = IO_IO_OUT1_DELAY_MAX + 1;
-	int32_t bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
-	int32_t end_curr = IO_IO_OUT1_DELAY_MAX + 1;
-	int32_t bgn_best = IO_IO_OUT1_DELAY_MAX + 1;
-	int32_t end_best = IO_IO_OUT1_DELAY_MAX + 1;
-	int32_t win_best = 0;
 
-	/* 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) {
 		scc_mgr_apply_group_dm_out1_delay(d);
 		writel(0, &sdr_scc_mgr->update);
@@ -2984,7 +2982,7 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 		if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
 						    PASS_ALL_BITS, &bit_chk,
 						    0)) {
-			/* USE Set current end of the window */
+			/* Set current end of the window. */
 			end_curr = -d;
 			/*
 			 * If a starting edge of our window has not been seen
@@ -3003,26 +3001,26 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 				end_best = end_curr;
 			}
 		} else {
-			/* We just saw a failing test. Reset temp edge */
+			/* 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);
 
 	/*
 	 * Check to see if the current window nudges up aganist 0 delay.
 	 * If so we need to continue the search by shifting DQS otherwise DQS
-	 * search begins as a new search. */
+	 * search begins as a new search.
+	 */
 	if (end_curr != 0) {
 		bgn_curr = IO_IO_OUT1_DELAY_MAX + 1;
 		end_curr = IO_IO_OUT1_DELAY_MAX + 1;
 	}
 
-	/* 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) {
 		/*
 		 * Note: This only shifts DQS, so are we limiting ourselve to
@@ -3035,7 +3033,7 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 		if (rw_mgr_mem_calibrate_write_test(rank_bgn, write_group, 1,
 						    PASS_ALL_BITS, &bit_chk,
 						    0)) {
-			/* USE Set current end of the window */
+			/* Set current end of the window. */
 			end_curr = d;
 			/*
 			 * If a beginning edge of our window has not been seen
@@ -3054,40 +3052,42 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 				end_best = end_curr;
 			}
 		} else {
-			/* We just saw a failing test. Reset temp edge */
+			/* 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 ther remaining delay
-			chain space is less than already seen largest window
-			we can exit */
+			/*
+			 * 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; */
-	left_edge[0] = -1*bgn_best;
+	/* Assign left and right edge for cal and reporting. */
+	left_edge[0] = -1 * bgn_best;
 	right_edge[0] = end_best;
 
-	debug_cond(DLEVEL == 2, "%s:%d dm_calib: left=%d right=%d\n", __func__,
-		   __LINE__, left_edge[0], right_edge[0]);
+	debug_cond(DLEVEL == 2, "%s:%d dm_calib: left=%d right=%d\n",
+		   __func__, __LINE__, left_edge[0], right_edge[0]);
 
-	/* Move DQS (back to orig) */
+	/* Move DQS (back to orig). */
 	scc_mgr_apply_group_dqs_io_and_oct_out1(write_group, new_dqs);
 
 	/* Move DM */
 
-	/* Find middle of window for the DM bit */
+	/* Find middle of window for the DM bit. */
 	mid = (left_edge[0] - right_edge[0]) / 2;
 
-	/* only move right, since we are not moving DQS/DQ */
+	/* Only move right, since we are not moving DQS/DQ. */
 	if (mid < 0)
 		mid = 0;
 
-	/* dm_marign should fail if we never find a window */
+	/* dm_marign should fail if we never find a window. */
 	if (win_best == 0)
 		dm_margin = -1;
 	else
@@ -3096,21 +3096,23 @@ static uint32_t rw_mgr_mem_calibrate_writes_center(uint32_t rank_bgn,
 	scc_mgr_apply_group_dm_out1_delay(mid);
 	writel(0, &sdr_scc_mgr->update);
 
-	debug_cond(DLEVEL == 2, "%s:%d dm_calib: left=%d right=%d mid=%d \
-		   dm_margin=%d\n", __func__, __LINE__, left_edge[0],
-		   right_edge[0], mid, dm_margin);
-	/* Export values */
+	debug_cond(DLEVEL == 2,
+		   "%s:%d dm_calib: left=%d right=%d mid=%d dm_margin=%d\n",
+		   __func__, __LINE__, left_edge[0], right_edge[0],
+		   mid, dm_margin);
+	/* Export values. */
 	gbl->fom_out += dq_margin + dqs_margin;
 
-	debug_cond(DLEVEL == 2, "%s:%d write_center: dq_margin=%d \
-		   dqs_margin=%d dm_margin=%d\n", __func__, __LINE__,
-		   dq_margin, dqs_margin, dm_margin);
+	debug_cond(DLEVEL == 2,
+		   "%s:%d write_center: dq_margin=%d dqs_margin=%d dm_margin=%d\n",
+		   __func__, __LINE__, dq_margin, dqs_margin, dm_margin);
 
 	/*
 	 * Do not remove this line as it makes sure all of our
 	 * decisions have been applied.
 	 */
 	writel(0, &sdr_scc_mgr->update);
+
 	return (dq_margin >= 0) && (dqs_margin >= 0) && (dm_margin >= 0);
 }
 
Signature · 1 line
2.1.4
#161 lore raw

PATCH 157/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 2

In reply to Marek Vasut

Factor out common code for searching best DM/DQS window.

---
 drivers/ddr/altera/sequencer.c | 167 ++++++++++++++++++++++-------------------
 1 file changed, 88 insertions(+), 79 deletions(-)
drivers/ddr/altera/sequencer.c +88 -79
index e99ecb4..cc5db16 100644
@@ -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
  * certain windows.
@@ -2891,8 +2974,7 @@ static int
 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 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 	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 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 	}
 
 	/* 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;
Signature · 1 line
2.1.4
#162 lore raw

PATCH 158/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 3

In reply to Marek Vasut

Zap the useless addr variable.

---
 drivers/ddr/altera/sequencer.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/ddr/altera/sequencer.c +2 -3
index cc5db16..986f088 100644
@@ -2977,7 +2977,6 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 	int i;
 	u32 sticky_bit_chk;
 	u32 min_index;
-	u32 addr;
 	int left_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
 	int right_edge[RW_MGR_MEM_DQ_PER_WRITE_DQS];
 	int mid;
@@ -2996,8 +2995,8 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 
 	dm_margin = 0;
 
-	addr = SDR_PHYGRP_SCCGRP_ADDRESS | SCC_MGR_IO_OUT1_DELAY_OFFSET;
-	start_dqs = readl(addr +
+	start_dqs = readl((SDR_PHYGRP_SCCGRP_ADDRESS |
+			  SCC_MGR_IO_OUT1_DELAY_OFFSET) +
 			  (RW_MGR_MEM_DQ_PER_WRITE_DQS << 2));
 
 	/* Per-bit deskew. */
Signature · 1 line
2.1.4
#163 lore raw

PATCH 159/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 4

In reply to Marek Vasut

Fix return values to match the common return value convention.

---
 drivers/ddr/altera/sequencer.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/ddr/altera/sequencer.c +7 -6
index 986f088..9cf2a1a 100644
@@ -3024,7 +3024,7 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 	if (ret) {
 		set_failing_group_stage(test_bgn + ret - 1, CAL_STAGE_WRITES,
 					CAL_SUBSTAGE_WRITES_CENTER);
-		return 0;
+		return -EINVAL;
 	}
 
 	min_index = get_window_mid_index(1, left_edge, right_edge, &mid_min);
@@ -3121,7 +3121,10 @@ rw_mgr_mem_calibrate_writes_center(const u32 rank_bgn, const u32 write_group,
 	 */
 	writel(0, &sdr_scc_mgr->update);
 
-	return (dq_margin >= 0) && (dqs_margin >= 0) && (dm_margin >= 0);
+	if ((dq_margin < 0) || (dqs_margin < 0) || (dm_margin < 0))
+		return -EINVAL;
+
+	return 0;
 }
 
 /**
@@ -3148,13 +3151,11 @@ static int rw_mgr_mem_calibrate_writes(const u32 rank_bgn, const u32 group,
 	reg_file_set_sub_stage(CAL_SUBSTAGE_WRITES_CENTER);
 
 	ret = rw_mgr_mem_calibrate_writes_center(rank_bgn, group, test_bgn);
-	if (!ret) {
+	if (ret)
 		set_failing_group_stage(group, CAL_STAGE_WRITES,
 					CAL_SUBSTAGE_WRITES_CENTER);
-		return -EIO;
-	}
 
-	return 0;
+	return ret;
 }
 
 /**
Signature · 1 line
2.1.4
#164 lore raw

PATCH 160/172 ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 5

In reply to Marek Vasut

Add kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/ddr/altera/sequencer.c +6 -1
index 9cf2a1a..99cd2b2 100644
@@ -2967,7 +2967,12 @@ static void search_window(const int search_dm,
 }
 
 /*
- * center all windows. do per-bit-deskew to possibly increase size of
+ * rw_mgr_mem_calibrate_writes_center() - Center all windows
+ * @rank_bgn:		Rank number
+ * @write_group:	Write group
+ * @test_bgn:		Rank at which the test begins
+ *
+ * Center all windows. Do per-bit-deskew to possibly increase size of
  * certain windows.
  */
 static int
Signature · 1 line
2.1.4
#165 lore raw

PATCH 161/172 ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 1

In reply to Marek Vasut

Move code around to get rid of the forward declaration. No change to the actual code.

---
 drivers/ddr/altera/sequencer.c | 406 ++++++++++++++++++++---------------------
 1 file changed, 201 insertions(+), 205 deletions(-)
drivers/ddr/altera/sequencer.c +201 -205
index 99cd2b2..659c0d8 100644
@@ -80,10 +80,6 @@ struct gbl_type *gbl;
 struct param_type *param;
 uint32_t curr_shadow_reg;
 
-static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
-	uint32_t write_group, uint32_t use_dm,
-	uint32_t all_correct, uint32_t *bit_chk, uint32_t all_ranks);
-
 static void set_failing_group_stage(uint32_t group, uint32_t stage,
 	uint32_t substage)
 {
@@ -1036,6 +1032,207 @@ static void rw_mgr_mem_handoff(void)
 	 */
 }
 
+/*
+ * issue write test command.
+ * two variants are provided. one that just tests a write pattern and
+ * another that tests datamask functionality.
+ */
+static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
+						  uint32_t test_dm)
+{
+	uint32_t mcc_instruction;
+	uint32_t quick_write_mode = (((STATIC_CALIB_STEPS) & CALIB_SKIP_WRITES) &&
+		ENABLE_SUPER_QUICK_CALIBRATION);
+	uint32_t rw_wl_nop_cycles;
+	uint32_t addr;
+
+	/*
+	 * Set counter and jump addresses for the right
+	 * number of NOP cycles.
+	 * The number of supported NOP cycles can range from -1 to infinity
+	 * Three different cases are handled:
+	 *
+	 * 1. For a number of NOP cycles greater than 0, the RW Mgr looping
+	 *    mechanism will be used to insert the right number of NOPs
+	 *
+	 * 2. For a number of NOP cycles equals to 0, the micro-instruction
+	 *    issuing the write command will jump straight to the
+	 *    micro-instruction that turns on DQS (for DDRx), or outputs write
+	 *    data (for RLD), skipping
+	 *    the NOP micro-instruction all together
+	 *
+	 * 3. A number of NOP cycles equal to -1 indicates that DQS must be
+	 *    turned on in the same micro-instruction that issues the write
+	 *    command. Then we need
+	 *    to directly jump to the micro-instruction that sends out the data
+	 *
+	 * NOTE: Implementing this mechanism uses 2 RW Mgr jump-counters
+	 *       (2 and 3). One jump-counter (0) is used to perform multiple
+	 *       write-read operations.
+	 *       one counter left to issue this command in "multiple-group" mode
+	 */
+
+	rw_wl_nop_cycles = gbl->rw_wl_nop_cycles;
+
+	if (rw_wl_nop_cycles == -1) {
+		/*
+		 * CNTR 2 - We want to execute the special write operation that
+		 * turns on DQS right away and then skip directly to the
+		 * instruction that sends out the data. We set the counter to a
+		 * large number so that the jump is always taken.
+		 */
+		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);
+
+		/* CNTR 3 - Not used */
+		if (test_dm) {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1;
+			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA,
+			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
+			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP,
+			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
+		} else {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0_WL_1;
+			writel(RW_MGR_LFSR_WR_RD_BANK_0_DATA,
+				&sdr_rw_load_jump_mgr_regs->load_jump_add2);
+			writel(RW_MGR_LFSR_WR_RD_BANK_0_NOP,
+				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
+		}
+	} else if (rw_wl_nop_cycles == 0) {
+		/*
+		 * CNTR 2 - We want to skip the NOP operation and go straight
+		 * to the DQS enable instruction. We set the counter to a large
+		 * number so that the jump is always taken.
+		 */
+		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);
+
+		/* CNTR 3 - Not used */
+		if (test_dm) {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0;
+			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS,
+			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
+		} else {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0;
+			writel(RW_MGR_LFSR_WR_RD_BANK_0_DQS,
+				&sdr_rw_load_jump_mgr_regs->load_jump_add2);
+		}
+	} else {
+		/*
+		 * CNTR 2 - In this case we want to execute the next instruction
+		 * and NOT take the jump. So we set the counter to 0. The jump
+		 * address doesn't count.
+		 */
+		writel(0x0, &sdr_rw_load_mgr_regs->load_cntr2);
+		writel(0x0, &sdr_rw_load_jump_mgr_regs->load_jump_add2);
+
+		/*
+		 * CNTR 3 - Set the nop counter to the number of cycles we
+		 * need to loop for, minus 1.
+		 */
+		writel(rw_wl_nop_cycles - 1, &sdr_rw_load_mgr_regs->load_cntr3);
+		if (test_dm) {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0;
+			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP,
+				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
+		} else {
+			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0;
+			writel(RW_MGR_LFSR_WR_RD_BANK_0_NOP,
+				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
+		}
+	}
+
+	writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
+		  RW_MGR_RESET_READ_DATAPATH_OFFSET);
+
+	if (quick_write_mode)
+		writel(0x08, &sdr_rw_load_mgr_regs->load_cntr0);
+	else
+		writel(0x40, &sdr_rw_load_mgr_regs->load_cntr0);
+
+	writel(mcc_instruction, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
+
+	/*
+	 * CNTR 1 - This is used to ensure enough time elapses
+	 * for read data to come back.
+	 */
+	writel(0x30, &sdr_rw_load_mgr_regs->load_cntr1);
+
+	if (test_dm) {
+		writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT,
+			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
+	} else {
+		writel(RW_MGR_LFSR_WR_RD_BANK_0_WAIT,
+			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
+	}
+
+	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
+	writel(mcc_instruction, addr + (group << 2));
+}
+
+/* Test writes, can check for a single bit pass or multiple bit pass */
+static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
+	uint32_t write_group, uint32_t use_dm, uint32_t all_correct,
+	uint32_t *bit_chk, uint32_t all_ranks)
+{
+	uint32_t r;
+	uint32_t correct_mask_vg;
+	uint32_t tmp_bit_chk;
+	uint32_t vg;
+	uint32_t rank_end = all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS :
+		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
+	uint32_t addr_rw_mgr;
+	uint32_t base_rw_mgr;
+
+	*bit_chk = param->write_correct_mask;
+	correct_mask_vg = param->write_correct_mask_vg;
+
+	for (r = rank_bgn; r < rank_end; r++) {
+		if (param->skip_ranks[r]) {
+			/* request to skip the rank */
+			continue;
+		}
+
+		/* set rank */
+		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
+
+		tmp_bit_chk = 0;
+		addr_rw_mgr = SDR_PHYGRP_RWMGRGRP_ADDRESS;
+		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS-1; ; vg--) {
+			/* reset the fifos to get pointers to known state */
+			writel(0, &phy_mgr_cmd->fifo_reset);
+
+			tmp_bit_chk = tmp_bit_chk <<
+				(RW_MGR_MEM_DQ_PER_WRITE_DQS /
+				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS);
+			rw_mgr_mem_calibrate_write_test_issue(write_group *
+				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS+vg,
+				use_dm);
+
+			base_rw_mgr = readl(addr_rw_mgr);
+			tmp_bit_chk = tmp_bit_chk | (correct_mask_vg & ~(base_rw_mgr));
+			if (vg == 0)
+				break;
+		}
+		*bit_chk &= tmp_bit_chk;
+	}
+
+	if (all_correct) {
+		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+		debug_cond(DLEVEL == 2, "write_test(%u,%u,ALL) : %u == \
+			   %u => %lu", write_group, use_dm,
+			   *bit_chk, param->write_correct_mask,
+			   (long unsigned int)(*bit_chk ==
+			   param->write_correct_mask));
+		return *bit_chk == param->write_correct_mask;
+	} else {
+		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
+		debug_cond(DLEVEL == 2, "write_test(%u,%u,ONE) : %u != ",
+		       write_group, use_dm, *bit_chk);
+		debug_cond(DLEVEL == 2, "%lu" " => %lu", (long unsigned int)0,
+			(long unsigned int)(*bit_chk != 0));
+		return *bit_chk != 0x00;
+	}
+}
+
 /**
  * rw_mgr_mem_calibrate_read_test_patterns() - Read back test patterns
  * @rank_bgn:	Rank number
@@ -2682,207 +2879,6 @@ static uint32_t rw_mgr_mem_calibrate_lfifo(void)
 	}
 }
 
-/*
- * issue write test command.
- * two variants are provided. one that just tests a write pattern and
- * another that tests datamask functionality.
- */
-static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
-						  uint32_t test_dm)
-{
-	uint32_t mcc_instruction;
-	uint32_t quick_write_mode = (((STATIC_CALIB_STEPS) & CALIB_SKIP_WRITES) &&
-		ENABLE_SUPER_QUICK_CALIBRATION);
-	uint32_t rw_wl_nop_cycles;
-	uint32_t addr;
-
-	/*
-	 * Set counter and jump addresses for the right
-	 * number of NOP cycles.
-	 * The number of supported NOP cycles can range from -1 to infinity
-	 * Three different cases are handled:
-	 *
-	 * 1. For a number of NOP cycles greater than 0, the RW Mgr looping
-	 *    mechanism will be used to insert the right number of NOPs
-	 *
-	 * 2. For a number of NOP cycles equals to 0, the micro-instruction
-	 *    issuing the write command will jump straight to the
-	 *    micro-instruction that turns on DQS (for DDRx), or outputs write
-	 *    data (for RLD), skipping
-	 *    the NOP micro-instruction all together
-	 *
-	 * 3. A number of NOP cycles equal to -1 indicates that DQS must be
-	 *    turned on in the same micro-instruction that issues the write
-	 *    command. Then we need
-	 *    to directly jump to the micro-instruction that sends out the data
-	 *
-	 * NOTE: Implementing this mechanism uses 2 RW Mgr jump-counters
-	 *       (2 and 3). One jump-counter (0) is used to perform multiple
-	 *       write-read operations.
-	 *       one counter left to issue this command in "multiple-group" mode
-	 */
-
-	rw_wl_nop_cycles = gbl->rw_wl_nop_cycles;
-
-	if (rw_wl_nop_cycles == -1) {
-		/*
-		 * CNTR 2 - We want to execute the special write operation that
-		 * turns on DQS right away and then skip directly to the
-		 * instruction that sends out the data. We set the counter to a
-		 * large number so that the jump is always taken.
-		 */
-		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);
-
-		/* CNTR 3 - Not used */
-		if (test_dm) {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1;
-			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA,
-			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
-			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP,
-			       &sdr_rw_load_jump_mgr_regs->load_jump_add3);
-		} else {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0_WL_1;
-			writel(RW_MGR_LFSR_WR_RD_BANK_0_DATA,
-				&sdr_rw_load_jump_mgr_regs->load_jump_add2);
-			writel(RW_MGR_LFSR_WR_RD_BANK_0_NOP,
-				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
-		}
-	} else if (rw_wl_nop_cycles == 0) {
-		/*
-		 * CNTR 2 - We want to skip the NOP operation and go straight
-		 * to the DQS enable instruction. We set the counter to a large
-		 * number so that the jump is always taken.
-		 */
-		writel(0xFF, &sdr_rw_load_mgr_regs->load_cntr2);
-
-		/* CNTR 3 - Not used */
-		if (test_dm) {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0;
-			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS,
-			       &sdr_rw_load_jump_mgr_regs->load_jump_add2);
-		} else {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0;
-			writel(RW_MGR_LFSR_WR_RD_BANK_0_DQS,
-				&sdr_rw_load_jump_mgr_regs->load_jump_add2);
-		}
-	} else {
-		/*
-		 * CNTR 2 - In this case we want to execute the next instruction
-		 * and NOT take the jump. So we set the counter to 0. The jump
-		 * address doesn't count.
-		 */
-		writel(0x0, &sdr_rw_load_mgr_regs->load_cntr2);
-		writel(0x0, &sdr_rw_load_jump_mgr_regs->load_jump_add2);
-
-		/*
-		 * CNTR 3 - Set the nop counter to the number of cycles we
-		 * need to loop for, minus 1.
-		 */
-		writel(rw_wl_nop_cycles - 1, &sdr_rw_load_mgr_regs->load_cntr3);
-		if (test_dm) {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_DM_BANK_0;
-			writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP,
-				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
-		} else {
-			mcc_instruction = RW_MGR_LFSR_WR_RD_BANK_0;
-			writel(RW_MGR_LFSR_WR_RD_BANK_0_NOP,
-				&sdr_rw_load_jump_mgr_regs->load_jump_add3);
-		}
-	}
-
-	writel(0, SDR_PHYGRP_RWMGRGRP_ADDRESS |
-		  RW_MGR_RESET_READ_DATAPATH_OFFSET);
-
-	if (quick_write_mode)
-		writel(0x08, &sdr_rw_load_mgr_regs->load_cntr0);
-	else
-		writel(0x40, &sdr_rw_load_mgr_regs->load_cntr0);
-
-	writel(mcc_instruction, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
-
-	/*
-	 * CNTR 1 - This is used to ensure enough time elapses
-	 * for read data to come back.
-	 */
-	writel(0x30, &sdr_rw_load_mgr_regs->load_cntr1);
-
-	if (test_dm) {
-		writel(RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT,
-			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
-	} else {
-		writel(RW_MGR_LFSR_WR_RD_BANK_0_WAIT,
-			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
-	}
-
-	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
-	writel(mcc_instruction, addr + (group << 2));
-}
-
-/* Test writes, can check for a single bit pass or multiple bit pass */
-static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
-	uint32_t write_group, uint32_t use_dm, uint32_t all_correct,
-	uint32_t *bit_chk, uint32_t all_ranks)
-{
-	uint32_t r;
-	uint32_t correct_mask_vg;
-	uint32_t tmp_bit_chk;
-	uint32_t vg;
-	uint32_t rank_end = all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS :
-		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
-	uint32_t addr_rw_mgr;
-	uint32_t base_rw_mgr;
-
-	*bit_chk = param->write_correct_mask;
-	correct_mask_vg = param->write_correct_mask_vg;
-
-	for (r = rank_bgn; r < rank_end; r++) {
-		if (param->skip_ranks[r]) {
-			/* request to skip the rank */
-			continue;
-		}
-
-		/* set rank */
-		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
-
-		tmp_bit_chk = 0;
-		addr_rw_mgr = SDR_PHYGRP_RWMGRGRP_ADDRESS;
-		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS-1; ; vg--) {
-			/* reset the fifos to get pointers to known state */
-			writel(0, &phy_mgr_cmd->fifo_reset);
-
-			tmp_bit_chk = tmp_bit_chk <<
-				(RW_MGR_MEM_DQ_PER_WRITE_DQS /
-				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS);
-			rw_mgr_mem_calibrate_write_test_issue(write_group *
-				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS+vg,
-				use_dm);
-
-			base_rw_mgr = readl(addr_rw_mgr);
-			tmp_bit_chk = tmp_bit_chk | (correct_mask_vg & ~(base_rw_mgr));
-			if (vg == 0)
-				break;
-		}
-		*bit_chk &= tmp_bit_chk;
-	}
-
-	if (all_correct) {
-		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "write_test(%u,%u,ALL) : %u == \
-			   %u => %lu", write_group, use_dm,
-			   *bit_chk, param->write_correct_mask,
-			   (long unsigned int)(*bit_chk ==
-			   param->write_correct_mask));
-		return *bit_chk == param->write_correct_mask;
-	} else {
-		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "write_test(%u,%u,ONE) : %u != ",
-		       write_group, use_dm, *bit_chk);
-		debug_cond(DLEVEL == 2, "%lu" " => %lu", (long unsigned int)0,
-			(long unsigned int)(*bit_chk != 0));
-		return *bit_chk != 0x00;
-	}
-}
-
 /**
  * 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
Signature · 1 line
2.1.4
#166 lore raw

PATCH 162/172 ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 2

In reply to Marek Vasut

Clean up coding style, mostly broken multiline formatting strings in debug output. Also clean up data types and constify where applicable.

---
 drivers/ddr/altera/sequencer.c | 75 ++++++++++++++++++++----------------------
 1 file changed, 36 insertions(+), 39 deletions(-)
drivers/ddr/altera/sequencer.c +36 -39
index 659c0d8..dd1ce85 100644
@@ -1169,66 +1169,63 @@ static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
 }
 
 /* Test writes, can check for a single bit pass or multiple bit pass */
-static uint32_t rw_mgr_mem_calibrate_write_test(uint32_t rank_bgn,
-	uint32_t write_group, uint32_t use_dm, uint32_t all_correct,
-	uint32_t *bit_chk, uint32_t all_ranks)
-{
-	uint32_t r;
-	uint32_t correct_mask_vg;
-	uint32_t tmp_bit_chk;
-	uint32_t vg;
-	uint32_t rank_end = all_ranks ? RW_MGR_MEM_NUMBER_OF_RANKS :
-		(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
-	uint32_t addr_rw_mgr;
-	uint32_t base_rw_mgr;
+static int
+rw_mgr_mem_calibrate_write_test(const u32 rank_bgn, const u32 write_group,
+				const u32 use_dm, const u32 all_correct,
+				u32 *bit_chk, const u32 all_ranks)
+{
+	const u32 rank_end = all_ranks ?
+				RW_MGR_MEM_NUMBER_OF_RANKS :
+				(rank_bgn + NUM_RANKS_PER_SHADOW_REG);
+	const u32 shift_ratio = RW_MGR_MEM_DQ_PER_WRITE_DQS /
+				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS;
+	const u32 correct_mask_vg = param->write_correct_mask_vg;
+
+	u32 tmp_bit_chk, base_rw_mgr;
+	int vg, r;
 
 	*bit_chk = param->write_correct_mask;
-	correct_mask_vg = param->write_correct_mask_vg;
 
 	for (r = rank_bgn; r < rank_end; r++) {
-		if (param->skip_ranks[r]) {
-			/* request to skip the rank */
+		/* Request to skip the rank */
+		if (param->skip_ranks[r])
 			continue;
-		}
 
-		/* set rank */
+		/* Set rank */
 		set_rank_and_odt_mask(r, RW_MGR_ODT_MODE_READ_WRITE);
 
 		tmp_bit_chk = 0;
-		addr_rw_mgr = SDR_PHYGRP_RWMGRGRP_ADDRESS;
-		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS-1; ; vg--) {
-			/* reset the fifos to get pointers to known state */
+		for (vg = RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS - 1;
+		     vg >= 0; vg--) {
+			/* Reset the FIFOs to get pointers to known state. */
 			writel(0, &phy_mgr_cmd->fifo_reset);
 
-			tmp_bit_chk = tmp_bit_chk <<
-				(RW_MGR_MEM_DQ_PER_WRITE_DQS /
-				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS);
-			rw_mgr_mem_calibrate_write_test_issue(write_group *
-				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS+vg,
+			rw_mgr_mem_calibrate_write_test_issue(
+				write_group *
+				RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS + vg,
 				use_dm);
 
-			base_rw_mgr = readl(addr_rw_mgr);
-			tmp_bit_chk = tmp_bit_chk | (correct_mask_vg & ~(base_rw_mgr));
-			if (vg == 0)
-				break;
+			base_rw_mgr = readl(SDR_PHYGRP_RWMGRGRP_ADDRESS);
+			tmp_bit_chk <<= shift_ratio;
+			tmp_bit_chk |= (correct_mask_vg & ~(base_rw_mgr));
 		}
+
 		*bit_chk &= tmp_bit_chk;
 	}
 
+	set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
 	if (all_correct) {
-		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "write_test(%u,%u,ALL) : %u == \
-			   %u => %lu", write_group, use_dm,
-			   *bit_chk, param->write_correct_mask,
-			   (long unsigned int)(*bit_chk ==
-			   param->write_correct_mask));
+		debug_cond(DLEVEL == 2,
+			   "write_test(%u,%u,ALL) : %u == %u => %i\n",
+			   write_group, use_dm, *bit_chk,
+			   param->write_correct_mask,
+			   *bit_chk == param->write_correct_mask);
 		return *bit_chk == param->write_correct_mask;
 	} else {
 		set_rank_and_odt_mask(0, RW_MGR_ODT_MODE_OFF);
-		debug_cond(DLEVEL == 2, "write_test(%u,%u,ONE) : %u != ",
-		       write_group, use_dm, *bit_chk);
-		debug_cond(DLEVEL == 2, "%lu" " => %lu", (long unsigned int)0,
-			(long unsigned int)(*bit_chk != 0));
+		debug_cond(DLEVEL == 2,
+			   "write_test(%u,%u,ONE) : %u != %i => %i\n",
+			   write_group, use_dm, *bit_chk, 0, *bit_chk != 0);
 		return *bit_chk != 0x00;
 	}
 }
Signature · 1 line
2.1.4
#167 lore raw

PATCH 163/172 ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 3

In reply to Marek Vasut

Add kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/ddr/altera/sequencer.c +11 -1
index dd1ce85..ce53800 100644
@@ -1168,7 +1168,17 @@ static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
 	writel(mcc_instruction, addr + (group << 2));
 }
 
-/* Test writes, can check for a single bit pass or multiple bit pass */
+/**
+ * rw_mgr_mem_calibrate_write_test() - Test writes, check for single/multiple pass
+ * @rank_bgn:		Rank number
+ * @write_group:	Write Group
+ * @use_dm:		Use DM
+ * @all_correct:	All bits must be correct in the mask
+ * @bit_chk:		Resulting bit mask after the test
+ * @all_ranks:		Test all ranks
+ *
+ * Test writes, can check for a single bit pass or multiple bit pass.
+ */
 static int
 rw_mgr_mem_calibrate_write_test(const u32 rank_bgn, const u32 write_group,
 				const u32 use_dm, const u32 all_correct,
Signature · 1 line
2.1.4
#168 lore raw

PATCH 164/172 ddr: altera: Clean up rw_mgr_mem_calibrate_write_test_issue()

In reply to Marek Vasut

Brief clean, add kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)
drivers/ddr/altera/sequencer.c +18 -13
index ce53800..6ae8a65 100644
@@ -1032,19 +1032,23 @@ static void rw_mgr_mem_handoff(void)
 	 */
 }
 
-/*
- * issue write test command.
- * two variants are provided. one that just tests a write pattern and
- * another that tests datamask functionality.
+
+/**
+ * rw_mgr_mem_calibrate_write_test_issue() - Issue write test command
+ * @group:	Write Group
+ * @use_dm:	Use DM
+ *
+ * Issue write test command. Two variants are provided, one that just tests
+ * a write pattern and another that tests datamask functionality.
  */
-static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
-						  uint32_t test_dm)
+static void rw_mgr_mem_calibrate_write_test_issue(u32 group,
+						  u32 test_dm)
 {
-	uint32_t mcc_instruction;
-	uint32_t quick_write_mode = (((STATIC_CALIB_STEPS) & CALIB_SKIP_WRITES) &&
-		ENABLE_SUPER_QUICK_CALIBRATION);
-	uint32_t rw_wl_nop_cycles;
-	uint32_t addr;
+	const u32 quick_write_mode =
+		(STATIC_CALIB_STEPS & CALIB_SKIP_WRITES) &&
+		ENABLE_SUPER_QUICK_CALIBRATION;
+	u32 mcc_instruction;
+	u32 rw_wl_nop_cycles;
 
 	/*
 	 * Set counter and jump addresses for the right
@@ -1164,8 +1168,9 @@ static void rw_mgr_mem_calibrate_write_test_issue(uint32_t group,
 			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
 	}
 
-	addr = SDR_PHYGRP_RWMGRGRP_ADDRESS | RW_MGR_RUN_SINGLE_GROUP_OFFSET;
-	writel(mcc_instruction, addr + (group << 2));
+	writel(mcc_instruction, (SDR_PHYGRP_RWMGRGRP_ADDRESS |
+				RW_MGR_RUN_SINGLE_GROUP_OFFSET) +
+				(group << 2));
 }
 
 /**
Signature · 1 line
2.1.4
#169 lore raw

PATCH 165/172 ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_end()

In reply to Marek Vasut

This function is implementing the DDR calibration Stage 3 as described in Altera EMI_RM 2015.05.04 . The main body of this function is almost identical to Stage 1.3 (DQ/DQS centering) for all but two flags -- use_read_test and update_fom. Convert this function to call rw_mgr_mem_calibrate_dq_dqs_centering() with the correct flags set to trim down the code duplication.

Moreover, reorder the remnants in the function a little and convert the function to return either 0 or -EIO in case of success and failure respectively, to match the common return value convention.

---
 drivers/ddr/altera/sequencer.c | 59 +++++++++++++++---------------------------
 1 file changed, 21 insertions(+), 38 deletions(-)
drivers/ddr/altera/sequencer.c +21 -38
index 6ae8a65..2baf77d 100644
@@ -2788,51 +2788,34 @@ cal_done_ok:
 	return 1;
 }
 
-/* VFIFO Calibration -- Read Deskew Calibration after write deskew */
-static uint32_t rw_mgr_mem_calibrate_vfifo_end(uint32_t read_group,
-					       uint32_t test_bgn)
+/**
+ * rw_mgr_mem_calibrate_vfifo_end() - DQ/DQS Centering.
+ * @rw_group:		Read/Write Group
+ * @test_bgn:		Rank at which the test begins
+ *
+ * Stage 3: DQ/DQS Centering.
+ *
+ * This function implements UniPHY calibration Stage 3, as explained in
+ * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
+ */
+static int rw_mgr_mem_calibrate_vfifo_end(const u32 rw_group,
+					  const u32 test_bgn)
 {
-	uint32_t rank_bgn, sr;
-	uint32_t grp_calibrated;
-	uint32_t write_group;
-
-	debug("%s:%d %u %u", __func__, __LINE__, read_group, test_bgn);
+	int ret;
 
-	/* update info for sims */
+	debug("%s:%d %u %u", __func__, __LINE__, rw_group, test_bgn);
 
+	/* Update info for sims. */
+	reg_file_set_group(rw_group);
 	reg_file_set_stage(CAL_STAGE_VFIFO_AFTER_WRITES);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_VFIFO_CENTER);
 
-	write_group = read_group;
-
-	/* update info for sims */
-	reg_file_set_group(read_group);
-
-	grp_calibrated = 1;
-	/* Read per-bit deskew can be done on a per shadow register basis */
-	for (rank_bgn = 0, sr = 0; rank_bgn < RW_MGR_MEM_NUMBER_OF_RANKS;
-		rank_bgn += NUM_RANKS_PER_SHADOW_REG, ++sr) {
-		/* Determine if this set of ranks should be skipped entirely */
-		if (!param->skip_shadow_regs[sr]) {
-		/* This is the last calibration round, update FOM here */
-			if (rw_mgr_mem_calibrate_vfifo_center(rank_bgn,
-								read_group,
-								test_bgn, 0,
-								1)) {
-				grp_calibrated = 0;
-			}
-		}
-	}
-
-
-	if (grp_calibrated == 0) {
-		set_failing_group_stage(write_group,
+	ret = rw_mgr_mem_calibrate_dq_dqs_centering(rw_group, test_bgn, 0, 1);
+	if (ret)
+		set_failing_group_stage(rw_group,
 					CAL_STAGE_VFIFO_AFTER_WRITES,
 					CAL_SUBSTAGE_VFIFO_CENTER);
-		return 0;
-	}
-
-	return 1;
+	return ret;
 }
 
 /* Calibrate LFIFO to find smallest read latency */
@@ -3483,7 +3466,7 @@ static uint32_t mem_calibrate(void)
 				if (STATIC_CALIB_STEPS & CALIB_SKIP_WRITES)
 					continue;
 
-				if (rw_mgr_mem_calibrate_vfifo_end(read_group,
+				if (!rw_mgr_mem_calibrate_vfifo_end(read_group,
 								read_test_bgn))
 					continue;
 
Signature · 1 line
2.1.4
#170 lore raw

PATCH 166/172 ddr: altera: Clean up rw_mgr_mem_calibrate_lfifo()

In reply to Marek Vasut

Minor coding style cleanup, add kerneldoc. No functional change.

---
 drivers/ddr/altera/sequencer.c | 49 +++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 22 deletions(-)
drivers/ddr/altera/sequencer.c +27 -22
index 2baf77d..eb0e8cf 100644
@@ -2818,60 +2818,65 @@ static int rw_mgr_mem_calibrate_vfifo_end(const u32 rw_group,
 	return ret;
 }
 
-/* Calibrate LFIFO to find smallest read latency */
+/**
+ * rw_mgr_mem_calibrate_lfifo() - Minimize latency
+ *
+ * Stage 4: Minimize latency.
+ *
+ * This function implements UniPHY calibration Stage 4, as explained in
+ * detail in Altera EMI_RM 2015.05.04 , "UniPHY Calibration Stages".
+ * Calibrate LFIFO to find smallest read latency.
+ */
 static uint32_t rw_mgr_mem_calibrate_lfifo(void)
 {
-	uint32_t found_one;
+	int found_one = 0;
 
 	debug("%s:%d\n", __func__, __LINE__);
 
-	/* update info for sims */
+	/* Update info for sims. */
 	reg_file_set_stage(CAL_STAGE_LFIFO);
 	reg_file_set_sub_stage(CAL_SUBSTAGE_READ_LATENCY);
 
 	/* Load up the patterns used by read calibration for all ranks */
 	rw_mgr_mem_calibrate_read_load_patterns(0, 1);
-	found_one = 0;
 
 	do {
 		writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
 		debug_cond(DLEVEL == 2, "%s:%d lfifo: read_lat=%u",
 			   __func__, __LINE__, gbl->curr_read_lat);
 
-		if (!rw_mgr_mem_calibrate_read_test_all_ranks(0,
-							      NUM_READ_TESTS,
-							      PASS_ALL_BITS,
-							      1)) {
+		if (!rw_mgr_mem_calibrate_read_test_all_ranks(0, NUM_READ_TESTS,
+							      PASS_ALL_BITS, 1))
 			break;
-		}
 
 		found_one = 1;
-		/* reduce read latency and see if things are working */
-		/* correctly */
+		/*
+		 * Reduce read latency and see if things are
+		 * working correctly.
+		 */
 		gbl->curr_read_lat--;
 	} while (gbl->curr_read_lat > 0);
 
-	/* reset the fifos to get pointers to known state */
-
+	/* Reset the fifos to get pointers to known state. */
 	writel(0, &phy_mgr_cmd->fifo_reset);
 
 	if (found_one) {
-		/* add a fudge factor to the read latency that was determined */
+		/* Add a fudge factor to the read latency that was determined */
 		gbl->curr_read_lat += 2;
 		writel(gbl->curr_read_lat, &phy_mgr_cfg->phy_rlat);
-		debug_cond(DLEVEL == 2, "%s:%d lfifo: success: using \
-			   read_lat=%u\n", __func__, __LINE__,
-			   gbl->curr_read_lat);
-		return 1;
+		debug_cond(DLEVEL == 2,
+			   "%s:%d lfifo: success: using read_lat=%u\n",
+			   __func__, __LINE__, gbl->curr_read_lat);
 	} else {
 		set_failing_group_stage(0xff, CAL_STAGE_LFIFO,
 					CAL_SUBSTAGE_READ_LATENCY);
 
-		debug_cond(DLEVEL == 2, "%s:%d lfifo: failed at initial \
-			   read_lat=%u\n", __func__, __LINE__,
-			   gbl->curr_read_lat);
-		return 0;
+		debug_cond(DLEVEL == 2,
+			   "%s:%d lfifo: failed at initial read_lat=%u\n",
+			   __func__, __LINE__, gbl->curr_read_lat);
 	}
+
+	return found_one;
 }
 
 /**
Signature · 1 line
2.1.4
#171 lore raw

PATCH 167/172 ddr: altera: Minor clean up of rw_mgr_mem_handoff()

In reply to Marek Vasut

Add kerneldoc and perform a minor comment cleanup.

---
 drivers/ddr/altera/sequencer.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)
drivers/ddr/altera/sequencer.c +8 -7
index eb0e8cf..9470aca 100644
@@ -1018,21 +1018,22 @@ static void rw_mgr_mem_initialize(void)
 			     0);
 }
 
-/*
- * At the end of calibration we have to program the user settings in, and
- * USER  hand off the memory to the user.
+/**
+ * rw_mgr_mem_handoff() - Hand off the memory to user
+ *
+ * At the end of calibration we have to program the user settings in
+ * and hand off the memory to the user.
  */
 static void rw_mgr_mem_handoff(void)
 {
 	rw_mgr_mem_load_user(RW_MGR_MRS0_USER_MIRR, RW_MGR_MRS0_USER, 1);
 	/*
-	 * USER  need to wait tMOD (12CK or 15ns) time before issuing
-	 * other commands, but we will have plenty of NIOS cycles before
-	 * actual handoff so its okay.
+	 * Need to wait tMOD (12CK or 15ns) time before issuing other
+	 * commands, but we will have plenty of NIOS cycles before actual
+	 * handoff so its okay.
 	 */
 }
 
-
 /**
  * rw_mgr_mem_calibrate_write_test_issue() - Issue write test command
  * @group:	Write Group
Signature · 1 line
2.1.4
#172 lore raw

PATCH 168/172 ddr: altera: Clean up of delay_for_n_mem_clocks() part 1

In reply to Marek Vasut

Fix data types, clean up comments a bit and fix coding style a bit. No functional change.

---
 drivers/ddr/altera/sequencer.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)
drivers/ddr/altera/sequencer.c +13 -14
index 9470aca..5a6c991 100644
@@ -758,40 +758,39 @@ static void set_jump_as_return(void)
  * should always use constants as argument to ensure all computations are
  * performed at compile time
  */
-static void delay_for_n_mem_clocks(const uint32_t clocks)
+static void delay_for_n_mem_clocks(const u32 clocks)
 {
-	uint32_t afi_clocks;
-	uint8_t inner = 0;
-	uint8_t outer = 0;
-	uint16_t c_loop = 0;
+	u32 afi_clocks;
+	u16 c_loop = 0;
+	u8 inner = 0;
+	u8 outer = 0;
 
 	debug("%s:%d: clocks=%u ... start\n", __func__, __LINE__, clocks);
 
-
-	afi_clocks = (clocks + AFI_RATE_RATIO-1) / AFI_RATE_RATIO;
 	/* scale (rounding up) to get afi clocks */
+	afi_clocks = DIV_ROUND_UP(clocks, AFI_RATE_RATIO);
 
 	/*
-	 * Note, we don't bother accounting for being off a little bit
-	 * because of a few extra instructions in outer loops
-	 * Note, the loops have a test at the end, and do the test before
-	 * the decrement, and so always perform the loop
+	 * Note, we don't bother accounting for being off a little
+	 * bit because of a few extra instructions in outer loops.
+	 * Note, the loops have a test at the end, and do the test
+	 * before the decrement, and so always perform the loop
 	 * 1 time more than the counter value
 	 */
 	if (afi_clocks == 0) {
 		;
 	} else if (afi_clocks <= 0x100) {
-		inner = afi_clocks-1;
+		inner = afi_clocks - 1;
 		outer = 0;
 		c_loop = 0;
 	} else if (afi_clocks <= 0x10000) {
 		inner = 0xff;
-		outer = (afi_clocks-1) >> 8;
+		outer = (afi_clocks - 1) >> 8;
 		c_loop = 0;
 	} else {
 		inner = 0xff;
 		outer = 0xff;
-		c_loop = (afi_clocks-1) >> 16;
+		c_loop = (afi_clocks - 1) >> 16;
 	}
 
 	/*
Signature · 1 line
2.1.4
#173 lore raw

PATCH 169/172 ddr: altera: Clean up of delay_for_n_mem_clocks() part 2

In reply to Marek Vasut

Factor out (afi_clocks - 1) into a single place instead of having it all around the function.

---
 drivers/ddr/altera/sequencer.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/ddr/altera/sequencer.c +10 -8
index 5a6c991..25de209 100644
@@ -767,8 +767,10 @@ static void delay_for_n_mem_clocks(const u32 clocks)
 
 	debug("%s:%d: clocks=%u ... start\n", __func__, __LINE__, clocks);
 
-	/* scale (rounding up) to get afi clocks */
+	/* Scale (rounding up) to get afi clocks. */
 	afi_clocks = DIV_ROUND_UP(clocks, AFI_RATE_RATIO);
+	if (afi_clocks)	/* Temporary underflow protection */
+		afi_clocks--;
 
 	/*
 	 * Note, we don't bother accounting for being off a little
@@ -779,18 +781,18 @@ static void delay_for_n_mem_clocks(const u32 clocks)
 	 */
 	if (afi_clocks == 0) {
 		;
-	} else if (afi_clocks <= 0x100) {
-		inner = afi_clocks - 1;
+	} else if (afi_clocks < 0x100) {
+		inner = afi_clocks;
 		outer = 0;
 		c_loop = 0;
-	} else if (afi_clocks <= 0x10000) {
+	} else if (afi_clocks < 0x10000) {
 		inner = 0xff;
-		outer = (afi_clocks - 1) >> 8;
+		outer = afi_clocks >> 8;
 		c_loop = 0;
-	} else {
+	} else {	/* >= 0x10000 */
 		inner = 0xff;
 		outer = 0xff;
-		c_loop = (afi_clocks - 1) >> 16;
+		c_loop = afi_clocks >> 16;
 	}
 
 	/*
@@ -810,7 +812,7 @@ static void delay_for_n_mem_clocks(const u32 clocks)
 	 * and sequencer rom and keeps the delays more accurate and reduces
 	 * overhead
 	 */
-	if (afi_clocks <= 0x100) {
+	if (afi_clocks < 0x100) {
 		writel(SKIP_DELAY_LOOP_VALUE_OR_ZERO(inner),
 			&sdr_rw_load_mgr_regs->load_cntr1);
 
Signature · 1 line
2.1.4
#174 lore raw

PATCH 170/172 ddr: altera: Clean up of delay_for_n_mem_clocks() part 3

In reply to Marek Vasut

Clean up the computation of c_loop, outer and inner variables.

---
 drivers/ddr/altera/sequencer.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)
drivers/ddr/altera/sequencer.c +6 -18
index 25de209..ed4d791 100644
@@ -761,9 +761,9 @@ static void set_jump_as_return(void)
 static void delay_for_n_mem_clocks(const u32 clocks)
 {
 	u32 afi_clocks;
-	u16 c_loop = 0;
-	u8 inner = 0;
-	u8 outer = 0;
+	u16 c_loop;
+	u8 inner;
+	u8 outer;
 
 	debug("%s:%d: clocks=%u ... start\n", __func__, __LINE__, clocks);
 
@@ -779,21 +779,9 @@ static void delay_for_n_mem_clocks(const u32 clocks)
 	 * before the decrement, and so always perform the loop
 	 * 1 time more than the counter value
 	 */
-	if (afi_clocks == 0) {
-		;
-	} else if (afi_clocks < 0x100) {
-		inner = afi_clocks;
-		outer = 0;
-		c_loop = 0;
-	} else if (afi_clocks < 0x10000) {
-		inner = 0xff;
-		outer = afi_clocks >> 8;
-		c_loop = 0;
-	} else {	/* >= 0x10000 */
-		inner = 0xff;
-		outer = 0xff;
-		c_loop = afi_clocks >> 16;
-	}
+	c_loop = afi_clocks >> 16;
+	outer = c_loop ? 0xff : (afi_clocks >> 8);
+	inner = outer ? 0xff : afi_clocks;
 
 	/*
 	 * rom instructions are structured as follows:
Signature · 1 line
2.1.4
#175 lore raw

PATCH 171/172 ddr: altera: Clean up of delay_for_n_mem_clocks() part 4

In reply to Marek Vasut

Simplify the loop code, optimizing compiler can deal with this. No functional change.

---
 drivers/ddr/altera/sequencer.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)
drivers/ddr/altera/sequencer.c +5 -12
index ed4d791..d4e720f 100644
@@ -822,18 +822,11 @@ static void delay_for_n_mem_clocks(const u32 clocks)
 		writel(RW_MGR_IDLE_LOOP2,
 			&sdr_rw_load_jump_mgr_regs->load_jump_add1);
 
-		/* hack to get around compiler not being smart enough */
-		if (afi_clocks <= 0x10000) {
-			/* only need to run once */
-			writel(RW_MGR_IDLE_LOOP2, SDR_PHYGRP_RWMGRGRP_ADDRESS |
-						  RW_MGR_RUN_SINGLE_GROUP_OFFSET);
-		} else {
-			do {
-				writel(RW_MGR_IDLE_LOOP2,
-					SDR_PHYGRP_RWMGRGRP_ADDRESS |
-					RW_MGR_RUN_SINGLE_GROUP_OFFSET);
-			} while (c_loop-- != 0);
-		}
+		do {
+			writel(RW_MGR_IDLE_LOOP2,
+				SDR_PHYGRP_RWMGRGRP_ADDRESS |
+				RW_MGR_RUN_SINGLE_GROUP_OFFSET);
+		} while (c_loop-- != 0);
 	}
 	debug("%s:%d clocks=%u ... end\n", __func__, __LINE__, clocks);
 }
Signature · 1 line
2.1.4
#176 lore raw

PATCH 172/172 ddr: altera: Clean up of delay_for_n_mem_clocks() part 5

In reply to Marek Vasut

Add kerneldoc.

---
 drivers/ddr/altera/sequencer.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/ddr/altera/sequencer.c +5 -3
index d4e720f..37f7354 100644
@@ -754,9 +754,11 @@ static void set_jump_as_return(void)
 	writel(RW_MGR_RETURN, &sdr_rw_load_jump_mgr_regs->load_jump_add0);
 }
 
-/*
- * should always use constants as argument to ensure all computations are
- * performed at compile time
+/**
+ * delay_for_n_mem_clocks() - Delay for N memory clocks
+ * @clocks:	Length of the delay
+ *
+ * Delay for N memory clocks.
  */
 static void delay_for_n_mem_clocks(const u32 clocks)
 {
Signature · 1 line
2.1.4
#177 lore raw

cover socfpga: SPL and DDR init

In reply to Marek Vasut

Hi!

Quoted 6 lines

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Do you have series in git somewhere? I guess I'd like to review different diffs than these...

Thanks,
Pavel

Quoted 251 lines

Dinh Nguyen (3):
driver/ddr/altera: Add DDR driver for Altera's SDRAM controller driver/ddr/altera: Add the sdram calibration portion
arm: socfpga: enable the Altera SDRAM controller driver

Marek Vasut (169):
arm: socfpga: Move sdram_config.h to board dir
ddr: altera: Move struct sdram_prot_rule prototype
ddr: altera: Fix typo in mp_threshold1 programming
ddr: altera: Fix debug message format in sequencer
arm: socfpga: reset: Add missing reset manager regs
arm: socfpga: reset: Start reworking the SoCFPGA reset manager
arm: socfpga: reset: Implement unified function to toggle reset
arm: socfpga: reset: Replace ad-hoc reset functions
arm: socfpga: reset: Repair bridge reset handling
arm: socfpga: reset: Add function to reset add peripherals
arm: socfpga: reset: Add SDMMC, QSPI and DMA defines
arm: socfpga: clock: Get rid of cm_config_t typedef
arm: socfpga: clock: Clean up pll_config.h
arm: socfpga: scan: Staticize scan_mgr_io_scan_chain_prg()
arm: socfpga: scan: Zap redundant params in
scan_mgr_io_scan_chain_prg()
arm: socfpga: scan: Zap iocsr_scan_chain*_table()
arm: socfpga: system: Rework sysmgr_enable_warmrstcfgio()
arm: socfpga: system: Clean up pinmux_config.c
arm: socfpga: spl: Toggle warm reset config I/O bit
arm: socfpga: spl: Configure SCU and NIC-301 early
arm: socfpga: spl: Add missing reset logic
arm: socfpga: spl: Merge spl_board_init() into board_init_f()
arm: socfpga: spl: Remove custom linker script
arm: socfpga: spl: Add support for booting from SD/MMC
arm: socfpga: spl: Add support for booting from QSPI
arm: socfpga: spl: Add support for selecting boot device from BSEL
arm: socfpga: misc: Fix warm reset
arm: socfpga: misc: Add support for printing boot mode
arm: socfpga: misc: Export bootmode into environment variable
arm: socfpga: misc: Probe ethernet GMAC from OF
arm: socfpga: misc: Reset ethernet from OF
arm: socfpga: config: Move SPL GD and malloc to RAM
arm: socfpga: config: Zap incorrect config options
arm: socfpga: config: Exclude CONFIG_SPI_FLASH_MTD from SPL build
arm: socfpga: config: Enable CONFIG_SPI_FLASH_BAR
arm: socfpga: config: Fix LOADADDR
arm: socfpga: config: Make CONFIG_SPI_FLASH_MTD useful
Makefile: Add target for building bootable SPL image for SoCFPGA
ddr: altera: Minor indent fix in set_rank_and_odt_mask()
ddr: altera: Clean up ugly casts in sdram_calibration_full()
ddr: altera: Zap invocation of sdr_get_addr((u32 *)BASE_RW_MGR)"
ddr: altera: Dissolve invocation of sdr_get_addr(&sdr_reg_file->.*)
ddr: altera: Dissolve invocation of sdr_get_addr(&sdr_scc_mgr->.*)
ddr: altera: Dissolve invocation of sdr_get_addr(&sdr_rw_load.*->.*)
ddr: altera: Dissolve invocation of sdr_get_addr(&sdr_mgr_.*->.*)
ddr: altera: Pluck out remaining sdr_get_addr() calls
ddr: altera: Wrap SOCFPGA_SDR_ADDRESS into SDR_PHYGRP.*ADDRESS
ddr: altera: Stop using SDR_CTRLGRP_ADDRESS directly
ddr: altera: Massage addr into I/O accessors
ddr: altera: Clean up hc_initialize_rom_data()
ddr: altera: Clean up initialize_reg_file()
ddr: altera: Clean up initialize_hps_phy()
ddr: altera: Clean up reg_file_set*()
ddr: altera: Clean up scc manager function args
ddr: altera: Reorder scc manager functions
ddr: altera: Implement universal scc manager config function
ddr: altera: Clean up scc_mgr_initialize()
ddr: altera: Shuffle around scc_mgr_set_*all_ranks()
ddr: altera: Implement universal scc_mgr_set_all_ranks()
ddr: altera: Clean up scc_mgr_load_dqs_for_write_group()
ddr: altera: Clean up scc_set_bypass_mode()
ddr: altera: Clean up scc_mgr_set_oct_out1_delay()
ddr: altera: Clean up scc_mgr_apply_group_dq_out1_delay()
ddr: altera: Clean up scc_mgr_*_delay() args
ddr: altera: Clean up scc_mgr_set_hhp_extras()
ddr: altera: Extract scc_mgr_set_hhp_extras()
ddr: altera: Clean up scc_mgr_zero_all()
ddr: altera: Clean up scc_mgr_zero_group()
FIXME: ddr: altera: Internal scc_mgr_apply_group_all_out_delay_add()
cleanup part 1
ddr: altera: Internal scc_mgr_apply_group_all_out_delay_add() cleanup
part 2
ddr: altera: Clean up
scc_mgr_apply_group_all_out_delay_add_all_ranks()
ddr: altera: Factor out instruction loading from
rw_mgr_mem_initialize()
ddr: altera: Factor out common code
ddr: altera: Minor clean up of set_jump_as_return()
ddr: altera: Fix ad-hoc iterative division implementation
ddr: altera: Rework initialize_tracking()
ddr: altera: Init my_param and my_gbl
ddr: altera: Rename initialize() to phy_mgr_initialize()
ddr: altera: Clean up run_mem_calibrate()
ddr: altera: Clean up phy_mgr_initialize()
ddr: altera: Clean up mem_config()
ddr: altera: Clean up mem_precharge_and_activate()
ddr: altera: Clean up set_rank_and_odt_mask() part 1
ddr: altera: Clean up set_rank_and_odt_mask() part 2
ddr: altera: Clean up set_rank_and_odt_mask() part 3
ddr: altera: Minor clean up of mem_skip_calibrate()
ddr: altera: Trivial mem_calibrate() indent cleanup
ddr: altera: Internal mem_calibrate() cleanup part 1
ddr: altera: Internal mem_calibrate() cleanup part 2
ddr: altera: Internal mem_calibrate() cleanup part 3
ddr: altera: Internal mem_calibrate() cleanup part 4
ddr: altera: Internal mem_calibrate() cleanup part 5
ddr: altera: Internal mem_calibrate() cleanup part 6
ddr: altera: Minor clean up of rw_mgr_mem_initialize()
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 1
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 2
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 3
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 4
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 5
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 6
ddr: altera: Internal rw_mgr_mem_calibrate_vfifo() cleanup part 7
ddr: altera: Extract guaranteed write from
rw_mgr_mem_calibrate_vfifo()
ddr: altera: Extract DQS enable calibration from
rw_mgr_mem_calibrate_vfifo()
ddr: altera: Extract Centering DQ/DQS from
rw_mgr_mem_calibrate_vfifo()
ddr: altera: Minor rw_mgr_mem_calibrate_read_load_patterns() cleanup
ddr: altera: Zap rw_mgr_mem_calibrate_read_test_patterns_all_ranks()
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test_patterns()
ddr: altera: Clean up
rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay() part 1
ddr: altera: Clean up
rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay() part 2
ddr: altera: Clean up
rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay() part 3
ddr: altera: Clean up
rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase_sweep_dq_in_delay() part 4
ddr: altera: Clean up sdr_find_window_centre() part 1
ddr: altera: Clean up sdr_find_window_centre() part 2
ddr: altera: Clean up sdr_find_window_centre() part 3
ddr: altera: Clean up sdr_*_phase() part 1
ddr: altera: Clean up sdr_*_phase() part 2
ddr: altera: Clean up sdr_*_phase() part 3
ddr: altera: Clean up sdr_*_phase() part 4
ddr: altera: Clean up sdr_*_phase() part 5
ddr: altera: Clean up sdr_*_phase() part 6
ddr: altera: Clean up sdr_*_phase() part 7
ddr: altera: Clean up sdr_*_phase() part 8
ddr: altera: Clean up sdr_*_phase() part 9
ddr: altera: Clean up sdr_*_phase() part 10
ddr: altera: Clean up rw_mgr_*_vfifo() part 1
ddr: altera: Clean up rw_mgr_*_vfifo() part 2
ddr: altera: Clean up find_vfifo_read()
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 1
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 2
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 3
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 4
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 5
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 6
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_find_dqs_en_phase()
part 7
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test_all_ranks()
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 1
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 2
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 3
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 4
ddr: altera: Clean up rw_mgr_mem_calibrate_read_test() part 5
ddr: altera: Clean up rw_mgr_mem_calibrate_writes()
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 1
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 2
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 3
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 4
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 5
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 6
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 7
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 8
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 9
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 10
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_center() part 11
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 1
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 2
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 3
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 4
ddr: altera: Clean up rw_mgr_mem_calibrate_writes_center() part 5
ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 1
ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 2
ddr: altera: Clean up rw_mgr_mem_calibrate_write_test() part 3
ddr: altera: Clean up rw_mgr_mem_calibrate_write_test_issue()
ddr: altera: Clean up rw_mgr_mem_calibrate_vfifo_end()
ddr: altera: Clean up rw_mgr_mem_calibrate_lfifo()
ddr: altera: Minor clean up of rw_mgr_mem_handoff()
ddr: altera: Clean up of delay_for_n_mem_clocks() part 1
ddr: altera: Clean up of delay_for_n_mem_clocks() part 2
ddr: altera: Clean up of delay_for_n_mem_clocks() part 3
ddr: altera: Clean up of delay_for_n_mem_clocks() part 4
ddr: altera: Clean up of delay_for_n_mem_clocks() part 5

 Makefile                                           |   13 +
 arch/arm/mach-socfpga/clock_manager.c              |   28 +-
 arch/arm/mach-socfpga/include/mach/clock_manager.h |   12 +-
 arch/arm/mach-socfpga/include/mach/reset_manager.h |   60 +-
 arch/arm/mach-socfpga/include/mach/scan_manager.h  |   23 +-
 arch/arm/mach-socfpga/include/mach/sdram.h         |  298 +-
 .../arm/mach-socfpga/include/mach/system_manager.h |    7 +-
 arch/arm/mach-socfpga/misc.c                       |  115 +-
 arch/arm/mach-socfpga/reset_manager.c              |   99 +-
 arch/arm/mach-socfpga/scan_manager.c               |   31 +-
 arch/arm/mach-socfpga/spl.c                        |  220 +-
 arch/arm/mach-socfpga/system_manager.c             |   16 +-
 arch/arm/mach-socfpga/u-boot-spl.lds               |   45 -
 board/altera/socfpga/Makefile                      |    4 +-
 board/altera/socfpga/qts/Makefile                  |    7 -
 board/altera/socfpga/qts/sdram_config.h            |  100 +
 board/altera/socfpga/wrap_iocsr_config.c           |   41 +
 board/altera/socfpga/wrap_pinmux_config.c          |   35 +
 board/altera/socfpga/wrap_pll_config.c             |  144 +
 configs/socfpga_arria5_defconfig                   |    9 +
 configs/socfpga_cyclone5_defconfig                 |   10 +
 configs/socfpga_socrates_defconfig                 |   11 +-
 drivers/ddr/altera/Makefile                        |   11 +
 drivers/ddr/altera/sdram.c                         |  817 +++++
 drivers/ddr/altera/sequencer.c                     | 3806 ++++++++++++++++++++
 drivers/ddr/altera/sequencer.h                     |  299 ++
 drivers/ddr/altera/sequencer_auto.h                |  128 +
 drivers/ddr/altera/sequencer_auto_ac_init.h        |   84 +
 drivers/ddr/altera/sequencer_auto_inst_init.h      |  268 ++
 drivers/ddr/altera/sequencer_defines.h             |  121 +
 include/configs/socfpga_arria5.h                   |    7 +-
 include/configs/socfpga_common.h                   |   63 +-
 include/configs/socfpga_cyclone5.h                 |    7 +-
 include/fdtdec.h                                   |    1 +
 lib/fdtdec.c                                       |    1 +
 scripts/Makefile.spl                               |   11 +
 36 files changed, 6566 insertions(+), 386 deletions(-)
 delete mode 100644 arch/arm/mach-socfpga/u-boot-spl.lds
 delete mode 100644 board/altera/socfpga/qts/Makefile
 create mode 100644 board/altera/socfpga/qts/sdram_config.h
 create mode 100644 board/altera/socfpga/wrap_iocsr_config.c
 create mode 100644 board/altera/socfpga/wrap_pinmux_config.c
 create mode 100644 board/altera/socfpga/wrap_pll_config.c
 create mode 100644 drivers/ddr/altera/Makefile
 create mode 100644 drivers/ddr/altera/sdram.c
 create mode 100644 drivers/ddr/altera/sequencer.c
 create mode 100644 drivers/ddr/altera/sequencer.h
 create mode 100644 drivers/ddr/altera/sequencer_auto.h
 create mode 100644 drivers/ddr/altera/sequencer_auto_ac_init.h
 create mode 100644 drivers/ddr/altera/sequencer_auto_inst_init.h
 create mode 100644 drivers/ddr/altera/sequencer_defines.h
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#178 lore raw

cover socfpga: SPL and DDR init

Quoted 6 lines · Pavel Machek

Hi!

Quoted 4 lines

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

Quoted 6 lines
Quoted 2 lines

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Do you have series in git somewhere? I guess I'd like to review different diffs than these...

Here is what you'd probably make most use of -- complete sockit support:
http://git.denx.de/?p=u-boot/u-boot-
socfpga.git;a=shortlog;h=refs/heads/wip/sockit

The sub-series are in branches with 01...05-* names.

Best regards,
Marek Vasut

#179 lore raw

cover socfpga: SPL and DDR init

Quoted 10 lines · Marek Vasut
Quoted 9 lines · Pavel Machek

Hi!

Quoted 6 lines

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Quoted 7 lines
Quoted 3 lines

Do you have series in git somewhere? I guess I'd like to review different diffs than these...

Here is what you'd probably make most use of -- complete sockit support:
http://git.denx.de/?p=u-boot/u-boot-
socfpga.git;a=shortlog;h=refs/heads/wip/sockit

Thanks!

Random notes:

+static int check_cache_range(unsigned long start, unsigned long stop) +{
+ int ok = 1;
+
+ if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
+ ok = 0;
+
+ if (!ok)
+ debug("CACHE: Misaligned operation at range [%08lx,
%08lx]\n",
+ start, stop);
+

if ((start | end) & (...))

    debug()

..and you get rid of a variable.

+int iocsr_get_config_table(const unsigned int chain_id,
+ const unsigned long **table,
+ unsigned int *table_len)
+{
+ switch (chain_id) {
+ case 0:

+               *table = iocsr_scan_chain0_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH;
+               break;
+       case 1:
+               *table = iocsr_scan_chain1_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH;
+               break;
+       case 2:
+               *table = iocsr_scan_chain2_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH;
+               break;
+       case 3:
+               *table = iocsr_scan_chain3_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH;
+               break;

+ default:
+ return -EINVAL;

I'd do *table = NULL, *table_len = 0 here, to catch any mistakes.

+static void sdram_set_rule(struct sdram_prot_rule *prule) +{
+ uint32_t lo_addr_bits;
+ uint32_t hi_addr_bits;

Can we do u32 here, and in other places like this?

+ rw_mgr_mem_load_user(RW_MGR_MRS0_USER_MIRR, RW_MGR_MRS0_USER,
1);
+ /*
+ * Need to wait tMOD (12CK or 15ns) time before issuing other
+ * commands, but we will have plenty of NIOS cycles before
actual
+ * handoff so its okay.
+ */

I don't understand this comment.

+ return 0;
+
+ /* Calibration Stage 1 completed OK. */
+cal_done_ok:
+ /*
+ * Reset the delay chains back to zero if they have moved > 1
+ * (check for > 1 because loop will increase d even when pass
in
+ * first case).
+ */
+ if (d > 2)
+ scc_mgr_zero_group(rw_group, 1);
+
+ return 1;
+}

Other functions use 0/-EIO protocol here, so it would be good to be consistent.

It looks much better now, thanks,
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#180 lore raw

cover socfpga: SPL and DDR init

Quoted 38 lines · Pavel Machek
Quoted 10 lines · Marek Vasut
Quoted 9 lines · Pavel Machek

Hi!

Quoted 6 lines

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Quoted 6 lines
Quoted 2 lines

Do you have series in git somewhere? I guess I'd like to review different diffs than these...

Here is what you'd probably make most use of -- complete sockit support:
http://git.denx.de/?p=u-boot/u-boot-
socfpga.git;a=shortlog;h=refs/heads/wip/sockit

Thanks!

Random notes:

(quoted diff) +12 -0
+static int check_cache_range(unsigned long start, unsigned long stop)
+{
+       int ok = 1;
+
+       if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
+               ok = 0;
+
+       if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
+               ok = 0;
+
+       if (!ok)
+               debug("CACHE: Misaligned operation at range [%08lx,

%08lx]\n",

(quoted diff) +2 -0
+                       start, stop);
+
Quoted 4 lines

if ((start | end) & (...))

    debug()

..and you get rid of a variable.

This is what I was afraid of -- you not commenting on a specific patch, but at bulk on a series which doesn't even contain the patch :'-(

I'd like to get some feedback on that patch from Albert/Tom though.

Quoted 24 lines
(quoted diff) +23 -0
+int iocsr_get_config_table(const unsigned int chain_id,
+                          const unsigned long **table,
+                          unsigned int *table_len)
+{
+       switch (chain_id) {
+       case 0:
+               *table = iocsr_scan_chain0_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN0_LENGTH;
+               break;
+       case 1:
+               *table = iocsr_scan_chain1_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN1_LENGTH;
+               break;
+       case 2:
+               *table = iocsr_scan_chain2_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN2_LENGTH;
+               break;
+       case 3:
+               *table = iocsr_scan_chain3_table;
+               *table_len = CONFIG_HPS_IOCSR_SCANCHAIN3_LENGTH;
+               break;
+       default:
+               return -EINVAL;
Quoted 1 line

I'd do *table = NULL, *table_len = 0 here, to catch any mistakes.

You can check the return value of the function, I explicitly don't want to modify the output args in case of a failure :)

Quoted 6 lines
(quoted diff) +4 -0
+static void sdram_set_rule(struct sdram_prot_rule *prule)
+{
+       uint32_t lo_addr_bits;
+       uint32_t hi_addr_bits;

Can we do u32 here, and in other places like this?

Yes, linting the rest for proper types is on my list, there is much more than these two variables.

Quoted 10 lines

+ rw_mgr_mem_load_user(RW_MGR_MRS0_USER_MIRR, RW_MGR_MRS0_USER,
1);

(quoted diff) +3 -0
+       /*
+        * Need to wait tMOD (12CK or 15ns) time before issuing other
+        * commands, but we will have plenty of NIOS cycles before

actual

(quoted diff) +2 -0
+        * handoff so its okay.
+        */

I don't understand this comment.

There's plenty of code between issuing the above instruction and triggering the mem handoff, so we don't need to add explicit delay into this function. Also, 15nS is like 15 instructions on the SoCFPGA, so there is zero chance we will trigger the handoff too early.

Quoted 16 lines
(quoted diff) +7 -0
+       return 0;
+
+       /* Calibration Stage 1 completed OK. */
+cal_done_ok:
+       /*
+        * Reset the delay chains back to zero if they have moved > 1
+        * (check for > 1 because loop will increase d even when pass

in

(quoted diff) +7 -0
+        * first case).
+        */
+       if (d > 2)
+               scc_mgr_zero_group(rw_group, 1);
+
+       return 1;
+}
Quoted 2 lines

Other functions use 0/-EIO protocol here, so it would be good to be consistent.

This is also on my list and will do that after the series is in -- this and the type cleanup.

Quoted 1 line

It looks much better now, thanks,

It's far from good though and there will be another series after this one I'm afraid. It might be even heftier, but I want to open the door to proper SoCFPGA support this MW even if it means blowing them to shreds ...

#181 lore raw

cover socfpga: SPL and DDR init

Hi!

Quoted 9 lines
Quoted 9 lines

+ rw_mgr_mem_load_user(RW_MGR_MRS0_USER_MIRR, RW_MGR_MRS0_USER,
1);

(quoted diff) +3 -0
+       /*
+        * Need to wait tMOD (12CK or 15ns) time before issuing other
+        * commands, but we will have plenty of NIOS cycles before

actual

(quoted diff) +2 -0
+        * handoff so its okay.
+        */
Quoted 6 lines
Quoted 1 line

I don't understand this comment.

There's plenty of code between issuing the above instruction and triggering the mem handoff, so we don't need to add explicit delay into this function. Also, 15nS is like 15 instructions on the SoCFPGA, so there is zero chance we will trigger the handoff too early.

What does this have to do with NIOS? CPU cores in FPGA are not mandatory, AFAICT.

Quoted 5 lines
Quoted 1 line

It looks much better now, thanks,

It's far from good though and there will be another series after this one I'm afraid. It might be even heftier, but I want to open the door to proper SoCFPGA support this MW even if it means blowing them to shreds ...

MW?

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#182 lore raw

cover socfpga: SPL and DDR init

Quoted 13 lines · Pavel Machek

Hi!

Quoted 11 lines
Quoted 10 lines

+ rw_mgr_mem_load_user(RW_MGR_MRS0_USER_MIRR, RW_MGR_MRS0_USER,
1);

(quoted diff) +3 -0
+       /*
+        * Need to wait tMOD (12CK or 15ns) time before issuing other
+        * commands, but we will have plenty of NIOS cycles before

actual

(quoted diff) +2 -0
+        * handoff so its okay.
+        */

I don't understand this comment.

Quoted 7 lines
Quoted 4 lines

There's plenty of code between issuing the above instruction and triggering the mem handoff, so we don't need to add explicit delay into this function. Also, 15nS is like 15 instructions on the SoCFPGA, so there is zero chance we will trigger the handoff too early.

What does this have to do with NIOS? CPU cores in FPGA are not mandatory, AFAICT.

I think the UniPHY has a NIOS in it, but Dinh might be able to clarify.

Quoted 8 lines
Quoted 6 lines
Quoted 1 line

It looks much better now, thanks,

It's far from good though and there will be another series after this one I'm afraid. It might be even heftier, but I want to open the door to proper SoCFPGA support this MW even if it means blowing them to shreds
...

MW?

Merge Window.

Best regards,
Marek Vasut

#183 lore raw

cover socfpga: SPL and DDR init

In reply to Marek Vasut
Quoted 7 lines · Marek Vasut

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Thank you so much for putting this series together! For the whole series:

Dinh

#184 lore raw

cover socfpga: SPL and DDR init

Quoted 11 lines · Dinh Nguyen
Quoted 6 lines · Marek Vasut

This series fixes the SPL support on SoCFPGA and cleans up the DDR init code such that it is becoming remotely mainlinable. After this series, the SPL is capable of booting from both SD/MMC and QSPI NOR.

There is still work to be done, but I'd like to start picking it up so it can land in 2015.10 . Reviews and comments are welcome.

Thank you so much for putting this series together! For the whole series:

Applied all to u-boot-socfpga/master, thanks!

Best regards,
Marek Vasut