123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995 |
- /*
- * Copyright (C) Marvell International Ltd. and its affiliates
- *
- * SPDX-License-Identifier: GPL-2.0
- */
- #include <common.h>
- #include <spl.h>
- #include <asm/io.h>
- #include <asm/arch/cpu.h>
- #include <asm/arch/soc.h>
- #include "ddr3_init.h"
- #define TYPICAL_PBS_VALUE 12
- u32 nominal_adll[MAX_INTERFACE_NUM * MAX_BUS_NUM];
- enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
- u8 result_mat[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
- u8 result_mat_rx_dqs[MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_CS_NUM];
- /* 4-EEWA, 3-EWA, 2-SWA, 1-Fail, 0-Pass */
- u8 result_all_bit[MAX_BUS_NUM * BUS_WIDTH_IN_BITS * MAX_INTERFACE_NUM];
- u8 max_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u8 min_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u8 max_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u8 min_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u32 pbsdelay_per_pup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u8 adll_shift_lock[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- u8 adll_shift_val[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- enum hws_pattern pbs_pattern = PATTERN_VREF;
- static u8 pup_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
- /*
- * Name: ddr3_tip_pbs
- * Desc: PBS
- * Args: TBD
- * Notes:
- * Returns: OK if success, other error code if fail.
- */
- int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
- {
- u32 res0[MAX_INTERFACE_NUM];
- int adll_tap = MEGA / freq_val[medium_freq] / 64;
- int pad_num = 0;
- enum hws_search_dir search_dir =
- (pbs_mode == PBS_RX_MODE) ? HWS_HIGH2LOW : HWS_LOW2HIGH;
- enum hws_dir dir = (pbs_mode == PBS_RX_MODE) ? OPER_READ : OPER_WRITE;
- int iterations = (pbs_mode == PBS_RX_MODE) ? 31 : 63;
- u32 res_valid_mask = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
- int init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
- enum hws_edge_compare search_edge = EDGE_FP;
- u32 pup = 0, bit = 0, if_id = 0, all_lock = 0, cs_num = 0;
- int reg_addr = 0;
- u32 validation_val = 0;
- u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
- u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
- u8 temp = 0;
- struct hws_topology_map *tm = ddr3_get_topology_map();
- /* save current cs enable reg val */
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- /* save current cs enable reg val */
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
- /* enable single cs */
- CHECK_STATUS(ddr3_tip_if_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- CS_ENABLE_REG, (1 << 3), (1 << 3)));
- }
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (READ_CENTRALIZATION_PHY_REG +
- (effective_cs * CS_REGISTER_ADDR_OFFSET)) :
- (WRITE_CENTRALIZATION_PHY_REG +
- (effective_cs * CS_REGISTER_ADDR_OFFSET));
- read_adll_value(nominal_adll, reg_addr, MASK_ALL_BITS);
- /* stage 1 shift ADLL */
- ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE, RESULT_PER_BIT,
- HWS_CONTROL_ELEMENT_ADLL, search_dir, dir,
- tm->if_act_mask, init_val, iterations,
- pbs_pattern, search_edge, CS_SINGLE, cs_num,
- train_status);
- validation_val = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0;
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- min_adll_per_pup[if_id][pup] =
- (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
- pup_state[if_id][pup] = 0x3;
- adll_shift_lock[if_id][pup] = 1;
- max_adll_per_pup[if_id][pup] = 0x0;
- }
- }
- /* EBA */
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- mask_results_dq_reg_map[
- bit + pup * BUS_WIDTH_IN_BITS],
- res0, MASK_ALL_BITS));
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
- if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
- if_id, bit, pup,
- res0[if_id]));
- if (pup_state[if_id][pup] != 3)
- continue;
- /* if not EBA state than move to next pup */
- if ((res0[if_id] & 0x2000000) == 0) {
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("-- Fail Training IP\n"));
- /* training machine failed */
- pup_state[if_id][pup] = 1;
- adll_shift_lock[if_id][pup] = 0;
- continue;
- }
- else if ((res0[if_id] & res_valid_mask) ==
- validation_val) {
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("-- FAIL EBA %d %d %d %d\n",
- if_id, bit, pup,
- res0[if_id]));
- pup_state[if_id][pup] = 4;
- /* this pup move to EEBA */
- adll_shift_lock[if_id][pup] = 0;
- continue;
- } else {
- /*
- * The search ended in Pass we need
- * Fail
- */
- res0[if_id] =
- (pbs_mode == PBS_RX_MODE) ?
- ((res0[if_id] &
- res_valid_mask) + 1) :
- ((res0[if_id] &
- res_valid_mask) - 1);
- max_adll_per_pup[if_id][pup] =
- (max_adll_per_pup[if_id][pup] <
- res0[if_id]) ?
- (u8)res0[if_id] :
- max_adll_per_pup[if_id][pup];
- min_adll_per_pup[if_id][pup] =
- (res0[if_id] >
- min_adll_per_pup[if_id][pup]) ?
- min_adll_per_pup[if_id][pup] :
- (u8)
- res0[if_id];
- /*
- * vs the Rx we are searching for the
- * smallest value of DQ shift so all
- * Bus would fail
- */
- adll_shift_val[if_id][pup] =
- (pbs_mode == PBS_RX_MODE) ?
- max_adll_per_pup[if_id][pup] :
- min_adll_per_pup[if_id][pup];
- }
- }
- }
- }
- /* EEBA */
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- if (pup_state[if_id][pup] != 4)
- continue;
- /*
- * if pup state different from EEBA than move to
- * next pup
- */
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x54 + effective_cs * 0x10) :
- (0x14 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
- reg_addr, 0x1f));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x55 + effective_cs * 0x10) :
- (0x15 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
- reg_addr, 0x1f));
- /* initialize the Edge2 Max. */
- adll_shift_val[if_id][pup] = 0;
- min_adll_per_pup[if_id][pup] =
- (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
- max_adll_per_pup[if_id][pup] = 0x0;
- ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE, RESULT_PER_BIT,
- HWS_CONTROL_ELEMENT_ADLL,
- search_dir, dir,
- tm->if_act_mask, init_val,
- iterations, pbs_pattern,
- search_edge, CS_SINGLE, cs_num,
- train_status);
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("ADLL shift results:\n"));
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- mask_results_dq_reg_map[
- bit + pup *
- BUS_WIDTH_IN_BITS],
- res0, MASK_ALL_BITS));
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
- if_id, bit, pup,
- res0[if_id]));
- if ((res0[if_id] & 0x2000000) == 0) {
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- (" -- EEBA Fail\n"));
- bit = BUS_WIDTH_IN_BITS;
- /* exit bit loop */
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("-- EEBA Fail Training IP\n"));
- /*
- * training machine failed but pass
- * before in the EBA so maybe the DQS
- * shift change env.
- */
- pup_state[if_id][pup] = 2;
- adll_shift_lock[if_id][pup] = 0;
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x54 + effective_cs * 0x10) :
- (0x14 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num,
- ACCESS_TYPE_UNICAST,
- if_id,
- ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- 0x0));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x55 + effective_cs * 0x10) :
- (0x15 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num,
- ACCESS_TYPE_UNICAST,
- if_id,
- ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- 0x0));
- continue;
- } else if ((res0[if_id] & res_valid_mask) ==
- validation_val) {
- /* exit bit loop */
- bit = BUS_WIDTH_IN_BITS;
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("-- FAIL EEBA\n"));
- /* this pup move to SBA */
- pup_state[if_id][pup] = 2;
- adll_shift_lock[if_id][pup] = 0;
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x54 + effective_cs * 0x10) :
- (0x14 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num,
- ACCESS_TYPE_UNICAST,
- if_id,
- ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- 0x0));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x55 + effective_cs * 0x10) :
- (0x15 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num,
- ACCESS_TYPE_UNICAST,
- if_id,
- ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- 0x0));
- continue;
- } else {
- adll_shift_lock[if_id][pup] = 1;
- /*
- * The search ended in Pass we need
- * Fail
- */
- res0[if_id] =
- (pbs_mode == PBS_RX_MODE) ?
- ((res0[if_id] &
- res_valid_mask) + 1) :
- ((res0[if_id] &
- res_valid_mask) - 1);
- max_adll_per_pup[if_id][pup] =
- (max_adll_per_pup[if_id][pup] <
- res0[if_id]) ?
- (u8)res0[if_id] :
- max_adll_per_pup[if_id][pup];
- min_adll_per_pup[if_id][pup] =
- (res0[if_id] >
- min_adll_per_pup[if_id][pup]) ?
- min_adll_per_pup[if_id][pup] :
- (u8)res0[if_id];
- /*
- * vs the Rx we are searching for the
- * smallest value of DQ shift so all Bus
- * would fail
- */
- adll_shift_val[if_id][pup] =
- (pbs_mode == PBS_RX_MODE) ?
- max_adll_per_pup[if_id][pup] :
- min_adll_per_pup[if_id][pup];
- }
- }
- }
- }
- /* Print Stage result */
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("FP I/F %d, ADLL Shift for EBA: pup[%d] Lock status = %d Lock Val = %d,%d\n",
- if_id, pup,
- adll_shift_lock[if_id][pup],
- max_adll_per_pup[if_id][pup],
- min_adll_per_pup[if_id][pup]));
- }
- }
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("Update ADLL Shift of all pups:\n"));
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- if (adll_shift_lock[if_id][pup] != 1)
- continue;
- /* if pup not locked continue to next pup */
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x3 + effective_cs * 4) :
- (0x1 + effective_cs * 4);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
- reg_addr, adll_shift_val[if_id][pup]));
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
- ("FP I/F %d, Pup[%d] = %d\n", if_id,
- pup, adll_shift_val[if_id][pup]));
- }
- }
- /* PBS EEBA&EBA */
- /* Start the Per Bit Skew search */
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- max_pbs_per_pup[if_id][pup] = 0x0;
- min_pbs_per_pup[if_id][pup] = 0x1f;
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- /* reset result for PBS */
- result_all_bit[bit + pup * BUS_WIDTH_IN_BITS +
- if_id * MAX_BUS_NUM *
- BUS_WIDTH_IN_BITS] = 0;
- }
- }
- }
- iterations = 31;
- search_dir = HWS_LOW2HIGH;
- /* !!!!! ran sh (search_dir == HWS_LOW2HIGH)?0:iterations; */
- init_val = 0;
- ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
- ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
- RESULT_PER_BIT, HWS_CONTROL_ELEMENT_DQ_SKEW,
- search_dir, dir, tm->if_act_mask, init_val,
- iterations, pbs_pattern, search_edge,
- CS_SINGLE, cs_num, train_status);
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- if (adll_shift_lock[if_id][pup] != 1) {
- /* if pup not lock continue to next pup */
- continue;
- }
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- mask_results_dq_reg_map[
- bit +
- pup * BUS_WIDTH_IN_BITS],
- res0, MASK_ALL_BITS));
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("Per Bit Skew search, FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
- if_id, bit, pup,
- res0[if_id]));
- if ((res0[if_id] & 0x2000000) == 0) {
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("--EBA PBS Fail - Training IP machine\n"));
- /* exit the bit loop */
- bit = BUS_WIDTH_IN_BITS;
- /*
- * ADLL is no long in lock need new
- * search
- */
- adll_shift_lock[if_id][pup] = 0;
- /* Move to SBA */
- pup_state[if_id][pup] = 2;
- max_pbs_per_pup[if_id][pup] = 0x0;
- min_pbs_per_pup[if_id][pup] = 0x1f;
- continue;
- } else {
- temp = (u8)(res0[if_id] &
- res_valid_mask);
- max_pbs_per_pup[if_id][pup] =
- (temp >
- max_pbs_per_pup[if_id][pup]) ?
- temp :
- max_pbs_per_pup[if_id][pup];
- min_pbs_per_pup[if_id][pup] =
- (temp <
- min_pbs_per_pup[if_id][pup]) ?
- temp :
- min_pbs_per_pup[if_id][pup];
- result_all_bit[bit +
- pup * BUS_WIDTH_IN_BITS +
- if_id * MAX_BUS_NUM *
- BUS_WIDTH_IN_BITS] =
- temp;
- }
- }
- }
- }
- /* Check all Pup lock */
- all_lock = 1;
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- all_lock = all_lock * adll_shift_lock[if_id][pup];
- }
- }
- /* Only if not all Pups Lock */
- if (all_lock == 0) {
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("##########ADLL shift for SBA###########\n"));
- /* ADLL shift for SBA */
- search_dir = (pbs_mode == PBS_RX_MODE) ? HWS_LOW2HIGH :
- HWS_HIGH2LOW;
- init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
- if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- if (adll_shift_lock[if_id][pup] == 1) {
- /*if pup lock continue to next pup */
- continue;
- }
- /*init the var altogth init before */
- adll_shift_lock[if_id][pup] = 0;
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x54 + effective_cs * 0x10) :
- (0x14 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr, 0));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x55 + effective_cs * 0x10) :
- (0x15 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr, 0));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x5f + effective_cs * 0x10) :
- (0x1f + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr, 0));
- /* initilaze the Edge2 Max. */
- adll_shift_val[if_id][pup] = 0;
- min_adll_per_pup[if_id][pup] = 0x1f;
- max_adll_per_pup[if_id][pup] = 0x0;
- ddr3_tip_ip_training(dev_num,
- ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- RESULT_PER_BIT,
- HWS_CONTROL_ELEMENT_ADLL,
- search_dir, dir,
- tm->if_act_mask,
- init_val, iterations,
- pbs_pattern,
- search_edge, CS_SINGLE,
- cs_num, train_status);
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num,
- ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- mask_results_dq_reg_map
- [bit +
- pup *
- BUS_WIDTH_IN_BITS],
- res0, MASK_ALL_BITS));
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
- if_id, bit, pup, res0[if_id]));
- if ((res0[if_id] & 0x2000000) == 0) {
- /* exit the bit loop */
- bit = BUS_WIDTH_IN_BITS;
- /* Fail SBA --> Fail PBS */
- pup_state[if_id][pup] = 1;
- DEBUG_PBS_ENGINE
- (DEBUG_LEVEL_INFO,
- (" SBA Fail\n"));
- continue;
- } else {
- /*
- * - increment to get all
- * 8 bit lock.
- */
- adll_shift_lock[if_id][pup]++;
- /*
- * The search ended in Pass
- * we need Fail
- */
- res0[if_id] =
- (pbs_mode == PBS_RX_MODE) ?
- ((res0[if_id] & res_valid_mask) + 1) :
- ((res0[if_id] & res_valid_mask) - 1);
- max_adll_per_pup[if_id][pup] =
- (max_adll_per_pup[if_id]
- [pup] < res0[if_id]) ?
- (u8)res0[if_id] :
- max_adll_per_pup[if_id][pup];
- min_adll_per_pup[if_id][pup] =
- (res0[if_id] >
- min_adll_per_pup[if_id]
- [pup]) ?
- min_adll_per_pup[if_id][pup] :
- (u8)res0[if_id];
- /*
- * vs the Rx we are searching for
- * the smallest value of DQ shift
- * so all Bus would fail
- */
- adll_shift_val[if_id][pup] =
- (pbs_mode == PBS_RX_MODE) ?
- max_adll_per_pup[if_id][pup] :
- min_adll_per_pup[if_id][pup];
- }
- }
- /* 1 is lock */
- adll_shift_lock[if_id][pup] =
- (adll_shift_lock[if_id][pup] == 8) ?
- 1 : 0;
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x3 + effective_cs * 4) :
- (0x1 + effective_cs * 4);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- adll_shift_val[if_id][pup]));
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- ("adll_shift_lock[%x][%x] = %x\n",
- if_id, pup,
- adll_shift_lock[if_id][pup]));
- }
- }
- /* End ADLL Shift for SBA */
- /* Start the Per Bit Skew search */
- /* The ADLL shift finished with a Pass */
- search_edge = (pbs_mode == PBS_RX_MODE) ? EDGE_PF : EDGE_FP;
- search_dir = (pbs_mode == PBS_RX_MODE) ?
- HWS_LOW2HIGH : HWS_HIGH2LOW;
- iterations = 0x1f;
- /* - The initial value is different in Rx and Tx mode */
- init_val = (pbs_mode == PBS_RX_MODE) ? 0 : iterations;
- ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE, RESULT_PER_BIT,
- HWS_CONTROL_ELEMENT_DQ_SKEW,
- search_dir, dir, tm->if_act_mask,
- init_val, iterations, pbs_pattern,
- search_edge, CS_SINGLE, cs_num,
- train_status);
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
- if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- CHECK_STATUS(ddr3_tip_if_read
- (dev_num,
- ACCESS_TYPE_MULTICAST,
- PARAM_NOT_CARE,
- mask_results_dq_reg_map
- [bit +
- pup *
- BUS_WIDTH_IN_BITS],
- res0, MASK_ALL_BITS));
- if (pup_state[if_id][pup] != 2) {
- /*
- * if pup is not SBA continue
- * to next pup
- */
- bit = BUS_WIDTH_IN_BITS;
- continue;
- }
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- ("Per Bit Skew search, PF I/F %d, bit:%d, pup:%d res0 0x%x\n",
- if_id, bit, pup, res0[if_id]));
- if ((res0[if_id] & 0x2000000) == 0) {
- DEBUG_PBS_ENGINE
- (DEBUG_LEVEL_INFO,
- ("SBA Fail\n"));
- max_pbs_per_pup[if_id][pup] =
- 0x1f;
- result_all_bit[
- bit + pup *
- BUS_WIDTH_IN_BITS +
- if_id * MAX_BUS_NUM *
- BUS_WIDTH_IN_BITS] =
- 0x1f;
- } else {
- temp = (u8)(res0[if_id] &
- res_valid_mask);
- max_pbs_per_pup[if_id][pup] =
- (temp >
- max_pbs_per_pup[if_id]
- [pup]) ? temp :
- max_pbs_per_pup
- [if_id][pup];
- min_pbs_per_pup[if_id][pup] =
- (temp <
- min_pbs_per_pup[if_id]
- [pup]) ? temp :
- min_pbs_per_pup
- [if_id][pup];
- result_all_bit[
- bit + pup *
- BUS_WIDTH_IN_BITS +
- if_id * MAX_BUS_NUM *
- BUS_WIDTH_IN_BITS] =
- temp;
- adll_shift_lock[if_id][pup] = 1;
- }
- }
- }
- }
- /* Check all Pup state */
- all_lock = 1;
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- /*
- * DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- * ("pup_state[%d][%d] = %d\n",if_id,pup,pup_state
- * [if_id][pup]));
- */
- }
- }
- /* END OF SBA */
- /* Norm */
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
- if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- /* if pup not lock continue to next pup */
- if (adll_shift_lock[if_id][pup] != 1) {
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_ERROR,
- ("PBS failed for IF #%d\n",
- if_id));
- training_result[training_stage][if_id]
- = TEST_FAILED;
- result_mat[if_id][pup][bit] = 0;
- max_pbs_per_pup[if_id][pup] = 0;
- min_pbs_per_pup[if_id][pup] = 0;
- } else {
- training_result[
- training_stage][if_id] =
- (training_result[training_stage]
- [if_id] == TEST_FAILED) ?
- TEST_FAILED : TEST_SUCCESS;
- result_mat[if_id][pup][bit] =
- result_all_bit[
- bit + pup *
- BUS_WIDTH_IN_BITS +
- if_id * MAX_BUS_NUM *
- BUS_WIDTH_IN_BITS] -
- min_pbs_per_pup[if_id][pup];
- }
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- ("The abs min_pbs[%d][%d] = %d\n",
- if_id, pup,
- min_pbs_per_pup[if_id][pup]));
- }
- }
- }
- /* Clean all results */
- ddr3_tip_clean_pbs_result(dev_num, pbs_mode);
- /* DQ PBS register update with the final result */
- for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- ("Final Results: if_id %d, pup %d, Pup State: %d\n",
- if_id, pup, pup_state[if_id][pup]));
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- if (dq_map_table == NULL) {
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_ERROR,
- ("dq_map_table not initialized\n"));
- return MV_FAIL;
- }
- pad_num = dq_map_table[
- bit + pup * BUS_WIDTH_IN_BITS +
- if_id * BUS_WIDTH_IN_BITS *
- tm->num_of_bus_per_interface];
- DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
- ("result_mat: %d ",
- result_mat[if_id][pup]
- [bit]));
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (PBS_RX_PHY_REG + effective_cs * 0x10) :
- (PBS_TX_PHY_REG + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr + pad_num,
- result_mat[if_id][pup][bit]));
- }
- pbsdelay_per_pup[pbs_mode][if_id][pup] =
- (max_pbs_per_pup[if_id][pup] ==
- min_pbs_per_pup[if_id][pup]) ?
- TYPICAL_PBS_VALUE :
- ((max_adll_per_pup[if_id][pup] -
- min_adll_per_pup[if_id][pup]) * adll_tap /
- (max_pbs_per_pup[if_id][pup] -
- min_pbs_per_pup[if_id][pup]));
- /* RX results ready, write RX also */
- if (pbs_mode == PBS_TX_MODE) {
- /* Write TX results */
- reg_addr = (0x14 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- (max_pbs_per_pup[if_id][pup] -
- min_pbs_per_pup[if_id][pup]) /
- 2));
- reg_addr = (0x15 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- (max_pbs_per_pup[if_id][pup] -
- min_pbs_per_pup[if_id][pup]) /
- 2));
- /* Write previously stored RX results */
- reg_addr = (0x54 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- result_mat_rx_dqs[if_id][pup]
- [effective_cs]));
- reg_addr = (0x55 + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr,
- result_mat_rx_dqs[if_id][pup]
- [effective_cs]));
- } else {
- /*
- * RX results may affect RL results correctess,
- * so just store the results that will written
- * in TX stage
- */
- result_mat_rx_dqs[if_id][pup][effective_cs] =
- (max_pbs_per_pup[if_id][pup] -
- min_pbs_per_pup[if_id][pup]) / 2;
- }
- DEBUG_PBS_ENGINE(
- DEBUG_LEVEL_INFO,
- (", PBS tap=%d [psec] ==> skew observed = %d\n",
- pbsdelay_per_pup[pbs_mode][if_id][pup],
- ((max_pbs_per_pup[if_id][pup] -
- min_pbs_per_pup[if_id][pup]) *
- pbsdelay_per_pup[pbs_mode][if_id][pup])));
- }
- }
- /* Write back to the phy the default values */
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (READ_CENTRALIZATION_PHY_REG + effective_cs * 4) :
- (WRITE_CENTRALIZATION_PHY_REG + effective_cs * 4);
- write_adll_value(nominal_adll, reg_addr);
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (0x5a + effective_cs * 0x10) :
- (0x1a + effective_cs * 0x10);
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, reg_addr,
- 0));
- /* restore cs enable value */
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- CHECK_STATUS(ddr3_tip_if_write
- (dev_num, ACCESS_TYPE_UNICAST, if_id,
- CS_ENABLE_REG, cs_enable_reg_val[if_id],
- MASK_ALL_BITS));
- }
- /* exit test mode */
- CHECK_STATUS(ddr3_tip_if_write
- (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
- ODPG_WRITE_READ_MODE_ENABLE_REG, 0xffff, MASK_ALL_BITS));
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- /*
- * meaning that there is no VW exist at all (No lock at
- * the EBA ADLL shift at EBS)
- */
- if (pup_state[if_id][pup] == 1)
- return MV_FAIL;
- }
- return MV_OK;
- }
- /*
- * Name: ddr3_tip_pbs_rx.
- * Desc: PBS TX
- * Args: TBD
- * Notes:
- * Returns: OK if success, other error code if fail.
- */
- int ddr3_tip_pbs_rx(u32 uidev_num)
- {
- return ddr3_tip_pbs(uidev_num, PBS_RX_MODE);
- }
- /*
- * Name: ddr3_tip_pbs_tx.
- * Desc: PBS TX
- * Args: TBD
- * Notes:
- * Returns: OK if success, other error code if fail.
- */
- int ddr3_tip_pbs_tx(u32 uidev_num)
- {
- return ddr3_tip_pbs(uidev_num, PBS_TX_MODE);
- }
- #ifndef EXCLUDE_SWITCH_DEBUG
- /*
- * Print PBS Result
- */
- int ddr3_tip_print_all_pbs_result(u32 dev_num)
- {
- u32 curr_cs;
- u32 max_cs = hws_ddr3_tip_max_cs_get();
- for (curr_cs = 0; curr_cs < max_cs; curr_cs++) {
- ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_RX_MODE);
- ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_TX_MODE);
- }
- return MV_OK;
- }
- /*
- * Print PBS Result
- */
- int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode)
- {
- u32 data_value = 0, bit = 0, if_id = 0, pup = 0;
- u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (PBS_RX_PHY_REG + cs_num * 0x10) :
- (PBS_TX_PHY_REG + cs_num * 0x10);
- struct hws_topology_map *tm = ddr3_get_topology_map();
- printf("CS%d, %s ,PBS\n", cs_num,
- (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
- for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
- printf("%s, DQ", (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- printf("%d ,PBS,,, ", bit);
- for (pup = 0; pup <= tm->num_of_bus_per_interface;
- pup++) {
- VALIDATE_ACTIVE(tm->bus_act_mask, pup);
- CHECK_STATUS(ddr3_tip_bus_read
- (dev_num, if_id,
- ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr + bit,
- &data_value));
- printf("%d , ", data_value);
- }
- }
- printf("\n");
- }
- printf("\n");
- return MV_OK;
- }
- #endif
- /*
- * Fixup PBS Result
- */
- int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode)
- {
- u32 if_id, pup, bit;
- u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
- (PBS_RX_PHY_REG + effective_cs * 0x10) :
- (PBS_TX_PHY_REG + effective_cs * 0x10);
- struct hws_topology_map *tm = ddr3_get_topology_map();
- for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
- VALIDATE_ACTIVE(tm->if_act_mask, if_id);
- for (pup = 0; pup <= tm->num_of_bus_per_interface; pup++) {
- for (bit = 0; bit <= BUS_WIDTH_IN_BITS + 3; bit++) {
- CHECK_STATUS(ddr3_tip_bus_write
- (dev_num, ACCESS_TYPE_UNICAST,
- if_id, ACCESS_TYPE_UNICAST, pup,
- DDR_PHY_DATA, reg_addr + bit, 0));
- }
- }
- }
- return MV_OK;
- }
|