blob: 8d8045aaaa45487440d2186640944c4fcb783bbd [file] [log] [blame]
/*******************************************************************************
* Copyright 2001, Marvell International Ltd.
* This code contains confidential information of Marvell semiconductor, inc.
* no rights are granted herein under any patent, mask work right or copyright
* of Marvell or any third party.
* Marvell reserves the right at its sole discretion to request that this code
* be immediately returned to Marvell. This code is provided "as is".
* Marvell makes no warranties, express, implied or otherwise, regarding its
* accuracy, completeness or performance.
********************************************************************************
* mvHwsDdr3TrainingIpEngine.c
*
* DESCRIPTION: DDR3 training IP Engine
*
*
* DEPENDENCIES:
*
* FILE REVISION NUMBER:
* $Revision: 80 $
******************************************************************************/
#include "mvDdr3TrainingIpEngine.h"
#include "mvDdrTrainingIpDb.h"
#include "mvDdr3TrainingIpBist.h"
#include "mvDdr3LoggingDef.h"
extern GT_U8 debugTrainingIp;
#define PATTERN_1 (0x55555555)
#define PATTERN_2 (0xAAAAAAAA)
#define VALIDATE_TRAINING_LIMIT(e1,e2) (((e2-e1+1)>33) && (e1<67))
GT_U32 phyRegBk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
#define PARAM_NOT_CARE (0)
extern MV_HWS_TOPOLOGY_MAP *topologyMap;
extern GT_U32 effective_cs;
/************************** globals ***************************************/
GT_U32 trainingRes[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS* MV_HWS_SearchDirLimit];
GT_U16 maskResultsDqRegMap[] =
{
RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG, RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG, RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG, RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG, RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG, RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG, RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG, RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG, RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG, RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG, RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
};
GT_U16 maskResultsPupRegMap[] =
{
RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG, RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG, RESULT_CONTROL_BYTE_PUP_4_REG
};
GT_U16 maskResultsDqRegMapPup3ECC[] =
{
RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG, RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG, RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG, RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG, RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG, RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG, RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG, RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG, RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG, RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG, RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
};
GT_U16 maskResultsPupRegMapPup3ECC[] =
{
RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG, RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG, RESULT_CONTROL_BYTE_PUP_4_REG
};
#ifdef CONFIG_DDR3
PatternInfo patternTable_16[] =
{
/* num tx phases tx burst delay between rx pattern start_address patternLen*/
{0x1, 1, 2, 1, 0x0080, 2 }, /* PATTERN_PBS1*/
{0x1, 1, 2, 1, 0x00C0, 2 }, /* PATTERN_PBS2*/
{0x1, 1, 2, 1, 0x0380, 2 }, /* PATTERN_PBS3*/
{0x1, 1, 2, 1, 0x0040, 2 }, /* PATTERN_TEST*/
{0x1, 1, 2, 1, 0x0100, 2 }, /* PATTERN_RL*/
{0x1, 1, 2, 1, 0x0000, 2 }, /* PATTERN_RL2*/
{0xf, 7, 2, 7, 0x0140, 16 }, /* PATTERN_STATIC_PBS*/
{0xf, 7, 2, 7, 0x0190, 16 }, /* PATTERN_KILLER_DQ0*/
{0xf, 7, 2, 7, 0x01D0, 16 }, /* PATTERN_KILLER_DQ1*/
{0xf, 7, 2, 7, 0x0210, 16 }, /* PATTERN_KILLER_DQ2*/
{0xf, 7, 2, 7, 0x0250, 16 }, /* PATTERN_KILLER_DQ3*/
{0xf, 7, 2, 7, 0x0290, 16 }, /* PATTERN_KILLER_DQ4*/
{0xf, 7, 2, 7, 0x02D0, 16 }, /* PATTERN_KILLER_DQ5*/
{0xf, 7, 2, 7, 0x0310, 16 }, /* PATTERN_KILLER_DQ6*/
{0xf, 7, 2, 7, 0x0350, 16 }, /* PATTERN_KILLER_DQ7*/
{0xf, 7, 2, 7, 0x04C0, 16 }, /* PATTERN_VREF*/
{0xf, 7, 2, 7, 0x03C0, 16 }, /* PATTERN_FULL_SSO_1T*/
{0xf, 7, 2, 7, 0x0400, 16 }, /* PATTERN_FULL_SSO_2T*/
{0xf, 7, 2, 7, 0x0440, 16 }, /* PATTERN_FULL_SSO_3T*/
{0xf, 7, 2, 7, 0x0480, 16 }, /* PATTERN_FULL_SSO_4T*/
{0xf, 7, 2, 7, 0x6280, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
{0xf, 7, 2, 7, 0x6680, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
{0xf, 7, 2, 7, 0x6A80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
{0xf, 7, 2, 7, 0x6E80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
{0xf, 7, 2, 7, 0x7280, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
{0xf, 7, 2, 7, 0x7680, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
{0xf, 7, 2, 7, 0x7A80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
{0xf, 7, 2, 7, 0x7E80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
{0xf, 7, 2, 7, 0x8280, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
{0xf, 7, 2, 7, 0x8680, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
{0xf, 7, 2, 7, 0x8A80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
{0xf, 7, 2, 7, 0x8E80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
{0xf, 7, 2, 7, 0x9280, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
{0xf, 7, 2, 7, 0x9680, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
{0xf, 7, 2, 7, 0x9A80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
{0xf, 7, 2, 7, 0x9E80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
{0xf, 7, 2, 7, 0xA280, 16 } /* PATTERN_ISI_XTALK_FREE*/
/*Note: actual start_address is <<3 of defined addess*/
};
PatternInfo patternTable_32[] =
{
/* num tx phases tx burst delay between rx pattern start_address patternLen*/
{0x3, 0x3, 2, 0x3, 0x0080, 4 }, /* PATTERN_PBS1*/
{0x3, 0x3, 2, 0x3, 0x00C0, 4 }, /* PATTERN_PBS2*/
{0x3, 0x3, 2, 0x3, 0x0380, 4 }, /* PATTERN_PBS3*/
{0x3, 0x3, 2, 0x3, 0x0040, 4 }, /* PATTERN_TEST*/
{0x3, 0x3, 2, 0x3, 0x0100, 4 }, /* PATTERN_RL*/
{0x3, 0x3, 2, 0x3, 0x0000, 4 }, /* PATTERN_RL2*/
{0x1f, 0xF, 2, 0xf, 0x0140, 32 }, /* PATTERN_STATIC_PBS*/
{0x1f, 0xF, 2, 0xf, 0x0190, 32 }, /* PATTERN_KILLER_DQ0*/
{0x1f, 0xF, 2, 0xf, 0x01D0, 32 }, /* PATTERN_KILLER_DQ1*/
{0x1f, 0xF, 2, 0xf, 0x0210, 32 }, /* PATTERN_KILLER_DQ2*/
{0x1f, 0xF, 2, 0xf, 0x0250, 32 }, /* PATTERN_KILLER_DQ3*/
{0x1f, 0xF, 2, 0xf, 0x0290, 32 }, /* PATTERN_KILLER_DQ4*/
{0x1f, 0xF, 2, 0xf, 0x02D0, 32 }, /* PATTERN_KILLER_DQ5*/
{0x1f, 0xF, 2, 0xf, 0x0310, 32 }, /* PATTERN_KILLER_DQ6*/
{0x1f, 0xF, 2, 0xf, 0x0350, 32 }, /* PATTERN_KILLER_DQ7*/
{0x1f, 0xF, 2, 0xf, 0x04C0, 32 }, /* PATTERN_VREF*/
{0x1f, 0xF, 2, 0xf, 0x03C0, 32 }, /* PATTERN_FULL_SSO_1T*/
{0x1f, 0xF, 2, 0xf, 0x0400, 32 }, /* PATTERN_FULL_SSO_2T*/
{0x1f, 0xF, 2, 0xf, 0x0440, 32 }, /* PATTERN_FULL_SSO_3T*/
{0x1f, 0xF, 2, 0xf, 0x0480, 32 }, /* PATTERN_FULL_SSO_4T*/
{0x1f, 0xF, 2, 0xf, 0x6280, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
{0x1f, 0xF, 2, 0xf, 0x6680, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
{0x1f, 0xF, 2, 0xf, 0x6A80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
{0x1f, 0xF, 2, 0xf, 0x6E80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
{0x1f, 0xF, 2, 0xf, 0x7280, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
{0x1f, 0xF, 2, 0xf, 0x7680, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
{0x1f, 0xF, 2, 0xf, 0x7A80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
{0x1f, 0xF, 2, 0xf, 0x7E80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
{0x1f, 0xF, 2, 0xf, 0x8280, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
{0x1f, 0xF, 2, 0xf, 0x8680, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
{0x1f, 0xF, 2, 0xf, 0x8A80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
{0x1f, 0xF, 2, 0xf, 0x8E80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
{0x1f, 0xF, 2, 0xf, 0x9280, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
{0x1f, 0xF, 2, 0xf, 0x9680, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
{0x1f, 0xF, 2, 0xf, 0x9A80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
{0x1f, 0xF, 2, 0xf, 0x9E80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
{0x1f, 0xF, 2, 0xf, 0xA280, 32 } /* PATTERN_ISI_XTALK_FREE*/
/*Note: actual start_address is <<3 of defined addess*/
};
#else
PatternInfo patternTable_16[] =
{
/* num tx phases tx burst delay between rx pattern start_address patternLen*/
{0x1, 0x1, 2, 0x1, 0x0000, 2 }, /* PATTERN_PBS1*/
{0x1, 0x1, 2, 0x1, 0x0080, 2 }, /* PATTERN_PBS2*/
{0x1, 0x1, 2, 0x1, 0x0100, 2 }, /* PATTERN_PBS3*/
{0x1, 0x1, 2, 0x1, 0x0180, 2 }, /* PATTERN_TEST*/
{0x1, 0x1, 2, 0x1, 0x0200, 2 }, /* PATTERN_RL*/
{0x1, 0x1, 2, 0x1, 0x0280, 2 }, /* PATTERN_RL2*/
{0xf, 0x7, 2, 0x7, 0x0680, 16 }, /* PATTERN_STATIC_PBS*/
{0xf, 0x7, 2, 0x7, 0x0A80, 16 }, /* PATTERN_KILLER_DQ0*/
{0xf, 0x7, 2, 0x7, 0x0E80, 16 }, /* PATTERN_KILLER_DQ1*/
{0xf, 0x7, 2, 0x7, 0x1280, 16 }, /* PATTERN_KILLER_DQ2*/
{0xf, 0x7, 2, 0x7, 0x1680, 16 }, /* PATTERN_KILLER_DQ3*/
{0xf, 0x7, 2, 0x7, 0x1A80, 16 }, /* PATTERN_KILLER_DQ4*/
{0xf, 0x7, 2, 0x7, 0x1E80, 16 }, /* PATTERN_KILLER_DQ5*/
{0xf, 0x7, 2, 0x7, 0x2280, 16 }, /* PATTERN_KILLER_DQ6*/
{0xf, 0x7, 2, 0x7, 0x2680, 16 }, /* PATTERN_KILLER_DQ7*/
{0xf, 0x7, 2, 0x7, 0x2A80, 16 }, /* PATTERN_KILLER_DQ0_INV*/
{0xf, 0x7, 2, 0x7, 0x2E80, 16 }, /* PATTERN_KILLER_DQ1_INV*/
{0xf, 0x7, 2, 0x7, 0x3280, 16 }, /* PATTERN_KILLER_DQ2_INV*/
{0xf, 0x7, 2, 0x7, 0x3680, 16 }, /* PATTERN_KILLER_DQ3_INV*/
{0xf, 0x7, 2, 0x7, 0x3A80, 16 }, /* PATTERN_KILLER_DQ4_INV*/
{0xf, 0x7, 2, 0x7, 0x3E80, 16 }, /* PATTERN_KILLER_DQ5_INV*/
{0xf, 0x7, 2, 0x7, 0x4280, 16 }, /* PATTERN_KILLER_DQ6_INV*/
{0xf, 0x7, 2, 0x7, 0x4680, 16 }, /* PATTERN_KILLER_DQ7_INV*/
{0xf, 0x7, 2, 0x7, 0x4A80, 16 }, /* PATTERN_VREF*/
{0xf, 0x7, 2, 0x7, 0x4E80, 16 }, /* PATTERN_VREF_INV*/
{0xf, 0x7, 2, 0x7, 0x5280, 16 }, /* PATTERN_FULL_SSO_0T*/
{0xf, 0x7, 2, 0x7, 0x5680, 16 }, /* PATTERN_FULL_SSO_1T*/
{0xf, 0x7, 2, 0x7, 0x5A80, 16 }, /* PATTERN_FULL_SSO_2T*/
{0xf, 0x7, 2, 0x7, 0x5E80, 16 }, /* PATTERN_FULL_SSO_3T*/
{0xf, 0x7, 2, 0x7, 0x6280, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
{0xf, 0x7, 2, 0x7, 0x6680, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
{0xf, 0x7, 2, 0x7, 0x6A80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
{0xf, 0x7, 2, 0x7, 0x6E80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
{0xf, 0x7, 2, 0x7, 0x7280, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
{0xf, 0x7, 2, 0x7, 0x7680, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
{0xf, 0x7, 2, 0x7, 0x7A80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
{0xf, 0x7, 2, 0x7, 0x7E80, 16 }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
{0xf, 0x7, 2, 0x7, 0x8280, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
{0xf, 0x7, 2, 0x7, 0x8680, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
{0xf, 0x7, 2, 0x7, 0x8A80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
{0xf, 0x7, 2, 0x7, 0x8E80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
{0xf, 0x7, 2, 0x7, 0x9280, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
{0xf, 0x7, 2, 0x7, 0x9680, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
{0xf, 0x7, 2, 0x7, 0x9A80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
{0xf, 0x7, 2, 0x7, 0x9E80, 16 }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
{0xf, 0x7, 2, 0x7, 0xA280, 16 }, /* PATTERN_ISI_XTALK_FREE*/
{0xf, 0x7, 2, 0x7, 0xA680, 16 }, /* PATTERN_RESONANCE_1T*/
{0xf, 0x7, 2, 0x7, 0xAA80, 16 }, /* PATTERN_RESONANCE_2T*/
{0xf, 0x7, 2, 0x7, 0xAE80, 16 }, /* PATTERN_RESONANCE_3T*/
{0xf, 0x7, 2, 0x7, 0xB280, 16 }, /* PATTERN_RESONANCE_4T*/
{0xf, 0x7, 2, 0x7, 0xB680, 16 }, /* PATTERN_RESONANCE_5T*/
{0xf, 0x7, 2, 0x7, 0xBA80, 16 }, /* PATTERN_RESONANCE_6T*/
{0xf, 0x7, 2, 0x7, 0xBE80, 16 }, /* PATTERN_RESONANCE_7T*/
{0xf, 0x7, 2, 0x7, 0xC280, 16 }, /* PATTERN_RESONANCE_8T*/
{0xf, 0x7, 2, 0x7, 0xC680, 16 } /* PATTERN_RESONANCE_9T*/
/*Note: actual start_address is <<3 of defined addess*/
};
PatternInfo patternTable_32[] =
{
/* num tx phases tx burst delay between rx pattern start_address patternLen*/
{0x3, 0x3, 2, 0x3, 0x0000, 4 }, /* PATTERN_PBS1*/
{0x3, 0x3, 2, 0x3, 0x0080, 4 }, /* PATTERN_PBS2*/
{0x3, 0x3, 2, 0x3, 0x0100, 4 }, /* PATTERN_PBS3*/
{0x3, 0x3, 2, 0x3, 0x0180, 4 }, /* PATTERN_TEST*/
{0x3, 0x3, 2, 0x3, 0x0200, 4 }, /* PATTERN_RL*/
{0x3, 0x3, 2, 0x3, 0x0280, 4 }, /* PATTERN_RL2*/
{0x1f, 0xf, 2, 0xf, 0x0680, 32 }, /* PATTERN_STATIC_PBS*/
{0x1f, 0xf, 2, 0xf, 0x0A80, 32 }, /* PATTERN_KILLER_DQ0*/
{0x1f, 0xf, 2, 0xf, 0x0E80, 32 }, /* PATTERN_KILLER_DQ1*/
{0x1f, 0xf, 2, 0xf, 0x1280, 32 }, /* PATTERN_KILLER_DQ2*/
{0x1f, 0xf, 2, 0xf, 0x1680, 32 }, /* PATTERN_KILLER_DQ3*/
{0x1f, 0xf, 2, 0xf, 0x1A80, 32 }, /* PATTERN_KILLER_DQ4*/
{0x1f, 0xf, 2, 0xf, 0x1E80, 32 }, /* PATTERN_KILLER_DQ5*/
{0x1f, 0xf, 2, 0xf, 0x2280, 32 }, /* PATTERN_KILLER_DQ6*/
{0x1f, 0xf, 2, 0xf, 0x2680, 32 }, /* PATTERN_KILLER_DQ7*/
{0x1f, 0xf, 2, 0xf, 0x2A80, 32 }, /* PATTERN_KILLER_DQ0_INV*/
{0x1f, 0xf, 2, 0xf, 0x2E80, 32 }, /* PATTERN_KILLER_DQ1_INV*/
{0x1f, 0xf, 2, 0xf, 0x3280, 32 }, /* PATTERN_KILLER_DQ2_INV*/
{0x1f, 0xf, 2, 0xf, 0x3680, 32 }, /* PATTERN_KILLER_DQ3_INV*/
{0x1f, 0xf, 2, 0xf, 0x3A80, 32 }, /* PATTERN_KILLER_DQ4_INV*/
{0x1f, 0xf, 2, 0xf, 0x3E80, 32 }, /* PATTERN_KILLER_DQ5_INV*/
{0x1f, 0xf, 2, 0xf, 0x4280, 32 }, /* PATTERN_KILLER_DQ6_INV*/
{0x1f, 0xf, 2, 0xf, 0x4680, 32 }, /* PATTERN_KILLER_DQ7_INV*/
{0x1f, 0xf, 2, 0xf, 0x4A80, 32 }, /* PATTERN_VREF*/
{0x1f, 0xf, 2, 0xf, 0x4E80, 32 }, /* PATTERN_VREF_INV*/
{0x1f, 0xf, 2, 0xf, 0x5280, 32 }, /* PATTERN_FULL_SSO_0T*/
{0x1f, 0xf, 2, 0xf, 0x5680, 32 }, /* PATTERN_FULL_SSO_1T*/
{0x1f, 0xf, 2, 0xf, 0x5A80, 32 }, /* PATTERN_FULL_SSO_2T*/
{0x1f, 0xf, 2, 0xf, 0x5E80, 32 }, /* PATTERN_FULL_SSO_3T*/
{0x1f, 0xf, 2, 0xf, 0x6280, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ0*/
{0x1f, 0xf, 2, 0xf, 0x6680, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ1*/
{0x1f, 0xf, 2, 0xf, 0x6A80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ2*/
{0x1f, 0xf, 2, 0xf, 0x6E80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ3*/
{0x1f, 0xf, 2, 0xf, 0x7280, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ4*/
{0x1f, 0xf, 2, 0xf, 0x7680, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ5*/
{0x1f, 0xf, 2, 0xf, 0x7A80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ6*/
{0x1f, 0xf, 2, 0xf, 0x7E80, 32 }, /* PATTERN_SSO_FULL_XTALK_DQ7*/
{0x1f, 0xf, 2, 0xf, 0x8280, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ0*/
{0x1f, 0xf, 2, 0xf, 0x8680, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ1*/
{0x1f, 0xf, 2, 0xf, 0x8A80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ2*/
{0x1f, 0xf, 2, 0xf, 0x8E80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ3*/
{0x1f, 0xf, 2, 0xf, 0x9280, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ4*/
{0x1f, 0xf, 2, 0xf, 0x9680, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ5*/
{0x1f, 0xf, 2, 0xf, 0x9A80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ6*/
{0x1f, 0xf, 2, 0xf, 0x9E80, 32 }, /* PATTERN_SSO_XTALK_FREE_DQ7*/
{0x1f, 0xf, 2, 0xf, 0xA280, 32 }, /* PATTERN_ISI_XTALK_FREE*/
{0x1f, 0xf, 2, 0xf, 0xA680, 32 }, /* PATTERN_RESONANCE_1T*/
{0x1f, 0xf, 2, 0xf, 0xAA80, 32 }, /* PATTERN_RESONANCE_2T*/
{0x1f, 0xf, 2, 0xf, 0xAE80, 32 }, /* PATTERN_RESONANCE_3T*/
{0x1f, 0xf, 2, 0xf, 0xB280, 32 }, /* PATTERN_RESONANCE_4T*/
{0x1f, 0xf, 2, 0xf, 0xB680, 32 }, /* PATTERN_RESONANCE_5T*/
{0x1f, 0xf, 2, 0xf, 0xBA80, 32 }, /* PATTERN_RESONANCE_6T*/
{0x1f, 0xf, 2, 0xf, 0xBE80, 32 }, /* PATTERN_RESONANCE_7T*/
{0x1f, 0xf, 2, 0xf, 0xC280, 32 }, /* PATTERN_RESONANCE_8T*/
{0x1f, 0xf, 2, 0xf, 0xC680, 32 } /* PATTERN_RESONANCE_9T*/
/*Note: actual start_address is <<3 of defined addess*/
};
#endif
/*******************************************************************************/
GT_U32 trainDevNum;
MV_HWS_DDR_CS traintrainCsType;
GT_U32 trainPupNum;
MV_HWS_TRAINING_RESULT trainResultType;
MV_HWS_ControlElement trainControlElement;
MV_HWS_SearchDirection traineSearchDir;
MV_HWS_DIRECTION trainDirection;
GT_U32 trainIfSelect;
GT_U32 trainInitValue;
GT_U32 trainNumberIterations;
MV_HWS_PATTERN trainPattern;
MV_HWS_EdgeCompare trainEdgeCompare;
GT_U32 trainCsNum;
GT_U32 trainIfAcess, trainIfId, trainPupAccess;
#ifdef CONFIG_DDR4
GT_U32 maxPollingForDone = 10000000; /* this counter was increased for DDR4
due to A390 DB-GP DDR4 failure */
#else /* DDR3 */
#ifdef CONFIG_BOBK
GT_U32 maxPollingForDone = 1000;
#else
GT_U32 maxPollingForDone = 1000000;
#endif /* CONFIG_BOBK */
#endif /* CONFIG_DDR4 */
extern MV_HWS_RESULT trainingResult[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
extern AUTO_TUNE_STAGE trainingStage;
/******************************************************************************/
GT_U32* ddr3TipGetBufPtr
(
GT_U32 devNum,
MV_HWS_SearchDirection search,
MV_HWS_TRAINING_RESULT resultType,
GT_U32 interfaceNum
)
{
GT_U32 *bufPtr = NULL;
/* avoid warnings */
devNum = devNum;
resultType = resultType;
bufPtr = &trainingRes[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS* search +
interfaceNum *MAX_BUS_NUM * BUS_WIDTH_IN_BITS];
return bufPtr;
}
/*****************************************************************************
IP Training search
Note: for one edge search only from fail to pass, else jitter can be be entered into solution.
******************************************************************************/
GT_STATUS ddr3TipIpTraining
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE accessType,
GT_U32 interfaceNum,
MV_HWS_ACCESS_TYPE pupAccessType,
GT_U32 pupNum,
MV_HWS_TRAINING_RESULT resultType,
MV_HWS_ControlElement controlElement,
MV_HWS_SearchDirection searchDir,
MV_HWS_DIRECTION direction,
GT_U32 interfaceMask,
GT_U32 initValue,
GT_U32 numIter,
MV_HWS_PATTERN pattern,
MV_HWS_EdgeCompare edgeComp,
MV_HWS_DDR_CS csType,
GT_U32 csNum,
MV_HWS_TrainingIpStatus* trainStatus
)
{
GT_U32 maskDqNumOfRegs, maskPupNumOfRegs, indexCnt,pollCnt, regData, pupId, triggerRegAddr;
GT_U32 txBurstSize;
GT_U32 delayBetweenBurst;
GT_U32 rdMode;
GT_U32 readData[MAX_INTERFACE_NUM];
PatternInfo *patternTable = ddr3TipGetPatternTable();
GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
GT_U16 *maskResultsDqRegMap = ddr3TipGetMaskResultsDqReg();
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
if (pupNum >= octetsPerInterfaceNum)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
}
if (interfaceNum >= MAX_INTERFACE_NUM)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("interfaceId %d not valid\n",interfaceNum));
}
if (trainStatus == NULL)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("error param 4\n"));
return GT_BAD_PARAM;
}
/* load pattern */
if (csType == CS_SINGLE)
{
/* All CS\92s to CS0 */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, CS_ENABLE_REG, 1<<3, 1<<3));
/* All CS\92s to CS0 */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_DATA_CONTROL_REG, (0x3 | (effective_cs<<26)) , 0xC000003));
}
else
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, CS_ENABLE_REG, 0, 1<<3));
/* CS select*/
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_DATA_CONTROL_REG, 0x3 | csNum<<26, 0x3 | 3<<26));
}
/* LOAD PATTERN TO ODPG */
/* load pattern to ODPG */
ddr3TipLoadPatternToOdpg(devNum, accessType, interfaceNum, pattern, patternTable[pattern].startAddr);
txBurstSize = (direction == OPER_WRITE) ? patternTable[pattern].txBurstSize : 0;
delayBetweenBurst = (direction == OPER_WRITE) ? 2 : 0;
rdMode = (direction == OPER_WRITE) ? 1 : 0;
CHECK_STATUS(ddr3TipConfigureOdpg(devNum, accessType, interfaceNum, direction, patternTable[pattern].numOfPhasesTx,
txBurstSize, patternTable[pattern].numOfPhasesRx, delayBetweenBurst,
rdMode, effective_cs, STRESS_NONE, DURATION_SINGLE));
regData = (direction == OPER_READ) ? 0 : (0x3<<30) ;
regData |= (direction == OPER_READ) ? 0x60 : 0xFA ;
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_WRITE_READ_MODE_ENABLE_REG, regData, MASK_ALL_BITS));
regData = (edgeComp == EDGE_PF || edgeComp == EDGE_FP) ? 0 : 1<<6;
regData |= (edgeComp == EDGE_PF || edgeComp == EDGE_PFP) ? (1<<7) : 0;
/* change from Pass to Fail will lock the result*/
#if 0
if (csType == CS_SINGLE)
{
/* Write2Dunit(0x1034, 0xe , [17:14]) */ /* All PUPs selected */
regData |= 0xe<<14;
}
else
{
/* Write2Dunit(0x1034, PUP# , [17:14]) */ /* PUP select */
regData |= pupNum<<14;
}
#else
if (pupAccessType == ACCESS_TYPE_MULTICAST)
{
regData |= 0xe<<14;
}
else
{
regData |= pupNum<<14;
}
#endif
if (edgeComp == EDGE_FP)
{
regData |= (0<<20); /* don't search for readl edge change, only the state */
}
else if (edgeComp == EDGE_FPF)
{
regData |= (0<<20);
}
else
{
regData |= (3<<20);
}
/* regData |= (0x7<<8);
if (edgeComp == EDGE_FP)
regData |= (0x7<<11);
*/
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_TRAINING_CONTROL_REG, regData | (0x7<<8) | (0x7<<11), (0x3 | (0x3<<2) | (0x3<<6) | (1<<5) | (0x7<<8) | (0x7<<11) | (0xf<<14) | (0x3<<18) | (3<<20))));
regData = (searchDir == MV_HWS_Low2High) ? 0 : (1 << 8);
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_OBJ1_OPCODE_REG, 1 | regData | initValue<<9 | (1<<25) | (1<<26), 0xFF | (1<<8) | (0xFFFF<<9) | (1<<25) | (1<<26)));
/*Write2Dunit(0x10B4, NumberIteration , [15:0]) Max number of iterations */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, ODPG_OBJ1_ITER_CNT_REG, numIter, 0xFFFF));
if (controlElement == MV_HWS_ControlElement_DQ_SKEW && direction == OPER_READ)
{
/*Write2Dunit(0x10C0, 0x5F , [7:0]) MC PBS Reg Address at DDR PHY*/
regData = 0x5f + effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
}
else if (controlElement == MV_HWS_ControlElement_DQ_SKEW && direction == OPER_WRITE)
{
regData = 0x1f + effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
}
else if (controlElement == MV_HWS_ControlElement_ADLL && direction == OPER_WRITE)
{
/*LOOP 0x00000001 + 4*n: where n (0-3) represents M_CS number */
/*Write2Dunit(0x10C0, 0x1 , [7:0]) ADLL WR Reg Address at DDR PHY*/
regData = 1 + effective_cs * CS_REGISTER_ADDR_OFFSET;
}
else if (controlElement == MV_HWS_ControlElement_ADLL && direction == OPER_READ)
{
/* ADLL RD Reg Address at DDR PHY*/
regData = 3 + effective_cs * CS_REGISTER_ADDR_OFFSET;
}
else if (controlElement == MV_HWS_ControlElement_DQS_SKEW && direction == OPER_WRITE)
{
/*TBD not defined in 0.5.0 requirement */
}
else if (controlElement == MV_HWS_ControlElement_DQS_SKEW && direction == OPER_READ)
{
/*TBD not defined in 0.5.0 requirement */
}
regData |= (0x6 << 28);
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, CALIB_OBJ_PRFA_REG, regData | (initValue << 8) , 0xff | (0xFFFF << 8)| (0xF << 24) | (GT_U32)(0xF << 28)));
maskDqNumOfRegs = octetsPerInterfaceNum * BUS_WIDTH_IN_BITS;
maskPupNumOfRegs = octetsPerInterfaceNum;
if (resultType == RESULT_PER_BIT)
{
for(indexCnt=0; indexCnt<maskDqNumOfRegs;indexCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsDqRegMap[indexCnt], 0, 1<<24));
}
/*Mask disabled buses*/
for(pupId = 0; pupId < octetsPerInterfaceNum ; pupId++)
{
if (IS_BUS_ACTIVE(topologyMap->activeBusMask, pupId) == GT_TRUE) continue;
for(indexCnt=pupId*8; indexCnt<(pupId+1)*8;indexCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsDqRegMap[indexCnt], (1<<24), 1<<24));
}
}
for(indexCnt=0; indexCnt<maskPupNumOfRegs;indexCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsPupRegMap[indexCnt], (1<<24) , 1<<24));
}
}
else if (resultType == RESULT_PER_BYTE)
{
/* write to adll */
for(indexCnt=0; indexCnt<maskPupNumOfRegs;indexCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsPupRegMap[indexCnt], 0, 1<<24));
}
for(indexCnt=0; indexCnt<maskDqNumOfRegs;indexCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, maskResultsDqRegMap[indexCnt],(1 << 24), (1<<24)));
}
}
/*Start Training Trigger */
triggerRegAddr = (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)?(ODPG_TRAINING_TRIGGER_REG):(ODPG_TRAINING_STATUS_REG);
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceNum, triggerRegAddr, 1, 1));
/*wait for all RFU tests to finish (or timeout)*/
/*WA for 16 bit mode, more investigation needed*/
hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1); /* 1 mSec */
/* Training "Done ?" for CPU contolled TIP*/
if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
{
for(indexCnt=0; indexCnt < MAX_INTERFACE_NUM;indexCnt++)
{
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) == 0)
{
continue;
}
if (interfaceMask & (1<<indexCnt))
{
/*need to check results for this Dunit */
for(pollCnt=0;pollCnt < maxPollingForDone;pollCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, ODPG_TRAINING_STATUS_REG, &regData, MASK_ALL_BITS));
if ((regData & 0x2) != 0)
{
/*done */
trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_SUCCESS;
break;
}
}
#ifdef CONFIG_BOBK
/* WA to avoid training stucking */
hwsOsExactDelayPtr((GT_U8)devNum, devNum, 50); /* 50 mSec */
#endif
if (pollCnt == maxPollingForDone)
{
trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_TIMEOUT;
}
}
/*Be sure that ODPG done*/
CHECK_STATUS(isOdpgAccessDone(devNum, indexCnt));
}
/*Write ODPG done in Dunit*/
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_STATUS_DONE_REG, 0, 0x1));
}
/*wait for all Dunit tests to finish (or timeout)*/
/* Training "Done ?" */
/* Training "Pass ?" */
for(indexCnt=0; indexCnt < MAX_INTERFACE_NUM;indexCnt++)
{
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, indexCnt) == 0)
{
continue;
}
if (interfaceMask & (1<<indexCnt))
{
/*need to check results for this Dunit */
for(pollCnt=0;pollCnt < maxPollingForDone;pollCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, indexCnt, triggerRegAddr, readData, MASK_ALL_BITS));
regData = readData[indexCnt];
if ((regData & 0x2) != 0)
{
/*done*/
if ((regData & 0x4) == 0)
{
trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_SUCCESS;
}
else
{
trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_FAIL;
}
break;
}
}
#ifdef CONFIG_BOBK
/* WA to avoid training stucking */
hwsOsExactDelayPtr((GT_U8)devNum, devNum, 50);
#endif
if (pollCnt == maxPollingForDone)
{
trainStatus[indexCnt] = MV_HWS_TrainingIpStatus_TIMEOUT;
}
}
}
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
return GT_OK;
}
/*****************************************************************************
Load expected Pattern to ODPG
******************************************************************************/
GT_STATUS ddr3TipLoadPatternToOdpg
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE accessType,
GT_U32 interfaceId,
MV_HWS_PATTERN pattern,
GT_U32 loadAddr
)
{
GT_U32 patternLengthCnt = 0;
PatternInfo *patternTable = ddr3TipGetPatternTable();
for(patternLengthCnt = 0; patternLengthCnt < patternTable[pattern].patternLen ; patternLengthCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, ODPG_PATTERN_DATA_LOW_REG,
patternTableGetWord(devNum, pattern, (GT_U8)(patternLengthCnt*2)), MASK_ALL_BITS));
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, ODPG_PATTERN_DATA_HI_REG,
patternTableGetWord(devNum, pattern, (GT_U8)(patternLengthCnt*2 + 1)), MASK_ALL_BITS));
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, ODPG_PATTERN_ADDR_REG, patternLengthCnt, MASK_ALL_BITS));
}
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, ODPG_PATTERN_ADDR_OFFSET_REG, loadAddr, MASK_ALL_BITS));
return GT_OK;
}
/*****************************************************************************
Configure ODPG
******************************************************************************/
GT_STATUS ddr3TipConfigureOdpg
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE accessType,
GT_U32 interfaceId,
MV_HWS_DIRECTION direction,
GT_U32 txPhases,
GT_U32 txBurstSize,
GT_U32 rxPhases,
GT_U32 delayBetweenBurst,
GT_U32 rdMode,
GT_U32 csNum,
GT_U32 addrStressJump,
GT_U32 singlePattern
)
{
GT_U32 dataValue = 0;
GT_STATUS retVal;
direction = direction; /* avoid warnings */
dataValue = ((singlePattern << 2) | (txPhases << 5) | (txBurstSize << 11) | (delayBetweenBurst << 15) | (rxPhases << 21) | (rdMode << 25) | (csNum << 26) | (addrStressJump << 29));
retVal = mvHwsDdr3TipIFWrite(devNum, accessType, interfaceId, ODPG_DATA_CONTROL_REG, dataValue, 0xAFFFFFFC);
if (retVal != GT_OK)
{
return retVal;
}
return GT_OK;
}
void ddr3TipDDR3IpTrainingStart
(
)
{
MV_HWS_TrainingIpStatus sTrainIpStatus[MAX_INTERFACE_NUM];
ddr3TipIpTraining(
trainDevNum,
trainIfAcess,
trainIfId,
trainPupAccess,
trainPupNum,
trainResultType,
trainControlElement,
traineSearchDir,
trainDirection,
trainIfSelect,
trainInitValue,
trainNumberIterations,
trainPattern,
trainEdgeCompare,
traintrainCsType,
trainCsNum,
sTrainIpStatus);
}
GT_STATUS ddr3TipProcessResult(GT_U32 *arResult, MV_HWS_Edge eEdge, MV_HWS_EdgeSearch eEdgeSearch, GT_U32 *edgeResult)
{
GT_U32 i, ResVal;
GT_32 tapVal, maxVal = -10000, minVal = 10000;
GT_BOOL lockSuccess = GT_TRUE;
for(i=0; i < BUS_WIDTH_IN_BITS; i++)
{
ResVal = GET_LOCK_RESULT(arResult[i]);
if (ResVal == 0)
{
lockSuccess = GT_FALSE;
break;
}
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("lock failed for bit %d\n",i));
}
}
if (lockSuccess == GT_TRUE)
{
for(i=0; i < BUS_WIDTH_IN_BITS; i++)
{
tapVal = GET_TAP_RESULT(arResult[i], eEdge);
if (tapVal > maxVal)
maxVal = tapVal;
if (tapVal < minVal)
minVal = tapVal;
if (eEdgeSearch == TRAINING_EDGE_MAX)
*edgeResult = (GT_U32)maxVal;
else
*edgeResult = (GT_U32)minVal;
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("i %d arResult[i] 0x%x tapVal %d maxVal %d minVal %d EdgeResult %d\n", i, arResult[i], tapVal, maxVal, minVal, *edgeResult));
}
}
else
{
return GT_FAIL;
}
return GT_OK;
}
/*****************************************************************************
Read training search result
******************************************************************************/
GT_STATUS ddr3TipReadTrainingResult
(
GT_U32 devNum,
GT_U32 interfaceId,
MV_HWS_ACCESS_TYPE pupAccessType,
GT_U32 pupNum,
GT_U32 bitNum,
MV_HWS_SearchDirection search,
MV_HWS_DIRECTION direction,
MV_HWS_TRAINING_RESULT resultType,
MV_HWS_TrainingLoadOperation operation,
GT_U32 csNumType,
GT_U32 **loadRes,
GT_BOOL isReadFromDB,
GT_U8 consTap,
GT_BOOL isCheckResultValidity
)
{
GT_U32 regOffset, pupCnt, startPup, endPup, startReg, endReg;
GT_U32 *interfaceTrainRes = NULL;
GT_U16 *regAddr = NULL;
GT_U32 readData[MAX_INTERFACE_NUM];
GT_U16 *maskResultsPupRegMap = ddr3TipGetMaskResultsPupRegMap();
GT_U16 *maskResultsDqRegMap = ddr3TipGetMaskResultsDqReg();
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
/* Agreed assumption: all CS mask contain same number of bits, i.e. in multi CS, the number of CS per memory is the same for all pups */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, (csNumType == 0) ? 1<<3 : 0, (1 << 3)));
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_DATA_CONTROL_REG, (csNumType << 26), (3 << 26)));
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("ReadFromDB %d csType %d oper %d resultType %d direction %d search %d pupNum %d interfaceId %d pupAccessType %d\n",isReadFromDB, csNumType , operation , resultType , direction , search , pupNum , interfaceId,pupAccessType));
if ((loadRes == NULL) && (isReadFromDB == GT_TRUE))
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("ddr3TipReadTrainingResult loadRes = NULL"));
return GT_FAIL;
}
if (pupNum >= octetsPerInterfaceNum)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
}
if (interfaceId >= MAX_INTERFACE_NUM)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("interfaceId %d not valid\n",interfaceId));
}
if (resultType == RESULT_PER_BIT)
{
regAddr = maskResultsDqRegMap;
}
else
{
regAddr = maskResultsPupRegMap;
}
if (pupAccessType == ACCESS_TYPE_UNICAST)
{
startPup = pupNum;
endPup = pupNum;
}
else /*pupAccessType == ACCESS_TYPE_MULTICAST)*/
{
startPup = 0;
endPup = octetsPerInterfaceNum-1;
}
for(pupCnt = startPup; pupCnt <= endPup ; pupCnt++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupCnt)
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("interfaceId %d startPup %d endPup %d pupCnt %d\n",interfaceId, startPup, endPup, pupCnt));
if (resultType == RESULT_PER_BIT)
{
if (bitNum == ALL_BITS_PER_PUP)
{
startReg = pupCnt*BUS_WIDTH_IN_BITS;
endReg = (pupCnt+1)*BUS_WIDTH_IN_BITS - 1;
}
else
{
startReg = pupCnt*BUS_WIDTH_IN_BITS + bitNum;
endReg = pupCnt*BUS_WIDTH_IN_BITS + bitNum;
}
}
else
{
startReg = pupCnt;
endReg = pupCnt;
}
interfaceTrainRes = ddr3TipGetBufPtr(devNum, search,resultType,interfaceId);
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("startReg %d endReg %d interface 0x%x\n",startReg, endReg, interfaceTrainRes));
if (interfaceTrainRes == NULL)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("interfaceTrainRes is NULL\n"));
return GT_FAIL;
}
for(regOffset=startReg; regOffset <= endReg; regOffset++)
{
if (operation == TrainingLoadOperation_UNLOAD)
{
if (isReadFromDB == GT_FALSE)
{
CHECK_STATUS(mvHwsDdr3TipIFRead(devNum, ACCESS_TYPE_UNICAST, interfaceId,
regAddr[regOffset], readData , MASK_ALL_BITS));
if(isCheckResultValidity == GT_TRUE){
if( (readData[interfaceId] & 0x02000000) == 0 ){
interfaceTrainRes[regOffset] = 0x02000000 + 64 + consTap;
}
else{
interfaceTrainRes[regOffset] = readData[interfaceId] + consTap;
}
}
else{
interfaceTrainRes[regOffset] = readData[interfaceId] + consTap;
}
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("regOffset %d value 0x%x addr 0x%x\n",regOffset, interfaceTrainRes[regOffset], &interfaceTrainRes[regOffset]));
}
else
{
*loadRes = &interfaceTrainRes[startReg];
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("*loadRes %d\n",*loadRes));
}
}
else
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("not supported\n"));
}
}
}
return GT_OK;
}
/*****************************************************************************
load all pattern to memory using ODPG
******************************************************************************/
GT_STATUS ddr3TipLoadAllPatternToMem
(
GT_U32 devNum
)
{
GT_U32 pattern = 0, interfaceId;
/*DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_INFO, ("=== LOAD ALL PATTERNS ==="));*/
for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
trainingResult[trainingStage][interfaceId] = TEST_SUCCESS;
}
for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
/* enable single cs */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, CS_ENABLE_REG, (1 << 3), (1 << 3)));
}
for(pattern = 0; pattern < PATTERN_LIMIT; pattern++)
{
ddr3TipLoadPatternToMem(devNum,pattern);
}
return GT_OK;
}
/*****************************************************************************
wait till ODPG access is ready
******************************************************************************/
GT_STATUS isOdpgAccessDone
(
GT_U32 devNum,
GT_U32 interfaceId
)
{
GT_U32 pollCnt = 0, dataValue, expectedVal;
GT_U32 readData[MAX_INTERFACE_NUM];
for (pollCnt = 0; pollCnt < MAX_POLLING_ITERATIONS ; pollCnt++)
{
CHECK_STATUS(mvHwsDdr3TipIFRead(devNum,ACCESS_TYPE_UNICAST, interfaceId, ODPG_BIST_DONE, readData, MASK_ALL_BITS));
dataValue = readData[interfaceId];
expectedVal = (ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) < MV_TIP_REV_3)?(ODPG_BIST_DONE_BIT_VALUE_REV2):(ODPG_BIST_DONE_BIT_VALUE_REV3);
if (((dataValue >> ODPG_BIST_DONE_BIT_OFFS )& 0x1) == expectedVal)
{
dataValue = dataValue & 0xfffffffe;
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ODPG_BIST_DONE, dataValue, MASK_ALL_BITS));
break;
}
}
if (pollCnt >= MAX_POLLING_ITERATIONS)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,("Bist Activate: poll failure 2\n"));
return GT_FAIL;
}
return GT_OK;
}
/*****************************************************************************
Load specific pattern to memory using ODPG
******************************************************************************/
GT_STATUS ddr3TipLoadPatternToMem
(
GT_U32 devNum,
MV_HWS_PATTERN pattern
)
{
GT_U32 regData, interfaceId;
PatternInfo *patternTable = ddr3TipGetPatternTable();
/*DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_INFO, ("=== LOAD PATTERN ==="));*/
/* load pattern to memory */
/* Write Tx mode, CS0, phases, Tx burst size, delay between burst, rx pattern phases */
regData = 0x1 | (patternTable[pattern].numOfPhasesTx << 5) | (patternTable[pattern].txBurstSize << 11) |
(patternTable[pattern].delayBetweenBursts << 15) | (patternTable[pattern].numOfPhasesRx << 21) | (0x1 << 25 ) | (effective_cs << 26);
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, regData, MASK_ALL_BITS));
/* ODPG Write enable from BIST */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, (0x1| (effective_cs<<26)), 0xC000003));
/* disable error injection */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_WRITE_DATA_ERROR_REG, 0, 0x1));
/* load pattern to ODPG */
ddr3TipLoadPatternToOdpg(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, pattern, patternTable[pattern].startAddr);
if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3)
{
for(interfaceId = 0; interfaceId < MAX_INTERFACE_NUM ; interfaceId++)
{
if (IS_INTERFACE_ACTIVE(topologyMap->interfaceActiveMask, interfaceId) == 0)
continue;
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, SDRAM_ODT_CONTROL_HIGH_REG, 0x3 , 0xf));
}
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS, (0x1 << ODPG_ENABLE_OFFS)));
}
else {
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, (GT_U32)(0x1 << 31), (GT_U32)(0x1 << 31)));
}
hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1); /* 1 mSec */
for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
CHECK_STATUS(isOdpgAccessDone(devNum, interfaceId));
}
/* Disable ODPG and stop write to memory*/
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, (0x1 << 30), (GT_U32)(0x3 << 30)));
/* return to default */
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
if(ddr3TipDevAttrGet(devNum, MV_ATTR_TIP_REV) >= MV_TIP_REV_3){
/*disable odt0 for CS0 training - need to adjust for multy CS*/
CHECK_STATUS(mvHwsDdr3TipIFWrite(devNum, ACCESS_TYPE_MULTICAST,PARAM_NOT_CARE , 0x1498, 0x0 , 0xf));
}
/* temporary added */
hwsOsExactDelayPtr((GT_U8)devNum, devNum, 1);
return GT_OK;
}
/*****************************************************************************
Training search routine
******************************************************************************/
GT_STATUS ddr3TipIpTrainingWrapperInt
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE accessType,
GT_U32 interfaceId,
MV_HWS_ACCESS_TYPE pupAccessType,
GT_U32 pupNum,
GT_U32 bitNum,
MV_HWS_TRAINING_RESULT resultType,
MV_HWS_ControlElement controlElement,
MV_HWS_SearchDirection searchDir,
MV_HWS_DIRECTION direction,
GT_U32 interfaceMask,
GT_U32 initValueL2h,
GT_U32 initValueH2l,
GT_U32 numIter,
MV_HWS_PATTERN pattern,
MV_HWS_EdgeCompare edgeComp,
MV_HWS_DDR_CS trainCsType,
GT_U32 csNum,
MV_HWS_TrainingIpStatus* trainStatus
)
{
GT_U32 interfaceNum = 0, startIf, endIf, initValueUsed;
MV_HWS_SearchDirection searchDirId , startSearch, endSearch;
MV_HWS_EdgeCompare edgeCompUsed;
GT_U8 consTap = (direction == OPER_WRITE)?(64):(0);
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
if (trainStatus == NULL)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("trainStatus is NULL\n"));
return GT_FAIL;
}
if ((trainCsType > CS_NON_SINGLE) ||
(edgeComp >= EDGE_PFP) ||
(pattern >= PATTERN_LIMIT) ||
(direction > OPER_WRITE_AND_READ) ||
(searchDir > MV_HWS_High2Low) ||
(controlElement > MV_HWS_ControlElement_DQS_SKEW) ||
(resultType > RESULT_PER_BYTE) ||
(pupNum >= octetsPerInterfaceNum) ||
(pupAccessType > ACCESS_TYPE_MULTICAST) ||
(interfaceId > 11)||
(accessType > ACCESS_TYPE_MULTICAST))
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("wrong parameter trainCsType %d edgeComp %d pattern %d direction %d searchDir %d controlElement %d resultType %d pupNum %d pupAccessType %d interfaceId %d accessType %d\n",trainCsType , edgeComp , pattern , direction , searchDir , controlElement , resultType , pupNum , pupAccessType , interfaceId , accessType ));
return GT_FAIL;
}
if (edgeComp == EDGE_FPF)
{
startSearch = MV_HWS_Low2High;
endSearch = MV_HWS_High2Low;
edgeCompUsed = EDGE_FP;
}
else
{
startSearch = searchDir;
endSearch = searchDir;
edgeCompUsed = edgeComp;
}
for(searchDirId = startSearch ; searchDirId <= endSearch ; searchDirId++)
{
initValueUsed = (searchDirId == MV_HWS_Low2High) ? initValueL2h : initValueH2l;
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE, ("devNum %d, accessType %d, interfaceId %d, pupAccessType %d,pupNum %d, resultType %d, controlElement %d searchDirId %d, direction %d, interfaceMask %d,initValueUsed %d, numIter %d, pattern %d, edgeCompUsed %d, trainCsType %d, csNum %d\n",
devNum, accessType, interfaceId, pupAccessType ,pupNum, resultType, controlElement,
searchDirId, direction, interfaceMask,
initValueUsed, numIter, pattern, edgeCompUsed, trainCsType, csNum));
ddr3TipIpTraining(devNum, accessType, interfaceId, pupAccessType ,pupNum, resultType, controlElement,
searchDirId, direction, interfaceMask,
initValueUsed, numIter, pattern, edgeCompUsed, trainCsType, csNum, trainStatus);
if (accessType == ACCESS_TYPE_MULTICAST)
{
startIf = 0;
endIf = MAX_INTERFACE_NUM-1;
}
else
{
startIf = interfaceId;
endIf = interfaceId;
}
for(interfaceNum = startIf; interfaceNum <= endIf ; interfaceNum++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceNum)
csNum = 0;
CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceNum, pupAccessType, pupNum, bitNum,
searchDirId, direction, resultType,
TrainingLoadOperation_UNLOAD, trainCsType,
NULL , GT_FALSE, consTap, GT_FALSE));
}
}
return GT_OK;
}
/*****************************************************************************
Training search & read result routine
******************************************************************************/
GT_STATUS ddr3TipIpTrainingWrapper
(
GT_U32 devNum,
MV_HWS_ACCESS_TYPE accessType,
GT_U32 interfaceId,
MV_HWS_ACCESS_TYPE pupAccessType,
GT_U32 pupNum,
MV_HWS_TRAINING_RESULT resultType,
MV_HWS_ControlElement controlElement,
MV_HWS_SearchDirection searchDir,
MV_HWS_DIRECTION direction,
GT_U32 interfaceMask,
GT_U32 initValueL2h,
GT_U32 initValueH2l,
GT_U32 numIter,
MV_HWS_PATTERN pattern,
MV_HWS_EdgeCompare edgeComp,
MV_HWS_DDR_CS trainCsType,
GT_U32 csNum,
MV_HWS_TrainingIpStatus* trainStatus
)
{
GT_U8 e1,e2;
GT_U32 interfaceCnt, bitId, startIf, endIf, bitEnd=0;
GT_U32 *result[MV_HWS_SearchDirLimit] = {0};
GT_U8 consTap = (direction == OPER_WRITE)?(64):(0);
GT_U8 bitBitMask[MAX_BUS_NUM] = {0}, bitBitMaskActive = 0;
GT_U8 pupId;
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
if (pupNum >= octetsPerInterfaceNum)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("pupNum %d not valid\n",pupNum));
}
if (interfaceId >= MAX_INTERFACE_NUM)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR, ("interfaceId %d not valid\n",interfaceId));
}
CHECK_STATUS(ddr3TipIpTrainingWrapperInt(devNum,accessType,interfaceId, pupAccessType, pupNum,
ALL_BITS_PER_PUP, resultType, controlElement, searchDir, direction,
interfaceMask, initValueL2h, initValueH2l, numIter, pattern, edgeComp, trainCsType,
csNum, trainStatus));
if (accessType == ACCESS_TYPE_MULTICAST)
{
startIf = 0;
endIf = MAX_INTERFACE_NUM-1;
}
else
{
startIf = interfaceId;
endIf = interfaceId;
}
for(interfaceCnt = startIf; interfaceCnt <= endIf; interfaceCnt++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceCnt)
for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
if (resultType == RESULT_PER_BIT)
{
bitEnd = BUS_WIDTH_IN_BITS-1;
}
else
{
bitEnd = 0;
}
bitBitMask[pupId] = 0;
for(bitId = 0; bitId <= bitEnd ; bitId++)
{
MV_HWS_SearchDirection searchDirId;
for(searchDirId = MV_HWS_Low2High ; searchDirId <= MV_HWS_High2Low ; searchDirId++)
{
CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceCnt, ACCESS_TYPE_UNICAST,
pupId, bitId, searchDirId, direction,
resultType, TrainingLoadOperation_UNLOAD,
CS_SINGLE, &result[searchDirId] , GT_TRUE, 0, GT_FALSE));
}
e1 = GET_TAP_RESULT(result[MV_HWS_Low2High][0], EDGE_1);
e2 = GET_TAP_RESULT(result[MV_HWS_High2Low][0], EDGE_1);
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_INFO, ("wrapper interfaceId %d pupId %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x) \n", interfaceCnt, pupId, bitId, result[MV_HWS_Low2High][0],e1, result[MV_HWS_High2Low][0], e2));
/* TBD validate is valid only for tx */
if( VALIDATE_TRAINING_LIMIT(e1,e2) == GT_TRUE &&
GET_LOCK_RESULT(result[MV_HWS_Low2High][0]) &&
GET_LOCK_RESULT(result[MV_HWS_Low2High][0]))
{
/*Mark problem bits*/
bitBitMask[pupId] |= 1<<bitId;
bitBitMaskActive = 1;
}
}/*For all bits*/
}/*For all PUPs*/
/*Fix problem bits*/
if(bitBitMaskActive != 0)
{
GT_U32 *L2HinterfaceTrainRes = NULL;
GT_U32 *H2LinterfaceTrainRes = NULL;
L2HinterfaceTrainRes = ddr3TipGetBufPtr(devNum, MV_HWS_Low2High,resultType,interfaceCnt);
H2LinterfaceTrainRes = ddr3TipGetBufPtr(devNum, MV_HWS_High2Low,resultType,interfaceCnt);
ddr3TipIpTraining(devNum, ACCESS_TYPE_UNICAST, interfaceCnt, ACCESS_TYPE_MULTICAST , PARAM_NOT_CARE,
resultType, controlElement,
MV_HWS_Low2High, direction, interfaceMask,
numIter/2, numIter/2, pattern, EDGE_FP, trainCsType, csNum, trainStatus);
for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
if(bitBitMask[pupId] == 0)
continue;
for(bitId = 0; bitId <= bitEnd ; bitId++)
{
if( (bitBitMask[pupId] & (1<<bitId)) == 0)
continue;
CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceCnt, ACCESS_TYPE_UNICAST,
pupId, bitId, MV_HWS_Low2High, direction,
resultType, TrainingLoadOperation_UNLOAD,
CS_SINGLE, &L2HinterfaceTrainRes , GT_FALSE, 0, GT_TRUE));
}
}
ddr3TipIpTraining(devNum, ACCESS_TYPE_UNICAST, interfaceCnt, ACCESS_TYPE_MULTICAST , PARAM_NOT_CARE,
resultType, controlElement,
MV_HWS_High2Low, direction, interfaceMask,
numIter/2, numIter/2, pattern, EDGE_FP, trainCsType, csNum, trainStatus);
for(pupId = 0; pupId <= (octetsPerInterfaceNum-1) ; pupId++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
if(bitBitMask[pupId] == 0)
continue;
for(bitId = 0; bitId <= bitEnd ; bitId++)
{
if( (bitBitMask[pupId] & (1<<bitId)) == 0)
continue;
CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceCnt, ACCESS_TYPE_UNICAST,
pupId, bitId, MV_HWS_High2Low, direction,
resultType, TrainingLoadOperation_UNLOAD,
CS_SINGLE, &H2LinterfaceTrainRes , GT_FALSE, consTap, GT_TRUE));
}
}
}/*if bitBitMaskActive*/
}/*For all Interfacess*/
return GT_OK;
}
/*****************************************************************************
Load phy values
******************************************************************************/
GT_STATUS ddr3TipLoadPhyValues(GT_BOOL bLoad)
{
GT_U32 busCnt = 0, interfaceId, devNum = 0;
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
for(busCnt = 0; busCnt < octetsPerInterfaceNum; busCnt++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, busCnt)
if (bLoad == GT_TRUE)
{
CHECK_STATUS(mvHwsDdr3TipBUSRead( devNum, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), &phyRegBk[interfaceId][busCnt][0]));
CHECK_STATUS(mvHwsDdr3TipBUSRead( devNum, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, RL_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), &phyRegBk[interfaceId][busCnt][1]));
CHECK_STATUS(mvHwsDdr3TipBUSRead( devNum, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, READ_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), &phyRegBk[interfaceId][busCnt][2]));
}
else
{
CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), phyRegBk[interfaceId][busCnt][0]));
CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, RL_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), phyRegBk[interfaceId][busCnt][1]));
CHECK_STATUS(mvHwsDdr3TipBUSWrite(devNum, ACCESS_TYPE_UNICAST, interfaceId, ACCESS_TYPE_UNICAST, busCnt, DDR_PHY_DATA, READ_CENTRALIZATION_PHY_REG + (effective_cs * CS_REGISTER_ADDR_OFFSET), phyRegBk[interfaceId][busCnt][2]));
}
}
}
return GT_OK;
}
GT_STATUS ddr3TipTrainingIpTest
(
GT_U32 devNum,
MV_HWS_TRAINING_RESULT resultType,
MV_HWS_SearchDirection searchDir,
MV_HWS_DIRECTION direction,
MV_HWS_EdgeCompare edge,
GT_U32 initVal1,
GT_U32 initVal2,
GT_U32 numOfItertaions,
GT_U32 startPattern,
GT_U32 endPattern
)
{
GT_U32 pattern, interfaceId, pupId;
MV_HWS_TrainingIpStatus trainStatus[MAX_INTERFACE_NUM];
GT_U32 *pRes = NULL;
GT_U32 searchState = 0;
GT_U8 octetsPerInterfaceNum = (GT_U8)ddr3TipDevAttrGet(devNum, MV_ATTR_OCTET_PER_INTERFACE);
ddr3TipLoadPhyValues(GT_TRUE);
for(pattern = startPattern; pattern <= endPattern; pattern++)
{
for(searchState = 0 ; searchState < MV_HWS_SearchDirLimit ; searchState++)
{
ddr3TipIpTrainingWrapper(devNum, ACCESS_TYPE_MULTICAST, 0, ACCESS_TYPE_MULTICAST,
0, resultType, MV_HWS_ControlElement_ADLL,
searchDir, direction, 0xFFF, initVal1, initVal2, numOfItertaions,
pattern, edge, CS_SINGLE, PARAM_NOT_CARE, trainStatus);
for(interfaceId = 0; interfaceId <= MAX_INTERFACE_NUM-1; interfaceId++)
{
VALIDATE_IF_ACTIVE(topologyMap->interfaceActiveMask, interfaceId)
for(pupId = 0; pupId < octetsPerInterfaceNum ; pupId++)
{
VALIDATE_BUS_ACTIVE(topologyMap->activeBusMask, pupId)
CHECK_STATUS(ddr3TipReadTrainingResult(devNum, interfaceId, ACCESS_TYPE_UNICAST,
pupId, ALL_BITS_PER_PUP, searchState, direction,
resultType, TrainingLoadOperation_UNLOAD,
CS_SINGLE, &pRes , GT_TRUE, 0, GT_FALSE));
if (resultType == RESULT_PER_BYTE)
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_INFO, ("searchState %d interfaceId %d pupId %d 0x%x\n",searchState, interfaceId, pupId, pRes[0]));
}
else
{
DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_INFO, ("searchState %d interfaceId %d pupId %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",searchState, interfaceId, pupId, pRes[0],pRes[1],pRes[2],pRes[3],pRes[4],pRes[5],pRes[6],pRes[7]));
}
}
}/*interface*/
}/*search*/
}/*pattern*/
ddr3TipLoadPhyValues(GT_FALSE);
return GT_OK;
}
/********************Get patterns structures API*******************************/
PatternInfo* ddr3TipGetPatternTable()
{
if( DDR3_IS_16BIT_DRAM_MODE(topologyMap->activeBusMask) == GT_FALSE)
return patternTable_32;
else
return patternTable_16;
}
GT_U16 *ddr3TipGetMaskResultsDqReg()
{
if(DDR3_IS_ECC_PUP3_MODE(topologyMap->activeBusMask))
return maskResultsDqRegMapPup3ECC;
else
return maskResultsDqRegMap;
}
GT_U16 *ddr3TipGetMaskResultsPupRegMap()
{
if(DDR3_IS_ECC_PUP3_MODE(topologyMap->activeBusMask))
return maskResultsPupRegMapPup3ECC;
else
return maskResultsPupRegMap;
}