This is an automated email from the ASF dual-hosted git repository.

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 697472dc0707999f09a45a7038a59f37eb70a6ba
Author: Jukka Laitinen <[email protected]>
AuthorDate: Sun Aug 27 14:41:06 2023 +0300

    arch/risc-v/src/mpfs/mpfs_ddr.c: Re-write write calibration
    
    Clean up the code and remove un-used global variables & structs
    
    Signed-off-by: Jukka Laitinen <[email protected]>
---
 arch/risc-v/src/mpfs/mpfs_ddr.c | 196 +++++++++++-----------------------------
 1 file changed, 51 insertions(+), 145 deletions(-)

diff --git a/arch/risc-v/src/mpfs/mpfs_ddr.c b/arch/risc-v/src/mpfs/mpfs_ddr.c
index 31cacb5e69..d4b2f43252 100644
--- a/arch/risc-v/src/mpfs/mpfs_ddr.c
+++ b/arch/risc-v/src/mpfs/mpfs_ddr.c
@@ -192,37 +192,6 @@ enum ddr_access_size_e
     DDR_64_BIT
 };
 
-typedef struct
-{
-  uint32_t status_lower;
-  uint32_t status_upper;
-  uint32_t lower;
-  uint32_t upper;
-  uint32_t vref_result;
-} mss_ddr_vref_t;
-
-typedef struct
-{
-  uint32_t status_lower;
-  uint32_t lower[MAX_LANES];
-  uint32_t lane_calib_result;
-} mss_mpfs_ddr_write_calibration_t;
-
-typedef struct
-{
-  uint32_t lower[MAX_LANES];
-  uint32_t upper[MAX_LANES];
-  uint32_t calibration_found[MAX_LANES];
-} mss_lpddr4_dq_calibration_t;
-
-typedef struct
-{
-  mss_mpfs_ddr_write_calibration_t write_cal;
-  mss_lpddr4_dq_calibration_t      dq_cal;
-  mss_ddr_vref_t                   fpga_vref;
-  mss_ddr_vref_t                   mem_vref;
-} mss_ddr_calibration_t;
-
 struct mpfs_ddr_priv_s
 {
   uint32_t               tip_cfg_params;
@@ -238,8 +207,6 @@ struct mpfs_ddr_priv_s
  * Private Data
  ****************************************************************************/
 
-static mss_ddr_calibration_t calib_data;
-
 static struct mpfs_ddr_priv_s g_mpfs_ddr_priv =
 {
   .en_addcmd0_ovrt9     = true,
@@ -582,8 +549,8 @@ static void mpfs_set_ddr_rpc_regs(struct mpfs_ddr_priv_s 
*priv)
 
   putreg32(0x04, MPFS_CFG_DDR_SGMII_PHY_RPC98);
 
-  /* Write TXDLY offset data. 0x14 is a constant copied from HSS reference 
code, it is
-   * unknown whether this needs to be adjustable at the moment
+  /* Write TXDLY offset data. 0x14 is a constant copied from HSS reference
+   * code, it is unknown whether this needs to be adjustable at the moment
    */
 
   putreg32(0x14, MPFS_CFG_DDR_SGMII_PHY_RPC226);
@@ -1731,8 +1698,6 @@ static void mpfs_load_dq(uint8_t lane)
     {
       modifyreg32(MPFS_CFG_DDR_SGMII_PHY_EXPERT_DLYCNT_LOAD_REG1, 0x0f, 0);
     }
-
-  putreg32(0x08, MPFS_CFG_DDR_SGMII_PHY_EXPERT_MODE_EN);
 }
 #endif
 
@@ -1900,12 +1865,6 @@ static int mpfs_mtc_test(uint8_t mask, uint64_t 
start_address,
       modifyreg32(MPFS_DDR_CSR_APB_MT_ERROR_MASK_4, 0x0000f000, 0);
     }
 
-  /* MT_EN - Enables memory test. If asserted at end of memory test,
-   * will keep going.
-   */
-
-  putreg32(0, MPFS_DDR_CSR_APB_MT_EN);
-
   /* MT_EN_SINGLE - Will not repeat if this is set */
 
   putreg32(0, MPFS_DDR_CSR_APB_MT_EN_SINGLE);
@@ -1969,6 +1928,7 @@ static int mpfs_mtc_test_all(uint8_t mask, uint64_t 
start_address,
 
   /* Test all patterns except MTC_USER */
 
+  result = 0;
   for (test_pattern = MTC_COUNTING_PATTERN;
        test_pattern <= MTC_PSEUDO_RANDOM_8BIT && result == 0;
        test_pattern++)
@@ -1988,50 +1948,6 @@ static int mpfs_mtc_test_all(uint8_t mask, uint64_t 
start_address,
   return result;
 }
 
-/****************************************************************************
- * Name: mpfs_set_write_calib
- *
- * Description:
- *   Sets and stores the calibrated values.
- *
- * Input Parameters:
- *   priv    - Instance of the ddr private state structure
- *
- * Returned Value:
- *   Zero (OK) is returned on success. A nonzero value indicates a fail.
- *
- ****************************************************************************/
-
-static void mpfs_set_write_calib(struct mpfs_ddr_priv_s *priv)
-{
-  uint32_t temp = 0;
-  uint8_t lane_to_set;
-  uint8_t shift = 0;
-  uint32_t lanes = priv->number_of_lanes_to_calibrate;
-
-  /* Calculate the calibrated value and write back */
-
-  calib_data.write_cal.lane_calib_result = 0;
-  for (lane_to_set = 0; lane_to_set < lanes; lane_to_set++)
-    {
-      temp = calib_data.write_cal.lower[lane_to_set];
-      calib_data.write_cal.lane_calib_result = \
-        calib_data.write_cal.lane_calib_result | (temp << (shift));
-      shift = (uint8_t)(shift + 0x04);
-    }
-
-  /* bit 3 must be set if we want to use the expert_wrcalib
-   * register.
-   */
-
-  putreg32(0x08, MPFS_CFG_DDR_SGMII_PHY_EXPERT_MODE_EN);
-
-  /* Set the calibrated value */
-
-  putreg32(calib_data.write_cal.lane_calib_result,
-           MPFS_CFG_DDR_SGMII_PHY_EXPERT_WRCALIB);
-}
-
 /****************************************************************************
  * Name: mpfs_write_calibration_using_mtc
  *
@@ -2054,17 +1970,24 @@ static int mpfs_write_calibration_using_mtc(struct 
mpfs_ddr_priv_s *priv)
   uint64_t start_address = 0x00;
   uint32_t size = ONE_MB_MTC;
   int result = 0;
-  uint8_t lane_to_test;
+  uint8_t done = 0x0;
+  uint8_t lane;
   uint32_t cal_data;
-  uint32_t lanes;
+  int lanes;
+  uint8_t offset[MAX_LANES];
+  uint8_t done_mask;
 
-  calib_data.write_cal.status_lower = 0U;
+  /* Initialize number of lanes */
+
+  lanes = priv->number_of_lanes_to_calibrate;
 
   /* Bit 3 must be set if we want to use the expert_wrcalib register. */
 
   putreg32(0x08, MPFS_CFG_DDR_SGMII_PHY_EXPERT_MODE_EN);
 
-  lanes = priv->number_of_lanes_to_calibrate;
+  /* mask of as many 1 bits as there are lanes */
+
+  done_mask = 0xff >> (8 - lanes);
 
   /* Training carried out here: sweeping write calibration offset from 0 to F
    * Explanation: A register, expert_wrcalib, is described in MSS DDR TIP
@@ -2073,73 +1996,62 @@ static int mpfs_write_calibration_using_mtc(struct 
mpfs_ddr_priv_s *priv)
    * with the respect to the address and command for each lane.
    */
 
-  for (cal_data = 0x00000; cal_data < 0xfffff && result != -ETIMEDOUT;
+  for (cal_data = 0x00000;
+       cal_data < 0xfffff && done != done_mask && result != -ETIMEDOUT;
        cal_data += 0x11111)
     {
       putreg32(cal_data, MPFS_CFG_DDR_SGMII_PHY_EXPERT_WRCALIB);
 
-      for (lane_to_test = 0x00;
-           lane_to_test < lanes && result != -ETIMEDOUT;
-           lane_to_test++)
+      for (lane = 0; lane < lanes && result != -ETIMEDOUT; lane++)
         {
-          uint8_t mask = (uint8_t)(1 << lane_to_test);
-          result = mpfs_mtc_test_all(mask, start_address, size,
-                                     MTC_ADD_SEQUENTIAL);
-
-          if (result == 0) /* if passed for this lane */
-            {
-              if ((calib_data.write_cal.status_lower &
-                  (0x01 << lane_to_test)) == 0)
-                {
-                  /* Still looking for good value */
-
-                  calib_data.write_cal.lower[lane_to_test] =
-                    (cal_data & 0xf);
-                  calib_data.write_cal.status_lower       |=
-                    (0x01 << lane_to_test);
-                }
+          uint8_t cal_value = cal_data & 0xf;
+          uint8_t mask = (uint8_t)(0x1 << lane);
 
-              /* Check the result */
+          /* Check if this lane is not yet done and the test passes */
 
-              uint32_t lane_to_check;
-
-              for (lane_to_check = 0; lane_to_check < lanes;
-                   lane_to_check++)
-                {
-                  if (((calib_data.write_cal.status_lower) &
-                       (0x01 << lane_to_check)) == 0)
-                    {
-                      /* not finished, still looking */
-
-                      result = 1;
-                      break;
-                    }
-                }
+          if (!(done & (0x1 << lane)))
+            {
+              /* First passing value is the offset point, record it */
 
+              result = mpfs_mtc_test_all(mask, start_address, size,
+                                         MTC_ADD_SEQUENTIAL);
               if (result == 0)
                 {
-                  /* We're good for all lanes, can stop */
-
-                  break;
+                  offset[lane] = cal_value;
+                  done |= 1 << lane;
                 }
             }
         }
+    }
 
-      if (result == 0)
-        {
-          /* if true, we are good for all lanes, can stop searching */
+  /* If calibration was successful, calculate and set the value */
 
-          break;
+  if (done == done_mask)
+    {
+      /* Calibration succeeded, set the result */
+
+      result = 0;
+
+      /* Create cal_data mask from individua lane offsets */
+
+      cal_data = 0x0;
+      for (lane = 0; lane < lanes; lane++)
+        {
+          cal_data |= offset[lane] << (lane * 4);
         }
-    }
 
-  /* If calibration successful, calculate and set the value */
+      /* Set the write calibration which has been calculated */
 
-  if (result == 0)
+      putreg32(cal_data,
+               MPFS_CFG_DDR_SGMII_PHY_EXPERT_WRCALIB);
+    }
+  else if (result == 0)
     {
-      /* Set the write calibration which has been calculated */
+      /* Just in case calibration is not done but last result from lane test
+       * was OK
+       */
 
-      mpfs_set_write_calib(priv);
+      result = 1;
     }
 
   return result;
@@ -3076,8 +2988,6 @@ static void mpfs_ddr_sm_init(struct mpfs_ddr_priv_s *priv)
   priv->refclk_sweep_index  = 0xf;
 
   priv->number_of_lanes_to_calibrate = mpfs_get_num_lanes();
-
-  memset(&calib_data, 0, sizeof(calib_data));
 }
 
 /****************************************************************************
@@ -3094,8 +3004,6 @@ static void mpfs_ddr_sm_init(struct mpfs_ddr_priv_s *priv)
 
 static void mpfs_ddr_fail(struct mpfs_ddr_priv_s *priv)
 {
-  memset(&calib_data, 0, sizeof(calib_data));
-
   putreg32(0, MPFS_DDR_CSR_APB_PHY_DFI_INIT_START);
 
   /* Reset controller */
@@ -3774,15 +3682,13 @@ static int mpfs_training_write_calibration(struct 
mpfs_ddr_priv_s *priv)
   /* Now start the write calibration as training has been successful */
 
 #ifdef CONFIG_MPFS_DDR_TYPE_LPDDR4
-  uint32_t nr_lanes;
   uint8_t lane;
 
   /* Changed default value to centre dq/dqs on window */
 
   putreg32(0x0c, MPFS_CFG_DDR_SGMII_PHY_RPC220);
 
-  nr_lanes = mpfs_get_num_lanes();
-  for (lane = 0; lane < nr_lanes; lane++)
+  for (lane = 0; lane < priv->number_of_lanes_to_calibrate; lane++)
     {
       mpfs_load_dq(lane);
     }

Reply via email to