arch/risc-v/src/mpfs/mpfs_ddr.c: Correct memory test timeouts
Especially the write calibration must bail out if the memory test timeouts, otherwise the device will get stuck in running the memory test in sequence, and it will always timeout. Negative error value was also not properly returned from mpfs_mtc_test. Signed-off-by: Jukka Laitinen <jukkax@ssrc.tii.ae>
This commit is contained in:
parent
d38eebc0e9
commit
6baeb7217e
|
@ -1722,10 +1722,10 @@ static void mpfs_load_dq(uint8_t lane)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint8_t mpfs_mtc_test(uint8_t mask, uint64_t start_address,
|
||||
uint32_t size,
|
||||
enum mtc_pattern_e data_pattern,
|
||||
enum mtc_add_pattern_e add_pattern)
|
||||
static int mpfs_mtc_test(uint8_t mask, uint64_t start_address,
|
||||
uint32_t size,
|
||||
enum mtc_pattern_e data_pattern,
|
||||
enum mtc_add_pattern_e add_pattern)
|
||||
{
|
||||
/* Write calibration:
|
||||
* Configure common memory test interface by writing registers:
|
||||
|
@ -1898,6 +1898,65 @@ static uint8_t mpfs_mtc_test(uint8_t mask, uint64_t start_address,
|
|||
return getreg32(MPFS_DDR_CSR_APB_MT_ERROR_STS) & 0x01;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpfs_mtc_test_all
|
||||
*
|
||||
* Description:
|
||||
* This performs a memory test with the NWL memory test core
|
||||
* using all available test patterns.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mask - Test bitmask
|
||||
* start_address - Test start address
|
||||
* size - Size of the area to test
|
||||
* add_pattern - Data modifier pattern
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned on success. A nonzero value indicates a fail.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mpfs_mtc_test_all(uint8_t mask, uint64_t start_address,
|
||||
uint32_t size,
|
||||
enum mtc_add_pattern_e add_pattern)
|
||||
{
|
||||
int result;
|
||||
enum mtc_pattern_e test_pattern;
|
||||
|
||||
/* Read once to flush MTC. During write calibration the first MTC
|
||||
* read must be discarded as it is unreliable after a series of
|
||||
* bad writes. Only check -ETIMEDOUT; if that occurs, we'll bail out
|
||||
*/
|
||||
|
||||
result = mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_COUNTING_PATTERN,
|
||||
add_pattern);
|
||||
if (result == -ETIMEDOUT)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Test all patterns except MTC_USER */
|
||||
|
||||
for (test_pattern = MTC_COUNTING_PATTERN;
|
||||
test_pattern <= MTC_PSEUDO_RANDOM_8BIT && result == 0;
|
||||
test_pattern++)
|
||||
{
|
||||
if (test_pattern == MTC_USER)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Read using different patterns */
|
||||
|
||||
result = mpfs_mtc_test(mask, start_address, size,
|
||||
test_pattern,
|
||||
add_pattern);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mpfs_set_write_calib
|
||||
*
|
||||
|
@ -1962,8 +2021,8 @@ static void mpfs_set_write_calib(struct mpfs_ddr_priv_s *priv)
|
|||
static int mpfs_write_calibration_using_mtc(struct mpfs_ddr_priv_s *priv)
|
||||
{
|
||||
uint64_t start_address = 0x00;
|
||||
uint32_t size = ONE_MB_MTC;
|
||||
uint32_t result = 0;
|
||||
uint32_t size = ONE_MB_MTC;
|
||||
int result = 0;
|
||||
uint8_t lane_to_test;
|
||||
uint32_t cal_data;
|
||||
uint32_t lanes;
|
||||
|
@ -1983,44 +2042,18 @@ 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; cal_data += 0x11111)
|
||||
for (cal_data = 0x00000; cal_data < 0xfffff && result != -ETIMEDOUT;
|
||||
cal_data += 0x11111)
|
||||
{
|
||||
putreg32(cal_data, MPFS_CFG_DDR_SGMII_PHY_EXPERT_WRCALIB);
|
||||
|
||||
for (lane_to_test = 0x00; lane_to_test < lanes; lane_to_test++)
|
||||
for (lane_to_test = 0x00;
|
||||
lane_to_test < lanes && result != -ETIMEDOUT;
|
||||
lane_to_test++)
|
||||
{
|
||||
/* Read once to flush MTC. During write calibration the first MTC
|
||||
* read must be discarded as it is unreliable after a series of
|
||||
* bad writes.
|
||||
*/
|
||||
|
||||
uint8_t mask = (uint8_t)(1 << lane_to_test);
|
||||
|
||||
result = mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_COUNTING_PATTERN, MTC_ADD_SEQUENTIAL);
|
||||
|
||||
/* Read using different patterns */
|
||||
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_COUNTING_PATTERN,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_WALKING_ONE, MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_NO_REPEATING_PSEUDO_RANDOM,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_ALT_ONES_ZEROS, MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_ALT_5_A, MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_PSEUDO_RANDOM_16BIT,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
result |= mpfs_mtc_test(mask, start_address, size,
|
||||
MTC_PSEUDO_RANDOM_8BIT,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
result = mpfs_mtc_test_all(mask, start_address, size,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
|
||||
if (result == 0) /* if passed for this lane */
|
||||
{
|
||||
|
@ -3766,7 +3799,7 @@ static int mpfs_training_write_calibration(struct mpfs_ddr_priv_s *priv)
|
|||
|
||||
static int mpfs_training_full_mtc_test(void)
|
||||
{
|
||||
uint32_t error = 0;
|
||||
int error = 0;
|
||||
uint8_t mask;
|
||||
|
||||
if (mpfs_get_num_lanes() <= 3)
|
||||
|
@ -3778,48 +3811,16 @@ static int mpfs_training_full_mtc_test(void)
|
|||
mask = 0xf;
|
||||
}
|
||||
|
||||
/* Read once to flush MTC. During write calibration the first MTC read
|
||||
* must be discarded as it is unreliable after a series of bad writes.
|
||||
*/
|
||||
/* Test sequential additions */
|
||||
|
||||
mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_COUNTING_PATTERN,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error = mpfs_mtc_test_all(mask, 0x00, ONE_MB_MTC, MTC_ADD_SEQUENTIAL);
|
||||
|
||||
/* Read using different patterns */
|
||||
if (error == 0)
|
||||
{
|
||||
/* Test random additions */
|
||||
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_COUNTING_PATTERN,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_WALKING_ONE,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC,
|
||||
MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_ALT_ONES_ZEROS,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_ALT_5_A,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM_16BIT,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM_8BIT,
|
||||
MTC_ADD_SEQUENTIAL);
|
||||
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_COUNTING_PATTERN,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_WALKING_ONE,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC,
|
||||
MTC_NO_REPEATING_PSEUDO_RANDOM, MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_ALT_ONES_ZEROS,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_ALT_5_A,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM_16BIT,
|
||||
MTC_ADD_RANDOM);
|
||||
error |= mpfs_mtc_test(mask, 0x00, ONE_MB_MTC, MTC_PSEUDO_RANDOM_8BIT,
|
||||
MTC_ADD_RANDOM);
|
||||
error = mpfs_mtc_test_all(mask, 0x00, ONE_MB_MTC, MTC_ADD_RANDOM);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue