Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ddr training improvements #173

Merged
merged 3 commits into from
Oct 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 42 additions & 83 deletions arch/risc-v/src/mpfs/mpfs_ddr.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@

/* Retraining limits */

#define ABNORMAL_RETRAIN_CA_DECREASE_COUNT 2
#define ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT 2
#define DQ_DQS_NUM_TAPS 5

/* PLL convenience bits */
Expand Down Expand Up @@ -3406,15 +3404,15 @@ static int mpfs_training_addcmd(void)

static int mpfs_training_verify(void)
{
uint32_t low_ca_dly_count;
uint32_t decrease_count;
uint32_t addcmd_status0;
uint32_t addcmd_status1;
uint32_t retries = MPFS_DEFAULT_RETRIES;
uint32_t t_status = 0;
uint32_t lane_sel;
uint32_t last;
uint32_t i;
uint32_t off_taps;
uint32_t width_taps;
uint32_t gt_clk_sel;

while (!(getreg32(MPFS_DDR_CSR_APB_STAT_DFI_TRAINING_COMPLETE) & 0x01) &&
--retries);
Expand All @@ -3425,19 +3423,15 @@ static int mpfs_training_verify(void)
return -ETIMEDOUT;
}

for (lane_sel = 0; lane_sel < LIBERO_SETTING_DATA_LANES_USED; lane_sel++)
{
mpfs_wait_cycles(10);

putreg32(lane_sel, MPFS_CFG_DDR_SGMII_PHY_LANE_SELECT);
mpfs_wait_cycles(10);

/* Verify cmd address results, rejects if not acceptable */
/* Verify cmd address results, rejects if not acceptable */

addcmd_status0 = getreg32(MPFS_CFG_DDR_SGMII_PHY_ADDCMD_STATUS0);
addcmd_status1 = getreg32(MPFS_CFG_DDR_SGMII_PHY_ADDCMD_STATUS1);
addcmd_status0 = getreg32(MPFS_CFG_DDR_SGMII_PHY_ADDCMD_STATUS0);
addcmd_status1 = getreg32(MPFS_CFG_DDR_SGMII_PHY_ADDCMD_STATUS1);

uint32_t ca_status[8] =
if ((LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT) != ADDCMD_BIT)
{
unsigned low_ca_dly_count = 0;
uint8_t ca_status[8] =
{
((addcmd_status0) & 0xff),
((addcmd_status0 >> 8) & 0xff),
Expand All @@ -3449,46 +3443,40 @@ static int mpfs_training_verify(void)
((addcmd_status1 >> 24) & 0xff)
};

low_ca_dly_count = 0;
last = 0;
decrease_count = 0;
uint8_t last = ca_status[7];

/* Retrain if abnormal CA training result detected
* Expected result is increasing numbers, starting at index n and
* wrapping around. For example:
* [0x35, 0x3b, 0x4, 0x14, 0x1b, 0x21, 0x28, 0x2f].
*
* Also they need to be separated by at least 5
*/

for (i = 0; i < 8; i++)
{
if (ca_status[i] < 5)
if (ca_status[i] < last + 5)
{
low_ca_dly_count++;
}

if (ca_status[i] <= last)
{
decrease_count++;
}

last = ca_status[i];
}

if (ca_status[0] <= ca_status[7])
{
decrease_count++;
}

if ((LIBERO_SETTING_TRAINING_SKIP_SETTING & ADDCMD_BIT) != ADDCMD_BIT)
if (low_ca_dly_count > 1)
{
/* Retrain if abnormal CA training result detected */
/* Retrain via reset */

if (low_ca_dly_count > ABNORMAL_RETRAIN_CA_DLY_DECREASE_COUNT)
{
t_status |= 0x01;
}
return -EIO;
}
}

/* Retrain if abnormal CA training result detected */
for (lane_sel = 0; lane_sel < LIBERO_SETTING_DATA_LANES_USED; lane_sel++)
{
mpfs_wait_cycles(10);

if (decrease_count > ABNORMAL_RETRAIN_CA_DECREASE_COUNT)
{
t_status |= 0x01;
}
}
putreg32(lane_sel, MPFS_CFG_DDR_SGMII_PHY_LANE_SELECT);
mpfs_wait_cycles(10);

/* Check that gate training passed without error */

Expand All @@ -3502,56 +3490,27 @@ static int mpfs_training_verify(void)
t_status |= 0x01;
}

/* Check that DQ/DQS calculated window is above 5 taps. */
/* Check that DQ/DQS calculated window is above 5 taps
* and centered with margin
*/

off_taps = getreg32(MPFS_CFG_DDR_SGMII_PHY_DQDQS_STATUS1);
width_taps = getreg32(MPFS_CFG_DDR_SGMII_PHY_DQDQS_STATUS2);

if (getreg32(MPFS_CFG_DDR_SGMII_PHY_DQDQS_STATUS2) < DQ_DQS_NUM_TAPS)
if (width_taps < DQ_DQS_NUM_TAPS ||
width_taps + off_taps <= 16 + DQ_DQS_NUM_TAPS / 2)
{
t_status |= 0x01;
}

/* Extra checks */

uint32_t temp = 0;
uint32_t gt_clk_sel = getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_CLK_SEL) &
0x03;
/* Check the GT_TXDLY result for the selected clock */

if ((getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_TXDLY) & 0xff) == 0)
{
temp++;
if (gt_clk_sel == 0)
{
t_status |= 0x01;
}
}

if (((getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_TXDLY) >> 8) & 0xff) == 0)
{
temp++;
if (gt_clk_sel == 1)
{
t_status |= 0x01;
}
}

if (((getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_TXDLY) >> 16) & 0xff) == 0)
{
temp++;
if (gt_clk_sel == 2)
{
t_status |= 0x01;
}
}

if (((getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_TXDLY) >> 24) & 0xff) == 0)
{
temp++;
if (gt_clk_sel == 3)
{
t_status |= 0x01;
}
}
gt_clk_sel = getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_CLK_SEL) & 0x03;

if (temp > 1)
if (((getreg32(MPFS_CFG_DDR_SGMII_PHY_GT_TXDLY) >> (gt_clk_sel * 8)) &
0xff) == 0)
{
t_status |= 0x01;
}
Expand Down