ddr: altera: Clean up sdr_*_phase() part 7
[oweals/u-boot.git] / drivers / ddr / altera / sequencer.c
index 451e141854bac5da61b8e5159d1d653af213b03d..d93b5fee498a30f198af728c84be5ca045ea946a 100644 (file)
@@ -1332,92 +1332,106 @@ static int find_vfifo_read(uint32_t grp, uint32_t *bit_chk)
        }
 }
 
-static int find_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)
+/**
+ * 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,
+                         u32 *i, u32 *p)
 {
-       uint32_t found_begin = 0;
-       uint32_t tmp_delay = 0;
-       uint32_t test_status;
-
-       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);
+       u32 ret, bit_chk;
+       const u32 end = VFIFO_SIZE + (working ? 0 : 1);
 
-               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 (; *i < end; (*i)++) {
+               if (working)
+                       *p = 0;
 
-                               test_status =
-                               rw_mgr_mem_calibrate_read_test_all_ranks
-                               (*grp, 1, PASS_ONE_BIT, bit_chk, 0);
+               for (; *p <= IO_DQS_EN_PHASE_MAX; (*p)++) {
+                       scc_mgr_set_dqs_en_phase_all_ranks(grp, *p);
 
-                               if (test_status) {
-                                       *max_working_cnt = 1;
-                                       found_begin = 1;
-                                       break;
-                               }
-                       }
+                       ret = rw_mgr_mem_calibrate_read_test_all_ranks(grp, 1,
+                                               PASS_ONE_BIT, &bit_chk, 0);
+                       if (!working)
+                               ret = !ret;
 
-                       if (found_begin)
-                               break;
+                       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 (found_begin)
-                       break;
+               if (*p > IO_DQS_EN_PHASE_MAX) {
+                       /* Fiddle with FIFO. */
+                       rw_mgr_incr_vfifo(grp, v);
+                       if (!working)
+                               *p = 0;
+               }
        }
 
-       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;
+       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)
+{
+       const u32 dtaps_per_ptap = IO_DELAY_PER_OPA_TAP /
+                                  IO_DELAY_PER_DQS_EN_DCHAIN_TAP;
+       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);
+               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 -EINVAL;
 }
 
-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 *p)
 {
-       uint32_t found_begin = 0;
        uint32_t tmp_delay;
+       u32 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;
+                                                            &bit_chk, 0)) {
                        *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).
@@ -1425,59 +1439,35 @@ 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 *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)
 {
-       uint32_t found_end = 0;
+       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);
+               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)) {
-                               found_end = 1;
-                               break;
-                       } else {
-                               (*max_working_cnt)++;
-                       }
-               }
-
-               if (found_end)
-                       break;
-
-               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);
+       if (ret) {
+               /* Cannot see edge of failing read. */
+               debug_cond(DLEVEL == 2, "%s:%d: end: failed\n",
+                          __func__, __LINE__);
        }
 
-       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;
-       }
+       return ret;
 }
 
 /**
@@ -1553,7 +1543,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;
@@ -1574,13 +1563,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 (find_working_phase(&grp, &bit_chk, dtaps_per_ptap, &work_bgn, &v, &d,
-                               &p, &i, &max_working_cnt) == 0)
+       if (sdr_working_phase(grp, &work_bgn, &v, &d, &p, &i))
                return 0;
 
        work_end = work_bgn;
@@ -1595,14 +1581,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,
-                                &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, &bit_chk, &work_bgn, &v, &d, &p,
-                                        &i, &max_working_cnt, &work_end) == 0)
+               if (sdr_nonworking_phase(grp, &work_bgn, &v, &d, &p,
+                                        &i, &work_end))
                        return 0;
 
                /* ********************************************************* */
@@ -1635,13 +1620,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 */