diff options
Diffstat (limited to 'drivers/ddr/mvebu/ddr3_dqs.c')
-rw-r--r-- | drivers/ddr/mvebu/ddr3_dqs.c | 1374 |
1 files changed, 0 insertions, 1374 deletions
diff --git a/drivers/ddr/mvebu/ddr3_dqs.c b/drivers/ddr/mvebu/ddr3_dqs.c deleted file mode 100644 index 71a986d54f..0000000000 --- a/drivers/ddr/mvebu/ddr3_dqs.c +++ /dev/null @@ -1,1374 +0,0 @@ -/* - * Copyright (C) Marvell International Ltd. and its affiliates - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include <common.h> -#include <i2c.h> -#include <spl.h> -#include <asm/io.h> -#include <asm/arch/cpu.h> -#include <asm/arch/soc.h> - -#include "ddr3_hw_training.h" - -/* - * Debug - */ -#define DEBUG_DQS_C(s, d, l) \ - DEBUG_DQS_S(s); DEBUG_DQS_D(d, l); DEBUG_DQS_S("\n") -#define DEBUG_DQS_FULL_C(s, d, l) \ - DEBUG_DQS_FULL_S(s); DEBUG_DQS_FULL_D(d, l); DEBUG_DQS_FULL_S("\n") -#define DEBUG_DQS_RESULTS_C(s, d, l) \ - DEBUG_DQS_RESULTS_S(s); DEBUG_DQS_RESULTS_D(d, l); DEBUG_DQS_RESULTS_S("\n") -#define DEBUG_PER_DQ_C(s, d, l) \ - puts(s); printf("%x", d); puts("\n") - -#define DEBUG_DQS_RESULTS_S(s) \ - debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%s", s) -#define DEBUG_DQS_RESULTS_D(d, l) \ - debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_2, "%x", d) - -#define DEBUG_PER_DQ_S(s) \ - debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%s", s) -#define DEBUG_PER_DQ_D(d, l) \ - debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%x", d) -#define DEBUG_PER_DQ_DD(d, l) \ - debug_cond(ddr3_get_log_level() >= MV_LOG_LEVEL_3, "%d", d) - -#ifdef MV_DEBUG_DQS -#define DEBUG_DQS_S(s) puts(s) -#define DEBUG_DQS_D(d, l) printf("%x", d) -#else -#define DEBUG_DQS_S(s) -#define DEBUG_DQS_D(d, l) -#endif - -#ifdef MV_DEBUG_DQS_FULL -#define DEBUG_DQS_FULL_S(s) puts(s) -#define DEBUG_DQS_FULL_D(d, l) printf("%x", d) -#else -#define DEBUG_DQS_FULL_S(s) -#define DEBUG_DQS_FULL_D(d, l) -#endif - -/* State machine for centralization - find low & high limit */ -enum { - PUP_ADLL_LIMITS_STATE_FAIL, - PUP_ADLL_LIMITS_STATE_PASS, - PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS, -}; - -/* Hold centralization low results */ -static int centralization_low_limit[MAX_PUP_NUM] = { 0 }; -/* Hold centralization high results */ -static int centralization_high_limit[MAX_PUP_NUM] = { 0 }; - -int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx); -int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx, - int *size_valid); -static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx); -int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx, u32 special_pattern_pup); -int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx, u32 special_pattern_pup); -int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx); - -#ifdef MV88F78X60 -extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN]; -extern u32 killer_pattern_64b[DQ_NUM][LEN_SPECIAL_PATTERN]; -extern int per_bit_data[MAX_PUP_NUM][DQ_NUM]; -#else -extern u32 killer_pattern[DQ_NUM][LEN_16BIT_KILLER_PATTERN]; -extern u32 killer_pattern_32b[DQ_NUM][LEN_SPECIAL_PATTERN]; -#if defined(MV88F672X) -extern int per_bit_data[MAX_PUP_NUM][DQ_NUM]; -#endif -#endif -extern u32 special_pattern[DQ_NUM][LEN_SPECIAL_PATTERN]; - -static u32 *ddr3_dqs_choose_pattern(MV_DRAM_INFO *dram_info, u32 victim_dq) -{ - u32 *pattern_ptr; - - /* Choose pattern */ - switch (dram_info->ddr_width) { -#if defined(MV88F672X) - case 16: - pattern_ptr = (u32 *)&killer_pattern[victim_dq]; - break; -#endif - case 32: - pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq]; - break; -#if defined(MV88F78X60) - case 64: - pattern_ptr = (u32 *)&killer_pattern_64b[victim_dq]; - break; -#endif - default: -#if defined(MV88F78X60) - pattern_ptr = (u32 *)&killer_pattern_32b[victim_dq]; -#else - pattern_ptr = (u32 *)&killer_pattern[victim_dq]; -#endif - break; - } - - return pattern_ptr; -} - -/* - * Name: ddr3_dqs_centralization_rx - * Desc: Execute the DQS centralization RX phase. - * Args: dram_info - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_dqs_centralization_rx(MV_DRAM_INFO *dram_info) -{ - u32 cs, ecc, reg; - int status; - - DEBUG_DQS_S("DDR3 - DQS Centralization RX - Starting procedure\n"); - - /* Enable SW override */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | - (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); - - /* [0] = 1 - Enable SW override */ - /* 0x15B8 - Training SW 2 Register */ - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - DEBUG_DQS_S("DDR3 - DQS Centralization RX - SW Override Enabled\n"); - - reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); - reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ - - /* Loop for each CS */ - for (cs = 0; cs < MAX_CS; cs++) { - if (dram_info->cs_ena & (1 << cs)) { - DEBUG_DQS_FULL_C("DDR3 - DQS Centralization RX - CS - ", - (u32) cs, 1); - - for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { - - /* ECC Support - Switch ECC Mux on ecc=1 */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & - ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg |= (dram_info->ecc_ena * - ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - if (ecc) - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Enabled\n"); - else - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - ECC Mux Disabled\n"); - - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Find all limits\n"); - - status = ddr3_find_adll_limits(dram_info, cs, - ecc, 0); - if (MV_OK != status) - return status; - - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization RX - Start calculating center\n"); - - status = ddr3_center_calc(dram_info, cs, ecc, - 0); - if (MV_OK != status) - return status; - } - } - } - - /* ECC Support - Disable ECC MUX */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & - ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - /* Disable SW override - Must be in a different stage */ - /* [0]=0 - Enable SW override */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR); - reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); - /* 0x15B8 - Training SW 2 Register */ - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | - (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); - reg_write(REG_DRAM_TRAINING_1_ADDR, reg); - - return MV_OK; -} - -/* - * Name: ddr3_dqs_centralization_tx - * Desc: Execute the DQS centralization TX phase. - * Args: dram_info - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_dqs_centralization_tx(MV_DRAM_INFO *dram_info) -{ - u32 cs, ecc, reg; - int status; - - DEBUG_DQS_S("DDR3 - DQS Centralization TX - Starting procedure\n"); - - /* Enable SW override */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) | - (1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); - - /* [0] = 1 - Enable SW override */ - /* 0x15B8 - Training SW 2 Register */ - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - DEBUG_DQS_S("DDR3 - DQS Centralization TX - SW Override Enabled\n"); - - reg = (1 << REG_DRAM_TRAINING_AUTO_OFFS); - reg_write(REG_DRAM_TRAINING_ADDR, reg); /* 0x15B0 - Training Register */ - - /* Loop for each CS */ - for (cs = 0; cs < MAX_CS; cs++) { - if (dram_info->cs_ena & (1 << cs)) { - DEBUG_DQS_FULL_C("DDR3 - DQS Centralization TX - CS - ", - (u32) cs, 1); - for (ecc = 0; ecc < (dram_info->ecc_ena + 1); ecc++) { - /* ECC Support - Switch ECC Mux on ecc=1 */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & - ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg |= (dram_info->ecc_ena * - ecc << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - if (ecc) - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Enabled\n"); - else - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - ECC Mux Disabled\n"); - - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Find all limits\n"); - - status = ddr3_find_adll_limits(dram_info, cs, - ecc, 1); - if (MV_OK != status) - return status; - - DEBUG_DQS_FULL_S("DDR3 - DQS Centralization TX - Start calculating center\n"); - - status = ddr3_center_calc(dram_info, cs, ecc, - 1); - if (MV_OK != status) - return status; - } - } - } - - /* ECC Support - Disable ECC MUX */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR) & - ~(1 << REG_DRAM_TRAINING_2_ECC_MUX_OFFS); - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - /* Disable SW override - Must be in a different stage */ - /* [0]=0 - Enable SW override */ - reg = reg_read(REG_DRAM_TRAINING_2_ADDR); - reg &= ~(1 << REG_DRAM_TRAINING_2_SW_OVRD_OFFS); - /* 0x15B8 - Training SW 2 Register */ - reg_write(REG_DRAM_TRAINING_2_ADDR, reg); - - reg = reg_read(REG_DRAM_TRAINING_1_ADDR) | - (1 << REG_DRAM_TRAINING_1_TRNBPOINT_OFFS); - reg_write(REG_DRAM_TRAINING_1_ADDR, reg); - - return MV_OK; -} - -/* - * Name: ddr3_find_adll_limits - * Desc: Execute the Find ADLL limits phase. - * Args: dram_info - * cs - * ecc_ena - * is_tx Indicate whether Rx or Tx - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_find_adll_limits(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, int is_tx) -{ - u32 victim_dq, pup, tmp; - u32 adll_addr; - u32 max_pup; /* maximal pup index */ - u32 pup_mask = 0; - u32 unlock_pup; /* bit array of un locked pups */ - u32 new_unlock_pup; /* bit array of compare failed pups */ - u32 curr_adll; - u32 adll_start_val; /* adll start loop value - for rx or tx limit */ - u32 high_limit; /* holds found High Limit */ - u32 low_limit; /* holds found Low Limit */ - int win_valid; - int update_win; - u32 sdram_offset; - u32 uj, cs_count, cs_tmp, ii; - u32 *pattern_ptr; - u32 dq; - u32 adll_end_val; /* adll end of loop val - for rx or tx limit */ - u8 analog_pbs[DQ_NUM][MAX_PUP_NUM][DQ_NUM][2]; - u8 analog_pbs_sum[MAX_PUP_NUM][DQ_NUM][2]; - int pup_adll_limit_state[MAX_PUP_NUM]; /* hold state of each pup */ - - adll_addr = ((is_tx == 1) ? PUP_DQS_WR : PUP_DQS_RD); - adll_end_val = ((is_tx == 1) ? ADLL_MIN : ADLL_MAX); - adll_start_val = ((is_tx == 1) ? ADLL_MAX : ADLL_MIN); - max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); - - DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - Starting Find ADLL Limits\n"); - - /* init the array */ - for (pup = 0; pup < max_pup; pup++) { - centralization_low_limit[pup] = ADLL_MIN; - centralization_high_limit[pup] = ADLL_MAX; - } - - /* Killer Pattern */ - cs_count = 0; - for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) { - if (dram_info->cs_ena & (1 << cs_tmp)) - cs_count++; - } - sdram_offset = cs_count * (SDRAM_CS_SIZE + 1); - sdram_offset += ((is_tx == 1) ? - SDRAM_DQS_TX_OFFS : SDRAM_DQS_RX_OFFS); - - /* Prepare pup masks */ - for (pup = 0; pup < max_pup; pup++) - pup_mask |= (1 << pup); - - for (pup = 0; pup < max_pup; pup++) { - for (dq = 0; dq < DQ_NUM; dq++) { - analog_pbs_sum[pup][dq][0] = adll_start_val; - analog_pbs_sum[pup][dq][1] = adll_end_val; - } - } - - /* Loop - use different pattern for each victim_dq */ - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Victim DQ - ", - (u32)victim_dq, 1); - /* - * The pups 3 bit arrays represent state machine. with - * 3 stages for each pup. - * 1. fail and didn't get pass in earlier compares. - * 2. pass compare - * 3. fail after pass - end state. - * The window limits are the adll values where the adll - * was in the pass stage. - */ - - /* Set all states to Fail (1st state) */ - for (pup = 0; pup < max_pup; pup++) - pup_adll_limit_state[pup] = PUP_ADLL_LIMITS_STATE_FAIL; - - /* Set current valid pups */ - unlock_pup = pup_mask; - - /* Set ADLL to start value */ - curr_adll = adll_start_val; - -#if defined(MV88F78X60) - for (pup = 0; pup < max_pup; pup++) { - for (dq = 0; dq < DQ_NUM; dq++) { - analog_pbs[victim_dq][pup][dq][0] = - adll_start_val; - analog_pbs[victim_dq][pup][dq][1] = - adll_end_val; - per_bit_data[pup][dq] = 0; - } - } -#endif - - for (uj = 0; uj < ADLL_MAX; uj++) { - DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Setting ADLL to ", - curr_adll, 2); - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { - tmp = ((is_tx == 1) ? curr_adll + - dram_info->wl_val[cs] - [pup * (1 - ecc) + ecc * ECC_PUP] - [D] : curr_adll); - ddr3_write_pup_reg(adll_addr, cs, pup + - (ecc * ECC_PUP), 0, tmp); - } - } - - /* Choose pattern */ - pattern_ptr = ddr3_dqs_choose_pattern(dram_info, - victim_dq); - - /* '1' - means pup failed, '0' - means pup pass */ - new_unlock_pup = 0; - - /* Read and compare results for Victim_DQ# */ - for (ii = 0; ii < 3; ii++) { - u32 tmp = 0; - if (MV_OK != ddr3_sdram_dqs_compare(dram_info, - unlock_pup, &tmp, - pattern_ptr, - LEN_KILLER_PATTERN, - sdram_offset + - LEN_KILLER_PATTERN * - 4 * victim_dq, - is_tx, 0, NULL, - 0)) - return MV_DDR3_TRAINING_ERR_DRAM_COMPARE; - - new_unlock_pup |= tmp; - } - - pup = 0; - DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - UnlockPup: ", - unlock_pup, 2); - DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - NewUnlockPup: ", - new_unlock_pup, 2); - - /* Update pup state */ - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(unlock_pup, pup) == 0) { - DEBUG_DQS_FULL_C("DDR3 - DQS Find Limits - Skipping pup ", - pup, 1); - continue; - } - - /* - * Still didn't find the window limit of the pup - */ - if (IS_PUP_ACTIVE(new_unlock_pup, pup) == 1) { - /* Current compare result == fail */ - if (pup_adll_limit_state[pup] == - PUP_ADLL_LIMITS_STATE_PASS) { - /* - * If now it failed but passed - * earlier - */ - DEBUG_DQS_S("DDR3 - DQS Find Limits - PASS to FAIL: CS - "); - DEBUG_DQS_D(cs, 1); - DEBUG_DQS_S(", DQ - "); - DEBUG_DQS_D(victim_dq, 1); - DEBUG_DQS_S(", Pup - "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_S(", ADLL - "); - DEBUG_DQS_D(curr_adll, 2); - DEBUG_DQS_S("\n"); - -#if defined(MV88F78X60) - for (dq = 0; dq < DQ_NUM; dq++) { - if ((analog_pbs[victim_dq][pup][dq][0] != adll_start_val) - && (analog_pbs[victim_dq][pup] - [dq][1] == adll_end_val)) - analog_pbs - [victim_dq] - [pup][dq] - [1] = - curr_adll; - } -#endif - win_valid = 1; - update_win = 0; - - /* Keep min / max limit value */ - if (is_tx == 0) { - /* RX - found upper limit */ - if (centralization_high_limit[pup] > - (curr_adll - 1)) { - high_limit = - curr_adll - 1; - low_limit = - centralization_low_limit[pup]; - update_win = 1; - } - } else { - /* TX - found lower limit */ - if (centralization_low_limit[pup] < (curr_adll + 1)) { - high_limit = - centralization_high_limit - [pup]; - low_limit = - curr_adll + 1; - update_win = - 1; - } - } - - if (update_win == 1) { - /* - * Before updating - * window limits we need - * to check that the - * limits are valid - */ - if (MV_OK != - ddr3_check_window_limits - (pup, high_limit, - low_limit, is_tx, - &win_valid)) - return MV_DDR3_TRAINING_ERR_WIN_LIMITS; - - if (win_valid == 1) { - /* - * Window limits - * should be - * updated - */ - centralization_low_limit - [pup] = - low_limit; - centralization_high_limit - [pup] = - high_limit; - } - } - - if (win_valid == 1) { - /* Found end of window - lock the pup */ - pup_adll_limit_state[pup] = - PUP_ADLL_LIMITS_STATE_FAIL_AFTER_PASS; - unlock_pup &= ~(1 << pup); - } else { - /* Probably false pass - reset status */ - pup_adll_limit_state[pup] = - PUP_ADLL_LIMITS_STATE_FAIL; - -#if defined(MV88F78X60) - /* Clear logging array of win size (per Dq) */ - for (dq = 0; - dq < DQ_NUM; - dq++) { - analog_pbs - [victim_dq] - [pup][dq] - [0] = - adll_start_val; - analog_pbs - [victim_dq] - [pup][dq] - [1] = - adll_end_val; - per_bit_data - [pup][dq] - = 0; - } -#endif - } - } - } else { - /* Current compare result == pass */ - if (pup_adll_limit_state[pup] == - PUP_ADLL_LIMITS_STATE_FAIL) { - /* If now it passed but failed earlier */ - DEBUG_DQS_S("DDR3 - DQS Find Limits - FAIL to PASS: CS - "); - DEBUG_DQS_D(cs, 1); - DEBUG_DQS_S(", DQ - "); - DEBUG_DQS_D(victim_dq, 1); - DEBUG_DQS_S(", Pup - "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_S(", ADLL - "); - DEBUG_DQS_D(curr_adll, 2); - DEBUG_DQS_S("\n"); - -#if defined(MV88F78X60) - for (dq = 0; dq < DQ_NUM; - dq++) { - if (analog_pbs[victim_dq][pup][dq][0] == adll_start_val) - analog_pbs - [victim_dq] - [pup][dq] - [0] = - curr_adll; - } -#endif - /* Found start of window */ - pup_adll_limit_state[pup] = - PUP_ADLL_LIMITS_STATE_PASS; - - /* Keep min / max limit value */ - if (is_tx == 0) { - /* RX - found low limit */ - if (centralization_low_limit[pup] <= curr_adll) - centralization_low_limit - [pup] = - curr_adll; - } else { - /* TX - found high limit */ - if (centralization_high_limit[pup] >= curr_adll) - centralization_high_limit - [pup] = - curr_adll; - } - } - } - } - - if (unlock_pup == 0) { - /* Found limit to all pups */ - DEBUG_DQS_FULL_S("DDR3 - DQS Find Limits - found PUP limit\n"); - break; - } - - /* - * Increment / decrement (Move to right / left - * one phase - ADLL) dqs RX / TX delay (for all un - * lock pups - */ - if (is_tx == 0) - curr_adll++; - else - curr_adll--; - } - - if (unlock_pup != 0) { - /* - * Found pups that didn't reach to the end of the - * state machine - */ - DEBUG_DQS_C("DDR3 - DQS Find Limits - Pups that didn't reached end of the state machine: ", - unlock_pup, 1); - - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { - if (pup_adll_limit_state[pup] == - PUP_ADLL_LIMITS_STATE_FAIL) { - /* ERROR - found fail for all window size */ - DEBUG_DQS_S("DDR3 - DQS Find Limits - Got FAIL for the complete range on pup - "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_C(" victim DQ ", - victim_dq, 1); - - /* For debug - set min limit to illegal limit */ - centralization_low_limit[pup] - = ADLL_ERROR; - /* - * In case the pup is in mode - * PASS - the limit is the min - * / max adll, no need to - * update because of the results - * array default value - */ - return MV_DDR3_TRAINING_ERR_PUP_RANGE; - } - } - } - } - } - - DEBUG_DQS_S("DDR3 - DQS Find Limits - DQ values per victim results:\n"); - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - for (pup = 0; pup < max_pup; pup++) { - DEBUG_DQS_S("Victim DQ-"); - DEBUG_DQS_D(victim_dq, 1); - DEBUG_DQS_S(", PUP-"); - DEBUG_DQS_D(pup, 1); - for (dq = 0; dq < DQ_NUM; dq++) { - DEBUG_DQS_S(", DQ-"); - DEBUG_DQS_D(dq, 1); - DEBUG_DQS_S(",S-"); - DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq] - [0], 2); - DEBUG_DQS_S(",E-"); - DEBUG_DQS_D(analog_pbs[victim_dq][pup][dq] - [1], 2); - - if (is_tx == 0) { - if (analog_pbs[victim_dq][pup][dq][0] - > analog_pbs_sum[pup][dq][0]) - analog_pbs_sum[pup][dq][0] = - analog_pbs[victim_dq][pup] - [dq][0]; - if (analog_pbs[victim_dq][pup][dq][1] - < analog_pbs_sum[pup][dq][1]) - analog_pbs_sum[pup][dq][1] = - analog_pbs[victim_dq][pup] - [dq][1]; - } else { - if (analog_pbs[victim_dq][pup][dq][0] - < analog_pbs_sum[pup][dq][0]) - analog_pbs_sum[pup][dq][0] = - analog_pbs[victim_dq][pup] - [dq][0]; - if (analog_pbs[victim_dq][pup][dq][1] - > analog_pbs_sum[pup][dq][1]) - analog_pbs_sum[pup][dq][1] = - analog_pbs[victim_dq][pup] - [dq][1]; - } - } - DEBUG_DQS_S("\n"); - } - } - - if (ddr3_get_log_level() >= MV_LOG_LEVEL_3) { - u32 dq; - - DEBUG_PER_DQ_S("\n########## LOG LEVEL 3(Windows margins per-DQ) ##########\n"); - if (is_tx) { - DEBUG_PER_DQ_C("DDR3 - TX CS: ", cs, 1); - } else { - DEBUG_PER_DQ_C("DDR3 - RX CS: ", cs, 1); - } - - if (ecc == 0) { - DEBUG_PER_DQ_S("\n DATA RESULTS:\n"); - } else { - DEBUG_PER_DQ_S("\n ECC RESULTS:\n"); - } - - /* Since all dq has the same value we take 0 as representive */ - dq = 0; - for (pup = 0; pup < max_pup; pup++) { - if (ecc == 0) { - DEBUG_PER_DQ_S("\nBYTE:"); - DEBUG_PER_DQ_D(pup, 1); - DEBUG_PER_DQ_S("\n"); - } else { - DEBUG_PER_DQ_S("\nECC BYTE:\n"); - } - DEBUG_PER_DQ_S(" DQ's LOW HIGH WIN-SIZE\n"); - DEBUG_PER_DQ_S("============================================\n"); - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - if (ecc == 0) { - DEBUG_PER_DQ_S("DQ["); - DEBUG_PER_DQ_DD((victim_dq + - DQ_NUM * pup), 2); - DEBUG_PER_DQ_S("]"); - } else { - DEBUG_PER_DQ_S("CB["); - DEBUG_PER_DQ_DD(victim_dq, 2); - DEBUG_PER_DQ_S("]"); - } - if (is_tx) { - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1], 2); /* low value */ - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* high value */ - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0] - analog_pbs[victim_dq][pup][dq][1], 2); /* win-size */ - } else { - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][0], 2); /* low value */ - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D((analog_pbs[victim_dq][pup][dq][1] - 1), 2); /* high value */ - DEBUG_PER_DQ_S(" 0x"); - DEBUG_PER_DQ_D(analog_pbs[victim_dq][pup][dq][1] - analog_pbs[victim_dq][pup][dq][0], 2); /* win-size */ - } - DEBUG_PER_DQ_S("\n"); - } - } - DEBUG_PER_DQ_S("\n"); - } - - if (is_tx) { - DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n"); - } else { - DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n"); - } - - for (pup = 0; pup < max_pup; pup++) { - DEBUG_DQS_S("PUP-"); - DEBUG_DQS_D(pup, 1); - for (dq = 0; dq < DQ_NUM; dq++) { - DEBUG_DQS_S(", DQ-"); - DEBUG_DQS_D(dq, 1); - DEBUG_DQS_S(",S-"); - DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2); - DEBUG_DQS_S(",E-"); - DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2); - } - DEBUG_DQS_S("\n"); - } - - if (is_tx) { - DEBUG_DQS_S("DDR3 - DQS TX - Find Limits - DQ values Summary:\n"); - } else { - DEBUG_DQS_S("DDR3 - DQS RX - Find Limits - DQ values Summary:\n"); - } - - for (pup = 0; pup < max_pup; pup++) { - if (max_pup == 1) { - /* For ECC PUP */ - DEBUG_DQS_S("DDR3 - DQS8"); - } else { - DEBUG_DQS_S("DDR3 - DQS"); - DEBUG_DQS_D(pup, 1); - } - - for (dq = 0; dq < DQ_NUM; dq++) { - DEBUG_DQS_S(", DQ-"); - DEBUG_DQS_D(dq, 1); - DEBUG_DQS_S("::S-"); - DEBUG_DQS_D(analog_pbs_sum[pup][dq][0], 2); - DEBUG_DQS_S(",E-"); - DEBUG_DQS_D(analog_pbs_sum[pup][dq][1], 2); - } - DEBUG_DQS_S("\n"); - } - - DEBUG_DQS_S("DDR3 - DQS Find Limits - Ended\n"); - - return MV_OK; -} - -/* - * Name: ddr3_check_window_limits - * Desc: Check window High & Low limits. - * Args: pup pup index - * high_limit window high limit - * low_limit window low limit - * is_tx Indicate whether Rx or Tx - * size_valid Indicate whether window size is valid - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_check_window_limits(u32 pup, int high_limit, int low_limit, int is_tx, - int *size_valid) -{ - DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Starting\n"); - - if (low_limit > high_limit) { - DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_S(" Low Limit grater than High Limit\n"); - *size_valid = 0; - return MV_OK; - } - - /* - * Check that window size is valid, if not it was probably false pass - * before - */ - if ((high_limit - low_limit) < MIN_WIN_SIZE) { - /* - * Since window size is too small probably there was false - * pass - */ - *size_valid = 0; - - DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_S(" Window size is smaller than MIN_WIN_SIZE\n"); - - } else if ((high_limit - low_limit) > ADLL_MAX) { - *size_valid = 0; - - DEBUG_DQS_S("DDR3 - DQS Check Win Limits - Pup "); - DEBUG_DQS_D(pup, 1); - DEBUG_DQS_S - (" Window size is bigger than max ADLL taps (31) Exiting.\n"); - - return MV_FAIL; - - } else { - *size_valid = 1; - - DEBUG_DQS_FULL_S("DDR3 - DQS Check Win Limits - Pup "); - DEBUG_DQS_FULL_D(pup, 1); - DEBUG_DQS_FULL_C(" window size is ", (high_limit - low_limit), - 2); - } - - return MV_OK; -} - -/* - * Name: ddr3_center_calc - * Desc: Execute the calculate the center of windows phase. - * Args: pDram Info - * is_tx Indicate whether Rx or Tx - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -static int ddr3_center_calc(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx) -{ - /* bit array of pups that need specail search */ - u32 special_pattern_i_pup = 0; - u32 special_pattern_ii_pup = 0; - u32 pup; - u32 max_pup; - - max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); - - for (pup = 0; pup < max_pup; pup++) { - if (is_tx == 0) { - /* Check special pattern I */ - /* - * Special pattern Low limit search - relevant only - * for Rx, win size < threshold and low limit = 0 - */ - if (((centralization_high_limit[pup] - - centralization_low_limit[pup]) < VALID_WIN_THRS) - && (centralization_low_limit[pup] == MIN_DELAY)) - special_pattern_i_pup |= (1 << pup); - - /* Check special pattern II */ - /* - * Special pattern High limit search - relevant only - * for Rx, win size < threshold and high limit = 31 - */ - if (((centralization_high_limit[pup] - - centralization_low_limit[pup]) < VALID_WIN_THRS) - && (centralization_high_limit[pup] == MAX_DELAY)) - special_pattern_ii_pup |= (1 << pup); - } - } - - /* Run special pattern Low limit search - for relevant pup */ - if (special_pattern_i_pup != 0) { - DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern I for Low limit search\n"); - if (MV_OK != - ddr3_special_pattern_i_search(dram_info, cs, ecc, is_tx, - special_pattern_i_pup)) - return MV_DDR3_TRAINING_ERR_DQS_LOW_LIMIT_SEARCH; - } - - /* Run special pattern High limit search - for relevant pup */ - if (special_pattern_ii_pup != 0) { - DEBUG_DQS_S("DDR3 - DQS Center Calc - Entering special pattern II for High limit search\n"); - if (MV_OK != - ddr3_special_pattern_ii_search(dram_info, cs, ecc, is_tx, - special_pattern_ii_pup)) - return MV_DDR3_TRAINING_ERR_DQS_HIGH_LIMIT_SEARCH; - } - - /* Set adll to center = (General_High_limit + General_Low_limit)/2 */ - return ddr3_set_dqs_centralization_results(dram_info, cs, ecc, is_tx); -} - -/* - * Name: ddr3_special_pattern_i_search - * Desc: Execute special pattern low limit search. - * Args: - * special_pattern_pup The pups that need the special search - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_special_pattern_i_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx, u32 special_pattern_pup) -{ - u32 victim_dq; /* loop index - victim DQ */ - u32 adll_idx; - u32 pup; - u32 unlock_pup; /* bit array of the unlock pups */ - u32 first_fail; /* bit array - of pups that get first fail */ - u32 new_lockup_pup; /* bit array of compare failed pups */ - u32 pass_pup; /* bit array of compare pass pup */ - u32 sdram_offset; - u32 max_pup; - u32 comp_val; - u32 special_res[MAX_PUP_NUM]; /* hold tmp results */ - - DEBUG_DQS_S("DDR3 - DQS - Special Pattern I Search - Starting\n"); - - max_pup = ecc + (1 - ecc) * dram_info->num_of_std_pups; - - /* Init the temporary results to max ADLL value */ - for (pup = 0; pup < max_pup; pup++) - special_res[pup] = ADLL_MAX; - - /* Run special pattern for all DQ - use the same pattern */ - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - unlock_pup = special_pattern_pup; - first_fail = 0; - - sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS + - LEN_KILLER_PATTERN * 4 * victim_dq; - - for (pup = 0; pup < max_pup; pup++) { - /* Set adll value per PUP. adll = high limit per pup */ - if (IS_PUP_ACTIVE(unlock_pup, pup)) { - /* only for pups that need special search */ - ddr3_write_pup_reg(PUP_DQS_RD, cs, - pup + (ecc * ECC_PUP), 0, - centralization_high_limit - [pup]); - } - } - - adll_idx = 0; - do { - /* - * Perform read and compare simultaneously for all - * un-locked MC use the special pattern mask - */ - new_lockup_pup = 0; - - if (MV_OK != - ddr3_sdram_dqs_compare(dram_info, unlock_pup, - &new_lockup_pup, - special_pattern - [victim_dq], - LEN_SPECIAL_PATTERN, - sdram_offset, 0, - 0, NULL, 1)) - return MV_FAIL; - - DEBUG_DQS_S("DDR3 - DQS - Special I - ADLL value is: "); - DEBUG_DQS_D(adll_idx, 2); - DEBUG_DQS_S(", UnlockPup: "); - DEBUG_DQS_D(unlock_pup, 2); - DEBUG_DQS_S(", NewLockPup: "); - DEBUG_DQS_D(new_lockup_pup, 2); - DEBUG_DQS_S("\n"); - - if (unlock_pup != new_lockup_pup) - DEBUG_DQS_S("DDR3 - DQS - Special I - Some Pup passed!\n"); - - /* Search for pups with passed compare & already fail */ - pass_pup = first_fail & ~new_lockup_pup & unlock_pup; - first_fail |= new_lockup_pup; - unlock_pup &= ~pass_pup; - - /* Get pass pups */ - if (pass_pup != 0) { - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(pass_pup, pup) == - 1) { - /* If pup passed and has first fail = 1 */ - /* keep min value of ADLL max value - current adll */ - /* (centralization_high_limit[pup] + adll_idx) = current adll !!! */ - comp_val = - (ADLL_MAX - - (centralization_high_limit - [pup] + adll_idx)); - - DEBUG_DQS_C - ("DDR3 - DQS - Special I - Pup - ", - pup, 1); - DEBUG_DQS_C - (" comp_val = ", - comp_val, 2); - - if (comp_val < - special_res[pup]) { - special_res[pup] = - comp_val; - centralization_low_limit - [pup] = - (-1) * - comp_val; - - DEBUG_DQS_C - ("DDR3 - DQS - Special I - Pup - ", - pup, 1); - DEBUG_DQS_C - (" Changed Low limit to ", - centralization_low_limit - [pup], 2); - } - } - } - } - - /* - * Did all PUP found missing window? - * Check for each pup if adll (different for each pup) - * reach maximum if reach max value - lock the pup - * if not - increment (Move to right one phase - ADLL) - * dqs RX delay - */ - adll_idx++; - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { - /* Check only unlocked pups */ - if ((centralization_high_limit[pup] + - adll_idx) >= ADLL_MAX) { - /* reach maximum - lock the pup */ - DEBUG_DQS_C("DDR3 - DQS - Special I - reach maximum - lock pup ", - pup, 1); - unlock_pup &= ~(1 << pup); - } else { - /* Didn't reach maximum - increment ADLL */ - ddr3_write_pup_reg(PUP_DQS_RD, - cs, - pup + - (ecc * - ECC_PUP), 0, - (centralization_high_limit - [pup] + - adll_idx)); - } - } - } - } while (unlock_pup != 0); - } - - return MV_OK; -} - -/* - * Name: ddr3_special_pattern_ii_search - * Desc: Execute special pattern high limit search. - * Args: - * special_pattern_pup The pups that need the special search - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_special_pattern_ii_search(MV_DRAM_INFO *dram_info, u32 cs, u32 ecc, - int is_tx, u32 special_pattern_pup) -{ - u32 victim_dq; /* loop index - victim DQ */ - u32 adll_idx; - u32 pup; - u32 unlock_pup; /* bit array of the unlock pups */ - u32 first_fail; /* bit array - of pups that get first fail */ - u32 new_lockup_pup; /* bit array of compare failed pups */ - u32 pass_pup; /* bit array of compare pass pup */ - u32 sdram_offset; - u32 max_pup; - u32 comp_val; - u32 special_res[MAX_PUP_NUM]; /* hold tmp results */ - - DEBUG_DQS_S("DDR3 - DQS - Special Pattern II Search - Starting\n"); - - max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); - - /* init the tmporary results to max ADLL value */ - for (pup = 0; pup < max_pup; pup++) - special_res[pup] = ADLL_MAX; - - sdram_offset = cs * SDRAM_CS_SIZE + SDRAM_DQS_RX_OFFS; - - /* run special pattern for all DQ - use the same pattern */ - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - unlock_pup = special_pattern_pup; - first_fail = 0; - - for (pup = 0; pup < max_pup; pup++) { - /* Set adll value per PUP. adll = 0 */ - if (IS_PUP_ACTIVE(unlock_pup, pup)) { - /* Only for pups that need special search */ - ddr3_write_pup_reg(PUP_DQS_RD, cs, - pup + (ecc * ECC_PUP), 0, - ADLL_MIN); - } - } - - adll_idx = 0; - do { - /* - * Perform read and compare simultaneously for all - * un-locked MC use the special pattern mask - */ - new_lockup_pup = 0; - - if (MV_OK != ddr3_sdram_dqs_compare( - dram_info, unlock_pup, &new_lockup_pup, - special_pattern[victim_dq], - LEN_SPECIAL_PATTERN, - sdram_offset, 0, 0, NULL, 0)) - return MV_FAIL; - - DEBUG_DQS_S("DDR3 - DQS - Special II - ADLL value is "); - DEBUG_DQS_D(adll_idx, 2); - DEBUG_DQS_S("unlock_pup "); - DEBUG_DQS_D(unlock_pup, 1); - DEBUG_DQS_S("new_lockup_pup "); - DEBUG_DQS_D(new_lockup_pup, 1); - DEBUG_DQS_S("\n"); - - if (unlock_pup != new_lockup_pup) { - DEBUG_DQS_S("DDR3 - DQS - Special II - Some Pup passed!\n"); - } - - /* Search for pups with passed compare & already fail */ - pass_pup = first_fail & ~new_lockup_pup & unlock_pup; - first_fail |= new_lockup_pup; - unlock_pup &= ~pass_pup; - - /* Get pass pups */ - if (pass_pup != 0) { - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(pass_pup, pup) == - 1) { - /* If pup passed and has first fail = 1 */ - /* keep min value of ADLL max value - current adll */ - /* (adll_idx) = current adll !!! */ - comp_val = adll_idx; - - DEBUG_DQS_C("DDR3 - DQS - Special II - Pup - ", - pup, 1); - DEBUG_DQS_C(" comp_val = ", - comp_val, 1); - - if (comp_val < - special_res[pup]) { - special_res[pup] = - comp_val; - centralization_high_limit - [pup] = - ADLL_MAX + - comp_val; - - DEBUG_DQS_C - ("DDR3 - DQS - Special II - Pup - ", - pup, 1); - DEBUG_DQS_C - (" Changed High limit to ", - centralization_high_limit - [pup], 2); - } - } - } - } - - /* - * Did all PUP found missing window? - * Check for each pup if adll (different for each pup) - * reach maximum if reach max value - lock the pup - * if not - increment (Move to right one phase - ADLL) - * dqs RX delay - */ - adll_idx++; - for (pup = 0; pup < max_pup; pup++) { - if (IS_PUP_ACTIVE(unlock_pup, pup) == 1) { - /* Check only unlocked pups */ - if ((adll_idx) >= ADLL_MAX) { - /* Reach maximum - lock the pup */ - DEBUG_DQS_C("DDR3 - DQS - Special II - reach maximum - lock pup ", - pup, 1); - unlock_pup &= ~(1 << pup); - } else { - /* Didn't reach maximum - increment ADLL */ - ddr3_write_pup_reg(PUP_DQS_RD, - cs, - pup + - (ecc * - ECC_PUP), 0, - (adll_idx)); - } - } - } - } while (unlock_pup != 0); - } - - return MV_OK; -} - -/* - * Name: ddr3_set_dqs_centralization_results - * Desc: Set to HW the DQS centralization phase results. - * Args: - * is_tx Indicates whether to set Tx or RX results - * Notes: - * Returns: MV_OK if success, other error code if fail. - */ -int ddr3_set_dqs_centralization_results(MV_DRAM_INFO *dram_info, u32 cs, - u32 ecc, int is_tx) -{ - u32 pup, pup_num; - int addl_val; - u32 max_pup; - - max_pup = (ecc + (1 - ecc) * dram_info->num_of_std_pups); - - DEBUG_DQS_RESULTS_S("\n############ LOG LEVEL 2(Windows margins) ############\n");; - - if (is_tx) { - DEBUG_DQS_RESULTS_C("DDR3 - DQS TX - Set Dqs Centralization Results - CS: ", - cs, 1); - } else { - DEBUG_DQS_RESULTS_C("DDR3 - DQS RX - Set Dqs Centralization Results - CS: ", - cs, 1); - } - - /* Set adll to center = (General_High_limit + General_Low_limit)/2 */ - DEBUG_DQS_RESULTS_S("\nDQS LOW HIGH WIN-SIZE Set\n"); - DEBUG_DQS_RESULTS_S("==============================================\n"); - for (pup = 0; pup < max_pup; pup++) { - addl_val = (centralization_high_limit[pup] + - centralization_low_limit[pup]) / 2; - - pup_num = pup * (1 - ecc) + ecc * ECC_PUP; - - DEBUG_DQS_RESULTS_D(pup_num, 1); - DEBUG_DQS_RESULTS_S(" 0x"); - DEBUG_DQS_RESULTS_D(centralization_low_limit[pup], 2); - DEBUG_DQS_RESULTS_S(" 0x"); - DEBUG_DQS_RESULTS_D(centralization_high_limit[pup], 2); - DEBUG_DQS_RESULTS_S(" 0x"); - DEBUG_DQS_RESULTS_D(centralization_high_limit[pup] - - centralization_low_limit[pup], 2); - DEBUG_DQS_RESULTS_S(" 0x"); - DEBUG_DQS_RESULTS_D(addl_val, 2); - DEBUG_DQS_RESULTS_S("\n"); - - if (addl_val < ADLL_MIN) { - addl_val = ADLL_MIN; - DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MIN (since it was lower than 0)\n"); - } - - if (addl_val > ADLL_MAX) { - addl_val = ADLL_MAX; - DEBUG_DQS_RESULTS_S("DDR3 - DQS - Setting ADLL value for Pup to MAX (since it was higher than 31)\n"); - } - - if (is_tx) { - ddr3_write_pup_reg(PUP_DQS_WR, cs, pup_num, 0, - addl_val + - dram_info->wl_val[cs][pup_num][D]); - } else { - ddr3_write_pup_reg(PUP_DQS_RD, cs, pup_num, 0, - addl_val); - } - } - - return MV_OK; -} - -/* - * Set training patterns - */ -int ddr3_load_dqs_patterns(MV_DRAM_INFO *dram_info) -{ - u32 cs, cs_count, cs_tmp, victim_dq; - u32 sdram_addr; - u32 *pattern_ptr; - - /* Loop for each CS */ - for (cs = 0; cs < MAX_CS; cs++) { - if (dram_info->cs_ena & (1 << cs)) { - cs_count = 0; - for (cs_tmp = 0; cs_tmp < cs; cs_tmp++) { - if (dram_info->cs_ena & (1 << cs_tmp)) - cs_count++; - } - - /* Init killer pattern */ - sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + - SDRAM_DQS_RX_OFFS); - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - pattern_ptr = ddr3_dqs_choose_pattern(dram_info, - victim_dq); - if (MV_OK != ddr3_sdram_dqs_compare( - dram_info, (u32)NULL, NULL, - pattern_ptr, LEN_KILLER_PATTERN, - sdram_addr + LEN_KILLER_PATTERN * - 4 * victim_dq, 1, 0, NULL, - 0)) - return MV_DDR3_TRAINING_ERR_DQS_PATTERN; - } - - /* Init special-killer pattern */ - sdram_addr = (cs_count * (SDRAM_CS_SIZE + 1) + - SDRAM_DQS_RX_SPECIAL_OFFS); - for (victim_dq = 0; victim_dq < DQ_NUM; victim_dq++) { - if (MV_OK != ddr3_sdram_dqs_compare( - dram_info, (u32)NULL, NULL, - special_pattern[victim_dq], - LEN_KILLER_PATTERN, sdram_addr + - LEN_KILLER_PATTERN * 4 * victim_dq, - 1, 0, NULL, 0)) - return MV_DDR3_TRAINING_ERR_DQS_PATTERN; - } - } - } - - return MV_OK; -} |