/* SPDX-License-Identifier: BSD-3-Clause */ //----------------------------------------------------------------------------- // Include files //----------------------------------------------------------------------------- #include "dramc_common.h" #include "dramc_int_global.h" #include "x_hal_io.h" #include "sv_c_data_traffic.h" #if (FOR_DV_SIMULATION_USED == 0) #include "dramc_top.h" #endif #define BITMAP_BITS_MAX 128 #define MAX_CLK_PI_DELAY 31 #define PASS_RANGE_NA 0x7fff #define DIE_NUM_MAX 1 static U8 fgwrlevel_done = 0; #if __ETT__ U8 gETT_WHILE_1_flag = 1; #endif //#define CBT_NEW_PAT_DEBUG U8 u1MR01Value[FSP_MAX]; U8 u1MR02Value[FSP_MAX]; U8 u1MR03Value[FSP_MAX]; U8 u1MR11Value[FSP_MAX]; U8 u1MR18Value[FSP_MAX]; U8 u1MR19Value[FSP_MAX]; U8 u1MR20Value[FSP_MAX]; U8 u1MR21Value[FSP_MAX]; U8 u1MR22Value[FSP_MAX]; U8 u1MR51Value[FSP_MAX]; U8 u1MR04Value[RANK_MAX]; U8 u1MR13Value[RANK_MAX]; U8 u1MR26Value[RANK_MAX]; U8 u1MR30Value[RANK_MAX]; U8 u1MR12Value[CHANNEL_NUM][RANK_MAX][FSP_MAX]; U8 u1MR14Value[CHANNEL_NUM][RANK_MAX][FSP_MAX]; U16 gu2MR0_Value[RANK_MAX] = {0xffff, 0xffff}; #if PINMUX_AUTO_TEST_PER_BIT_RX S16 gFinalRXPerbitFirstPass[CHANNEL_NUM][DQ_DATA_WIDTH]; #endif #if PINMUX_AUTO_TEST_PER_BIT_TX S16 gFinalTXPerbitFirstPass[CHANNEL_NUM][DQ_DATA_WIDTH]; #endif #if PINMUX_AUTO_TEST_PER_BIT_CA S16 gFinalCAPerbitFirstPass[CHANNEL_NUM][RANK_MAX][CATRAINING_NUM_LP4]; #endif #ifdef FOR_HQA_TEST_USED U16 gFinalCBTVrefCA[CHANNEL_NUM][RANK_MAX]; U16 gFinalCBTCA[CHANNEL_NUM][RANK_MAX][10]; U16 gFinalRXPerbitWin[CHANNEL_NUM][RANK_MAX][DQ_DATA_WIDTH]; U16 gFinalTXPerbitWin[CHANNEL_NUM][RANK_MAX][DQ_DATA_WIDTH]; U16 gFinalTXPerbitWin_min_max[CHANNEL_NUM][RANK_MAX]; U16 gFinalTXPerbitWin_min_margin[CHANNEL_NUM][RANK_MAX]; U16 gFinalTXPerbitWin_min_margin_bit[CHANNEL_NUM][RANK_MAX]; S8 gFinalClkDuty[CHANNEL_NUM]; U32 gFinalClkDutyMinMax[CHANNEL_NUM][2]; S8 gFinalDQSDuty[CHANNEL_NUM][DQS_BYTE_NUMBER]; U32 gFinalDQSDutyMinMax[CHANNEL_NUM][DQS_BYTE_NUMBER][2]; #endif U8 gFinalCBTVrefDQ[CHANNEL_NUM][RANK_MAX]; U8 gFinalRXVrefDQ[CHANNEL_NUM][RANK_MAX][2]; U8 gFinalTXVrefDQ[CHANNEL_NUM][RANK_MAX]; #if defined(RELEASE) U8 gEye_Scan_color_flag = 0; U8 gCBT_EYE_Scan_flag = 0; U8 gCBT_EYE_Scan_only_higheset_freq_flag = 1; U8 gRX_EYE_Scan_flag = 0; U8 gRX_EYE_Scan_only_higheset_freq_flag = 1; U8 gTX_EYE_Scan_flag = 1; U8 gTX_EYE_Scan_only_higheset_freq_flag = 1; U8 gEye_Scan_unterm_highest_flag = 0; #elif (CFG_DRAM_LOG_TO_STORAGE) U8 gEye_Scan_color_flag = 0; U8 gCBT_EYE_Scan_flag = 0; U8 gCBT_EYE_Scan_only_higheset_freq_flag = 1; U8 gRX_EYE_Scan_flag = 1; U8 gRX_EYE_Scan_only_higheset_freq_flag = 1; U8 gTX_EYE_Scan_flag = 1; U8 gTX_EYE_Scan_only_higheset_freq_flag = 1; U8 gEye_Scan_unterm_highest_flag = 0; #else U8 gEye_Scan_color_flag = 1; U8 gCBT_EYE_Scan_flag = 0; U8 gCBT_EYE_Scan_only_higheset_freq_flag = 1; U8 gRX_EYE_Scan_flag = 0; U8 gRX_EYE_Scan_only_higheset_freq_flag = 1; U8 gTX_EYE_Scan_flag = 0; U8 gTX_EYE_Scan_only_higheset_freq_flag = 1; U8 gEye_Scan_unterm_highest_flag = 0; #endif #ifdef DEVIATION U8 gSetSpecificedVref_Enable[3]={0}; U8 gSetSpecificedVref_Type=0; U8 gSetSpecificedVref_All_ChRk[3]={0}; U8 gSetSpecificedVref_Channel[3]={0}; U8 gSetSpecificedVref_Rank[3]={0}; S8 gSetSpecificedVref_Vref_Offset[3]={0}; #endif #ifdef FOR_HQA_REPORT_USED #if CFG_DRAM_LOG_TO_STORAGE U8 gHQALog_flag = 1; #else U8 gHQALog_flag = 0; #endif U16 gHQALOG_RX_delay_cell_ps_075V = 0; U8 gHQALog_SLT_BIN[DRAM_DFS_SRAM_MAX] = {0}; #endif #if (TX_AUTO_K_SUPPORT && TX_AUTO_K_WORKAROUND) U32 u4DQM_MCK_RK1_backup; U32 u4DQM_UI_RK1_backup; U32 u4DQM_PI_RK1_backup[2]; U32 u4DQ_MCK_RK1_backup; U32 u4DQ_UI_RK1_backup; U32 u4DQ_PI_RK1_backup[2]; #endif #if SIMULATION_RX_DVS U8 u1DVS_increase[RANK_MAX][DQS_BYTE_NUMBER]; #endif //static U8 gu1DieNum[RANK_MAX]; static S32 CATrain_CmdDelay[CHANNEL_NUM][RANK_MAX]; static U32 CATrain_CsDelay[CHANNEL_NUM][RANK_MAX]; //static S8 iFirstCAPass[RANK_MAX][DIE_NUM_MAX][CATRAINING_NUM]; //static S8 iLastCAPass[RANK_MAX][DIE_NUM_MAX][CATRAINING_NUM]; static S32 wrlevel_dqs_final_delay[RANK_MAX][DQS_BYTE_NUMBER]; //static U16 u2rx_window_sum; U8 gFinalRXVrefDQForSpeedUp[CHANNEL_NUM][RANK_MAX][2][2] = {0}; U32 gDramcImpedanceResult[IMP_VREF_MAX][IMP_DRV_MAX] = {{0,0,0,0},{0,0,0,0},{0,0,0,0}}; S16 gu2RX_DQS_Duty_Offset[DQS_BYTE_NUMBER][2]; #define RX_DELAY_PRE_CAL 1 #if RX_DELAY_PRE_CAL S16 s2RxDelayPreCal=PASS_RANGE_NA; #endif #if MRW_CHECK_ONLY U16 u2MRRecord[CHANNEL_NUM][RANK_MAX][FSP_MAX][MR_NUM]; #endif #if MRW_CHECK_ONLY || MRW_BACKUP U8 gFSPWR_Flag[RANK_MAX]={FSP_0}; #endif #define IN_CBT (0) #define OUT_CBT (1) #if PRINT_CALIBRATION_SUMMARY static void vSetCalibrationResult(DRAMC_CTX_T *p, U8 ucCalType, U8 ucResult) { U32 *Pointer_CalExecute,*Pointer_CalResult; if (ucCalType == DRAM_CALIBRATION_SW_IMPEDANCE) { Pointer_CalExecute = &p->SWImpCalExecute; Pointer_CalResult = &p->SWImpCalResult; } else { Pointer_CalExecute = &p->aru4CalExecuteFlag[p->channel][p->rank]; Pointer_CalResult = &p->aru4CalResultFlag[p->channel][p->rank]; } if (ucResult == DRAM_FAIL) { *Pointer_CalExecute |= (1<FastKExecuteFlag[p->channel][p->rank]; Pointer_FastKResult = &p->FastKResultFlag[p->channel][p->rank]; if ((ucCalType==DRAM_CALIBRATION_TX_PERBIT)||(ucCalType==DRAM_CALIBRATION_DATLAT)||(ucCalType==DRAM_CALIBRATION_RX_PERBIT)) { DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_XTALK_PATTERN, 0, TE_NO_UI_SHIFT); CheckResult = DramcEngine2Run(p,TE_OP_WRITE_READ_CHECK , TEST_XTALK_PATTERN); DramcEngine2End(p); FastK_Check_flag=1; } else if (ucCalType==DRAM_CALIBRATION_RX_RDDQC) { DramcRxWinRDDQCInit(p); CheckResult = DramcRxWinRDDQCRun(p); DramcRxWinRDDQCEnd(p); FastK_Check_flag=1; } else if (ucCalType==DRAM_CALIBRATION_GATING) { DramcEngine2Init(p, 0x55000000, 0xaa000000 |0x23, TEST_AUDIO_PATTERN, 0, TE_NO_UI_SHIFT); DramPhyReset(p); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 1, MISC_STBCAL2_DQSG_CNT_RST); mcDELAY_US(1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0, MISC_STBCAL2_DQSG_CNT_RST); DramcEngine2Run(p, TE_OP_READ_CHECK, TEST_AUDIO_PATTERN); debug_cnt[0] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CAL_DQSG_CNT_B0)); debug_cnt[1] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CAL_DQSG_CNT_B1)); //mcSHOW_DBG_MSG((" 0x%X ",u4DebugCnt)) if (debug_cnt[0]==0x4646 && debug_cnt[1]==0x4646) CheckResult=0; DramcEngine2End(p); FastK_Check_flag=1; } if ((FastK_Check_flag==1)&&(CheckResult==0)) { //mcSHOW_DBG_MSG((" [FAST K CHECK]->PASS\n")) *Pointer_FastKResult &= (~(1<FAIL\n")) *Pointer_FastKResult |= (1<frequency)); //for(ucFreqIdx=0; ucFreqIdxfrequency)); for(ucCHIdx=0; ucCHIdxsupport_channel_num; ucCHIdx++) { for(ucRankIdx=0; ucRankIdxsupport_rank_num; ucRankIdx++) { u1CalibrationFail =0; ucCalExecute_All = p->aru4CalExecuteFlag[ucCHIdx][ucRankIdx]; ucCalResult_All = p->aru4CalResultFlag[ucCHIdx][ucRankIdx]; mcSHOW_DBG_MSG(("CH %d, Rank %d\n", ucCHIdx, ucRankIdx)); //mcSHOW_DBG_MSG(("[vPrintCalibrationResult] Channel = %d, Rank= %d, Freq.= %d, (ucCalExecute_All 0x%x, ucCalResult_All 0x%x)\n", ucCHIdx, ucRankIdx, ucFreqIdx, ucCalExecute_All, ucCalResult_All)); for(ucCalIdx =0; ucCalIdxSWImpCalExecute; ucCalResult = (U8)p->SWImpCalResult; } else { ucCalExecute = (U8)((ucCalExecute_All >>ucCalIdx) & 0x1); ucCalResult = (U8)((ucCalResult_All >>ucCalIdx) & 0x1); } #if PRINT_CALIBRATION_SUMMARY_DETAIL mcSHOW_DBG_MSG(("%s: ", szCalibStatusName[ucCalIdx])) if(ucCalExecute==1 && ucCalResult ==1) { u1CalibrationFail =1; mcSHOW_DBG_MSG(("%s\n", "@_@FAIL@_@")) #if defined(SLT) mcSHOW_ERR_MSG(("[dramc] DRAM_FATAL_ERR_FLAG = 0x00000001, line: %d\n",__LINE__)); while (1); #endif } else if (ucCalExecute==1 && ucCalResult ==0) { mcSHOW_DBG_MSG(("%s\n", "PASS")) } else if (ucCalExecute==0 && ucCalResult ==0) { mcSHOW_DBG_MSG(("%s\n", "FAST K")) } else { mcSHOW_DBG_MSG(("%s\n", "NO K")) } #else if(ucCalExecute==1 && ucCalResult ==1) { u1CalibrationFail =1; mcSHOW_DBG_MSG(("%s: %s\n", szCalibStatusName[ucCalIdx],"@_@FAIL@_@")) #if defined(SLT) mcSHOW_ERR_MSG(("[dramc] DRAM_FATAL_ERR_FLAG = 0x00000001, line: %d\n",__LINE__)); while (1); #endif } #endif } if(u1CalibrationFail ==0) { mcSHOW_DBG_MSG(("All Pass.\n")); } mcSHOW_DBG_MSG(("\n")); } } } } #endif #ifdef DEVIATION static void DeviationAddVrefOffset(U8 k_type, U16 *u2FinalRange, U16 *u2FinalVref, S8 Vref_Offset) { S16 temp_vref_value; if (k_type==Deviation_RX) { temp_vref_value = *u2FinalVref + Vref_Offset; if (temp_vref_value < 0) { *u2FinalVref = 0; } else if (temp_vref_value < RX_VREF_RANGE_END) { *u2FinalVref = temp_vref_value; } else { *u2FinalVref = RX_VREF_RANGE_END; } } else { temp_vref_value = (*u2FinalRange*30) + *u2FinalVref + Vref_Offset; if (temp_vref_value < 0) { *u2FinalRange = 0; *u2FinalVref = 0; } else if (temp_vref_value <=50) { *u2FinalRange = 0; *u2FinalVref = temp_vref_value; } else if (temp_vref_value < 81) { *u2FinalRange = 1; *u2FinalVref = temp_vref_value - 30; } else { *u2FinalRange = 1; *u2FinalVref = 50; } } } void SetDeviationVref(DRAMC_CTX_T *p) { U8 u1ChannelIdx, u1RankIdx; U16 deviation_Vref, deviation_Vref_Range; U16 temp_Vref; U8 backup_channel, backup_rank; backup_channel = vGetPHY2ChannelMapping(p); backup_rank = u1GetRank(p); mcSHOW_DBG_MSG2(("[SetDeviationVref]\n")); for(u1ChannelIdx=0; u1ChannelIdxsupport_channel_num; u1ChannelIdx++) { vSetPHY2ChannelMapping(p, u1ChannelIdx); for(u1RankIdx=0; u1RankIdxsupport_rank_num; u1RankIdx++) { vSetRank(p, u1RankIdx); if (gSetSpecificedVref_Enable[Deviation_CA]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[Deviation_CA] && p->rank==gSetSpecificedVref_Rank[Deviation_CA]) || gSetSpecificedVref_All_ChRk[Deviation_CA]==ENABLE)) { deviation_Vref = u1MR12Value[p->channel][p->rank][p->dram_fsp]& 0x3f; deviation_Vref_Range = (u1MR12Value[p->channel][p->rank][p->dram_fsp]>>6)&0x1; DeviationAddVrefOffset(Deviation_CA, &deviation_Vref_Range, &deviation_Vref, gSetSpecificedVref_Vref_Offset[Deviation_CA]); temp_Vref= ((deviation_Vref & 0x3f)|((deviation_Vref_Range & 0x1) <<6)); DramcModeRegWriteByRank(p, p->rank, 12, temp_Vref); u1MR12Value[p->channel][p->rank][p->dram_fsp]=temp_Vref; mcSHOW_DBG_MSG2(("CBT Channel%d, Rank%d, u1MR12Value = 0x%x\n", p->channel, p->rank, u1MR12Value[p->channel][p->rank][p->dram_fsp])); } if (gSetSpecificedVref_Enable[Deviation_TX]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[Deviation_TX] && p->rank==gSetSpecificedVref_Rank[Deviation_TX]) || gSetSpecificedVref_All_ChRk[Deviation_TX]==ENABLE)) { deviation_Vref = u1MR14Value[p->channel][p->rank][p->dram_fsp]& 0x3f; deviation_Vref_Range = (u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&0x1; DeviationAddVrefOffset(Deviation_TX, &deviation_Vref_Range, &deviation_Vref, gSetSpecificedVref_Vref_Offset[Deviation_TX]); temp_Vref= ((deviation_Vref & 0x3f)|((deviation_Vref_Range & 0x1) <<6)); DramcModeRegWriteByRank(p, p->rank, 14, temp_Vref); u1MR14Value[p->channel][p->rank][p->dram_fsp]=temp_Vref; mcSHOW_DBG_MSG2(("TX Channel%d, Rank%d, u1MR14Value = 0x%x\n", p->channel, p->rank, u1MR14Value[p->channel][p->rank][p->dram_fsp])); } if (gSetSpecificedVref_Enable[Deviation_RX]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[Deviation_RX] && p->rank==gSetSpecificedVref_Rank[Deviation_RX]) || gSetSpecificedVref_All_ChRk[Deviation_RX]==ENABLE)) { deviation_Vref = gFinalRXVrefDQ[p->channel][p->rank][BYTE_0]; DeviationAddVrefOffset(Deviation_RX, NULL, &deviation_Vref, gSetSpecificedVref_Vref_Offset[Deviation_RX]); gFinalRXVrefDQ[p->channel][p->rank][BYTE_0] = deviation_Vref; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL), P_Fld(deviation_Vref, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B0) | P_Fld(deviation_Vref, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B0)); mcSHOW_DBG_MSG2(("RX Channel%d, Rank%d, RX Vref B0 = 0x%x\n", p->channel, p->rank, gFinalRXVrefDQ[p->channel][p->rank][BYTE_0])); deviation_Vref = gFinalRXVrefDQ[p->channel][p->rank][BYTE_1]; DeviationAddVrefOffset(Deviation_RX, NULL, &deviation_Vref, gSetSpecificedVref_Vref_Offset[Deviation_RX]); gFinalRXVrefDQ[p->channel][p->rank][BYTE_1] = deviation_Vref; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL), P_Fld(deviation_Vref, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B1) | P_Fld(deviation_Vref, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B1)); mcSHOW_DBG_MSG2(("RX Channel%d, Rank%d, RX Vref B1 = 0x%x\n", p->channel, p->rank, gFinalRXVrefDQ[p->channel][p->rank][BYTE_1])); } } } vSetRank(p, backup_rank); vSetPHY2ChannelMapping(p, backup_channel); } #endif void vInitGlobalVariablesByCondition(DRAMC_CTX_T *p) { U8 u1CHIdx, u1RankIdx, u1FSPIdx; u1MR01Value[FSP_0] = 0x26; u1MR01Value[FSP_1] = 0x56; u1MR03Value[FSP_0] = 0x31; u1MR03Value[FSP_1] = 0x31; #ifndef ENABLE_POST_PACKAGE_REPAIR u1MR03Value[FSP_0] |= 0x4; u1MR03Value[FSP_1] |= 0x4; #endif #if ENABLE_WRITE_POST_AMBLE_1_POINT_5_TCK u1MR03Value[FSP_1] |= 0x2; #endif u1MR04Value[RANK_0] = 0x3; u1MR04Value[RANK_1] = 0x3; u1MR21Value[FSP_0] = 0x0; u1MR21Value[FSP_1] = 0x0; u1MR51Value[FSP_0] = 0x0; u1MR51Value[FSP_1] = 0x0; for (u1FSPIdx = 0; u1FSPIdx < p->support_fsp_num; u1FSPIdx++) { u1MR02Value[u1FSPIdx] = 0x1a; } for (u1CHIdx = 0; u1CHIdx < CHANNEL_NUM; u1CHIdx++) for (u1RankIdx = 0; u1RankIdx < RANK_MAX; u1RankIdx++) for (u1FSPIdx = 0; u1FSPIdx < p->support_fsp_num; u1FSPIdx++) { u1MR14Value[u1CHIdx][u1RankIdx][u1FSPIdx] = (u1FSPIdx == FSP_0)? 0x5d: 0x18; #if FSP1_CLKCA_TERM u1MR12Value[u1CHIdx][u1RankIdx][u1FSPIdx] = (u1FSPIdx == FSP_0)? 0x5d: 0x1b; #else u1MR12Value[u1CHIdx][u1RankIdx][u1FSPIdx] = 0x5d; #endif #if MRW_CHECK_ONLY for (u1MRIdx = 0; u1MRIdx < MR_NUM; u1MRIdx++) u2MRRecord[u1CHIdx][u1RankIdx][u1FSPIdx][u1MRIdx] = 0xffff; #endif } memset(gu2RX_DQS_Duty_Offset, 0, sizeof(gu2RX_DQS_Duty_Offset)); } const U8 uiLPDDR4_CA_DRAM_Pinmux[PINMUX_MAX][CHANNEL_NUM][6] = { { { 3, 1, 0, 5, 7, 4 }, #if (CHANNEL_NUM>1) { 3, 2, 4, 0, 5, 1 }, #endif #if (CHANNEL_NUM>2) { 3, 1, 0, 5, 7, 4 }, { 3, 2, 4, 0, 5, 1 }, #endif }, { { 5, 2, 1, 3, 4, 0 }, #if (CHANNEL_NUM>1) { 0, 2, 1, 3, 4, 5 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 4, 5 }, { 0, 1, 2, 3, 4, 5 }, #endif }, { { 5, 4, 3, 2, 1, 0 }, #if (CHANNEL_NUM>1) { 4, 5, 2, 0, 3, 1 }, #endif #if (CHANNEL_NUM>2) { 5, 4, 0, 2, 1, 3 }, { 3, 5, 2, 4, 0, 1 }, #endif }, { { 3, 0, 2, 4, 1, 5 }, #if (CHANNEL_NUM>1) { 4, 1, 0, 2, 3, 5 }, #endif #if (CHANNEL_NUM>2) { 5, 0, 4, 3, 1, 2 }, { 2, 5, 3, 0, 4, 1 }, #endif }, }; const U8 uiLPDDR4_O1_DRAM_Pinmux[PINMUX_MAX][CHANNEL_NUM][16] = { { { 0, 1, 2, 3, 5, 7, 6, 4, 9, 8, 13, 15, 10, 14, 11, 12 }, #if (CHANNEL_NUM>1) { 0, 1, 5, 4, 3, 7, 6, 2, 9, 8, 13, 14, 10, 15, 11, 12 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 5, 7, 6, 4, 9, 8, 13, 15, 10, 14, 11, 12 }, { 0, 1, 5, 4, 3, 7, 6, 2, 9, 8, 13, 14, 10, 15, 11, 12 }, #endif }, { { 0, 1, 4, 3, 2, 5, 7, 6, 9, 8, 10, 11, 14, 13, 15, 12 }, #if (CHANNEL_NUM>1) { 0, 1, 2, 4, 5, 3, 7, 6, 8, 9, 10, 11, 15, 14, 13, 12 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, #endif }, { { 0, 1, 3, 6, 4, 7, 2, 5, 8, 9, 10, 13, 11, 12, 15, 14 }, #if (CHANNEL_NUM>1) { 0, 1, 4, 7, 3, 5, 6, 2, 9, 8, 10, 12, 11, 14, 13, 15 }, #endif #if (CHANNEL_NUM>2) { 1, 0, 3, 2, 4, 7, 6, 5, 8, 9, 10, 14, 11, 15, 13, 12 }, { 0, 1, 4, 7, 3, 5, 6, 2, 9, 8, 10, 12, 11, 14, 13, 15 }, #endif }, { { 9, 8, 11, 10, 14, 15, 13, 12, 0, 1, 7, 6, 4, 5, 2, 3 }, #if (CHANNEL_NUM>1) { 8, 9, 11, 10, 12, 14, 13, 15, 1, 0, 5, 6, 3, 2, 7, 4 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 7, 6, 4, 5, 2, 3, 9, 8, 11, 10, 14, 15, 13, 12 }, { 1, 0, 5, 6, 3, 2, 7, 4, 8, 9, 11, 10, 12, 14, 13, 15 }, #endif }, }; #if (CA_PER_BIT_DELAY_CELL || PINMUX_AUTO_TEST_PER_BIT_CA) U8 uiLPDDR4_CA_Mapping_POP[CHANNEL_NUM][6] = { { 2, 1, 0, 5, 3, 4 }, #if (CHANNEL_NUM>1) { 3, 5, 1, 0, 2, 4 }, #endif #if (CHANNEL_NUM>2) { 2, 1, 0, 5, 3, 4 }, { 3, 5, 1, 0, 2, 4 }, #endif }; #endif U8 uiLPDDR4_O1_Mapping_POP[CHANNEL_NUM][16] = { { 0, 1, 2, 3, 5, 7, 6, 4, 9, 8, 13, 15, 10, 14, 11, 12 }, #if (CHANNEL_NUM>1) { 0, 1, 5, 4, 3, 7, 6, 2, 9, 8, 13, 14, 10, 15, 11, 12 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 5, 7, 6, 4, 9, 8, 13, 15, 10, 14, 11, 12 }, { 0, 1, 5, 4, 3, 7, 6, 2, 9, 8, 13, 14, 10, 15, 11, 12 }, #endif }; #ifdef IMPEDANCE_TRACKING_ENABLE static void ImpedanceTracking_DisImpHw_Setting(DRAMC_CTX_T *p, U8 u1DisImpHw) { vIO32WriteFldMulti(DDRPHY_REG_MISC_SHU_IMPEDAMCE_UPD_DIS1, P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_ODTN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DRVN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DRVP_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_ODTN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_DRVN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_DRVP_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQ_ODTN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQ_DRVN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQ_DRVP_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQS_ODTN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQS_DRVN_UPD_DIS) | P_Fld(u1DisImpHw, MISC_SHU_IMPEDAMCE_UPD_DIS1_DQS_DRVP_UPD_DIS) | P_Fld(1, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_DRVP_UPD_DIS) | P_Fld(1, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_DRVN_UPD_DIS) | P_Fld(1, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_ODTN_UPD_DIS)); #if (fcFOR_CHIP_ID == fc8195) if (p->DRAMPinmux == PINMUX_DSC){ vIO32WriteFldAlign(DDRPHY_REG_MISC_SHU_IMPEDAMCE_UPD_DIS1, 1, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_ODTN_UPD_DIS); }else{ vIO32WriteFldAlign(DDRPHY_REG_MISC_SHU_IMPEDAMCE_UPD_DIS1, 0, MISC_SHU_IMPEDAMCE_UPD_DIS1_WCK_ODTN_UPD_DIS); } #endif vIO32WriteFldAlign(DDRPHY_REG_SHU_MISC_IMPCAL1, (u1DisImpHw? 0x0:0x40), SHU_MISC_IMPCAL1_IMPCALCNT); vIO32WriteFldMulti(DDRPHY_REG_SHU_MISC_DRVING1, P_Fld(u1DisImpHw, SHU_MISC_DRVING1_DIS_IMPCAL_HW) | P_Fld(u1DisImpHw, SHU_MISC_DRVING1_DIS_IMP_ODTN_TRACK)); vIO32WriteFldAlign(DDRPHY_REG_SHU_MISC_DRVING2, u1DisImpHw, SHU_MISC_DRVING2_DIS_IMPCAL_ODT_EN); vIO32WriteFldAlign(DDRPHY_REG_SHU_CA_CMD12, u1DisImpHw, SHU_CA_CMD12_RG_RIMP_UNTERM_EN); } #endif void vBeforeCalibration(DRAMC_CTX_T *p) { BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; #if SIMULATION_RX_DVS || ENABLE_RX_TRACKING DramcRxInputDelayTrackingInit_byFreq(p); #endif DramcHWGatingOnOff(p, 0); CKEFixOnOff(p, TO_ALL_RANK, CKE_FIXON, TO_ALL_CHANNEL); #if ENABLE_TMRRI_NEW_MODE SetCKE2RankIndependent(p); #endif vIO32WriteFldAlign_All(DRAMC_REG_SHU_TX_SET0, 0x0, SHU_TX_SET0_DBIWR); #ifdef IMPEDANCE_TRACKING_ENABLE U8 u1DisImpHw; U32 u4TermFreq, u4WbrBackup; u4TermFreq = LP4_MRFSP_TERM_FREQ; u1DisImpHw = (p->frequency >= u4TermFreq)? 0: 1; u4WbrBackup = GetDramcBroadcast(); DramcBroadcastOnOff(DRAMC_BROADCAST_ON); ImpedanceTracking_DisImpHw_Setting(p, u1DisImpHw); DramcBroadcastOnOff(u4WbrBackup); #endif vIO32WriteFldMulti_All(DDRPHY_REG_MISC_CLK_CTRL, P_Fld(0, MISC_CLK_CTRL_DVFS_CLK_MEM_SEL) | P_Fld(0, MISC_CLK_CTRL_DVFS_MEM_CK_MUX_UPDATE_EN)); vIO32WriteFldMulti_All(DRAMC_REG_SHU_ZQ_SET0, P_Fld(0x1ff, SHU_ZQ_SET0_ZQCSCNT) | P_Fld(0x1b, SHU_ZQ_SET0_TZQLAT)); if (p->support_channel_num == CHANNEL_SINGLE) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_ZQ_SET0), P_Fld(0, ZQ_SET0_ZQCSDUAL) | P_Fld(0x0, ZQ_SET0_ZQCSMASK)); } else if (p->support_channel_num == CHANNEL_DUAL) { #ifdef ZQCS_ENABLE_LP4 vIO32WriteFldMulti_All(DRAMC_REG_ZQ_SET0, P_Fld(1, ZQ_SET0_ZQCSDUAL) | P_Fld(0, ZQ_SET0_ZQCSMASK_OPT) | P_Fld(0, ZQ_SET0_ZQMASK_CGAR) | P_Fld(0, ZQ_SET0_ZQCS_MASK_SEL_CGAR)); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_A << POS_BANK_NUM), 1, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + SHIFT_TO_CHB_ADDR, 0, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign_All(DRAMC_REG_ZQ_SET0, 0, ZQ_SET0_ZQCS_MASK_SEL); #endif } #if (CHANNEL_NUM > 2) else if (p->support_channel_num == CHANNEL_FOURTH) { #ifdef ZQCS_ENABLE_LP4 vIO32WriteFldMulti_All(DRAMC_REG_ZQ_SET0, P_Fld(1, ZQ_SET0_ZQCSDUAL) | P_Fld(0, ZQ_SET0_ZQCALL) | P_Fld(0, ZQ_SET0_ZQ_SRF_OPT) | P_Fld(0, ZQ_SET0_ZQCSMASK_OPT) | P_Fld(0, ZQ_SET0_ZQMASK_CGAR) | P_Fld(0, ZQ_SET0_ZQCS_MASK_SEL_CGAR)); #if fcFOR_CHIP_ID == fcPetrus vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_A << POS_BANK_NUM), 1, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_B << POS_BANK_NUM), 0, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_C << POS_BANK_NUM), 0, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_D << POS_BANK_NUM), 1, ZQ_SET0_ZQCSMASK); #elif (fcFOR_CHIP_ID == fc8195) vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_A << POS_BANK_NUM), 1, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_B << POS_BANK_NUM), 0, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_C << POS_BANK_NUM), 1, ZQ_SET0_ZQCSMASK); vIO32WriteFldAlign(DRAMC_REG_ZQ_SET0 + (CHANNEL_D << POS_BANK_NUM), 0, ZQ_SET0_ZQCSMASK); #endif vIO32WriteFldAlign_All(DRAMC_REG_ZQ_SET0, 0, ZQ_SET0_ZQCS_MASK_SEL); #endif } #endif vIO32WriteFldAlign_All(DDRPHY_REG_SHU_B0_DQ2, 0, SHU_B0_DQ2_RG_ARPI_OFFSET_LAT_EN_B0); if (!isLP4_DSC) vIO32WriteFldAlign_All(DDRPHY_REG_SHU_B1_DQ2, 0, SHU_B1_DQ2_RG_ARPI_OFFSET_LAT_EN_B1); else vIO32WriteFldAlign_All(DDRPHY_REG_SHU_CA_CMD2, 0, SHU_CA_CMD2_RG_ARPI_OFFSET_LAT_EN_CA); #if ENABLE_PA_IMPRO_FOR_TX_AUTOK vIO32WriteFldAlign_All(DRAMC_REG_DCM_SUB_CTRL, 0x0, DCM_SUB_CTRL_SUBCLK_CTRL_TX_AUTOK); #endif #if ENABLE_PA_IMPRO_FOR_TX_TRACKING vIO32WriteFldAlign_All(DRAMC_REG_DCM_SUB_CTRL, 0, DCM_SUB_CTRL_SUBCLK_CTRL_TX_TRACKING); #endif vIO32WriteFldAlign_All(DRAMC_REG_DQSOSCR, 0x1, DQSOSCR_DQSOSCRDIS); vIO32WriteFldAlign_All(DRAMC_REG_REFCTRL0, 0x1, REFCTRL0_REFDIS); vIO32WriteFldAlign_All(DRAMC_REG_SHU_MATYPE, u1MaType, SHU_MATYPE_MATYPE); TX_Path_Algorithm(p); } void vAfterCalibration(DRAMC_CTX_T *p) { #if ENABLE_READ_DBI EnableDRAMModeRegReadDBIAfterCalibration(p); #endif #if ENABLE_WRITE_DBI EnableDRAMModeRegWriteDBIAfterCalibration(p); #endif SetMr13VrcgToNormalOperation(p); CKEFixOnOff(p, TO_ALL_RANK, CKE_DYNAMIC, TO_ALL_CHANNEL); vIO32WriteFldAlign_All(DRAMC_REG_DUMMY_RD, p->support_rank_num, DUMMY_RD_RANK_NUM); #if ENABLE_PER_BANK_REFRESH DramcSetPerBankRefreshMode(p); #endif #if FOR_DV_SIMULATION_USED == 1 cal_sv_rand_args_t *psra = get_psra(); if (psra) { u1MR03Value[p->dram_fsp] = psra->mr3_value; } #endif vIO32WriteFldAlign_All(DDRPHY_REG_MISC_CG_CTRL7, 0, MISC_CG_CTRL7_CK_BFE_DCM_EN); vIO32WriteFldAlign_All(DRAMC_REG_TEST2_A4, 4, TEST2_A4_TESTAGENTRKSEL); vIO32WriteFldAlign_All(DRAMC_REG_TEST2_A2, 0x20, TEST2_A2_TEST2_OFF); vIO32WriteFldAlign_All(DDRPHY_REG_MISC_DUTYSCAN1, 0, MISC_DUTYSCAN1_DQSERRCNT_DIS); vIO32WriteFldAlign_All(DDRPHY_REG_MISC_CTRL1, 0, MISC_CTRL1_R_DMSTBENCMP_RK_OPT); } static void O1PathOnOff(DRAMC_CTX_T *p, U8 u1OnOff) { BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; #if 0 const U32 u4O1RegBackupAddress[] = { (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ5)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ5)) }; #endif U8 u1VrefSel; if (u1OnOff == ON) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_VREF), 1, SHU_B0_VREF_RG_RX_ARDQ_VREF_UNTERM_EN_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_VREF), 1, SHU_B1_VREF_RG_RX_ARDQ_VREF_UNTERM_EN_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_VREF), 1, SHU_CA_VREF_RG_RX_ARCA_VREF_UNTERM_EN_CA); u1VrefSel = 0x37; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL), P_Fld(u1VrefSel, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B0) | P_Fld(u1VrefSel, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL), P_Fld(u1VrefSel, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B1) | P_Fld(u1VrefSel, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_PHY_VREF_SEL), P_Fld(u1VrefSel, SHU_CA_PHY_VREF_SEL_RG_RX_ARCA_VREF_SEL_LB) | P_Fld(u1VrefSel, SHU_CA_PHY_VREF_SEL_RG_RX_ARCA_VREF_SEL_UB)); } } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), u1OnOff, B0_DQ6_RG_RX_ARDQ_O1_SEL_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6), u1OnOff, B1_DQ6_RG_RX_ARDQ_O1_SEL_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD6), u1OnOff, CA_CMD6_RG_RX_ARCMD_O1_SEL); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ3), P_Fld(u1OnOff, B0_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B0) | P_Fld(u1OnOff, B0_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ3), P_Fld(u1OnOff, B1_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B1) | P_Fld(u1OnOff, B1_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD3), P_Fld(u1OnOff, CA_CMD3_RG_RX_ARCMD_IN_BUFF_EN) | P_Fld(u1OnOff, CA_CMD3_RG_RX_ARCLK_IN_BUFF_EN)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY3), u1OnOff, B0_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY3), u1OnOff, B1_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_PHY3), u1OnOff, CA_PHY3_RG_RX_ARCA_BUFF_EN_SEL_CA); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_IN_GATE_EN_CTRL),(u1OnOff << 1) | u1OnOff, MISC_RX_IN_GATE_EN_CTRL_FIX_IN_GATE_EN); mcDELAY_US(1); } static inline u8 get_ca_pi_per_ui(DRAMC_CTX_T *p) { return 32; } static int get_capi_max(DRAMC_CTX_T *p) { if (u1IsPhaseMode(p) == TRUE) { return 32; } return 64; } #if 0 static u8 get_autok_sweep_max_cnt(u8 lenpi, u8 respi) { u8 max; lenpi += 1; max = 64 / (1 << (respi & 0x3)); return lenpi > max? max: lenpi; } static int cbt_wlev_train_autok(DRAMC_CTX_T *p, ATUOK_MODE_T autok_mode, u8 initpi, u8 lenpi, u8 respi, u32 *cmp0_array, u32 *cmp1_array, u8 pin_num) { u8 sweep_max_cnt, i; u32 cnt, ready; cnt = TIME_OUT_CNT * 3; switch (autok_mode){ case AUTOK_CS: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_ARPICS_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0, CBT_WLEV_ATK_CTRL1_UICS_SW)); break; case AUTOK_CA: vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CLK) | P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CS)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_ARPICA_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0, CBT_WLEV_ATK_CTRL1_UICA_SW)); break; case AUTOK_DQS: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_ARPIDQS_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0, CBT_WLEV_ATK_CTRL1_UIDQS_SW)); break; } vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), (get_ca_pi_per_ui(p) == 64) ? 0x1 : 0x0, CBT_WLEV_ATK_CTRL1_CBT_ATK_CA1UI64PI); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), 0x3, CBT_WLEV_ATK_CTRL0_CBT_WLEV_ATK_INTV); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(lenpi, CBT_WLEV_ATK_CTRL0_CBT_WLEV_ATK_LENPI) | P_Fld(respi, CBT_WLEV_ATK_CTRL0_CBT_WLEV_ATK_RESPI) | P_Fld(initpi, CBT_WLEV_ATK_CTRL0_CBT_WLEV_ATK_INITPI)); switch (autok_mode){ case AUTOK_CS: if (p->new_cbt_mode) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_CATRAIN_ATKEN)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_CSTRAIN_ATKEN)); } break; case AUTOK_CA: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_CATRAIN_ATKEN)); break; case AUTOK_DQS: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_WLEV_ATKEN)); break; } do { ready = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_STATUS), CBT_WLEV_STATUS_CBT_WLEV_ATK_RESPONSE); cnt--; mcDELAY_US(1); } #if FOR_DV_SIMULATION_USED while (ready == 0); #else while ((ready == 0) && (cnt > 0)); #endif if (cnt == 0){ mcSHOW_ERR_MSG(("[cbt_autok] Resp fail (time out) for ")) switch (autok_mode) { case AUTOK_CS: mcSHOW_ERR_MSG(("CSTrain\n")); break; case AUTOK_CA: mcSHOW_ERR_MSG(("CATrain\n")); break; case AUTOK_DQS: mcSHOW_ERR_MSG(("DQSTrain\n")); break; } } sweep_max_cnt = get_autok_sweep_max_cnt(lenpi, respi); for (i = 0; i < pin_num; i++) { cmp0_array[i] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_RESULT0 + i * 8)); if (sweep_max_cnt > 32) { cmp1_array[i] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_RESULT1 + i * 8)); } else { cmp1_array[i] = 0xFFFFFFFF; } } for (i = 0; i < pin_num; i++) { mcSHOW_DBG_MSG4(("cmp0[%d]=0x%x, cmp1[%d]=0x%x\n", i, cmp0_array[i], i, cmp1_array[i])); } switch (autok_mode){ case AUTOK_CS: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_ARPICS_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0x3, CBT_WLEV_ATK_CTRL1_UICS_SW)); if (p->new_cbt_mode) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_CATRAIN_ATKEN)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_CSTRAIN_ATKEN)); } break; case AUTOK_CA: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_ARPICA_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0x7F, CBT_WLEV_ATK_CTRL1_UICA_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_CATRAIN_ATKEN)); break; case AUTOK_DQS: vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(1, CBT_WLEV_ATK_CTRL0_ARPIDQS_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL1), P_Fld(0xF, CBT_WLEV_ATK_CTRL1_UIDQS_SW)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_ATK_CTRL0), P_Fld(0, CBT_WLEV_ATK_CTRL0_WLEV_ATKEN)); break; } return 0; } #endif struct cbt_intv { DRAM_PLL_FREQ_SEL_T freq_sel; DIV_MODE_T divmode; u8 tcmdo1lat; u8 catrain_intv; u8 new_cbt_pat_intv; u8 wlev_dqspat_lat; }; static void set_cbt_intv_rg(DRAMC_CTX_T *p, struct cbt_intv *pintv) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL1), P_Fld(pintv->tcmdo1lat, CBT_WLEV_CTRL1_TCMDO1LAT) | P_Fld(pintv->catrain_intv, CBT_WLEV_CTRL1_CATRAIN_INTV)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL5), P_Fld(pintv->new_cbt_pat_intv, CBT_WLEV_CTRL5_NEW_CBT_PAT_INTV)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), P_Fld(pintv->wlev_dqspat_lat, CBT_WLEV_CTRL0_WLEV_DQSPAT_LAT)); } static struct cbt_intv *lookup_cbt_intv(struct cbt_intv *intv, int cnt, DRAM_PLL_FREQ_SEL_T fsel, DIV_MODE_T dmode) { struct cbt_intv *pintv = NULL; int i; for (i = 0; i < cnt; i++) { if (intv[i].freq_sel == fsel && intv[i].divmode == dmode) { pintv = &intv[i]; break; } } return pintv; } static void set_cbt_wlev_intv_lp4(DRAMC_CTX_T *p) { struct cbt_intv intv[] = { { LP4_DDR4266, DIV8_MODE, 17, 14, 19, 19, }, { LP4_DDR3733, DIV8_MODE, 16, 13, 18, 18, }, { LP4_DDR3200, DIV8_MODE, 14, 11, 16, 16, }, { LP4_DDR2667, DIV8_MODE, 13, 10, 15, 15, }, { LP4_DDR2400, DIV8_MODE, 12, 9, 14, 14, }, { LP4_DDR1866, DIV8_MODE, 11, 9, 13, 13, }, { LP4_DDR1600, DIV8_MODE, 10, 8, 12, 12, }, { LP4_DDR1200, DIV8_MODE, 9, 8, 11, 11, }, { LP4_DDR800, DIV8_MODE, 8, 8, 10, 10, }, { LP4_DDR1600, DIV4_MODE, 16, 13, 16, 16, }, { LP4_DDR1200, DIV4_MODE, 14, 13, 14, 14, }, { LP4_DDR800, DIV4_MODE, 12, 13, 12, 12, }, { LP4_DDR400, DIV4_MODE, 12, 13, 12, 12, }, }; struct cbt_intv *pintv; pintv = lookup_cbt_intv(intv, ARRAY_SIZE(intv), p->freq_sel, vGet_Div_Mode(p)); if (!pintv) { mcSHOW_ERR_MSG(("not found entry!\n")); return; } set_cbt_intv_rg(p, pintv); } static void set_cbt_wlev_intv(DRAMC_CTX_T *p) { set_cbt_wlev_intv_lp4(p); } #if SIMUILATION_CBT == 1 struct cbt_pinmux { u8 dram_dq_b0; u8 dram_dq_b1; u8 dram_dmi_b0; u8 dram_dmi_b1; u8 dram_dq7_b0; u8 dram_dq7_b1; }; static struct cbt_pinmux lp4_cp[CHANNEL_NUM] = { { .dram_dq_b0 = 0, .dram_dq_b1 = 1, .dram_dmi_b0 = 0, .dram_dmi_b1 = 1, }, #if (CHANNEL_NUM>1) { .dram_dq_b0 = 0, .dram_dq_b1 = 1, .dram_dmi_b0 = 0, .dram_dmi_b1 = 1, }, #endif #if (CHANNEL_NUM>2) { .dram_dq_b0 = 0, .dram_dq_b1 = 1, .dram_dmi_b0 = 0, .dram_dmi_b1 = 1, }, { .dram_dq_b0 = 0, .dram_dq_b1 = 1, .dram_dmi_b0 = 0, .dram_dmi_b1 = 1, }, #endif }; #if 0 static struct cbt_pinmux lp5_cp[CHANNEL_NUM] = { { .dram_dq_b0 = 1, .dram_dq_b1 = 0, .dram_dmi_b0 = 1, .dram_dmi_b1 = 0, .dram_dq7_b0 = 13, .dram_dq7_b1 = 5, }, #if (CHANNEL_NUM > 1) { .dram_dq_b0 = 1, .dram_dq_b1 = 0, .dram_dmi_b0 = 1, .dram_dmi_b1 = 0, .dram_dq7_b0 = 13, .dram_dq7_b1 = 5, }, #endif }; #endif static inline u8 is_byte_mode(DRAMC_CTX_T *p) { return p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1? 1: 0; } static void vSetDramMRCBTOnOff(DRAMC_CTX_T *p, U8 u1OnOff, U8 operating_fsp) { if (u1OnOff) { if (operating_fsp) { MRWriteFldMulti(p, 13, P_Fld(0, MR13_FSP_OP) | P_Fld(1, MR13_FSP_WR) | P_Fld(1, MR13_CBT), TO_MR); } else { MRWriteFldMulti(p, 13, P_Fld(1, MR13_FSP_OP) | P_Fld(0, MR13_FSP_WR) | P_Fld(1, MR13_CBT), TO_MR); } if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), P_Fld(1, CBT_WLEV_CTRL0_BYTEMODECBTEN) | P_Fld(1, CBT_WLEV_CTRL0_CBT_CMP_BYTEMODE)); } } else { if (operating_fsp) { MRWriteFldMulti(p, 13, P_Fld(0, MR13_FSP_OP) | P_Fld(1, MR13_FSP_WR) | P_Fld(0, MR13_CBT), TO_MR); } else { MRWriteFldMulti(p, 13, P_Fld(1, MR13_FSP_OP) | P_Fld(0, MR13_FSP_WR) | P_Fld(0, MR13_CBT), TO_MR); } } } static void CBTEntryLP4(DRAMC_CTX_T *p, U8 operating_fsp, U16 operation_frequency) { struct cbt_pinmux *cp = &lp4_cp[p->channel]; #if MR_CBT_SWITCH_FREQ if (p->dram_fsp == FSP_1) DramcModeRegInit_CATerm(p, 1); #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL), 0, MISC_STBCAL_DQSIENCG_NORMAL_EN); CKEFixOnOff(p, p->rank, CKE_FIXON, TO_ONE_CHANNEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0), u1GetRank(p), SWCMD_CTRL0_MRSRK); vSetDramMRCBTOnOff(p, ENABLE, operating_fsp); if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 1, CBT_WLEV_CTRL0_WRITE_LEVEL_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 0x1, CBT_WLEV_CTRL0_DQSOEAOEN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), (1 << cp->dram_dq_b0), CBT_WLEV_CTRL0_CBT_DQBYTE_OEAO_EN); } mcDELAY_US(1); CKEFixOnOff(p, p->rank, CKE_FIXOFF, TO_ONE_CHANNEL); (operating_fsp == FSP_1)? DramcMRWriteFldAlign(p, 13, 1, MR13_FSP_OP, JUST_TO_GLOBAL_VALUE): DramcMRWriteFldAlign(p, 13, 0, MR13_FSP_OP, JUST_TO_GLOBAL_VALUE); if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE) { //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0x3, PADCTRL_FIXDQIEN); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 1, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1); O1PathOnOff(p, ON); } if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 1, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0); O1PathOnOff(p, ON); } mcDELAY_US(1); } static void CBTExitLP4(DRAMC_CTX_T *p, U8 operating_fsp, U8 operation_frequency) { //U8 u1MROP; if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE || p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { CKEFixOnOff(p, p->rank, CKE_FIXON, TO_ONE_CHANNEL); mcDELAY_US(1); vSetDramMRCBTOnOff(p, DISABLE, operating_fsp); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 0, CBT_WLEV_CTRL0_WRITE_LEVEL_EN); } if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE) { //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 0, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1); O1PathOnOff(p, OFF); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0, PADCTRL_FIXDQIEN); } if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 0, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0); O1PathOnOff(p, OFF); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), P_Fld(0, CBT_WLEV_CTRL0_BYTEMODECBTEN) | P_Fld(0, CBT_WLEV_CTRL0_CBT_CMP_BYTEMODE)); } mcDELAY_US(1); } static u8 get_mck_ck_ratio(DRAMC_CTX_T *p) { u32 ratio; //u32 ui_max; ratio = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_LP5_CMD), SHU_LP5_CMD_LP5_CMD1TO2EN); mcSHOW_DBG_MSG5(("LP5 MCK:CK=%s\n", ratio == 1 ? "1:1" : "1:2")); return ratio; } static u8 get_cbtui_adjustable_maxvalue(DRAMC_CTX_T *p) { u8 ratio; ratio = (vGet_Div_Mode(p) == DIV4_MODE) ? 3 : 7; return ratio; } static inline u32 get_ca_mck(DRAMC_CTX_T *p) { u32 dly; dly = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA3)); return dly & 0x0FFFFFFFU; } static inline void put_ca_mck(DRAMC_CTX_T *p, u32 ca_mck) { u32 dly; dly = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA3)); dly &= 0xF0000000U; ca_mck &= 0x0FFFFFFFU; dly |= ca_mck; vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA3), dly); } static inline u32 get_ca_ui(DRAMC_CTX_T *p) { u32 dly; dly = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7)); return dly & 0x0FFFFFFFU; } static inline void put_ca_ui(DRAMC_CTX_T *p, u32 ca_ui) { u32 dly; dly = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7)); dly &= 0xF0000000U; ca_ui &= 0x0FFFFFFFU; dly |= ca_ui; vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), dly); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), ca_ui & 0xF, SHU_SELPH_CA5_DLY_CKE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA6), ca_ui & 0xF, SHU_SELPH_CA6_DLY_CKE1); } static void xlate_ca_mck_ui(DRAMC_CTX_T *p, u32 ui_delta, u32 mck_old, u32 ui_old, u32 *mck_new, u32 *ui_new) { u8 i; u32 mask, max; u32 bit_ui, bit_mck; u32 ui_tmp = 0, mck_tmp = 0; max = get_cbtui_adjustable_maxvalue(p); mask = max; for (i = 0; i < CATRAINING_NUM_LP5; i++) { bit_mck = 0; bit_ui = ((ui_old >> (i * 4)) & mask) + ui_delta; if (bit_ui > max) { bit_mck = bit_ui / (max + 1); bit_ui = bit_ui % (max + 1); } mck_tmp += (bit_mck << (i * 4)); ui_tmp += (bit_ui << (i * 4)); } if (ui_new) *ui_new = ui_tmp; if (mck_new) *mck_new = mck_old + mck_tmp; } static S16 adjust_ca_ui(DRAMC_CTX_T *p, U32 ca_mck, U32 ca_ui, S16 pi_dly) { S16 p2u; S16 ui, pi; U32 ui_new = 0, mck_new = 0; if (pi_dly < get_capi_max(p)) { return pi_dly; } p2u = get_ca_pi_per_ui(p); ui = pi_dly / p2u; pi = pi_dly % p2u; xlate_ca_mck_ui(p, ui, ca_mck, ca_ui, &mck_new, &ui_new); put_ca_ui(p, ui_new); put_ca_mck(p, mck_new); mcSHOW_DBG_MSG5(("mck_new: 0x%x, ui_new: 0x%x, pi:%d\n", mck_new, ui_new, pi)); return pi; } static inline u32 get_cs_mck(DRAMC_CTX_T *p) { if (p->rank == RANK_1) return u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA1), SHU_SELPH_CA1_TXDLY_CS1); else return u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA1), SHU_SELPH_CA1_TXDLY_CS); } static inline void put_cs_mck(DRAMC_CTX_T *p, u32 cs_ui) { if (p->rank == RANK_1) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA1), cs_ui, SHU_SELPH_CA1_TXDLY_CS1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA1), cs_ui, SHU_SELPH_CA1_TXDLY_CS); } static inline u32 get_cs_ui(DRAMC_CTX_T *p) { if (p->rank == RANK_1) return u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), SHU_SELPH_CA5_DLY_CS1); else return u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), SHU_SELPH_CA5_DLY_CS); } static inline void put_cs_ui(DRAMC_CTX_T *p, u32 cs_ui) { if (p->rank == RANK_1) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), cs_ui, SHU_SELPH_CA5_DLY_CS1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), cs_ui, SHU_SELPH_CA5_DLY_CS); } static S16 adjust_cs_ui(DRAMC_CTX_T *p, u32 cs_mck, u32 cs_ui, S16 pi_dly) { S16 p2u; S16 ui = 0, pi = 0; u8 ratio; u32 ui_max; u32 cs_bit_mask, cs_ui_tmp, cs_mck_tmp; if (pi_dly < get_capi_max(p)) { return pi_dly; } p2u = get_ca_pi_per_ui(p); ui = pi_dly / p2u; pi = pi_dly % p2u; ratio = get_mck_ck_ratio(p); if (ratio) { cs_bit_mask = 1; } else { cs_bit_mask = 3; } ui_max = get_cbtui_adjustable_maxvalue(p); cs_ui_tmp = (cs_ui & cs_bit_mask) + ui; cs_mck_tmp = 0; if (cs_ui_tmp > ui_max) { cs_mck_tmp = cs_ui_tmp / (ui_max + 1); cs_ui_tmp = cs_ui_tmp % (ui_max + 1); } cs_mck_tmp += cs_mck; put_cs_ui(p, cs_ui_tmp); put_cs_mck(p, cs_mck_tmp); mcSHOW_DBG_MSG5(("csmck:%d, csui: %d, pi:%d before\n", cs_mck, cs_ui, 0)); mcSHOW_DBG_MSG5(("csmck:%d, csui: %d, pi:%d after\n", cs_mck_tmp, cs_ui_tmp, pi)); return pi; } static u32 get_capi_step(DRAMC_CTX_T *p, int autok) { u32 step; #if FOR_DV_SIMULATION_USED step = 8; #else switch (p->freq_sel) { case LP5_DDR800: case LP5_DDR1200: case LP5_DDR1600: case LP5_DDR3733: step = 8; break; default: if (vGet_DDR_Loop_Mode(p) == SEMI_OPEN_LOOP_MODE) step = 8; else if (vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE) step = 16; else step = 1; break; } #endif if (step > 8 && autok) step = 8; return step; } void CmdOEOnOff(DRAMC_CTX_T *p, U8 u1OnOff, CMDOE_DIS_CHANNEL CmdOeDisChannelNUM) { BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; if (CmdOeDisChannelNUM ==CMDOE_DIS_TO_ALL_CHANNEL) { if (!isLP4_DSC) { vIO32WriteFldMulti_All(DDRPHY_REG_CA_CMD2, P_Fld(!u1OnOff, CA_CMD2_RG_TX_ARCMD_OE_DIS_CA) | P_Fld(u1OnOff, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA) | P_Fld(0xff, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA)); } else { vIO32WriteFldMulti_All(DDRPHY_REG_B1_DQ2, P_Fld(!u1OnOff, B1_DQ2_RG_TX_ARDQ_OE_DIS_B1) | P_Fld(u1OnOff, B1_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B1) | P_Fld(0xff, B1_DQ2_RG_TX_ARDQ_OE_TIE_EN_B1)); } } else { if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld(!u1OnOff, CA_CMD2_RG_TX_ARCMD_OE_DIS_CA) | P_Fld(u1OnOff, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA) | P_Fld(0xff, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld(!u1OnOff, B1_DQ2_RG_TX_ARDQ_OE_DIS_B1) | P_Fld(u1OnOff, B1_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B1) | P_Fld(0xff, B1_DQ2_RG_TX_ARDQ_OE_TIE_EN_B1)); } } } void CBTDelayCACLK(DRAMC_CTX_T *p, S32 iDelay) { if (iDelay < 0) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CMD) | P_Fld(-iDelay, SHU_R0_CA_CMD0_RG_ARPI_CLK) | P_Fld(-iDelay, SHU_R0_CA_CMD0_RG_ARPI_CS)); } /* else if (iDelay >= 64) { DramcCmdUIDelaySetting(p, 2); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), P_Fld(iDelay - 64, SHU_R0_CA_CMD0_RG_ARPI_CMD) | P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CLK) | P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CS)); } */ else { // DramcCmdUIDelaySetting(p, 0); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), P_Fld(iDelay, SHU_R0_CA_CMD0_RG_ARPI_CMD) | P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CLK) | P_Fld(0, SHU_R0_CA_CMD0_RG_ARPI_CS)); } } #if CBT_AUTO_K_SUPPORT #if 0 static int cbt_catrain_autok(DRAMC_CTX_T *p, u8 initpi, u8 steps, u8 respi, u32 *cmp0_array, u32 *cmp1_array, u8 n) { u8 lenpi; int res; if (steps == 0) steps = 1; lenpi = steps - 1; return cbt_wlev_train_autok(p, AUTOK_CA, initpi, lenpi, respi, cmp0_array, cmp1_array, n); } static int cbt_cstrain_autok(DRAMC_CTX_T *p, u8 initpi, u8 steps, u8 respi, u32 *cmp0, u32 *cmp1) { u8 lenpi; if (steps == 0) steps = 1; lenpi = steps - 1; return cbt_wlev_train_autok(p, AUTOK_CS, initpi, lenpi, respi, cmp0, cmp1, 1); } static int cbt_catrain_autok_next_window(DRAMC_CTX_T *p, u32 *bitmap, u8 start_pos, u8 initpi, u8 steps, u8 respi, PASS_WIN_DATA_T *pwin) { u8 lenpi; u8 sweep_max_cnt, win_left, win_right; int res; if (steps == 0) steps = 1; lenpi = steps - 1; sweep_max_cnt = get_autok_sweep_max_cnt(lenpi, respi); res = find_zero_window(bitmap, start_pos, sweep_max_cnt - 1, &win_left, &win_right); if (!res) { mcSHOW_DBG_MSG4(("can't find zero window.\n")); return 0; } else { mcSHOW_DBG_MSG4(("find max zero window [%d, %d]\n", win_left, win_right)); pwin->first_pass = initpi + win_left * (1 << respi); pwin->last_pass = initpi + win_right * (1 << respi); return 1; } } static void cbt_autok_maxwindow(DRAMC_CTX_T *p, u32 *bitmap, u8 uiDelay, u8 pi_step, u8 steps, u8 respi, S32 *iFirstPass, S32 *iLastPass) { int res; u8 start_pos; PASS_WIN_DATA_T win; start_pos = 0; while (1) { res = cbt_catrain_autok_next_window(p, bitmap, start_pos, uiDelay, steps, respi, &win); if (!res) { mcSHOW_DBG_MSG2(("no window @pi [%d, %d]\n", uiDelay + start_pos, uiDelay + pi_step - 1)); if ((*iFirstPass != PASS_RANGE_NA) && (*iLastPass == PASS_RANGE_NA)) { if ((uiDelay - *iFirstPass) < 5) { *iFirstPass = PASS_RANGE_NA; } else { *iLastPass = uiDelay - pi_step; } } break; } else { mcSHOW_DBG_MSG2(("find pi pass window [%d, %d] in [%d, %d]\n", win.first_pass, win.last_pass, uiDelay, uiDelay + pi_step - 1)); start_pos = win.last_pass - uiDelay + 1; if (*iFirstPass == PASS_RANGE_NA) { *iFirstPass = win.first_pass; } else if (*iLastPass != PASS_RANGE_NA) { if (*iLastPass + (1 << respi) >= win.first_pass) { *iLastPass = win.last_pass; } else { if (win.last_pass - win.first_pass >= *iLastPass - *iFirstPass) { *iFirstPass = win.first_pass; *iLastPass = win.last_pass; } } continue; } if (*iLastPass == PASS_RANGE_NA) { if ((win.last_pass - *iFirstPass) < 5) { *iFirstPass = PASS_RANGE_NA; continue; } *iLastPass = win.last_pass; } } } } #endif #endif static void CBTAdjustCS(DRAMC_CTX_T *p, int autok) { S32 iCSFinalDelay = 0;//iFirstCSPass = 0, iLastCSPass = 0, iCSCenter //U32 uiDelay, u4ValueReadBack, u4CSWinSize; U8 backup_rank, ii; //u32 pi_start, pi_end, pi_step; u32 pi_dly; u32 cs_ui, cs_mck; //u16 u2HalfCSWin; //u8 idx = 0; //u8 step_respi = AUTOK_RESPI_1; //u32 capi_max; backup_rank = u1GetRank(p); cs_ui = get_cs_ui(p); cs_mck = get_cs_mck(p); #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT) if (p->femmc_Ready == 1) { CATrain_CsDelay[p->channel][p->rank] = p->pSavetimeData->u1CBTCsDelay_Save[p->channel][p->rank]; } #endif if(backup_rank == RANK_1) { iCSFinalDelay = (CATrain_CsDelay[p->channel][RANK_0] + CATrain_CsDelay[p->channel][RANK_1]) >> 1; } else { iCSFinalDelay = CATrain_CsDelay[p->channel][p->rank]; } for (ii = RANK_0; ii <= backup_rank; ii++) { vSetRank(p, ii); pi_dly = adjust_cs_ui(p, cs_mck, cs_ui, iCSFinalDelay); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), pi_dly, SHU_R0_CA_CMD0_RG_ARPI_CS); #ifdef FOR_HQA_REPORT_USED if (gHQALog_flag == 1) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CS_Center", " ", 0, pi_dly, NULL); } #endif } vSetRank(p, backup_rank); //mcSHOW_DBG_MSG(("CS delay=%d (%d~%d)\n", iCSFinalDelay, iFirstCSPass, iLastCSPass)); //mcDUMP_REG_MSG(("CS delay=%d (%d~%d)\n", iCSFinalDelay, iFirstCSPass, iLastCSPass)); } #if CA_PER_BIT_DELAY_CELL static void CATrainingSetPerBitDelayCell(DRAMC_CTX_T *p, S16 *iCAFinalCenter, U8 ca_pin_num) { U8 *uiLPDDR_CA_Mapping = NULL; U8 u1CA; S8 iCA_PerBit_DelayLine[8] = {0}; { uiLPDDR_CA_Mapping = (U8 *)uiLPDDR4_CA_Mapping_POP[p->channel]; } for (u1CA = 0;u1CA < ca_pin_num;u1CA++) { iCA_PerBit_DelayLine[uiLPDDR_CA_Mapping[u1CA]] = iCAFinalCenter[u1CA]; } vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_TXDLY0), P_Fld(iCA_PerBit_DelayLine[0], SHU_R0_CA_TXDLY0_TX_ARCA0_DLY) | P_Fld(iCA_PerBit_DelayLine[1], SHU_R0_CA_TXDLY0_TX_ARCA1_DLY) | P_Fld(iCA_PerBit_DelayLine[2], SHU_R0_CA_TXDLY0_TX_ARCA2_DLY) | P_Fld(iCA_PerBit_DelayLine[3], SHU_R0_CA_TXDLY0_TX_ARCA3_DLY)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_TXDLY1), P_Fld(iCA_PerBit_DelayLine[4], SHU_R0_CA_TXDLY1_TX_ARCA4_DLY) | P_Fld(iCA_PerBit_DelayLine[5], SHU_R0_CA_TXDLY1_TX_ARCA5_DLY) | P_Fld(iCA_PerBit_DelayLine[6], SHU_R0_CA_TXDLY1_TX_ARCA6_DLY) | P_Fld(iCA_PerBit_DelayLine[7], SHU_R0_CA_TXDLY1_TX_ARCA7_DLY)); } #endif static void CBTSetCACLKResult(DRAMC_CTX_T *p, U32 u4MCK, U32 u4UI, U8 ca_pin_num) { S8 iFinalCACLK; U8 backup_rank, rank_i, uiCA; S16 iCAFinalCenter[CATRAINING_NUM]={0}; #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT) if (p->femmc_Ready == 1) { CATrain_CmdDelay[p->channel][p->rank] = p->pSavetimeData->s1CBTCmdDelay_Save[p->channel][p->rank]; vSetCalibrationResult(p, DRAM_CALIBRATION_CA_TRAIN, DRAM_FAST_K); #if CA_PER_BIT_DELAY_CELL for (uiCA = 0; uiCA < ca_pin_num; uiCA++) iCAFinalCenter[uiCA] = p->pSavetimeData->u1CBTCA_PerBit_DelayLine_Save[p->channel][p->rank][uiCA]; #endif } #endif iFinalCACLK = CATrain_CmdDelay[p->channel][p->rank]; mcSHOW_DBG_MSG(("\n[CBTSetCACLKResult] CA Dly = %d\n", iFinalCACLK)); iFinalCACLK = adjust_ca_ui(p, u4MCK, u4UI, iFinalCACLK); backup_rank = u1GetRank(p); for (rank_i = RANK_0; rank_i <= p->support_rank_num;rank_i++) { vSetRank(p, rank_i); CBTDelayCACLK(p, iFinalCACLK); #if CA_PER_BIT_DELAY_CELL CATrainingSetPerBitDelayCell(p, iCAFinalCenter, ca_pin_num); #endif } vSetRank(p, backup_rank); } static U8 GetCBTVrefPinMuxValue(DRAMC_CTX_T *p, U8 u1VrefRange, U8 u1VrefLevel) { U8 u2VrefBit, u2Vref_org; U16 u2Vref_new; if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) return ((u1VrefRange & 0x1) << 6) | (u1VrefLevel & 0x3f); u2Vref_org = ((u1VrefRange & 0x1) << 6) | (u1VrefLevel & 0x3f); u2Vref_new = 0; for (u2VrefBit = 0; u2VrefBit < 8; u2VrefBit++) { //mcSHOW_DBG_MSG(("=== u2VrefBit: %d, %d\n",u2VrefBit,uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit])); if (u2Vref_org & (1 << u2VrefBit)) { u2Vref_new |= (1 << uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit]); } } mcSHOW_DBG_MSG4(("=== u2Vref_new: 0x%x --> 0x%x\n", u2Vref_org, u2Vref_new)); if (lp4_cp[p->channel].dram_dq_b0) u2Vref_new >>= 8; return u2Vref_new; } static void CBTSetVrefLP4(DRAMC_CTX_T *p, U8 u1VrefRange, U8 u1VrefLevel, U8 operating_fsp, U8 stateFlag) { U32 fld; U8 u4DbgValue; U8 u1VrefValue_pinmux; struct cbt_pinmux *cp = &lp4_cp[p->channel]; if ((p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE) && (stateFlag == IN_CBT)) { u1VrefValue_pinmux = GetCBTVrefPinMuxValue(p, u1VrefRange, u1VrefLevel); #if !REDUCE_LOG_FOR_PRELOADER mcSHOW_DBG_MSG(("\nCH_%d, RK_%d, Range=%d, VrefValue_pinmux = 0x%x\n", p->channel, p->rank, u1VrefRange, u1VrefValue_pinmux)); #endif u1MR12Value[p->channel][p->rank][operating_fsp] = ((u1VrefRange & 0x1) << 6) | u1VrefLevel; fld = (cp->dram_dq_b0) ? CBT_WLEV_CTRL4_CBT_TXDQ_B1 : CBT_WLEV_CTRL4_CBT_TXDQ_B0; //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), ((u1VrefRange&0x1) <<6) | (u1VrefLevel & 0x3f), WRITE_LEV_DMVREFCA); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL4), u1VrefValue_pinmux, fld); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), (0x1 << cp->dram_dq_b0), CBT_WLEV_CTRL0_CBT_WLEV_DQS_SEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL3), 0xa, CBT_WLEV_CTRL3_DQSBX_G); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 1, CBT_WLEV_CTRL0_CBT_WLEV_DQS_TRIG); mcDELAY_US(1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 0, CBT_WLEV_CTRL0_CBT_WLEV_DQS_TRIG); } else { if (operating_fsp == FSP_1) { DramcMRWriteFldAlign(p, 13, 1, MR13_FSP_WR, TO_MR); } u4DbgValue = (((u1VrefRange & 0x1) << 6) | (u1VrefLevel & 0x3f)); u1MR12Value[p->channel][p->rank][operating_fsp] = u4DbgValue; mcSHOW_DBG_MSG5(("u4DbgValue = 0x%x\n", u4DbgValue)); DramcModeRegWriteByRank(p, p->rank, 12, u4DbgValue); } mcDELAY_US(1); } static void CBTEntryLP45(DRAMC_CTX_T *p, U8 u1FSP, U16 u2Freq) { { if(p->dram_fsp == FSP_1) { CmdOEOnOff(p, DISABLE, CMDOE_DIS_TO_ONE_CHANNEL); cbt_switch_freq(p, CBT_LOW_FREQ); CmdOEOnOff(p, ENABLE, CMDOE_DIS_TO_ONE_CHANNEL); } #if ENABLE_LP4Y_WA && LP4Y_BACKUP_SOLUTION CmdBusTrainingLP4YWA(p, DISABLE); #endif CBTEntryLP4(p, u1FSP, u2Freq); if(p->dram_fsp == FSP_1) { cbt_switch_freq(p, CBT_HIGH_FREQ); } } } static void CBTExitLP45(DRAMC_CTX_T *p, U8 u1FSP, U8 u2Freq, U8 stateFlag) { { if (stateFlag == OUT_CBT || p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { (p->dram_fsp == FSP_1)? cbt_switch_freq(p, CBT_LOW_FREQ): NULL; CBTExitLP4(p, u1FSP, u2Freq); #if ENABLE_LP4Y_WA && LP4Y_BACKUP_SOLUTION CmdBusTrainingLP4YWA(p, ENABLE); #endif } } } static void CBTSetVrefLP45(DRAMC_CTX_T *p, U8 u1VrefRange, U8 u1VrefLevel, U8 u1FSP, U16 u2Freq, U8 stateFlag) { { if (stateFlag == IN_CBT && p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) { (p->dram_fsp == FSP_1)? cbt_switch_freq(p, CBT_LOW_FREQ): NULL; CBTExitLP4(p, u1FSP, u2Freq); CBTSetVrefLP4(p, u1VrefRange, u1VrefLevel, u1FSP, stateFlag); CBTEntryLP4(p, u1FSP, u2Freq); if(p->dram_fsp == FSP_1) { cbt_switch_freq(p, CBT_HIGH_FREQ); } } else { CBTSetVrefLP4(p, u1VrefRange, u1VrefLevel, u1FSP, stateFlag); } } } static void CBTScanPI(DRAMC_CTX_T *p, S16 *s2PIStart, S16 *s2PIEnd, S16 *s2PIStep, int autok) { u16 p2u; p2u = get_ca_pi_per_ui(p); if (is_discrete_lpddr4()) *s2PIStart = -16; else *s2PIStart = 0; *s2PIEnd = p2u * 3 - 1; { #if !CBT_MOVE_CA_INSTEAD_OF_CLK if (vGet_DDR_Loop_Mode(p) == SEMI_OPEN_LOOP_MODE) { *s2PIStart = -24; } else if (vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE) { *s2PIStart = -16; } else { *s2PIStart = -MAX_CLK_PI_DELAY; } *s2PIEnd = p2u * 2 - 1; #endif } *s2PIStep = get_capi_step(p, autok); } DRAM_STATUS_T CmdBusTrainingLP45(DRAMC_CTX_T *p, int autok, U8 K_Type) { U8 u1FinalVref, u1FinalRange=0; //u1VrefLevel, u1VrefRange, //U32 u1vrefidx, u1BitIdx, ii; //U8 u1VRangeStart, u1VRangeEnd; //U8 u1VrefStart, u1VrefEnd, u1VrefStep; //U8 u1VrefScanStart, u1VrefScanEnd; //U8 u1CBTError_flag=0; //U32 u4CompareResult; //PASS_WIN_DATA_T FinalWinPerCA[CATRAINING_NUM] = {{0,0,0,0,0}}; //U32 uiCA, uiFinishCount, uiTemp; //S16 iDelay, pi_dly; //S32 iFirstPass_tmp[CATRAINING_NUM], iLastPass_tmp[CATRAINING_NUM]; //uiCAWinSum, U8 operating_fsp; U16 operation_frequency; //S32 iCA_PerBit_DelayLine[CATRAINING_NUM] = {0}, iCK_MIN = 1000 #if CA_PER_BIT_DELAY_CELL S16 iCAFinalCenter[CATRAINING_NUM] = {0}; //for CA_PER_BIT #endif U8 u1CBTEyeScanEnable=(K_Type==NORMAL_K ? DISABLE : ENABLE); U8 backup_MR12Value=0; S32 backup_CATrain_CmdDelay=0; U32 backup_CATrain_CsDelay=0; S32 backup_CATrain_ClkDelay=0; U32 backup_CATrain_CmdUIDelay=0; U32 backup_CATrain_CmdCKEUIDelay=0; U32 backup_CATrain_CmdCKE1UIDelay=0; U32 backup_CATrain_CmdMCKDelay=0; #if ENABLE_EYESCAN_GRAPH U8 EyeScan_index[CATRAINING_NUM]; #endif S16 pi_step; //, pi_step_bk; S16 pi_start, pi_end; u32 ca_ui; //, ca_ui_tmp u32 ca_mck; //Vca_mck_tmp, a_mck_default u8 ca_pin_num; u8 step_respi = AUTOK_RESPI_1; //u32 capi_max; U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL)), (DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ2)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL1)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL2)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL3)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL4)), (DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0)), (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_PHY_VREF_SEL)), }; CBTScanPI(p, &pi_start, &pi_end, &pi_step, autok); while (((1 << step_respi) < pi_step) && autok) step_respi++; #if MRW_CHECK_ONLY mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__)); #endif { u1FinalRange = u1MR12Value[p->channel][p->rank][p->dram_fsp] >> 6; u1FinalVref = u1MR12Value[p->channel][p->rank][p->dram_fsp] & 0x3f; ca_pin_num = CATRAINING_NUM_LP4; } #if ENABLE_EYESCAN_GRAPH if (u1CBTEyeScanEnable) { backup_MR12Value = u1MR12Value[p->channel][p->rank][p->dram_fsp]; backup_CATrain_CmdDelay = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), SHU_R0_CA_CMD0_RG_ARPI_CMD); backup_CATrain_CsDelay = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), SHU_R0_CA_CMD0_RG_ARPI_CS); backup_CATrain_ClkDelay = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), SHU_R0_CA_CMD0_RG_ARPI_CLK); backup_CATrain_CmdUIDelay = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7)); backup_CATrain_CmdCKEUIDelay = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), SHU_SELPH_CA5_DLY_CKE); backup_CATrain_CmdCKE1UIDelay = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA6), SHU_SELPH_CA6_DLY_CKE1); backup_CATrain_CmdMCKDelay = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA3)); for (u1vrefidx = 0; u1vrefidx < VREF_VOLTAGE_TABLE_NUM_LP5-1; u1vrefidx++) { for (uiCA = 0; uiCA < ca_pin_num; uiCA++) { for (ii = 0; ii < EYESCAN_BROKEN_NUM; ii++) { gEyeScan_Min[u1vrefidx][uiCA][ii] = EYESCAN_DATA_INVALID; gEyeScan_Max[u1vrefidx][uiCA][ii] = EYESCAN_DATA_INVALID; } } } } #endif //DUMP_REG_MSG(("\n[dumpRG] CmdBusTraining \n")); vPrintCalibrationBasicInfo(p); mcSHOW_DBG_MSG(("[CmdBusTrainingLP45] new_cbt_mode=%d, autok=%d\n", p->new_cbt_mode, autok)); mcSHOW_DBG_MSG2(("pi_start=%d, pi_end=%d, pi_step=%d\n", pi_start, pi_end, pi_step)); DramcBackupRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); if (u1CBTEyeScanEnable == DISABLE) { vSetCalibrationResult(p, DRAM_CALIBRATION_CA_TRAIN, DRAM_FAIL); #if CA_PER_BIT_DELAY_CELL CATrainingSetPerBitDelayCell(p, iCAFinalCenter, ca_pin_num); #endif } #if CBT_MOVE_CA_INSTEAD_OF_CLK if (u1IsLP4Family(p->dram_type)) { U8 u1CaPI = 0, u1CaUI = 0; u1CaUI = 1; u1CaPI = 0; DramcCmdUIDelaySetting(p, u1CaUI); CBTDelayCACLK(p, u1CaPI); } #endif ca_ui = get_ca_ui(p); ca_mck = get_ca_mck(p); u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0)); vAutoRefreshSwitch(p, DISABLE); //vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL1), // P_Fld(0x1F, CBT_WLEV_CTRL1_CATRAIN_INTV)); set_cbt_wlev_intv(p); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), p->rank, TX_SET0_TXRANK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 1, TX_SET0_TXRANKFIX); operating_fsp = p->dram_fsp; operation_frequency = p->frequency; vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), P_Fld(0, DRAMC_PD_CTRL_DCMEN2) | P_Fld(1, DRAMC_PD_CTRL_MIOCKCTRLOFF) | P_Fld(0, DRAMC_PD_CTRL_PHYCLKDYNGEN) | P_Fld(0, DRAMC_PD_CTRL_COMBCLKCTRL) | P_Fld(1, DRAMC_PD_CTRL_APHYCKCG_FIXOFF) | P_Fld(1, DRAMC_PD_CTRL_TCKFIXON)); CBTEntryLP45(p, operating_fsp, operation_frequency); #if PINMUX_AUTO_TEST_PER_BIT_CA CheckCADelayCell(p); #endif #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && (BYPASS_VREF_CAL || BYPASS_CBT)) if (p->femmc_Ready == 1) { u1FinalVref = p->pSavetimeData->u1CBTVref_Save[p->channel][p->rank]; } #endif if (u1CBTEyeScanEnable) { u1FinalVref = backup_MR12Value & 0x3f; u1FinalRange = (backup_MR12Value>>6) & 1; } mcSHOW_DBG_MSG(("\n[CmdBusTrainingLP45] Vref(ca) range %d: %d\n", u1FinalRange, u1FinalVref)); //DUMP_REG_MSG(("\n[CmdBusTrainingLP45] Vref(ca) range %d: %d\n", u1FinalRange, u1FinalVref)); #ifdef FOR_HQA_TEST_USED gFinalCBTVrefCA[p->channel][p->rank] = u1FinalVref; #endif CBTSetVrefLP45(p, u1FinalRange, u1FinalVref, operating_fsp, operation_frequency, IN_CBT); #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT) #if CBT_MOVE_CA_INSTEAD_OF_CLK DramcCmdUIDelaySetting(p, 0); ca_ui = get_ca_ui(p); #endif #endif put_ca_ui(p, ca_ui); if (u1CBTEyeScanEnable == DISABLE) { CBTSetCACLKResult(p, ca_mck, ca_ui, ca_pin_num); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_CA_CMD0), P_Fld(backup_CATrain_CmdDelay, SHU_R0_CA_CMD0_RG_ARPI_CMD) | P_Fld(backup_CATrain_ClkDelay, SHU_R0_CA_CMD0_RG_ARPI_CLK) | P_Fld(backup_CATrain_CsDelay, SHU_R0_CA_CMD0_RG_ARPI_CS)); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), backup_CATrain_CmdUIDelay); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA5), backup_CATrain_CmdCKEUIDelay, SHU_SELPH_CA5_DLY_CKE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA6), backup_CATrain_CmdCKE1UIDelay, SHU_SELPH_CA6_DLY_CKE1); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA3), backup_CATrain_CmdMCKDelay); } #if ENABLE_EYESCAN_GRAPH gEyeScan_CaliDelay[0] = CATrain_CmdDelay[p->channel][p->rank] -pi_start; #endif if (u1CBTEyeScanEnable == DISABLE) { CBTAdjustCS(p, autok); } CBTExitLP45(p, operating_fsp, operation_frequency, OUT_CBT); CBTSetVrefLP45(p, u1FinalRange, u1FinalVref, operating_fsp, operation_frequency, OUT_CBT); { if (p->dram_fsp == FSP_1) { #if MR_CBT_SWITCH_FREQ DramcModeRegInit_CATerm(p, 0); #else DramcMRWriteFldAlign(p, 13, 1, MR13_FSP_OP, TO_MR); #endif } } #if EYESCAN_LOG || defined(FOR_HQA_TEST_USED) gFinalCBTVrefDQ[p->channel][p->rank] = u1FinalVref; #endif mcSHOW_DBG_MSG4(("\n[CmdBusTrainingLP45] Done\n")); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 0, TX_SET0_TXRANK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 0, TX_SET0_TXRANKFIX); DramcRestoreRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); return DRAM_OK; } #endif /* SIMUILATION_CBT */ #define WRITE_LEVELING_MOVD_DQS 1 U8 u1MCK2UI_DivShift(DRAMC_CTX_T *p) { { if (vGet_Div_Mode(p) == DIV4_MODE) { return MCK_TO_4UI_SHIFT; } else { return MCK_TO_8UI_SHIFT; } } } static DRAM_STATUS_T ExecuteMoveDramCDelay(DRAMC_CTX_T *p, REG_TRANSFER_T ui_reg, REG_TRANSFER_T mck_reg, S8 iShiftUI) { S32 s4HighLevelDelay, s4DelaySum; U32 u4TmpUI, u4TmpMCK; U8 ucDataRateDivShift = 0; DRAM_STATUS_T MoveResult; ucDataRateDivShift = u1MCK2UI_DivShift(p); u4TmpUI = u4IO32ReadFldAlign(DRAMC_REG_ADDR(ui_reg.u4Addr), ui_reg.u4Fld) & (~(1 << ucDataRateDivShift)); u4TmpMCK = u4IO32ReadFldAlign(DRAMC_REG_ADDR(mck_reg.u4Addr), mck_reg.u4Fld); //mcSHOW_DBG_MSG(("Base: u4TmpMCK:%d, u4TmpUI: %d,\n", u4TmpMCK, u4TmpUI)); s4HighLevelDelay = (u4TmpMCK << ucDataRateDivShift) + u4TmpUI; s4DelaySum = (s4HighLevelDelay + iShiftUI); if (s4DelaySum < 0) { u4TmpUI = 0; u4TmpMCK = 0; MoveResult = DRAM_FAIL; } else { u4TmpMCK = s4DelaySum >> ucDataRateDivShift; u4TmpUI = s4DelaySum - (u4TmpMCK << ucDataRateDivShift); MoveResult = DRAM_OK; } vIO32WriteFldAlign(DRAMC_REG_ADDR(ui_reg.u4Addr), u4TmpUI, ui_reg.u4Fld); vIO32WriteFldAlign(DRAMC_REG_ADDR(mck_reg.u4Addr), u4TmpMCK, mck_reg.u4Fld); //mcSHOW_DBG_MSG(("[%d] Final ==> u4TmpMCK:%d, u4TmpUI: %d,\n", iShiftUI, u4TmpMCK, u4TmpUI)); return MoveResult; } static void _LoopAryToDelay(DRAMC_CTX_T *p, REG_TRANSFER_T *ui_reg, REG_TRANSFER_T *mck_reg, U8 u8RG_num, S8 iShiftUI, BYTES_T eByteIdx) { U8 idx = 0, step = 1; if (eByteIdx == BYTE_0) { idx = 0; step = 2; } else if (eByteIdx == BYTE_1) { idx = 1; step = 2; } for (; idx < u8RG_num; idx += step) { ExecuteMoveDramCDelay(p, ui_reg[idx], mck_reg[idx], iShiftUI); } } static void LP4_ShiftDQSUI(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { REG_TRANSFER_T TransferUIRegs[] = {{DRAMC_REG_SHU_SELPH_DQS1, SHU_SELPH_DQS1_DLY_DQS0}, {DRAMC_REG_SHU_SELPH_DQS1, SHU_SELPH_DQS1_DLY_DQS1}}; REG_TRANSFER_T TransferMCKRegs[] = {{DRAMC_REG_SHU_SELPH_DQS0, SHU_SELPH_DQS0_TXDLY_DQS0}, {DRAMC_REG_SHU_SELPH_DQS0, SHU_SELPH_DQS0_TXDLY_DQS1}}; _LoopAryToDelay(p, TransferUIRegs, TransferMCKRegs, sizeof(TransferUIRegs) / sizeof(REG_TRANSFER_T), iShiftUI, eByteIdx); } void LP4_ShiftDQS_OENUI(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { REG_TRANSFER_T TransferUIRegs[] = {{DRAMC_REG_SHU_SELPH_DQS1, SHU_SELPH_DQS1_DLY_OEN_DQS0}, {DRAMC_REG_SHU_SELPH_DQS1, SHU_SELPH_DQS1_DLY_OEN_DQS1}}; REG_TRANSFER_T TransferMCKRegs[] = {{DRAMC_REG_SHU_SELPH_DQS0, SHU_SELPH_DQS0_TXDLY_OEN_DQS0}, {DRAMC_REG_SHU_SELPH_DQS0, SHU_SELPH_DQS0_TXDLY_OEN_DQS1}}; _LoopAryToDelay(p, TransferUIRegs, TransferMCKRegs, sizeof(TransferUIRegs) / sizeof(REG_TRANSFER_T), iShiftUI, eByteIdx); } static void ShiftDQUI(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { REG_TRANSFER_T TransferUIRegs[] = {{DRAMC_REG_SHURK_SELPH_DQ3, SHURK_SELPH_DQ3_DLY_DQM0}, {DRAMC_REG_SHURK_SELPH_DQ3, SHURK_SELPH_DQ3_DLY_DQM1}, {DRAMC_REG_SHURK_SELPH_DQ2, SHURK_SELPH_DQ2_DLY_DQ0}, {DRAMC_REG_SHURK_SELPH_DQ2, SHURK_SELPH_DQ2_DLY_DQ1}}; REG_TRANSFER_T TransferMCKRegs[] = {{DRAMC_REG_SHURK_SELPH_DQ1, SHURK_SELPH_DQ1_TXDLY_DQM0}, {DRAMC_REG_SHURK_SELPH_DQ1, SHURK_SELPH_DQ1_TXDLY_DQM1}, {DRAMC_REG_SHURK_SELPH_DQ0, SHURK_SELPH_DQ0_TXDLY_DQ0}, {DRAMC_REG_SHURK_SELPH_DQ0, SHURK_SELPH_DQ0_TXDLY_DQ1}}; _LoopAryToDelay(p, TransferUIRegs, TransferMCKRegs, sizeof(TransferUIRegs) / sizeof(REG_TRANSFER_T), iShiftUI, eByteIdx); } static void ShiftDQUI_AllRK(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { U8 backup_rank, rk_i; backup_rank = u1GetRank(p); for (rk_i = RANK_0; rk_i < p->support_rank_num; rk_i++) { vSetRank(p, rk_i); ShiftDQUI(p, iShiftUI, eByteIdx); } vSetRank(p, backup_rank); } static void ShiftDQ_OENUI(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { REG_TRANSFER_T TransferUIRegs[] = {{DRAMC_REG_SHURK_SELPH_DQ3, SHURK_SELPH_DQ3_DLY_OEN_DQM0}, {DRAMC_REG_SHURK_SELPH_DQ3, SHURK_SELPH_DQ3_DLY_OEN_DQM1}, {DRAMC_REG_SHURK_SELPH_DQ2, SHURK_SELPH_DQ2_DLY_OEN_DQ0}, {DRAMC_REG_SHURK_SELPH_DQ2, SHURK_SELPH_DQ2_DLY_OEN_DQ1}}; REG_TRANSFER_T TransferMCKRegs[] = {{DRAMC_REG_SHURK_SELPH_DQ1, SHURK_SELPH_DQ1_TXDLY_OEN_DQM0}, {DRAMC_REG_SHURK_SELPH_DQ1, SHURK_SELPH_DQ1_TXDLY_OEN_DQM1}, {DRAMC_REG_SHURK_SELPH_DQ0, SHURK_SELPH_DQ0_TXDLY_OEN_DQ0}, {DRAMC_REG_SHURK_SELPH_DQ0, SHURK_SELPH_DQ0_TXDLY_OEN_DQ1}}; _LoopAryToDelay(p, TransferUIRegs, TransferMCKRegs, sizeof(TransferUIRegs) / sizeof(REG_TRANSFER_T), iShiftUI, eByteIdx); } void ShiftDQ_OENUI_AllRK(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { U8 backup_rank, rk_i; backup_rank = u1GetRank(p); for (rk_i = RANK_0; rk_i < p->support_rank_num; rk_i++) { vSetRank(p, rk_i); ShiftDQ_OENUI(p, iShiftUI, eByteIdx); } vSetRank(p, backup_rank); } //void WriteLevelingMoveDQSInsteadOfCLK(DRAMC_CTX_T *p, S8 iShiftUI) //{ // LP4_ShiftDQSUI(p, iShiftUI, ALL_BYTES); // LP4_ShiftDQUI(p, iShiftUI, ALL_BYTES); //} static void ShiftDQSWCK_UI(DRAMC_CTX_T *p, S8 iShiftUI, BYTES_T eByteIdx) { { LP4_ShiftDQSUI(p, iShiftUI, eByteIdx); LP4_ShiftDQS_OENUI(p, iShiftUI, eByteIdx); } } U8 u1IsLP4Div4DDR800(DRAMC_CTX_T *p) { if ((vGet_Div_Mode(p) == DIV4_MODE) && (p->frequency == 400)) return TRUE; else return FALSE; } static void vSetDramMRWriteLevelingOnOff(DRAMC_CTX_T *p, U8 u1OnOff) { if (u1OnOff) u1MR02Value[p->dram_fsp] |= 0x80; else u1MR02Value[p->dram_fsp] &= 0x7f; DramcModeRegWriteByRank(p, p->rank, 2, u1MR02Value[p->dram_fsp]); } U8 u1IsPhaseMode(DRAMC_CTX_T *p) { if ((vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE) || (vGet_DDR_Loop_Mode(p) == SEMI_OPEN_LOOP_MODE)) return TRUE; else return FALSE; } #if 0 static DRAM_STATUS_T DramcTriggerAndWait(DRAMC_CTX_T *p, REG_TRANSFER_T TriggerReg, REG_TRANSFER_T RepondsReg) { U32 u4TimeCnt = DDR_HW_AUTOK_POLLING_CNT; DRAM_STATUS_T u4RespFlag = 0; vIO32WriteFldAlign(DRAMC_REG_ADDR(TriggerReg.u4Addr), 0, TriggerReg.u4Fld); vIO32WriteFldAlign(DRAMC_REG_ADDR(TriggerReg.u4Addr), 1, TriggerReg.u4Fld); do { u4RespFlag = u4IO32ReadFldAlign(DRAMC_REG_ADDR(RepondsReg.u4Addr), RepondsReg.u4Fld); u4TimeCnt --; mcDELAY_US(1); }while ((u4RespFlag == 0) && (u4TimeCnt > 0)); if (u4TimeCnt == 0) { mcSHOW_ERR_MSG(("[DramcTriggerAndWait] Wait 0x%x respond fail (time out)\n", RepondsReg.u4Addr)); return DRAM_FAIL; } return DRAM_OK; } static DRAM_STATUS_T DramcTriggerAndWait_For_RX_AutoK_WorkAround(DRAMC_CTX_T *p, REG_TRANSFER_T TriggerReg, REG_TRANSFER_T RepondsReg, U16 u16DelayStep) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_AUTOK_CFG0), 0, MISC_RX_AUTOK_CFG0_RX_CAL_STEP); vIO32WriteFldAlign(DRAMC_REG_ADDR(TriggerReg.u4Addr), 0, TriggerReg.u4Fld); vIO32WriteFldAlign(DRAMC_REG_ADDR(TriggerReg.u4Addr), 1, TriggerReg.u4Fld); vIO32WriteFldAlign(DRAMC_REG_ADDR(TriggerReg.u4Addr), 0, TriggerReg.u4Fld); DramPhyReset(p); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_AUTOK_CFG0), u16DelayStep, MISC_RX_AUTOK_CFG0_RX_CAL_STEP); return DramcTriggerAndWait(p, TriggerReg, RepondsReg); } #endif #if (SIMULATION_WRITE_LEVELING == 1) #define DQPI_PER_UI (32) #define STORAGED_DLY_UNIT (24) static void WriteLevelingScanRange_PI(DRAMC_CTX_T *p, S32 *ps4DlyBegin, S32 *ps4DlyEnd, U8 *pu1PIStep, S16 *pPI_bound, WLEV_DELAY_BASED_T stDelayBase) { S32 s4DlyBegin = 0, s4DlyEnd; U8 u1PIStep; S16 PI_bound; if (stDelayBase == PI_BASED) { s4DlyBegin = WRITE_LEVELING_MOVD_DQS * 32 - MAX_CLK_PI_DELAY - 1; s4DlyEnd = s4DlyBegin + 64 - 1; if ((vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE)) { u1PIStep = 16; PI_bound = 32; } else if ((vGet_DDR_Loop_Mode(p) == SEMI_OPEN_LOOP_MODE)) { u1PIStep = 8; PI_bound = 32; } else { u1PIStep = 1; PI_bound = 64; } } else { s4DlyBegin = 0; s4DlyEnd = 2 * STORAGED_DLY_UNIT; u1PIStep = 1; PI_bound = 1024; } mcSHOW_DBG_MSG2(("Delay: %d->%d, Step: %d, Bound: %d\n", s4DlyBegin, s4DlyEnd, u1PIStep, PI_bound)); *ps4DlyBegin = s4DlyBegin; *ps4DlyEnd = s4DlyEnd; *pu1PIStep = u1PIStep; *pPI_bound = PI_bound; } #if ENABLE_WDQS_MODE_2 void WriteLevelingPosCal(DRAMC_CTX_T *p, WLEV_DELAY_BASED_T stDelayBase) { DRAM_RANK_T backup_rank = u1GetRank(p); U8 wrlevel_dqs_delay[DQS_BYTE_NUMBER] = {0}; U8 rank_i = 0; if((wrlevel_dqs_final_delay[RANK_0][0] - wrlevel_dqs_final_delay[RANK_1][0])>=9 || (wrlevel_dqs_final_delay[RANK_0][0] - wrlevel_dqs_final_delay[RANK_1][0])<=-9 || (wrlevel_dqs_final_delay[RANK_0][1] - wrlevel_dqs_final_delay[RANK_1][1])>=9 || (wrlevel_dqs_final_delay[RANK_0][1] - wrlevel_dqs_final_delay[RANK_1][1])<=-9 ) { mcSHOW_ERR_MSG(("[WARNING] Larger WL R2R !!\n")); #if CHECK_HQA_CRITERIA while(1); #endif } wrlevel_dqs_delay[0] = (wrlevel_dqs_final_delay[RANK_0][0] + wrlevel_dqs_final_delay[RANK_1][0]) >> 1; wrlevel_dqs_delay[1] = (wrlevel_dqs_final_delay[RANK_0][1] + wrlevel_dqs_final_delay[RANK_1][1]) >> 1; wrlevel_dqs_final_delay[RANK_0][0] = wrlevel_dqs_final_delay[RANK_1][0] = wrlevel_dqs_delay[0]; wrlevel_dqs_final_delay[RANK_0][1] = wrlevel_dqs_final_delay[RANK_1][1] = wrlevel_dqs_delay[1]; for (rank_i = p->rank; rank_i < p->support_rank_num; rank_i++) { vSetRank(p, rank_i); if (stDelayBase == PI_BASED) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), wrlevel_dqs_delay[0], SHU_R0_B0_DQ0_ARPI_PBYTE_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), wrlevel_dqs_delay[1], SHU_R0_B1_DQ0_ARPI_PBYTE_B1); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY3), wrlevel_dqs_delay[0], SHU_R0_B0_TXDLY3_TX_ARWCK_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY3), wrlevel_dqs_delay[1], SHU_R0_B1_TXDLY3_TX_ARWCK_DLY_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY3), wrlevel_dqs_delay[0], SHU_R0_B0_TXDLY3_TX_ARWCKB_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY3), wrlevel_dqs_delay[1], SHU_R0_B1_TXDLY3_TX_ARWCKB_DLY_B1); } } vSetRank(p, backup_rank); mcSHOW_DBG_MSG(("[WriteLevelingPosCal] DQS PI B0/B1 = %d/%d\n", wrlevel_dqs_delay[0], wrlevel_dqs_delay[1])); } #endif #define SET_PATTERN_MANUALLY_FOR_DEBUG 1 DRAM_STATUS_T DramcWriteLeveling(DRAMC_CTX_T *p, u8 isAutoK, WLEV_DELAY_BASED_T stDelayBase) { DRAM_STATUS_T KResult = DRAM_FAIL; //U8 *uiLPDDR_O1_Mapping = NULL; //U32 u4value = 0, u4dq_o1 = 0 u4value1 = 0, u4dq_o1_tmp[DQS_BYTE_NUMBER]; U8 byte_i, rank_i, ucDoneFlg; //S32 iDelay, ClockDelayMax; //U8 ucStatus[DQS_BYTE_NUMBER], ucdq_o1[DQS_BYTE_NUMBER], ucdq_o1_shift[DQS_BYTE_NUMBER] //U8 ucHW_cmp_raw_data, uccmp_result[DQS_BYTE_NUMBER]; DRAM_RANK_T backup_rank; //S32 wrlevel_dq_delay[DQS_BYTE_NUMBER]; // 3 is channel number S32 wrlevel_dqs_delay[DQS_BYTE_NUMBER]; // 3 is channel number //u32 bitmap31_0[DQS_BYTE_NUMBER] = {0}; //u32 bitmap63_32[DQS_BYTE_NUMBER] = {0}; //u8 idx = 0; //U16 _bitmap_stored_num = 0; S32 s4DlyBegin, s4DlyEnd; U8 u1PIStep; U8 u1OverBoundCnt = 0; //jj = 0 S16 PI_bound = 64; vAutoRefreshSwitch(p, DISABLE); if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } //DUMP_REG_MSG(("\n[dumpRG] DramcWriteLeveling \n")); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif mcSHOW_DBG_MSG(("[Write Leveling] autok: %d\n", isAutoK)); fgwrlevel_done = 0; backup_rank = u1GetRank(p); //DramcRankSwap(p, p->rank); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), p->rank, TX_SET0_TXRANK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 1, TX_SET0_TXRANKFIX); U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL1)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL3)), (DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL5)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_VREF)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_PHY_VREF_SEL)), (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)) }; DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); vSetCalibrationResult(p, DRAM_CALIBRATION_WRITE_LEVEL, DRAM_FAIL); #if MRW_CHECK_ONLY mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__)); #endif if (p->isWLevInitShift[p->channel] == FALSE) { #if __ETT__ while (stDelayBase != PI_BASED); #else ASSERT(stDelayBase == PI_BASED); #endif p->isWLevInitShift[p->channel] = TRUE; ShiftDQUI_AllRK(p, -WRITE_LEVELING_MOVD_DQS, ALL_BYTES); ShiftDQ_OENUI_AllRK(p, -WRITE_LEVELING_MOVD_DQS, ALL_BYTES); ShiftDQSWCK_UI(p, -WRITE_LEVELING_MOVD_DQS, ALL_BYTES); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), 0, SHU_R0_B0_DQ0_ARPI_PBYTE_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), 0, SHU_R0_B1_DQ0_ARPI_PBYTE_B1); } WriteLevelingScanRange_PI(p, &s4DlyBegin, &s4DlyEnd, &u1PIStep, &PI_bound, stDelayBase); if (stDelayBase == DLY_BASED) isAutoK = FALSE; #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_WRITELEVELING) if (p->femmc_Ready == 1) { wrlevel_dqs_final_delay[p->rank][0] = p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][0]; wrlevel_dqs_final_delay[p->rank][1] = p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][1]; ucDoneFlg = 0xff; KResult = DRAM_OK; vSetCalibrationResult(p, DRAM_CALIBRATION_WRITE_LEVEL, DRAM_FAST_K); } #endif if (u1OverBoundCnt > 0) ShiftDQSWCK_UI(p, -u1OverBoundCnt * (PI_bound / DQPI_PER_UI), ALL_BYTES); if (ucDoneFlg == 0xff) { fgwrlevel_done = 1; KResult = DRAM_OK; } else { KResult = DRAM_FAIL; #if PIN_CHECK_TOOL PINInfo_flashtool.WL_ERR_FLAG|=(0x1<<(p->channel*2+p->rank)); #endif } vSetCalibrationResult(p, DRAM_CALIBRATION_WRITE_LEVEL, KResult); mcSHOW_DBG_MSG2(("pass bytecount = 0x%x (0xff: all bytes pass) \n\n", ucDoneFlg)); #if defined(FOR_HQA_TEST_USED) && defined(FOR_HQA_REPORT_USED) if (gHQALog_flag == 1) { for (byte_i = 0; byte_i < DQS_BYTE_NUMBER; byte_i++) { if (byte_i==0) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "", "WriteLeveling_MCK_DQS", byte_i, u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS0), SHU_SELPH_DQS0_TXDLY_DQS0), NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "", "WriteLeveling_UI_DQS", byte_i, u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS1), SHU_SELPH_DQS1_DLY_DQS0), NULL); } else { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "", "WriteLeveling_MCK_DQS", byte_i, u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS0), SHU_SELPH_DQS0_TXDLY_DQS1), NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "", "WriteLeveling_UI_DQS", byte_i, u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS1), SHU_SELPH_DQS1_DLY_DQS1), NULL); } HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "", "WriteLeveling_DQS", byte_i, wrlevel_dqs_final_delay[p->rank][byte_i], NULL); } } #endif vSetDramMRWriteLevelingOnOff(p, DISABLE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CBT_WLEV_CTRL0), 0, CBT_WLEV_CTRL0_WRITE_LEVEL_EN); O1PathOnOff(p, OFF); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 0, TX_SET0_TXRANK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_SET0), 0, TX_SET0_TXRANKFIX); DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); for (byte_i = 0; byte_i < DQS_BYTE_NUMBER; byte_i++) { mcSHOW_DBG_MSG(("Write leveling (Byte %d): %d", byte_i, wrlevel_dqs_final_delay[p->rank][byte_i])); //DUMP_REG_MSG(("Write leveling (Byte %d): %d", byte_i, wrlevel_dqs_final_delay[p->rank][byte_i])); if (wrlevel_dqs_final_delay[p->rank][byte_i] >= PI_bound) { ShiftDQSWCK_UI(p, (wrlevel_dqs_final_delay[p->rank][byte_i] / PI_bound) * (PI_bound / DQPI_PER_UI), byte_i); wrlevel_dqs_final_delay[p->rank][byte_i] %= PI_bound; } wrlevel_dqs_delay[byte_i] = wrlevel_dqs_final_delay[p->rank][byte_i]; mcSHOW_DBG_MSG((" => %d\n", wrlevel_dqs_delay[byte_i])); //DUMP_REG_MSG((" => %d\n", wrlevel_dqs_delay[byte_i])); } for (rank_i = p->rank; rank_i < RANK_MAX; rank_i++) { vSetRank(p, rank_i); if (stDelayBase == PI_BASED) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), wrlevel_dqs_delay[0], SHU_R0_B0_DQ0_ARPI_PBYTE_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), wrlevel_dqs_delay[1], SHU_R0_B1_DQ0_ARPI_PBYTE_B1); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY3), wrlevel_dqs_delay[0], SHU_R0_B0_TXDLY3_TX_ARWCK_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY3), wrlevel_dqs_delay[1], SHU_R0_B1_TXDLY3_TX_ARWCK_DLY_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY3), wrlevel_dqs_delay[0], SHU_R0_B0_TXDLY3_TX_ARWCKB_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY3), wrlevel_dqs_delay[1], SHU_R0_B1_TXDLY3_TX_ARWCKB_DLY_B1); } } vSetRank(p, backup_rank); mcSHOW_DBG_MSG4(("[DramcWriteLeveling] Done\n\n")); return KResult; } #endif //SIMULATION_WRITE_LEVELING #if (fcFOR_CHIP_ID == fcA60868) static void RunTime_SW_Cmd(DRAMC_CTX_T *p, RUNTIME_SWCMD_SEL_T runtime_SW_cmd_sel) { U32 u4Response = 0; U32 u4TimeCnt = TIME_OUT_CNT; U32 u4BackupCKECTRL; u4BackupCKECTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)); CKEFixOnOff(p, TO_ALL_RANK, CKE_FIXON, TO_ALL_CHANNEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), runtime_SW_cmd_sel, SWCMD_EN_RTSWCMD_SEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RTSWCMD_CNT), 0x30, RTSWCMD_CNT_RTSWCMD_CNT); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), P_Fld(0, SWCMD_CTRL2_RTSWCMD_AGE) | P_Fld(p->rank, SWCMD_CTRL2_RTSWCMD_RK)); U8 _rank_idx_CAS_OFF = 0; U8 _is_differential_mode = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_WCKCTRL), SHU_WCKCTRL_WCKDUAL); while (1) { if (runtime_SW_cmd_sel == RUNTIME_SWCMD_CAS_OFF) { if ( _is_differential_mode == 0) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), _rank_idx_CAS_OFF, SWCMD_CTRL2_RTSWCMD_RK); } else if (runtime_SW_cmd_sel == RUNTIME_SWCMD_CAS_FS) { if (_is_differential_mode == 0) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), 0x3, SWCMD_CTRL2_RTSWCMD_RK); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_RTSWCMDEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP3), SPCMDRESP3_RTSWCMD_RESPONSE); u4TimeCnt --; mcDELAY_US(1); }while ((u4Response == 0) && (u4TimeCnt > 0)); if (u4TimeCnt == 0) { mcSHOW_ERR_MSG(("[LP5 RT SW Cmd ] Resp fail (time out)\n")); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_RTSWCMDEN); if (runtime_SW_cmd_sel == RUNTIME_SWCMD_CAS_OFF) { if (_is_differential_mode == 0) if (++_rank_idx_CAS_OFF <= 1) continue; } break; } vIO32Write4B_All(DRAMC_REG_CKECTRL, u4BackupCKECTRL); } #else #if 0 static void RunTime_SW_Cmd(DRAMC_CTX_T *p, RUNTIME_SWCMD_SEL_T runtime_SW_cmd_sel) { U32 u4Response = 0; U32 u4TimeCnt = TIME_OUT_CNT; vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), runtime_SW_cmd_sel, SWCMD_EN_RTSWCMD_SEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RTSWCMD_CNT), 0x30, RTSWCMD_CNT_RTSWCMD_CNT); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), P_Fld(0, SWCMD_CTRL2_RTSWCMD_AGE) | P_Fld(p->rank, SWCMD_CTRL2_RTSWCMD_RK)); if ((runtime_SW_cmd_sel == RUNTIME_SWCMD_CAS_FS) || (runtime_SW_cmd_sel == RUNTIME_SWCMD_CAS_OFF)) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), 0x3, SWCMD_CTRL2_RTSWCMD_RK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_RTSWCMDEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP3), SPCMDRESP3_RTSWCMD_RESPONSE); u4TimeCnt --; mcDELAY_US(1); }while ((u4Response == 0) && (u4TimeCnt > 0)); if (u4TimeCnt == 0) { mcSHOW_ERR_MSG(("[LP5 RT SW Cmd ] Resp fail (time out)\n")); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_RTSWCMDEN); } #endif #endif #if (SIMULATION_DUTY_CYC_MONITOR == 1) static U8 FetchRGSettingVal(int step_val) { if (step_val <= 0) return (U8)(-step_val); else return ((U8)step_val | 0x08); } DRAM_STATUS_T DramcDutyCycleMonitor(DRAMC_CTX_T *p) { U8 backup_rank; // U8 u8ResultDutyCycMonitor[WHOLE_STEPS_NUM] = {0}; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } vAutoRefreshSwitch(p, DISABLE); //CKEFixOnOff(p, p->rank, CKE_FIXON, TO_ONE_CHANNEL); backup_rank = u1GetRank(p); RunTime_SW_Cmd(p, RUNTIME_SWCMD_CAS_FS); int i = -7; for (i = -7; i <= 7; i++) { U8 u8RGSettingVal = FetchRGSettingVal(i); mcSHOW_ERR_MSG(("Set value %d into MR30\n", u8RGSettingVal)); MRWriteFldMulti(p, 30, P_Fld(u8RGSettingVal, MR30_DCAU) | P_Fld(u8RGSettingVal, MR30_DCAL), TO_MR); DramcMRWriteFldAlign(p, 26, 1, MR26_DCM_START_STOP, TO_MR); mcDELAY_US(2); DramcMRWriteFldAlign(p, 26, 1, MR26_DCM_FLIP, TO_MR); mcDELAY_US(2); DramcMRWriteFldAlign(p, 26, 0, MR26_DCM_FLIP, TO_MR); mcDELAY_US(2); DramcMRWriteFldAlign(p, 26, 0, MR26_DCM_START_STOP, TO_MR); mcDELAY_US(2); mcSHOW_ERR_MSG(("Wait tMRD and MRR MR26\n")); } RunTime_SW_Cmd(p, RUNTIME_SWCMD_CAS_OFF); vAutoRefreshSwitch(p, ENABLE); //CKEFixOnOff(p, p->rank, CKE_DYNAMIC, TO_ONE_CHANNEL); vSetRank(p, backup_rank); } #endif void vResetDelayChainBeforeCalibration(DRAMC_CTX_T *p) { U8 u1RankIdx, u1RankIdxBak; U32 u4WbrBackup = GetDramcBroadcast(); DramcBroadcastOnOff(DRAMC_BROADCAST_OFF); u1RankIdxBak = u1GetRank(p); for(u1RankIdx=RANK_0; u1RankIdx0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_ZQCEN_SWTRIG); if(u4TimeCnt==0) { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Start fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Start fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); u4TimeCnt = TIME_OUT_CNT; vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_ZQLATEN_SWTRIG); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP3), SPCMDRESP3_ZQLAT_SWTRIG_RESPONSE); u4TimeCnt --; mcDELAY_US(1); mcSHOW_DBG_MSG4(("%d=\n\n", u4TimeCnt)); //mcFPRINTF((fp_A60501, "%d= ", u4TimeCnt)); }while((u4Response==0) &&(u4TimeCnt>0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_ZQLATEN_SWTRIG); if(u4TimeCnt==0)//time out { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Latch fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Latch fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), u4SWCMDEN); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0), u4SWCMDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), u4SPDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), u4CKECTRL); vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_OK); mcSHOW_DBG_MSG4(("[DramcZQCalibration] Done\n\n")); //mcFPRINTF((fp_A60501, "\n[DramcZQCalibration] Done\n\n")); return DRAM_OK; } #endif #if ZQ_RTSWCMD_MODE static DRAM_STATUS_T ZQ_RTSWCMD_MODE_Cal(DRAMC_CTX_T *p, U8 rank) { U32 u4Response; U32 u4TimeCnt = TIME_OUT_CNT; U32 u4SWCMDEN, u4SWCMDCTRL, u4MPCCTRL, u4RTSWCMD, u4SPDCTRL, u4CKECTRL; u4SWCMDEN = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN)); u4SWCMDCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2)); u4MPCCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_MPC_CTRL)); u4RTSWCMD = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_RTSWCMD_CNT)); u4SPDCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)); u4CKECTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)); mcSHOW_DBG_MSG4(("[ZQCalibration]\n")); //mcFPRINTF((fp_A60501, "[ZQCalibration]\n")); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_APHYCKCG_FIXOFF); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_TCKFIXON); mcDELAY_US(1); //CKEFixOnOff(p, rank, CKE_FIXON, TO_ONE_CHANNEL); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), P_Fld(rank, SWCMD_CTRL2_RTSWCMD_RK) | P_Fld(0x20, SWCMD_CTRL2_RTSWCMD_AGE)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_CTRL), 0x1, MPC_CTRL_RTSWCMD_HPRI_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RTSWCMD_CNT), 0x2a, RTSWCMD_CNT_RTSWCMD_CNT); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0x5, SWCMD_EN_RTSWCMD_SEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_RTSWCMDEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP3), SPCMDRESP3_RTSWCMD_RESPONSE); u4TimeCnt --; mcDELAY_US(1); mcSHOW_DBG_MSG4(("%d- ", u4TimeCnt)); //mcFPRINTF((fp_A60501, "%d- ", u4TimeCnt)); }while((u4Response==0) &&(u4TimeCnt>0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_RTSWCMDEN); if(u4TimeCnt==0) { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Start fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Start fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); u4TimeCnt = TIME_OUT_CNT; vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0x6, SWCMD_EN_RTSWCMD_SEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_RTSWCMDEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP3), SPCMDRESP3_RTSWCMD_RESPONSE); u4TimeCnt --; mcDELAY_US(1); mcSHOW_DBG_MSG4(("%d=", u4TimeCnt)); //mcFPRINTF((fp_A60501, "%d= ", u4TimeCnt)); }while((u4Response==0) &&(u4TimeCnt>0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_RTSWCMDEN); if(u4TimeCnt==0) { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Latch fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Latch fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), u4SWCMDEN); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), u4SWCMDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_MPC_CTRL), u4MPCCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_RTSWCMD_CNT), u4RTSWCMD); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), u4SPDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), u4CKECTRL); vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_OK); mcSHOW_DBG_MSG4(("\n[DramcZQCalibration] Done\n\n")); //mcFPRINTF((fp_A60501, "\n[DramcZQCalibration] Done\n\n")); return DRAM_OK; } #endif #if ZQ_SCSM_MODE static DRAM_STATUS_T ZQ_SCSM_MODE_Cal(DRAMC_CTX_T *p, U8 rank) { U32 u4Response; U32 u4TimeCnt = TIME_OUT_CNT; U32 u4SWCMDEN, u4MPCCTRL, u4SWCMDCTRL, u4SPDCTRL, u4CKECTRL; u4SWCMDEN = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN)); u4SWCMDCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0)); u4MPCCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION)); u4SPDCTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)); u4CKECTRL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)); mcSHOW_DBG_MSG4(("[ZQCalibration]\n")); //mcFPRINTF((fp_A60501, "[ZQCalibration]\n")); DramCLKAlwaysOnOff(p, ON, TO_ONE_CHANNEL); mcDELAY_US(1); CKEFixOnOff(p, rank, CKE_FIXON, TO_ONE_CHANNEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0), rank, SWCMD_CTRL0_MRSRK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_ZQCEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_ZQC_RESPONSE); u4TimeCnt --; mcDELAY_US(1); mcSHOW_DBG_MSG4(("%d- ", u4TimeCnt)); //mcFPRINTF((fp_A60501, "%d- ", u4TimeCnt)); }while((u4Response==0) &&(u4TimeCnt>0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_ZQCEN); if(u4TimeCnt==0) { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Start fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Start fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); u4TimeCnt = TIME_OUT_CNT; vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 1, SWCMD_EN_ZQLATEN); do { u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_ZQLAT_RESPONSE); u4TimeCnt --; mcDELAY_US(1); mcSHOW_DBG_MSG4(("%d=", u4TimeCnt)); //mcFPRINTF((fp_A60501, "%d= ", u4TimeCnt)); }while((u4Response==0) &&(u4TimeCnt>0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_ZQLATEN); if(u4TimeCnt==0) { vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL); mcSHOW_ERR_MSG(("ZQCAL Latch fail (time out)\n")); //mcFPRINTF((fp_A60501, "ZQCAL Latch fail (time out)\n")); return DRAM_FAIL; } mcDELAY_US(1); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), u4SWCMDEN); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL2), u4SWCMDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_MPC_CTRL), u4MPCCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), u4SPDCTRL); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), u4CKECTRL); vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_OK); mcSHOW_DBG_MSG4(("\n[DramcZQCalibration] Done\n\n")); //mcFPRINTF((fp_A60501, "\n[DramcZQCalibration] Done\n\n")); return DRAM_OK; } #endif DRAM_STATUS_T DramcZQCalibration(DRAMC_CTX_T *p, U8 rank) { #if ZQ_SWCMD_MODE return ZQ_SWCMD_MODE_Cal(p, rank); #elif ZQ_RTSWCMD_MODE return ZQ_RTSWCMD_MODE_Cal(p, rank); #else return ZQ_SCSM_MODE_Cal(p, rank); #endif } #endif #if ENABLE_RX_INPUT_BUFF_OFF_K static U8 RXInputBuf_DelayExchange(S8 iOfst) { U8 u1Value; if(iOfst <0) { u1Value = 0x8 | (-iOfst); } else { u1Value = iOfst; } return u1Value; } DRAM_STATUS_T DramcRXInputBufferOffsetCal(DRAMC_CTX_T *p) { S8 iOffset, s1begin, s1end; S8 s1DQFinalFlagChange[DQ_DATA_WIDTH], s1DQMFinalFlagChange[DQM_BYTE_NUM]; U8 u1BitIdx, u1ByteIdx, u1FinishCount, u1step, u1DQFinal_rg_offset[DQ_DATA_WIDTH], u1DQMFinal_rg_offset[DQM_BYTE_NUM]; //U8 *uiLPDDR_O1_Mapping = NULL; U8 ii, read_val_b0 = u1GetRank(p); //u1rank_backup U8 u1Offc_RgValue, u1O1_value; U32 u4RestltDQ, u4RestltDQ_B0, u4RestltDQ_B1, u4RestltDQM[DQM_BYTE_NUM]; BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ5)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ5)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD5)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD6)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ3)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ3)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD3)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY3)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY3)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_PHY3)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_IN_GATE_EN_CTRL)), }; vSetCalibrationResult(p, DRAM_CALIBRATION_RX_INPUT_BUFF_OFFC, DRAM_FAIL); mcSHOW_DBG_MSG2(("\n[DramcRXInputBufferOffsetCal] \n")); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif DramcBackupRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); DramcEngine2Run(p, TE_OP_READ_CHECK, TEST_AUDIO_PATTERN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_IN_GATE_EN_CTRL), 0xf, MISC_RX_IN_GATE_EN_CTRL_FIX_IN_GATE_EN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), P_Fld(1, B0_DQ6_RG_RX_ARDQ_BIAS_PS_B0) | P_Fld(1, B0_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B0) | P_Fld(0, B0_DQ6_RG_RX_ARDQ_DDR3_SEL_B0) | P_Fld(1, B0_DQ6_RG_RX_ARDQ_DDR4_SEL_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6), P_Fld(1, B1_DQ6_RG_RX_ARDQ_BIAS_PS_B1) | P_Fld(1, B1_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B1) | P_Fld(0, B1_DQ6_RG_TX_ARDQ_DDR3_SEL_B1) | P_Fld(1, B1_DQ6_RG_TX_ARDQ_DDR4_SEL_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD6), P_Fld(1, CA_CMD6_RG_RX_ARCMD_BIAS_PS) | P_Fld(1, CA_CMD6_RG_RX_ARCMD_RES_BIAS_EN) | P_Fld(0, CA_CMD6_RG_TX_ARCMD_DDR3_SEL) | P_Fld(1, CA_CMD6_RG_TX_ARCMD_DDR4_SEL)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD5), 1, CA_CMD5_RG_RX_ARCMD_VREF_EN); mcDELAY_US(1); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ3), P_Fld(1, B0_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B0) | P_Fld(1, B0_DQ3_RG_RX_ARDQ_OFFC_EN_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ3), P_Fld(1, B1_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B1) | P_Fld(1, B1_DQ3_RG_RX_ARDQ_OFFC_EN_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD3), P_Fld(1, CA_CMD3_RG_RX_ARCMD_IN_BUFF_EN) | P_Fld(1, CA_CMD3_RG_RX_ARCLK_IN_BUFF_EN)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY3), 1, B0_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B0); if (!isLP4_DSC) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY3), 1, B1_PHY3_RG_RX_ARDQ_BUFF_EN_SEL_B1); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_PHY3), 1, CA_PHY3_RG_RX_ARCA_BUFF_EN_SEL_CA); } vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), P_Fld(0x1, SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_BIAS_EN_B0) | P_Fld(0x1, SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_EN_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), P_Fld(0x1, SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_BIAS_EN_B1) | P_Fld(0x1, SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_EN_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD11), P_Fld(0x1, SHU_CA_CMD11_RG_RX_ARCA_OFFSETC_BIAS_EN_CA) | P_Fld(0x1, SHU_CA_CMD11_RG_RX_ARCA_OFFSETC_EN_CA)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 1, B0_DQ6_RG_RX_ARDQ_O1_SEL_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6), 1, B1_DQ6_RG_RX_ARDQ_O1_SEL_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD6), 1, CA_CMD6_RG_RX_ARCMD_O1_SEL); u1FinishCount =0; s1begin = -7; s1end = 8; u1step = 1; memset(s1DQFinalFlagChange, 0x7f, sizeof(s1DQFinalFlagChange)); memset(s1DQMFinalFlagChange, 0x7f, sizeof(s1DQMFinalFlagChange)); for(iOffset = s1begin; iOffset < s1end; iOffset+=u1step) { u1Offc_RgValue = RXInputBuf_DelayExchange(iOffset); mcSHOW_DBG_MSG2(("iOffset= %2d, set %2d,", iOffset, u1Offc_RgValue)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQ0), P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ0_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ1_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ2_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ3_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ4_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ5_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ6_OFFC_B0) | P_Fld(u1Offc_RgValue, SHU_RK_B0_DQ0_RG_RX_ARDQ7_OFFC_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQ0), P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ0_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ1_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ2_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ3_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ4_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ5_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ6_OFFC_B1) | P_Fld(u1Offc_RgValue, SHU_RK_B1_DQ0_RG_RX_ARDQ7_OFFC_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_CMD0), P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA0_OFFC) | P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA1_OFFC) | P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA2_OFFC) | P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA3_OFFC) | P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA4_OFFC) | P_Fld(u1Offc_RgValue, SHU_RK_CA_CMD0_RG_RX_ARCA5_OFFC)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_DQ_OFFSET), P_Fld(u1Offc_RgValue, SHU_RK_CA_DQ_OFFSET_RG_RX_ARDQ6_OFFSETC_C0) | P_Fld(u1Offc_RgValue, SHU_RK_CA_DQ_OFFSET_RG_RX_ARDQ7_OFFSETC_C0)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQ1), u1Offc_RgValue, SHU_RK_B0_DQ1_RG_RX_ARDQM0_OFFC_B0); if (!isLP4_DSC) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQ1), u1Offc_RgValue, SHU_RK_B1_DQ1_RG_RX_ARDQM0_OFFC_B1); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_CMD1), u1Offc_RgValue, SHU_RK_CA_CMD1_RG_RX_ARCS0_OFFC); } mcDELAY_US(1); u4RestltDQ_B0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B0); if (!isLP4_DSC) { u4RestltDQ_B1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B1); } else { u4RestltDQ_B1 = ((u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_CMD_O1)))&0x3f)\ |(u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ6_O1_C0)<<0x6)\ |(u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ7_O1_C0)<<0x7); } u4RestltDQ = u4RestltDQ_B0|(u4RestltDQ_B1<<8); mcSHOW_DBG_MSG2((" DQ O1 = 0x%x, ", u4RestltDQ)); for(u1BitIdx= 0; u1BitIdx < DQ_DATA_WIDTH ; u1BitIdx++) { if(s1DQFinalFlagChange[u1BitIdx] == 0x7f) { u1O1_value = (u4RestltDQ >> u1BitIdx) & 0x1; if(u1O1_value ==0) { s1DQFinalFlagChange[u1BitIdx] = iOffset; u1FinishCount ++; #if __ETT__ if(iOffset == s1begin) { mcSHOW_ERR_MSG(("Error! didn't find trainsition point\n")); } #endif } else if(iOffset >= (s1end - u1step)) { s1DQFinalFlagChange[u1BitIdx] = iOffset; u1FinishCount ++; mcSHOW_ERR_MSG(("Error! didn't find trainsition point\n")); } } } u4RestltDQM[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQM0_O1_B0); if (!isLP4_DSC) { u4RestltDQM[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQM0_O1_B1); } else { u4RestltDQM[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_AD_RX_CMD_O1), MISC_AD_RX_CMD_O1_AD_RX_ARCS0_O1); } mcSHOW_DBG_MSG2(("DQM O1 (B1)= 0x%2x, (B0)= 0x%2x\n", u4RestltDQM[1], u4RestltDQM[0])); for(u1ByteIdx= 0; u1ByteIdx < DQM_BYTE_NUM; u1ByteIdx++) { if(s1DQMFinalFlagChange[u1ByteIdx]== 0x7f) { if(u4RestltDQM[u1ByteIdx]==0) { s1DQMFinalFlagChange[u1ByteIdx]= iOffset; u1FinishCount++; #if __ETT__ if(iOffset == s1begin) { mcSHOW_ERR_MSG(("Error! didn't find trainsition point\n")); } #endif } else if(iOffset == (s1end - u1step)) { s1DQMFinalFlagChange[u1ByteIdx] = iOffset; u1FinishCount ++; mcSHOW_ERR_MSG(("Error! didn't find trainsition point\n")); } } } if(u1FinishCount==(DQM_BYTE_NUM+DQ_DATA_WIDTH)) { vSetCalibrationResult(p, DRAM_CALIBRATION_RX_INPUT_BUFF_OFFC, DRAM_OK); mcSHOW_DBG_MSG2(("All bits find pass window, early break!\n")); break; } } mcSHOW_DBG_MSG2(("O1 Result DQ : [00]%3d [01]%3d [02]%3d [03]%3d [04]%3d [05]%3d [06]%3d [07]%3d\n", s1DQFinalFlagChange[0], s1DQFinalFlagChange[1], s1DQFinalFlagChange[2], s1DQFinalFlagChange[3], s1DQFinalFlagChange[4], s1DQFinalFlagChange[5], s1DQFinalFlagChange[6], s1DQFinalFlagChange[7])); mcSHOW_DBG_MSG2(("O1 Result DQ : [08]%3d [09]%3d [10]%3d [11]%3d [12]%3d [13]%3d [14]%3d [15]%3d\n", s1DQFinalFlagChange[8], s1DQFinalFlagChange[9], s1DQFinalFlagChange[10], s1DQFinalFlagChange[11], s1DQFinalFlagChange[12], s1DQFinalFlagChange[13], s1DQFinalFlagChange[14],s1DQFinalFlagChange[15])); mcSHOW_DBG_MSG2(("O1 Result DQM0 %2d Result DQM1 %2d,\n", s1DQMFinalFlagChange[0], s1DQMFinalFlagChange[1])); for(u1BitIdx= 0; u1BitIdx channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Input_Offset", " ", u1BitIdx, s1DQFinalFlagChange[u1BitIdx], NULL); } #endif } u1DQMFinal_rg_offset[0]= RXInputBuf_DelayExchange(s1DQMFinalFlagChange[0]); u1DQMFinal_rg_offset[1]= RXInputBuf_DelayExchange(s1DQMFinalFlagChange[1]); #ifdef FOR_HQA_REPORT_USED if (gHQALog_flag == 1) { HQA_LOG_Print_Prefix_String(p); mcSHOW_DBG_MSG(("RX_Input_Offset Channel%d Rank%d DQM0 %d\n", p->channel, p->rank, s1DQMFinalFlagChange[0])); HQA_LOG_Print_Prefix_String(p); mcSHOW_DBG_MSG(("RX_Input_Offset Channel%d Rank%d DQM1 %d\n", p->channel, p->rank, s1DQMFinalFlagChange[1])); } #endif for (ii = RANK_0; ii < p->support_rank_num; ii++) { vSetRank(p, ii); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQ0), P_Fld(u1DQFinal_rg_offset[0], SHU_RK_B0_DQ0_RG_RX_ARDQ0_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[1], SHU_RK_B0_DQ0_RG_RX_ARDQ1_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[2], SHU_RK_B0_DQ0_RG_RX_ARDQ2_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[3], SHU_RK_B0_DQ0_RG_RX_ARDQ3_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[4], SHU_RK_B0_DQ0_RG_RX_ARDQ4_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[5], SHU_RK_B0_DQ0_RG_RX_ARDQ5_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[6], SHU_RK_B0_DQ0_RG_RX_ARDQ6_OFFC_B0) | P_Fld(u1DQFinal_rg_offset[7], SHU_RK_B0_DQ0_RG_RX_ARDQ7_OFFC_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQ0), P_Fld(u1DQFinal_rg_offset[8], SHU_RK_B1_DQ0_RG_RX_ARDQ0_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[9], SHU_RK_B1_DQ0_RG_RX_ARDQ1_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[10], SHU_RK_B1_DQ0_RG_RX_ARDQ2_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[11], SHU_RK_B1_DQ0_RG_RX_ARDQ3_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[12], SHU_RK_B1_DQ0_RG_RX_ARDQ4_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[13], SHU_RK_B1_DQ0_RG_RX_ARDQ5_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[14], SHU_RK_B1_DQ0_RG_RX_ARDQ6_OFFC_B1) | P_Fld(u1DQFinal_rg_offset[15], SHU_RK_B1_DQ0_RG_RX_ARDQ7_OFFC_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_CMD0), P_Fld(u1DQFinal_rg_offset[8], SHU_RK_CA_CMD0_RG_RX_ARCA0_OFFC) | P_Fld(u1DQFinal_rg_offset[9], SHU_RK_CA_CMD0_RG_RX_ARCA1_OFFC) | P_Fld(u1DQFinal_rg_offset[10], SHU_RK_CA_CMD0_RG_RX_ARCA2_OFFC) | P_Fld(u1DQFinal_rg_offset[11], SHU_RK_CA_CMD0_RG_RX_ARCA3_OFFC) | P_Fld(u1DQFinal_rg_offset[12], SHU_RK_CA_CMD0_RG_RX_ARCA4_OFFC) | P_Fld(u1DQFinal_rg_offset[13], SHU_RK_CA_CMD0_RG_RX_ARCA5_OFFC)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_DQ_OFFSET), P_Fld(u1DQFinal_rg_offset[14], SHU_RK_CA_DQ_OFFSET_RG_RX_ARDQ6_OFFSETC_C0) | P_Fld(u1DQFinal_rg_offset[15], SHU_RK_CA_DQ_OFFSET_RG_RX_ARDQ7_OFFSETC_C0)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQ1), u1DQMFinal_rg_offset[0], SHU_RK_B0_DQ1_RG_RX_ARDQM0_OFFC_B0); if (!isLP4_DSC) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQ1), u1DQMFinal_rg_offset[1], SHU_RK_B1_DQ1_RG_RX_ARDQM0_OFFC_B1); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_CA_CMD1), u1DQMFinal_rg_offset[1], SHU_RK_CA_CMD1_RG_RX_ARCS0_OFFC); } } vSetRank(p, read_val_b0); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_IN_GATE_EN_CTRL), 0x0, MISC_RX_IN_GATE_EN_CTRL_FIX_IN_GATE_EN); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), 0x0, SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_EN_B0); //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), 0x0, SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_EN_B1); DramcRestoreRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), P_Fld(0x1, SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_BIAS_EN_B0) | P_Fld(0x0, SHU_B0_DQ11_RG_RX_ARDQ_OFFSETC_EN_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), P_Fld(0x1, SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_BIAS_EN_B1) | P_Fld(0x0, SHU_B1_DQ11_RG_RX_ARDQ_OFFSETC_EN_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD11), P_Fld(0x1, SHU_CA_CMD11_RG_RX_ARCA_OFFSETC_BIAS_EN_CA) | P_Fld(0x0, SHU_CA_CMD11_RG_RX_ARCA_OFFSETC_EN_CA)); } mcSHOW_DBG_MSG2(("[DramcRXInputBufferOffsetCal] ====Done====\n")); return DRAM_OK; } #endif #if (SIMULATION_GATING == 1) #define GATING_PATTERN_NUM_LP5 0x23 #define GATING_GOLDEND_DQSCNT_LP5 0x4646 #define RXDQS_GATING_AUTO_DBG_REG_NUM 6 #if GATING_ADJUST_TXDLY_FOR_TRACKING U8 u1TXDLY_Cal_min =0xff, u1TXDLY_Cal_max=0; U8 ucbest_coarse_mck_backup[RANK_MAX][DQS_BYTE_NUMBER]; U8 ucbest_coarse_ui_backup[RANK_MAX][DQS_BYTE_NUMBER]; U8 ucbest_coarse_mck_P1_backup[RANK_MAX][DQS_BYTE_NUMBER]; U8 ucbest_coarse_ui_P1_backup[RANK_MAX][DQS_BYTE_NUMBER]; #endif struct rxdqs_gating_cal { U8 dqsien_dly_mck; U8 dqsien_dly_ui; U8 dqsien_dly_pi; U8 dqsien_dly_mck_p1; U8 dqsien_dly_ui_p1; U8 dqsien_pi_adj_step; U8 dqsien_pi_per_ui; U8 dqsien_ui_per_mck; U8 dqsien_freq_div; }; struct rxdqs_gating_trans { U8 dqs_lead[DQS_BYTE_NUMBER]; U8 dqs_lag[DQS_BYTE_NUMBER]; U8 dqs_high[DQS_BYTE_NUMBER]; #if GATING_LEADLAG_LOW_LEVEL_CHECK U8 dqs_low[DQS_BYTE_NUMBER]; #endif U8 dqs_transition[DQS_BYTE_NUMBER]; U8 dqs_transitioned[DQS_BYTE_NUMBER]; U8 dqsien_dly_mck_leadlag[DQS_BYTE_NUMBER]; U8 dqsien_dly_ui_leadlag[DQS_BYTE_NUMBER]; U8 dqsien_dly_pi_leadlag[DQS_BYTE_NUMBER]; }; struct rxdqs_gating_best_win { U8 best_dqsien_dly_mck[DQS_BYTE_NUMBER]; U8 best_dqsien_dly_ui[DQS_BYTE_NUMBER]; U8 best_dqsien_dly_pi[DQS_BYTE_NUMBER]; U8 best_dqsien_dly_mck_p1[DQS_BYTE_NUMBER]; U8 best_dqsien_dly_ui_p1[DQS_BYTE_NUMBER]; U8 best_dqsien_dly_pi_p1[DQS_BYTE_NUMBER]; }; struct rxdqs_gating_auto_param { U8 early_break; U8 dbg_mode; U8 init_mck; U8 init_ui; U8 end_mck; U8 end_ui; U8 pi_offset; U8 burst_len; }; #if ENABLE_GATING_AUTOK_WA U8 __wa__gating_swk_for_autok = 0; U8 __wa__gating_autok_init_ui[RANK_MAX] = { 0 }; #endif static U8 u1GetGatingStartPos(DRAMC_CTX_T *p, U8 u1AutoK) { const U8 au1MR2MappingToRL[2][8] = {{6, 10, 14, 20, 24, 28, 32, 36}, {6, 10, 16, 22, 26, 32, 36, 40}}; //U8 u1CK2WCK, u1DVFSCEn; U8 u1MR0_LatencyMode; U8 u1MR2RLValue; u1MR2RLValue = u1MR02Value[p->dram_fsp] & 0x7; U8 u1RX_Path_delay_UI, u1RealRL,u1StartUI, u1ExtraMCKfor1_4mode; U8 u1MCK2CK_UI, u1ReadDQSINCTL, u1DQSINCTL_UI; U8 u4TDQSCK_UI_min; U8 u1GatingAheadDQS_UI; if(gu2MR0_Value[p->rank] == 0xffff) { u1MR0_LatencyMode = CBT_NORMAL_MODE; } else { u1MR0_LatencyMode = (gu2MR0_Value[p->rank]>>1) & 0x1; } { u4TDQSCK_UI_min = 1500 * DDRPhyGetRealFreq(p) *2/ 1000000; u1RealRL = au1MR2MappingToRL[u1MR0_LatencyMode][u1MR2RLValue]; } if(vGet_Div_Mode(p) == DIV4_MODE) { u1MCK2CK_UI = 4; u1ExtraMCKfor1_4mode = 1; u1GatingAheadDQS_UI = 3; } else if (vGet_Div_Mode(p) == DIV8_MODE) { u1MCK2CK_UI = 8; u1ExtraMCKfor1_4mode = 0; u1GatingAheadDQS_UI = 5; } else { u1MCK2CK_UI = 16; u1ExtraMCKfor1_4mode = 0; u1GatingAheadDQS_UI = 8; } u1RX_Path_delay_UI = (u1RealRL<<1) + u4TDQSCK_UI_min - u1GatingAheadDQS_UI + (u1MCK2CK_UI*u1ExtraMCKfor1_4mode); u1ReadDQSINCTL = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RK_DQSCTL), MISC_SHU_RK_DQSCTL_DQSINCTL); u1DQSINCTL_UI = u1ReadDQSINCTL * u1MCK2CK_UI; if(u1AutoK) u1RX_Path_delay_UI += 0; else u1RX_Path_delay_UI -= 3; if(u1RX_Path_delay_UI >= u1DQSINCTL_UI) u1StartUI = u1RX_Path_delay_UI - u1DQSINCTL_UI; else { u1StartUI =0; mcSHOW_ERR_MSG(("GatingStartPos err! Need to fine-tune default DQSINCTL value.\n(RX_Path_delay_UI %d) < DQSINCTL_UI %d)\n", u1RX_Path_delay_UI, u1DQSINCTL_UI)); #if __ETT__ while(1); #endif } mcSHOW_DBG_MSG2(("[DUMPLOG] %d GatingStartPos_MR0_LatencyMode %d, u1RealRL %d , u4TDQSCK_UI_min %d, 1:4ExtraMCK %d\n", p->frequency * 2, u1MR0_LatencyMode, u1RealRL, u4TDQSCK_UI_min, u1ExtraMCKfor1_4mode)); if(u1AutoK) { mcSHOW_DBG_MSG2(("RX_Path_delay_UI(%d) - DQSINCTL_UI(%d) = u1StartUI(%d)\n", u1RX_Path_delay_UI, u1DQSINCTL_UI, u1StartUI)); } else { mcSHOW_DBG_MSG2(("RX_Path_delay_UI(%d) -3 - DQSINCTL_UI(%d) = u1StartUI(%d)\n", u1RX_Path_delay_UI, u1DQSINCTL_UI, u1StartUI)); } return u1StartUI; } #if GATING_RODT_LATANCY_EN static U8 get_rodt_mck2ui(DRAMC_CTX_T *p) { if (vGet_Div_Mode(p) == DIV16_MODE) return 8; else if (vGet_Div_Mode(p) == DIV8_MODE) return 4; else return 2; } #endif static u8 rxdqs_gating_bypass(DRAMC_CTX_T *p) { #if SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_GatingCal if (p->femmc_Ready == 1) { mcSHOW_DBG_MSG(("[FAST_K] Bypass Gating Calibration\n")); return 1; } #endif return 0; } static void rxdqs_gating_fastk_save_restore(DRAMC_CTX_T *p, struct rxdqs_gating_best_win *best_win, struct rxdqs_gating_cal *gating_cal) { #if SUPPORT_SAVE_TIME_FOR_CALIBRATION u8 ui_per_mck = gating_cal->dqsien_ui_per_mck; u8 freq_div = gating_cal->dqsien_freq_div; u8 ch = p->channel; u8 rk = p->rank; u8 dqs_i; if (p->femmc_Ready == 1) { for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { best_win->best_dqsien_dly_mck[dqs_i] = p->pSavetimeData->u1Gating_MCK_Save[ch][rk][dqs_i]; best_win->best_dqsien_dly_ui[dqs_i] = p->pSavetimeData->u1Gating_UI_Save[ch][rk][dqs_i]; best_win->best_dqsien_dly_pi[dqs_i] = p->pSavetimeData->u1Gating_PI_Save[ch][rk][dqs_i]; /* Calculate P1 */ best_win->best_dqsien_dly_ui_p1[dqs_i] = best_win->best_dqsien_dly_mck[dqs_i] * ui_per_mck + best_win->best_dqsien_dly_ui[dqs_i] + freq_div; best_win->best_dqsien_dly_mck_p1[dqs_i] = best_win->best_dqsien_dly_ui_p1[dqs_i] / ui_per_mck; best_win->best_dqsien_dly_ui_p1[dqs_i] = best_win->best_dqsien_dly_ui_p1[dqs_i] % ui_per_mck; vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_FAST_K); mcSHOW_DBG_MSG(("[FAST_K] CH%d RK%d best DQS%d dly(MCK, UI, PI) = (%d, %d, %d)\n", ch, rk, dqs_i, best_win->best_dqsien_dly_mck[dqs_i], best_win->best_dqsien_dly_ui[dqs_i], best_win->best_dqsien_dly_pi[dqs_i])); mcSHOW_DBG_MSG(("[FAST_K] CH%d RK%d best DQS%d P1 dly(MCK, UI, PI) = (%d, %d, %d)\n", ch, rk, dqs_i, best_win->best_dqsien_dly_mck_p1[dqs_i], best_win->best_dqsien_dly_ui_p1[dqs_i], best_win->best_dqsien_dly_pi_p1[dqs_i])); } } #endif } static void rxdqs_gating_misc_process(DRAMC_CTX_T *p, struct rxdqs_gating_best_win *rxdqs_best_win) { #if GATING_ADJUST_TXDLY_FOR_TRACKING U8 u1TX_dly_DQSgated = 0; #endif U8 dqs_i; for (dqs_i=0; dqs_ichannel, p->rank, HQA_REPORT_FORMAT6, "DQSINCTL ", "", 0, u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RK_DQSCTL), MISC_SHU_RK_DQSCTL_DQSINCTL), NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_", "2T", dqs_i, rxdqs_best_win->best_dqsien_dly_mck[dqs_i], NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_", "05T", dqs_i, rxdqs_best_win->best_dqsien_dly_ui[dqs_i], NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_", "PI", dqs_i, rxdqs_best_win->best_dqsien_dly_pi[dqs_i], NULL); #endif mcSHOW_DBG_MSG(("best DQS%d dly(MCK, UI, PI) = (%d, %d, %d)\n", dqs_i, rxdqs_best_win->best_dqsien_dly_mck[dqs_i], rxdqs_best_win->best_dqsien_dly_ui[dqs_i], rxdqs_best_win->best_dqsien_dly_pi[dqs_i])); #if GATING_ADJUST_TXDLY_FOR_TRACKING u1TX_dly_DQSgated = (rxdqs_best_win->best_dqsien_dly_mck[dqs_i] << 4) + rxdqs_best_win->best_dqsien_dly_ui[dqs_i]; if (vGet_Div_Mode(p) == DIV16_MODE) u1TX_dly_DQSgated >>= 4; else if (vGet_Div_Mode(p) == DIV8_MODE) u1TX_dly_DQSgated >>= 3; else u1TX_dly_DQSgated >>= 2; if (u1TX_dly_DQSgated < u1TXDLY_Cal_min) u1TXDLY_Cal_min = u1TX_dly_DQSgated; ucbest_coarse_ui_backup[p->rank][dqs_i] = rxdqs_best_win->best_dqsien_dly_ui[dqs_i]; ucbest_coarse_mck_backup[p->rank][dqs_i] = rxdqs_best_win->best_dqsien_dly_mck[dqs_i]; #endif } mcSHOW_DBG_MSG(("\n")); for (dqs_i=0; dqs_ibest_dqsien_dly_mck_p1[dqs_i], rxdqs_best_win->best_dqsien_dly_ui_p1[dqs_i], rxdqs_best_win->best_dqsien_dly_pi_p1[dqs_i])); #if GATING_ADJUST_TXDLY_FOR_TRACKING u1TX_dly_DQSgated = (rxdqs_best_win->best_dqsien_dly_mck_p1[dqs_i] << 4) + rxdqs_best_win->best_dqsien_dly_ui_p1[dqs_i]; if (vGet_Div_Mode(p) == DIV16_MODE) u1TX_dly_DQSgated >>= 4; else if (vGet_Div_Mode(p) == DIV8_MODE) u1TX_dly_DQSgated >>= 3; else u1TX_dly_DQSgated >>= 2; if(u1TX_dly_DQSgated > u1TXDLY_Cal_max) u1TXDLY_Cal_max = u1TX_dly_DQSgated; ucbest_coarse_ui_P1_backup[p->rank][dqs_i] = rxdqs_best_win->best_dqsien_dly_ui_p1[dqs_i]; ucbest_coarse_mck_P1_backup[p->rank][dqs_i] = rxdqs_best_win->best_dqsien_dly_mck_p1[dqs_i]; #endif } #if RDSEL_TRACKING_EN if(p->frequency >= RDSEL_TRACKING_TH) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_INI_UIPI), (ucbest_coarse_mck_backup[p->rank][0] << 4) | (ucbest_coarse_ui_backup[p->rank][0]), SHU_R0_B0_INI_UIPI_CURR_INI_UI_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_INI_UIPI), rxdqs_best_win->best_dqsien_dly_pi[0], SHU_R0_B0_INI_UIPI_CURR_INI_PI_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_INI_UIPI), (ucbest_coarse_mck_backup[p->rank][1] << 4) | (ucbest_coarse_ui_backup[p->rank][1]), SHU_R0_B1_INI_UIPI_CURR_INI_UI_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_INI_UIPI), rxdqs_best_win->best_dqsien_dly_pi[1], SHU_R0_B1_INI_UIPI_CURR_INI_PI_B1); } #endif } #if GATING_AUTO_K_SUPPORT static void rxdqs_gating_auto_cal_reset(DRAMC_CTX_T *p) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), P_Fld(0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_RK0_SW_RST) | P_Fld(0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_RK1_SW_RST) | P_Fld(0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_SW_RST)); mcDELAY_US(1); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), P_Fld(0x0, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_RK0_SW_RST) | P_Fld(0x0, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_RK1_SW_RST) | P_Fld(0x0, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_SW_RST)); } static void rxdqs_gating_auto_cal_cfg(DRAMC_CTX_T *p, struct rxdqs_gating_auto_param *auto_param) { rxdqs_gating_auto_cal_reset(p); if (p->frequency == 800) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_STBCNT_SW_RST); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_STBCNT_SHU_RST_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN); if (p->dram_type == TYPE_LPDDR5) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_STB_PICG_EARLY_1T_EN); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_DIS_PI_TRACK_AS_NOT_RD); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x1, B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x1, B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_STB_PICG_EARLY_1T_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_STBCAL), 0x1, MISC_SHU_STBCAL_DQSIEN_BURST_MODE); { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ9), 0x1, B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ9), 0x1, B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x2, B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6), 0x2, B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL), 0x1, MISC_STBCAL_DQSIENMODE); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), P_Fld(0x1, MISC_STBCAL2_STB_IG_XRANK_CG_RST) | P_Fld(0x1, MISC_STBCAL2_STB_RST_BY_RANK) | P_Fld(0x1, MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY2), 0x1, B0_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY2), 0x1, B1_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DUMMY_RD), 0x1, DUMMY_RD_DUMMY_RD_PA_OPT); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_CG_CTRL0), 0x1, MISC_CG_CTRL0_RG_CG_PHY_OFF_DIABLE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK_DUMMY_RD_ADR), 3, RK_DUMMY_RD_ADR_DMY_RD_LEN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TEST2_A4), 0x4, TEST2_A4_TESTAGENTRKSEL); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), P_Fld(auto_param->init_mck, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_INI_MCK) | P_Fld(auto_param->init_ui, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_INI__UI) | P_Fld(auto_param->end_mck, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_END_MCK) | P_Fld(auto_param->end_ui, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_END__UI) | P_Fld(auto_param->pi_offset, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_PI_OFFSET) | P_Fld(p->rank, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_CUR_RANK) | P_Fld(auto_param->burst_len, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_BURST_LENGTH) | P_Fld(0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_B0_EN) | P_Fld(0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_B1_EN)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), auto_param->dbg_mode, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_DEBUG_MODE_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), auto_param->early_break, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_EARLY_BREAK_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL), 0x0, MISC_STBCAL_PICGEN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_STBCAL), P_Fld(0x0, MISC_SHU_STBCAL_STBCALEN) | P_Fld(0x0, MISC_SHU_STBCAL_STB_SELPHCALEN)); mcSHOW_DBG_MSG(("[Gating] AUTO K with param:\n")); mcSHOW_DBG_MSG(("\tinit_mck: %d, init_ui: %d, end_mck: %d, end_ui: %d\n", auto_param->init_mck, auto_param->init_ui, auto_param->end_mck, auto_param->end_ui)); mcSHOW_DBG_MSG(("\tpi_offset: %d, early_break: %s\n", auto_param->pi_offset, (auto_param->early_break)? "ENABLE" : "DISABLE")); } static void rxdqs_gating_auto_cal_trigger(DRAMC_CTX_T *p) { mcSHOW_DBG_MSG(("[Gating] AUTO K start...\n")); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), 0x1, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_GO); } static void rxdqs_gating_auto_cal_stop(DRAMC_CTX_T *p) { mcSHOW_DBG_MSG(("[Gating] AUTO K stop...\n")); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DQSIEN_AUTOK_CFG0), 0x0, MISC_DQSIEN_AUTOK_CFG0_DQSIEN_AUTOK_GO); rxdqs_gating_auto_cal_reset(p); } #endif static void rxdqs_gating_set_final_result(DRAMC_CTX_T *p, U8 mck2ui, struct rxdqs_gating_best_win *best_win) { //U8 reg_mck, reg_ui; //U8 value; //U8 reg_mck_rodt[DQS_BYTE_NUMBER], reg_ui_rodt[DQS_BYTE_NUMBER]; //U8 reg_mck_rodt_p1[DQS_BYTE_NUMBER], reg_ui_rodt_p1[DQS_BYTE_NUMBER]; //U8 dqs_i; #if GATING_RODT_LATANCY_EN for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { reg_mck = best_win->best_dqsien_dly_mck[dqs_i]; reg_ui = best_win->best_dqsien_dly_ui[dqs_i]; value = (reg_mck * mck2ui) + reg_ui; if (value >= 11) { U8 rodt_mck2ui = get_rodt_mck2ui(p); value -= 11; reg_mck_rodt[dqs_i] = value / rodt_mck2ui; reg_ui_rodt[dqs_i] = value % rodt_mck2ui; reg_mck_rodt_p1[dqs_i] = reg_mck_rodt[dqs_i]; reg_ui_rodt_p1[dqs_i] = reg_ui_rodt[dqs_i]; } else { reg_mck_rodt[dqs_i] = 0; reg_ui_rodt[dqs_i] = 0; reg_mck_rodt_p1[dqs_i] = 4; reg_ui_rodt_p1[dqs_i] = 4; mcSHOW_DBG_MSG(("[Warning] RODT cannot be -11UI for B%d\n", dqs_i)); } mcSHOW_DBG_MSG(("DQS%d Final RODTEN: (%2d, %2d)\n", dqs_i, reg_mck_rodt[dqs_i], reg_ui_rodt[dqs_i])); mcSHOW_DBG_MSG(("DQS%d Final RODTEN_P1: (%2d, %2d)\n", dqs_i, reg_mck_rodt_p1[dqs_i], reg_ui_rodt_p1[dqs_i])); } #endif vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_MCK_UI_DLY), P_Fld(best_win->best_dqsien_dly_mck[0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0) | P_Fld(best_win->best_dqsien_dly_ui[0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0) | P_Fld(best_win->best_dqsien_dly_mck_p1[0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0) | P_Fld(best_win->best_dqsien_dly_ui_p1[0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQSIEN_MCK_UI_DLY), P_Fld(best_win->best_dqsien_dly_mck[1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1) | P_Fld(best_win->best_dqsien_dly_ui[1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1) | P_Fld(best_win->best_dqsien_dly_mck_p1[1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1) | P_Fld(best_win->best_dqsien_dly_ui_p1[1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1)); #if GATING_RODT_LATANCY_EN vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_RODTEN_MCK_UI_DLY), P_Fld(reg_mck_rodt[0], SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_MCK_P0_B0) | P_Fld(reg_ui_rodt[0], SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_UI_P0_B0) | P_Fld(reg_mck_rodt_p1[0], SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_MCK_P1_B0) | P_Fld(reg_ui_rodt_p1[0], SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_UI_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_RODTEN_MCK_UI_DLY), P_Fld(reg_mck_rodt[1], SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_MCK_P0_B1) | P_Fld(reg_ui_rodt[1], SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_UI_P0_B1) | P_Fld(reg_mck_rodt_p1[1], SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_MCK_P1_B1) | P_Fld(reg_ui_rodt_p1[1], SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_UI_P1_B1)); #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_PI_DLY), best_win->best_dqsien_dly_pi[0], SHU_RK_B0_DQSIEN_PI_DLY_DQSIEN_PI_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQSIEN_PI_DLY), best_win->best_dqsien_dly_pi[1], SHU_RK_B1_DQSIEN_PI_DLY_DQSIEN_PI_B1); } #if GATING_AUTO_K_SUPPORT static void rxdqs_gating_auto_xlate(DRAMC_CTX_T *p, struct rxdqs_gating_best_win *best_win, struct rxdqs_gating_cal *rxdqs_cal) { u8 mck, ui, pi; U8 mck_p1, ui_p1; u8 mck2ui, freq_div; U8 total_ui; #if GATING_RODT_LATANCY_EN U8 mck_rodt, ui_rodt; U8 mck_rodt_p1, ui_rodt_p1; #endif U16 value; u8 dqs_i; for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { mck = best_win->best_dqsien_dly_mck[dqs_i]; ui = best_win->best_dqsien_dly_ui[dqs_i]; pi = best_win->best_dqsien_dly_pi[dqs_i]; mck2ui = rxdqs_cal->dqsien_ui_per_mck; freq_div = rxdqs_cal->dqsien_freq_div; if (vGet_Div_Mode(p) == DIV16_MODE) total_ui = (mck << 4) + ui; else if (vGet_Div_Mode(p) == DIV8_MODE) total_ui = (mck << 3) + ui; else total_ui = (mck << 2) + ui; mck = (total_ui >> 4); ui = (total_ui & 0xf); value = mck * mck2ui + ui; mck_p1 = (value + freq_div) / mck2ui; ui_p1 = (value + freq_div) % mck2ui; mcSHOW_DBG_MSG(("[Gating][RG] DQS%d Final result: (%d, %d, %d)\n", dqs_i, mck, ui, pi)); mcSHOW_DBG_MSG(("[Gating][RG] DQS%d Final result P1: (%d, %d)\n", dqs_i, mck_p1, ui_p1)); best_win->best_dqsien_dly_mck[dqs_i] = mck; best_win->best_dqsien_dly_ui[dqs_i] = ui; best_win->best_dqsien_dly_pi[dqs_i] = pi; best_win->best_dqsien_dly_mck_p1[dqs_i] = mck_p1; best_win->best_dqsien_dly_ui_p1[dqs_i] = ui_p1; best_win->best_dqsien_dly_pi_p1[dqs_i] = pi; } } #define RXDQS_GATING_AUTO_CAL_STATUS_BYTE_OFFSET 0x40 static DRAM_STATUS_T rxdqs_gating_auto_cal_status(DRAMC_CTX_T *p, struct rxdqs_gating_auto_param *auto_param, struct rxdqs_gating_best_win *best_win) { U8 mck_center[DQS_BYTE_NUMBER], ui_center[DQS_BYTE_NUMBER], pi_center[DQS_BYTE_NUMBER]; U8 mck_left[DQS_BYTE_NUMBER], ui_left[DQS_BYTE_NUMBER], pi_left[DQS_BYTE_NUMBER]; U8 mck_right[DQS_BYTE_NUMBER], ui_right[DQS_BYTE_NUMBER], pi_right[DQS_BYTE_NUMBER]; U8 done[DQS_BYTE_NUMBER] = { 0 }, error[DQS_BYTE_NUMBER] = { 0 }; DRAM_STATUS_T ret; U8 done_bytes, total_bytes; U8 byte_ofst; U8 dqs_i; //U8 div_mode; total_bytes = DQS_BYTE_NUMBER; done_bytes = 0; ret = DRAM_OK; while (done_bytes < total_bytes) { for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { if (done[dqs_i]) continue; byte_ofst = dqs_i * RXDQS_GATING_AUTO_CAL_STATUS_BYTE_OFFSET; done[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS0 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS0_AUTOK_DONE_B0_RK0); error[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS0 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS0_AUTOK_ERR_B0_RK0); if (done[dqs_i] || error[dqs_i]) { if (error[dqs_i] == 0) { mck_center[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS0 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS0_DQSIEN_AUTOK_C_MCK_B0_RK0); ui_center[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS0 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS0_DQSIEN_AUTOK_C__UI_B0_RK0); pi_center[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS0 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS0_DQSIEN_AUTOK_C__PI_B0_RK0); mck_left[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_L_MCK_B0_RK0); ui_left[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_L__UI_B0_RK0); pi_left[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_L__PI_B0_RK0); if (auto_param->early_break == DISABLE) { mck_right[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_R_MCK_B0_RK0); ui_right[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_R__UI_B0_RK0); pi_right[dqs_i] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_STATUS1 + byte_ofst), DQSIEN_AUTOK_B0_RK0_STATUS1_DQSIEN_AUTOK_R__PI_B0_RK0); } } else { done[dqs_i] = 1; } if (auto_param->dbg_mode == ENABLE) { U32 dbg_reg_addr; U32 dbg_reg_idx; U32 dbg_reg_val; dbg_reg_addr = DRAMC_REG_ADDR( DDRPHY_REG_DQSIEN_AUTOK_B0_RK0_DBG_STATUS0 + byte_ofst); for (dbg_reg_idx = 0; dbg_reg_idx < RXDQS_GATING_AUTO_DBG_REG_NUM; dbg_reg_idx++, dbg_reg_addr += 4) { dbg_reg_val = u4IO32Read4B(dbg_reg_addr); mcSHOW_ERR_MSG(("B%d Gating AUTOK DBG Status-%d: [0x%08x]\n", dqs_i, dbg_reg_idx, dbg_reg_val)); } } } else { mcSHOW_ERR_MSG(("B%d Gating AUTOK didn't be done\n", dqs_i)); } done_bytes++; } mcDELAY_MS(1); } for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { mcSHOW_DBG_MSG(("[Gating][%s] AUTOK of CH-%d, Rk-%d, Byte-%d:\n", error[dqs_i]? "Fail" : "Pass", p->channel, p->rank, dqs_i)); if (done[dqs_i]) { if (error[dqs_i] == 0) { mcSHOW_DBG_MSG(("\tcenter(%2d, %2d, %2d)\n", mck_center[dqs_i], ui_center[dqs_i], pi_center[dqs_i])); mcSHOW_DBG_MSG(("\tleft(%2d, %2d, %2d)\n", mck_left[dqs_i], ui_left[dqs_i], pi_left[dqs_i])); if (auto_param->early_break == DISABLE) { mcSHOW_DBG_MSG(("\tright(%2d, %2d, %2d)\n", mck_right[dqs_i], ui_right[dqs_i], pi_right[dqs_i])); } } if (error[dqs_i]) { ret = DRAM_FAIL; } else { best_win->best_dqsien_dly_mck[dqs_i] = mck_center[dqs_i]; best_win->best_dqsien_dly_ui[dqs_i] = ui_center[dqs_i]; best_win->best_dqsien_dly_pi[dqs_i] = pi_center[dqs_i]; } } } rxdqs_gating_auto_cal_stop(p); return ret; } static DRAM_STATUS_T dramc_rx_dqs_gating_auto_cal(DRAMC_CTX_T *p) { struct rxdqs_gating_auto_param auto_param; struct rxdqs_gating_best_win rxdqs_best_win; struct rxdqs_gating_cal rxdqs_cal; DRAM_STATUS_T ret; U8 start_ui, end_ui; U8 mck2ui_hw; //mck2ui_rg, freq_div U32 reg_backup_address[ ] = { (DRAMC_REG_ADDR(DRAMC_REG_DUMMY_RD)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_CG_CTRL0)), (DRAMC_REG_ADDR(DRAMC_REG_TEST2_A4)), (DRAMC_REG_ADDR(DRAMC_REG_RK_DUMMY_RD_ADR)) }; DramcBackupRegisters(p, reg_backup_address, sizeof (reg_backup_address) / sizeof (U32)); ret = DRAM_OK; memset((void *)&auto_param, 0, sizeof auto_param); memset((void *)&rxdqs_best_win, 0, sizeof rxdqs_best_win); memset((void *)&rxdqs_cal, 0, sizeof rxdqs_cal); if (vGet_Div_Mode(p) == DIV4_MODE) rxdqs_cal.dqsien_freq_div = 2; else rxdqs_cal.dqsien_freq_div = 4; rxdqs_cal.dqsien_ui_per_mck = DQS_GW_UI_PER_MCK; if (!rxdqs_gating_bypass(p)) { if (vGet_Div_Mode(p) == DIV16_MODE) mck2ui_hw = 16; else if (vGet_Div_Mode(p) == DIV8_MODE) mck2ui_hw = 8; else mck2ui_hw = 4; #if ENABLE_GATING_AUTOK_WA if (__wa__gating_autok_init_ui[p->rank] > 3) start_ui = __wa__gating_autok_init_ui[p->rank] - 3; else #endif start_ui = u1GetGatingStartPos(p, AUTOK_ON); end_ui = start_ui + 32; auto_param.early_break = ENABLE; auto_param.dbg_mode = ENABLE; auto_param.init_mck = start_ui / mck2ui_hw; auto_param.init_ui = start_ui % mck2ui_hw; auto_param.end_mck = end_ui / mck2ui_hw; auto_param.end_ui = end_ui % mck2ui_hw; auto_param.pi_offset = 2; auto_param.burst_len = RXDQS_BURST_LEN_8; #if FOR_DV_SIMULATION_USED == 1 cal_sv_rand_args_t *psra = get_psra(); if (psra) { auto_param.early_break = psra->dqsien_autok_early_break_en? ENABLE: DISABLE; auto_param.dbg_mode = psra->dqsien_autok_dbg_mode_en? ENABLE: DISABLE; auto_param.pi_offset = psra->dqsien_autok_pi_offset? ENABLE: DISABLE; } #endif rxdqs_gating_auto_cal_cfg(p, &auto_param); rxdqs_gating_auto_cal_trigger(p); ret = rxdqs_gating_auto_cal_status(p, &auto_param, &rxdqs_best_win); if (ret == DRAM_OK) vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_OK); rxdqs_gating_auto_xlate(p, &rxdqs_best_win, &rxdqs_cal); } rxdqs_gating_fastk_save_restore(p, &rxdqs_best_win, &rxdqs_cal); rxdqs_gating_set_final_result(p, rxdqs_cal.dqsien_ui_per_mck, &rxdqs_best_win); rxdqs_gating_misc_process(p, &rxdqs_best_win); DramcRestoreRegisters(p, reg_backup_address, sizeof (reg_backup_address) / sizeof (U32)); DramPhyReset(p); return ret; } #endif static void rxdqs_gating_sw_cal_init(DRAMC_CTX_T *p, U8 use_enhanced_rdqs) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF0), 0, SHU_CONF0_PBREFEN); if (p->frequency == 800) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_STBCNT_SW_RST); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_STBCNT_SHU_RST_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN); if (p->dram_type == TYPE_LPDDR5) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_STB_PICG_EARLY_1T_EN); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1), 0x1, MISC_STBCAL1_DIS_PI_TRACK_AS_NOT_RD); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x1, B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x1, B0_DQ6_RG_RX_ARDQ_OP_BIAS_SW_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0x1, MISC_STBCAL2_STB_PICG_EARLY_1T_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_STBCAL), 0x1, MISC_SHU_STBCAL_DQSIEN_BURST_MODE); { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ9), 0x1, B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ9), 0x1, B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6), 0x2, B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6), 0x2, B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL), 0x1, MISC_STBCAL_DQSIENMODE); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), P_Fld(0x1, MISC_STBCAL2_STB_IG_XRANK_CG_RST) | P_Fld(0x1, MISC_STBCAL2_STB_RST_BY_RANK) | P_Fld(0x1, MISC_STBCAL2_DQSIEN_SELPH_BY_RANK_EN)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY2), 0x1, B0_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY2), 0x1, B1_PHY2_RG_RX_ARDQS_DQSIEN_UI_LEAD_LAG_EN_B1); //DramcHWGatingOnOff(p, 0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 1, MISC_STBCAL2_STBENCMPEN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RX_SET0), 0, RX_SET0_DM4TO1MODE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 1, MISC_STBCAL2_DQSG_CNT_EN); mcDELAY_US(4); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 1, MISC_STBCAL2_DQSG_CNT_RST); mcDELAY_US(1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0, MISC_STBCAL2_DQSG_CNT_RST); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_CTRL1), u1GetRank(p), MISC_CTRL1_R_DMSTBENCMP_RK_OPT); DramcEngine2Init(p, 0x55000000, 0xaa000000 | GATING_PATTERN_NUM_LP5, TEST_AUDIO_PATTERN, 0, TE_NO_UI_SHIFT); if (use_enhanced_rdqs) { } } static void rxdqs_gating_set_dqsien_dly(DRAMC_CTX_T *p, U8 dly_ui, struct rxdqs_gating_cal *rxdqs_cal) { //U32 value; U32 reg_mck, reg_ui; U32 reg_mck_p1, reg_ui_p1; #if GATING_RODT_LATANCY_EN U32 reg_mck_rodt, reg_ui_rodt; U32 reg_mck_rodt_p1, reg_ui_rodt_p1; #endif U8 mck2ui = rxdqs_cal->dqsien_ui_per_mck; rxdqs_cal->dqsien_dly_mck = dly_ui / rxdqs_cal->dqsien_ui_per_mck; rxdqs_cal->dqsien_dly_ui = dly_ui % rxdqs_cal->dqsien_ui_per_mck; rxdqs_cal->dqsien_dly_mck_p1 = (dly_ui + rxdqs_cal->dqsien_freq_div) / mck2ui; rxdqs_cal->dqsien_dly_ui_p1 = (dly_ui + rxdqs_cal->dqsien_freq_div) % mck2ui; reg_mck = rxdqs_cal->dqsien_dly_mck; reg_ui = rxdqs_cal->dqsien_dly_ui; reg_mck_p1 = rxdqs_cal->dqsien_dly_mck_p1; reg_ui_p1 = rxdqs_cal->dqsien_dly_ui_p1; #if GATING_RODT_LATANCY_EN value = (reg_mck * mck2ui) + reg_ui; if (value >= 11) { U8 rodt_mck2ui = get_rodt_mck2ui(p); value -= 11; reg_mck_rodt = value / rodt_mck2ui; reg_ui_rodt = value % rodt_mck2ui; reg_mck_rodt_p1 = reg_mck_rodt; reg_ui_rodt_p1 = reg_ui_rodt; } else { reg_mck_rodt = 0; reg_ui_rodt = 0; reg_mck_rodt_p1 = 4; reg_ui_rodt_p1 = 4; mcSHOW_DBG_MSG(("[Warning] RODT cannot be -11UI\n")); } #endif vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_MCK_UI_DLY), P_Fld(reg_mck, SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0) | P_Fld(reg_ui, SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0) | P_Fld(reg_mck_p1, SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0) | P_Fld(reg_ui_p1, SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQSIEN_MCK_UI_DLY), P_Fld(reg_mck, SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1) | P_Fld(reg_ui, SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1) | P_Fld(reg_mck_p1, SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1) | P_Fld(reg_ui_p1, SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1)); #if GATING_RODT_LATANCY_EN vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_RODTEN_MCK_UI_DLY), P_Fld(reg_mck_rodt, SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_MCK_P0_B0) | P_Fld(reg_ui_rodt, SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_UI_P0_B0) | P_Fld(reg_mck_rodt_p1, SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_MCK_P1_B0) | P_Fld(reg_ui_rodt_p1, SHU_RK_B0_RODTEN_MCK_UI_DLY_RODTEN_UI_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_RODTEN_MCK_UI_DLY), P_Fld(reg_mck_rodt, SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_MCK_P0_B1) | P_Fld(reg_ui_rodt, SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_UI_P0_B1) | P_Fld(reg_mck_rodt_p1, SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_MCK_P1_B1) | P_Fld(reg_ui_rodt_p1, SHU_RK_B1_RODTEN_MCK_UI_DLY_RODTEN_UI_P1_B1)); #endif } static void rxdqs_gating_sw_cal_trigger(DRAMC_CTX_T *p, struct rxdqs_gating_cal *rxdqs_cal) { #if 0 if (u1IsPhaseMode(p) == TRUE) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), rxdqs_cal->dqsien_dly_pi >> 4, SHU_R0_B0_DQ0_DA_ARPI_DDR400_0D5UI_RK0_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), rxdqs_cal->dqsien_dly_pi >> 4, SHU_R0_B1_DQ0_DA_ARPI_DDR400_0D5UI_RK0_B1); } else #endif { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_PI_DLY), rxdqs_cal->dqsien_dly_pi, SHU_RK_B0_DQSIEN_PI_DLY_DQSIEN_PI_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQSIEN_PI_DLY), rxdqs_cal->dqsien_dly_pi, SHU_RK_B1_DQSIEN_PI_DLY_DQSIEN_PI_B1); } DramPhyReset(p); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 1, MISC_STBCAL2_DQSG_CNT_RST); mcDELAY_US(1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2), 0, MISC_STBCAL2_DQSG_CNT_RST); DramcEngine2Run(p, TE_OP_READ_CHECK, TEST_AUDIO_PATTERN); } static void rxdqs_gating_get_leadlag(DRAMC_CTX_T *p, struct rxdqs_gating_trans *rxdqs_trans, struct rxdqs_gating_cal *rxdqs_cal) { U8 dqs_i; U8 debounce_thrd_PI = 16; BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { if (dqs_i == 0) { rxdqs_trans->dqs_lead[0] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_B0), MISC_PHY_RGS_STBEN_B0_AD_RX_ARDQS0_STBEN_LEAD_B0); rxdqs_trans->dqs_lag[0] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_B0), MISC_PHY_RGS_STBEN_B0_AD_RX_ARDQS0_STBEN_LAG_B0); } else { if (isLP4_DSC){ rxdqs_trans->dqs_lead[1] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_CMD), MISC_PHY_RGS_STBEN_CMD_AD_RX_ARCLK_STBEN_LEAD); rxdqs_trans->dqs_lag[1] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_CMD), MISC_PHY_RGS_STBEN_CMD_AD_RX_ARCLK_STBEN_LAG); } else { rxdqs_trans->dqs_lead[1] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_B1), MISC_PHY_RGS_STBEN_B1_AD_RX_ARDQS0_STBEN_LEAD_B1); rxdqs_trans->dqs_lag[1] = u4IO32ReadFldAlign( DRAMC_REG_ADDR(DDRPHY_REG_MISC_PHY_RGS_STBEN_B1), MISC_PHY_RGS_STBEN_B1_AD_RX_ARDQS0_STBEN_LAG_B1); } } if ((rxdqs_trans->dqs_lead[dqs_i] == 1) && (rxdqs_trans->dqs_lag[dqs_i] == 1)) { rxdqs_trans->dqs_high[dqs_i]++; rxdqs_trans->dqs_transition[dqs_i] = 1; rxdqs_trans->dqsien_dly_mck_leadlag[dqs_i] = rxdqs_cal->dqsien_dly_mck; rxdqs_trans->dqsien_dly_ui_leadlag[dqs_i] = rxdqs_cal->dqsien_dly_ui; rxdqs_trans->dqsien_dly_pi_leadlag[dqs_i] = rxdqs_cal->dqsien_dly_pi; } else if ((rxdqs_trans->dqs_high[dqs_i] * rxdqs_cal->dqsien_pi_adj_step) >= debounce_thrd_PI) { if (((rxdqs_trans->dqs_lead[dqs_i] == 1) && (rxdqs_trans->dqs_lag[dqs_i] == 0)) || ((rxdqs_trans->dqs_lead[dqs_i] == 0) && (rxdqs_trans->dqs_lag[dqs_i] == 1))) { rxdqs_trans->dqs_transition[dqs_i]++; } #if GATING_LEADLAG_LOW_LEVEL_CHECK else if ((rxdqs_trans->dqs_lead[dqs_i] == 0) && (rxdqs_trans->dqs_lag[dqs_i] == 0)){ if ((rxdqs_trans->dqs_low[dqs_i] * rxdqs_cal->dqsien_pi_adj_step) >= debounce_thrd_PI) { rxdqs_trans->dqs_transitioned[dqs_i] = 1; } rxdqs_trans->dqs_low[dqs_i]++; }else { rxdqs_trans->dqs_high[dqs_i] = 0; rxdqs_trans->dqs_low[dqs_i] = 0; } #else else { rxdqs_trans->dqs_transitioned[dqs_i] = 1; } #endif } else { rxdqs_trans->dqs_high[dqs_i] = 0; #if GATING_LEADLAG_LOW_LEVEL_CHECK rxdqs_trans->dqs_low[dqs_i] = 0; #endif } } } static U8 rxdqs_gating_sw_cal(DRAMC_CTX_T *p, struct rxdqs_gating_trans *rxdqs_trans, struct rxdqs_gating_cal *rxdqs_cal, U8 *pass_byte_count, struct rxdqs_gating_best_win *best_win, U8 dly_ui, U8 dly_ui_end) { U8 gating_error[DQS_BYTE_NUMBER]; U32 debug_cnt[DQS_BYTE_NUMBER]; U32 debug_pass_cnt; U8 dqs_i; //U8 dqs_result_r, dqs_result_f; //U16 debug_cnt_per_byte; U8 passed_bytes; memset(debug_cnt, 0, sizeof(debug_cnt)); passed_bytes = *pass_byte_count; rxdqs_gating_sw_cal_trigger(p, rxdqs_cal); if (p->rank == RANK_0) { gating_error[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_MISC_STBERR_ALL), MISC_STBERR_ALL_GATING_ERROR_B0_RK0); gating_error[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_MISC_STBERR_ALL), MISC_STBERR_ALL_GATING_ERROR_B1_RK0); } else { gating_error[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_MISC_STBERR_ALL), MISC_STBERR_ALL_GATING_ERROR_B0_RK1); gating_error[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR( DDRPHY_REG_MISC_STBERR_ALL), MISC_STBERR_ALL_GATING_ERROR_B1_RK1); } debug_cnt[0] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CAL_DQSG_CNT_B0)); debug_cnt[1] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CAL_DQSG_CNT_B1)); rxdqs_gating_get_leadlag(p, rxdqs_trans, rxdqs_cal); mcSHOW_DBG_MSG2(("%2d %2d %2d | ", rxdqs_cal->dqsien_dly_mck, rxdqs_cal->dqsien_dly_ui, rxdqs_cal->dqsien_dly_pi)); mcSHOW_DBG_MSG2(("B1->B0 | %x %x | %x %x | (%d %d) (%d %d)\n", debug_cnt[1], debug_cnt[0], gating_error[1], gating_error[0], rxdqs_trans->dqs_lead[1], rxdqs_trans->dqs_lag[1], rxdqs_trans->dqs_lead[0], rxdqs_trans->dqs_lag[0])); debug_pass_cnt = GATING_GOLDEND_DQSCNT_LP5; for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { if (passed_bytes & (1 << dqs_i)) continue; if ((gating_error[dqs_i] == 0) && (debug_cnt[dqs_i] == debug_pass_cnt)) { if (rxdqs_trans->dqs_transitioned[dqs_i] != 0) { U8 pass_count = rxdqs_trans->dqs_transition[dqs_i]; U8 offset = (pass_count * rxdqs_cal->dqsien_pi_adj_step) / 2; U8 mck2ui, ui2pi, freq_div; U8 tmp; mck2ui = rxdqs_cal->dqsien_ui_per_mck; ui2pi = rxdqs_cal->dqsien_pi_per_ui; freq_div = rxdqs_cal->dqsien_freq_div; tmp = rxdqs_trans->dqsien_dly_pi_leadlag[dqs_i] + offset; best_win->best_dqsien_dly_pi[dqs_i] = tmp % ui2pi; best_win->best_dqsien_dly_pi_p1[dqs_i] = best_win->best_dqsien_dly_pi[dqs_i]; tmp /= ui2pi; tmp = rxdqs_trans->dqsien_dly_ui_leadlag[dqs_i] + tmp; best_win->best_dqsien_dly_ui[dqs_i] = tmp % mck2ui; best_win->best_dqsien_dly_mck[dqs_i] = rxdqs_trans->dqsien_dly_mck_leadlag[dqs_i] + (tmp / mck2ui); best_win->best_dqsien_dly_ui_p1[dqs_i] = best_win->best_dqsien_dly_mck[dqs_i] * mck2ui + best_win->best_dqsien_dly_ui[dqs_i] + freq_div; /*mcSHOW_DBG_MSG(("Total UI for P1: %d, mck2ui %d\n", best_win->best_dqsien_dly_mck_p1[dqs_i], mck2ui));*/ best_win->best_dqsien_dly_mck_p1[dqs_i] = best_win->best_dqsien_dly_ui_p1[dqs_i] / mck2ui; best_win->best_dqsien_dly_ui_p1[dqs_i] = best_win->best_dqsien_dly_ui_p1[dqs_i] % mck2ui; /*mcSHOW_DBG_MSG(("best dqsien dly found for B%d: " "(%2d, %2d, %2d)\n", dqs_i, best_win->best_dqsien_dly_mck[dqs_i], best_win->best_dqsien_dly_ui[dqs_i], best_win->best_dqsien_dly_pi[dqs_i]));*/ passed_bytes |= 1 << dqs_i; if ((p->data_width == DATA_WIDTH_16BIT) && (passed_bytes == 0x3)) { dly_ui = dly_ui_end; break; } } } else { rxdqs_trans->dqs_high[dqs_i] = 0; rxdqs_trans->dqs_transition[dqs_i] = 0; rxdqs_trans->dqs_transitioned[dqs_i] = 0; } } *pass_byte_count = passed_bytes; return dly_ui; } static DRAM_STATUS_T dramc_rx_dqs_gating_sw_cal(DRAMC_CTX_T *p, U8 use_enhance_rdqs) { struct rxdqs_gating_cal rxdqs_cal; struct rxdqs_gating_trans rxdqs_trans; struct rxdqs_gating_best_win rxdqs_best_win; U8 dly_ui, dly_ui_start, dly_ui_end; U8 pi_per_ui, ui_per_mck, freq_div; U8 pass_byte_count; //U32 value; //U8 dqs_i; U8 u1GatingErrorFlag=0; if (p == NULL) { mcSHOW_ERR_MSG(("[Error] Context NULL\n")); return DRAM_FAIL; } memset(&rxdqs_cal, 0, sizeof(struct rxdqs_gating_cal)); memset(&rxdqs_trans, 0, sizeof(struct rxdqs_gating_trans)); memset(&rxdqs_best_win, 0, sizeof(struct rxdqs_gating_best_win)); pi_per_ui = DQS_GW_PI_PER_UI; ui_per_mck = DQS_GW_UI_PER_MCK; if (vGet_Div_Mode(p) == DIV4_MODE) freq_div = 2; else freq_div = 4; if (u1IsPhaseMode(p)) rxdqs_cal.dqsien_pi_adj_step = (0x1 << 4); else rxdqs_cal.dqsien_pi_adj_step = DQS_GW_FINE_STEP; #if ENABLE_GATING_AUTOK_WA if (__wa__gating_swk_for_autok) rxdqs_cal.dqsien_pi_adj_step = pi_per_ui; #endif rxdqs_cal.dqsien_pi_per_ui = pi_per_ui; rxdqs_cal.dqsien_ui_per_mck = ui_per_mck; rxdqs_cal.dqsien_freq_div = freq_div; U32 reg_backup_address[ ] = { (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL1)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2)), }; DramcBackupRegisters(p, reg_backup_address, sizeof (reg_backup_address) / sizeof (U32)); if (!rxdqs_gating_bypass(p)) { rxdqs_gating_sw_cal_init(p, use_enhance_rdqs); #if 1 #if (LP5_DDR4266_RDBI_WORKAROUND) if((is_lp5_family(p)) && (p->frequency == 2133)) dly_ui_start = 15; else if((is_lp5_family(p)) && (p->frequency == 2750)) dly_ui_start = 12; else dly_ui_start = u1GetGatingStartPos(p, AUTOK_OFF); #else dly_ui_start = u1GetGatingStartPos(p, AUTOK_OFF); #endif dly_ui_end = dly_ui_start+ 32; pass_byte_count = 0; #else { dly_ui_start = 9; if(p->freq_sel==LP4_DDR4266) { dly_ui_start = 16; } dly_ui_end = dly_ui_start + 32; pass_byte_count = 0; } #endif for (dly_ui = dly_ui_start; dly_ui < dly_ui_end; dly_ui += DQS_GW_COARSE_STEP) { rxdqs_gating_set_dqsien_dly(p, dly_ui, &rxdqs_cal); for (rxdqs_cal.dqsien_dly_pi = 0; rxdqs_cal.dqsien_dly_pi < pi_per_ui; rxdqs_cal.dqsien_dly_pi += rxdqs_cal.dqsien_pi_adj_step) { dly_ui = rxdqs_gating_sw_cal(p, &rxdqs_trans, &rxdqs_cal, &pass_byte_count, &rxdqs_best_win, dly_ui, dly_ui_end); if (dly_ui == dly_ui_end) break; } } DramcEngine2End(p); if (pass_byte_count == 0x3) { u1GatingErrorFlag=0; vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_OK); } else { u1GatingErrorFlag=1; mcSHOW_ERR_MSG(("error, no all pass taps in DQS!,pass_byte_count=%d\n", pass_byte_count)); } (void)u1GatingErrorFlag; #if (ENABLE_GATING_AUTOK_WA) if (!u1GatingErrorFlag && __wa__gating_swk_for_autok) { U8 ui[DQS_BYTE_NUMBER], ui_min = 0xff; U8 dqs_i; for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++){ ui[dqs_i] = rxdqs_best_win.best_dqsien_dly_mck[dqs_i] * ui_per_mck + rxdqs_best_win.best_dqsien_dly_ui[dqs_i]; if (ui[dqs_i] < ui_min) ui_min = ui[dqs_i]; } __wa__gating_autok_init_ui[p->rank] = ui_min; DramcRestoreRegisters(p, reg_backup_address, sizeof (reg_backup_address) / sizeof (U32)); return DRAM_OK; } #endif } rxdqs_gating_fastk_save_restore(p, &rxdqs_best_win, &rxdqs_cal); rxdqs_gating_misc_process(p, &rxdqs_best_win); mcSHOW_DBG_MSG4(("[Gating] SW calibration Done\n")); rxdqs_gating_set_final_result(p, ui_per_mck, &rxdqs_best_win); DramcRestoreRegisters(p, reg_backup_address, sizeof (reg_backup_address) / sizeof (U32)); DramPhyReset(p); return DRAM_OK; } DRAM_STATUS_T dramc_rx_dqs_gating_cal(DRAMC_CTX_T *p, u8 autok, U8 use_enhanced_rdqs) { DRAM_STATUS_T ret; vPrintCalibrationBasicInfo(p); mcSHOW_DBG_MSG(("[DramcGating] \n")); #if ENABLE_GATING_AUTOK_WA if (autok) { __wa__gating_swk_for_autok = 1; dramc_rx_dqs_gating_sw_cal(p, use_enhanced_rdqs); __wa__gating_swk_for_autok = 0; } #endif vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_FAIL); #if GATING_AUTO_K_SUPPORT if (autok) { #if ENABLE_GATING_AUTOK_WA if (rxdqs_gating_bypass(p)) return DRAM_OK; #endif ret = dramc_rx_dqs_gating_auto_cal(p); if (ret == DRAM_OK) { return DRAM_OK; } mcSHOW_ERR_MSG(("[Error] Gating auto calibration fail!!\n")); } #endif mcSHOW_DBG_MSG(("SW mode calibration\n")); return dramc_rx_dqs_gating_sw_cal(p, use_enhanced_rdqs); } #if GATING_ADJUST_TXDLY_FOR_TRACKING void DramcRxdqsGatingPostProcess(DRAMC_CTX_T *p) { U8 dqs_i; //u1RankRxDVS = 0 U8 u1RankIdx, u1RankMax; //u1RankBak S8 s1ChangeDQSINCTL; #if XRTRTR_NEW_CROSS_RK_MODE U16 u2PHSINCTL = 0; U32 u4Rank_Sel_MCK_P0[2], u4Rank_Sel_MCK_P1[2], u4RANKINCTL_STB; #endif #if RDSEL_TRACKING_EN //U32 u4PI_value[2] = {0}; #endif U32 backup_rank; U32 u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R, reg_TX_dly_DQSgated_min = 0; //U32 u4ReadRODT, u4ReadTXDLY[RANK_MAX][DQS_BYTE_NUMBER], u4ReadTXDLY_P1[RANK_MAX][DQS_BYTE_NUMBER] U8 mck2ui_shift; backup_rank = u1GetRank(p); #ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY if (vGet_Div_Mode(p) == DIV8_MODE) { if (p->frequency >= 1333) { reg_TX_dly_DQSgated_min = 2; } else { reg_TX_dly_DQSgated_min = 1; } } else { reg_TX_dly_DQSgated_min = 1; } #else if (p->frequency >= 1333) { reg_TX_dly_DQSgated_min = 3; } else { reg_TX_dly_DQSgated_min = 2; } #endif #if 0 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU_B0_DQ7), u1RankRxDVS, SHU_B0_DQ7_R_DMRANKRXDVS_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU_B1_DQ7), u1RankRxDVS, SHU_B1_DQ7_R_DMRANKRXDVS_B1); #endif s1ChangeDQSINCTL = reg_TX_dly_DQSgated_min - u1TXDLY_Cal_min; //mcDUMP_REG_MSG(("\n[dumpRG] RxdqsGatingPostProcess\n")); mcSHOW_DBG_MSG(("[RxdqsGatingPostProcess] freq %d\n" "ChangeDQSINCTL %d, reg_TX_dly_DQSgated_min %d, u1TXDLY_Cal_min %d\n", p->frequency, s1ChangeDQSINCTL, reg_TX_dly_DQSgated_min, u1TXDLY_Cal_min)); /*mcDUMP_REG_MSG(("[RxdqsGatingPostProcess] freq %d\n" "ChangeDQSINCTL %d, reg_TX_dly_DQSgated_min %d, u1TXDLY_Cal_min %d\n", p->frequency, s1ChangeDQSINCTL, reg_TX_dly_DQSgated_min, u1TXDLY_Cal_min));*/ if (vGet_Div_Mode(p) == DIV16_MODE) mck2ui_shift = 4; else if (vGet_Div_Mode(p) == DIV8_MODE) mck2ui_shift = 3; else mck2ui_shift = 2; if (s1ChangeDQSINCTL != 0) { u1TXDLY_Cal_min += s1ChangeDQSINCTL; u1TXDLY_Cal_max += s1ChangeDQSINCTL; if (p->support_rank_num == RANK_DUAL) u1RankMax = RANK_MAX; else u1RankMax = RANK_1; for (u1RankIdx = 0; u1RankIdx < u1RankMax; u1RankIdx++) { mcSHOW_DBG_MSG2(("Rank: %d\n", u1RankIdx)); //mcDUMP_REG_MSG(("Rank: %d\n", u1RankIdx)); for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { #if 1 U8 total_ui, total_ui_P1; total_ui = (ucbest_coarse_mck_backup[u1RankIdx][dqs_i] << 4) + ucbest_coarse_ui_backup[u1RankIdx][dqs_i]; total_ui_P1 = (ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i] << 4) + ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i]; total_ui += (s1ChangeDQSINCTL << mck2ui_shift); total_ui_P1 += (s1ChangeDQSINCTL << mck2ui_shift); ucbest_coarse_mck_backup[u1RankIdx][dqs_i] = (total_ui >> 4); ucbest_coarse_ui_backup[u1RankIdx][dqs_i] = total_ui & 0xf; ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i] = (total_ui_P1 >> 4); ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i] = total_ui_P1 & 0xf; #else if (vGet_Div_Mode(p) == DIV8_MODE) { u4ReadTXDLY[u1RankIdx][dqs_i] = ucbest_coarse_mck_backup[u1RankIdx][dqs_i]; u4ReadTXDLY_P1[u1RankIdx][dqs_i] = ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i]; u4ReadTXDLY[u1RankIdx][dqs_i] += s1ChangeDQSINCTL; u4ReadTXDLY_P1[u1RankIdx][dqs_i] += s1ChangeDQSINCTL; ucbest_coarse_mck_backup[u1RankIdx][dqs_i] = u4ReadTXDLY[u1RankIdx][dqs_i]; ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i] = u4ReadTXDLY_P1[u1RankIdx][dqs_i]; } else { u4ReadTXDLY[u1RankIdx][dqs_i] = ((ucbest_coarse_mck_backup[u1RankIdx][dqs_i] << 1) + ((ucbest_coarse_ui_backup[u1RankIdx][dqs_i] >> 2) & 0x1)); u4ReadTXDLY_P1[u1RankIdx][dqs_i] = ((ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i] << 1) + ((ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i] >> 2) & 0x1)); u4ReadTXDLY[u1RankIdx][dqs_i] += s1ChangeDQSINCTL; u4ReadTXDLY_P1[u1RankIdx][dqs_i] += s1ChangeDQSINCTL; ucbest_coarse_mck_backup[u1RankIdx][dqs_i] = (u4ReadTXDLY[u1RankIdx][dqs_i] >> 1); ucbest_coarse_ui_backup[u1RankIdx][dqs_i] = ((u4ReadTXDLY[u1RankIdx][dqs_i] & 0x1) << 2) + (ucbest_coarse_ui_backup[u1RankIdx][dqs_i] & 0x3); ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i] = (u4ReadTXDLY_P1[u1RankIdx][dqs_i] >> 1); ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i] = ((u4ReadTXDLY_P1[u1RankIdx][dqs_i] & 0x1) << 2) + (ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i] & 0x3); } #endif mcSHOW_DBG_MSG(("PostProcess best DQS%d dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_mck_backup[u1RankIdx][dqs_i], ucbest_coarse_ui_backup[u1RankIdx][dqs_i])); //mcDUMP_REG_MSG(("PostProcess best DQS%d dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_mck_backup[u1RankIdx][dqs_i], ucbest_coarse_ui_backup[u1RankIdx][dqs_i])); #ifdef FOR_HQA_REPORT_USED HQA_Log_Message_for_Report(p, p->channel, u1RankIdx, HQA_REPORT_FORMAT0, "Gating_Center_", "2T", dqs_i, ucbest_coarse_mck_backup[u1RankIdx][dqs_i], NULL); HQA_Log_Message_for_Report(p, p->channel, u1RankIdx, HQA_REPORT_FORMAT0, "Gating_Center_", "05T", dqs_i, ucbest_coarse_ui_backup[u1RankIdx][dqs_i], NULL); #endif } for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { mcSHOW_DBG_MSG(("PostProcess best DQS%d P1 dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i], ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i])); //mcDUMP_REG_MSG(("PostProcess best DQS%d P1 dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_mck_P1_backup[u1RankIdx][dqs_i], ucbest_coarse_ui_P1_backup[u1RankIdx][dqs_i])); } } for (u1RankIdx = 0; u1RankIdx < u1RankMax; u1RankIdx++) { vSetRank(p, u1RankIdx); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_MCK_UI_DLY), P_Fld(ucbest_coarse_mck_backup[u1RankIdx][0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B0) | P_Fld(ucbest_coarse_ui_backup[u1RankIdx][0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B0) | P_Fld(ucbest_coarse_mck_P1_backup[u1RankIdx][0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B0) | P_Fld(ucbest_coarse_ui_P1_backup[u1RankIdx][0], SHU_RK_B0_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B1_DQSIEN_MCK_UI_DLY), P_Fld(ucbest_coarse_mck_backup[u1RankIdx][1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P0_B1) | P_Fld(ucbest_coarse_ui_backup[u1RankIdx][1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P0_B1) | P_Fld(ucbest_coarse_mck_P1_backup[u1RankIdx][1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_MCK_P1_B1) | P_Fld(ucbest_coarse_ui_P1_backup[u1RankIdx][1], SHU_RK_B1_DQSIEN_MCK_UI_DLY_DQSIEN_UI_P1_B1)); #if RDSEL_TRACKING_EN if(p->frequency >= RDSEL_TRACKING_TH) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_INI_UIPI), (ucbest_coarse_mck_backup[u1RankIdx][0] << 4) | (ucbest_coarse_ui_backup[u1RankIdx][0]), SHU_R0_B0_INI_UIPI_CURR_INI_UI_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_INI_UIPI), (ucbest_coarse_mck_backup[u1RankIdx][1] << 4) | (ucbest_coarse_ui_backup[u1RankIdx][1]), SHU_R0_B1_INI_UIPI_CURR_INI_UI_B1); } #endif } } vSetRank(p, backup_rank); u4ReadDQSINCTL = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RK_DQSCTL), MISC_SHU_RK_DQSCTL_DQSINCTL); //mcDUMP_REG_MSG(("u4ReadDQSINCTL=%d\n", u4ReadDQSINCTL)); u4ReadDQSINCTL -= s1ChangeDQSINCTL; #if ENABLE_READ_DBI if (p->DBI_R_onoff[p->dram_fsp]) { u4ReadDQSINCTL++; #if 0 u4ReadRODT = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), SHU_ODTCTRL_RODT); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), u4ReadRODT + 1, SHU_ODTCTRL_RODT); #endif } #endif #if XRTRTR_NEW_CROSS_RK_MODE for (dqs_i = 0; dqs_i < DQS_BYTE_NUMBER; dqs_i++) { if (ucbest_coarse_mck_backup[RANK_0][dqs_i] > ucbest_coarse_mck_backup[RANK_1][dqs_i]) { u4Rank_Sel_MCK_P0[dqs_i] = (ucbest_coarse_mck_backup[RANK_0][dqs_i] > 0)? (ucbest_coarse_mck_backup[RANK_0][dqs_i] - 1): 0; u4Rank_Sel_MCK_P1[dqs_i] = (ucbest_coarse_mck_P1_backup[RANK_0][dqs_i] > 0)? (ucbest_coarse_mck_P1_backup[RANK_0][dqs_i] - 1): 0; } else { u4Rank_Sel_MCK_P0[dqs_i] = (ucbest_coarse_mck_backup[RANK_1][dqs_i] > 0)? (ucbest_coarse_mck_backup[RANK_1][dqs_i] - 1): 0; u4Rank_Sel_MCK_P1[dqs_i] = (ucbest_coarse_mck_P1_backup[RANK_1][dqs_i] > 0)? (ucbest_coarse_mck_P1_backup[RANK_1][dqs_i] - 1): 0; } } vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_RANK_SELPH_UI_DLY), P_Fld(u4Rank_Sel_MCK_P0[0], SHU_B0_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P0_B0) | P_Fld(u4Rank_Sel_MCK_P1[0], SHU_B0_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P1_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_RANK_SELPH_UI_DLY), P_Fld(u4Rank_Sel_MCK_P0[1], SHU_B1_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P0_B1) | P_Fld(u4Rank_Sel_MCK_P1[1], SHU_B1_RANK_SELPH_UI_DLY_RANKSEL_MCK_DLY_P1_B1)); u4RANKINCTL_STB = (u4ReadDQSINCTL > 2)? (u4ReadDQSINCTL - 2): 0; u2PHSINCTL = (u4ReadDQSINCTL == 0)? 0: (u4ReadDQSINCTL - 1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RANKCTL), u4RANKINCTL_STB, MISC_SHU_RANKCTL_RANKINCTL_STB); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_RANK_SEL_STB), u2PHSINCTL, SHU_MISC_RANK_SEL_STB_RANK_SEL_PHSINCTL); #endif #ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY if (u4ReadDQSINCTL >= 2) { u4RankINCTL_ROOT = u4ReadDQSINCTL - 2; } else { u4RankINCTL_ROOT = 0; mcSHOW_ERR_MSG(("u4RankINCTL_ROOT <2, Please check\n")); #if (__ETT__) while (1); #endif } #else if (u4ReadDQSINCTL >= 3) { u4RankINCTL_ROOT = u4ReadDQSINCTL - 3; } else { u4RankINCTL_ROOT = 0; mcSHOW_ERR_MSG(("u4RankINCTL_ROOT <3, Risk for supporting 1066/RL8\n")); } #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RK_DQSCTL), u4ReadDQSINCTL, MISC_SHU_RK_DQSCTL_DQSINCTL); vSetRank(p, RANK_1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RK_DQSCTL), u4ReadDQSINCTL, MISC_SHU_RK_DQSCTL_DQSINCTL); vSetRank(p, backup_rank); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RANKCTL), u4ReadDQSINCTL, MISC_SHU_RANKCTL_RANKINCTL_PHY); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RANKCTL), u4RankINCTL_ROOT, MISC_SHU_RANKCTL_RANKINCTL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RANKCTL), u4RankINCTL_ROOT, MISC_SHU_RANKCTL_RANKINCTL_ROOT1); #ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RANKCTL), u4RankINCTL_ROOT, MISC_SHU_RANKCTL_RANKINCTL_RXDLY); u4XRTR2R = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ACTIM_XRT), SHU_ACTIM_XRT_XRTR2R); mcSHOW_DBG_MSG2(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL)); mcSHOW_DBG_MSG2(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R)); //mcDUMP_REG_MSG(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL)); //mcDUMP_REG_MSG(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R)); #else u4XRTR2R = 8 + u1TXDLY_Cal_max + 1; if (u4XRTR2R > 12) { u4XRTR2R = 12; mcSHOW_ERR_MSG(("XRTR2R > 12, Max value is 12\n")); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ACTIM_XRT), u4XRTR2R, SHU_ACTIM_XRT_XRTR2R); mcSHOW_DBG_MSG2(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL)); mcSHOW_DBG_MSG2(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R)); //mcDUMP_REG_MSG(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL)); //mcDUMP_REG_MSG(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R)); #endif #if 0 U8 u1ReadROEN; u1ReadROEN = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), SHU_ODTCTRL_ROEN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_RODTENSTB), P_Fld(0xff, SHU_RODTENSTB_RODTENSTB_EXT) | \ P_Fld(u1ReadROEN, SHU_RODTENSTB_RODTENSTB_TRACK_EN)); #endif #ifdef XRTR2W_PERFORM_ENHANCE_RODTEN vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RODTENSTB), P_Fld(0x0fff, MISC_SHU_RODTENSTB_RODTENSTB_EXT) | P_Fld(1, MISC_SHU_RODTENSTB_RODTEN_P1_ENABLE) | P_Fld(1, MISC_SHU_RODTENSTB_RODTENSTB_TRACK_EN)); #endif vSetRank(p, backup_rank); } #endif #if GATING_ADJUST_TXDLY_FOR_TRACKING void DramcRxdqsGatingPreProcess(DRAMC_CTX_T *p) { u1TXDLY_Cal_min = 0xff; u1TXDLY_Cal_max = 0; } #endif #endif #if RDSEL_TRACKING_EN void RDSELRunTimeTracking_preset(DRAMC_CTX_T *p) { S32 s4PosVH, s4NegVH; s4PosVH = divRoundClosest(400, ((1000000 / p->frequency) / 64)); s4NegVH = 1; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_RDSEL_TRACK), P_Fld(s4PosVH, SHU_MISC_RDSEL_TRACK_SHU_GW_THRD_POS) | P_Fld(s4NegVH, SHU_MISC_RDSEL_TRACK_SHU_GW_THRD_NEG)); } #endif #if RDDQC_PINMUX_WORKAROUND static void RDDQCPinmuxWorkaround(DRAMC_CTX_T *p) { U8 *uiLPDDR_RDDQC_Mapping; const U8 uiLPDDR4_RDDQC_Mapping_POP[PINMUX_MAX][CHANNEL_NUM][16] = { { { 0, 1, 2, 3, 7, 4, 6, 5, 9, 8, 12, 14, 15, 10, 13, 11 }, #if (CHANNEL_NUM>1) { 0, 1, 7, 4, 3, 2, 6, 5, 9, 8, 12, 14, 15, 10, 11, 13 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 7, 4, 6, 5, 9, 8, 12, 14, 15, 10, 13, 11 }, { 0, 1, 7, 4, 3, 2, 6, 5, 9, 8, 12, 14, 15, 10, 11, 13 }, #endif }, { { 0, 1, 4, 3, 2, 5, 7, 6, 9, 8, 10, 11, 15, 13, 12, 14 }, #if (CHANNEL_NUM>1) { 0, 1, 2, 5, 3, 4, 7, 6, 8, 9, 10, 11, 15, 14, 13, 12 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, #endif }, { { 0, 1, 6, 2, 4, 7, 3, 5, 8, 9, 10, 12, 13, 11, 15, 14 }, #if (CHANNEL_NUM>1) { 0, 1, 7, 4, 2, 5, 6, 3, 9, 8, 10, 12, 11, 14, 13, 15 }, #endif #if (CHANNEL_NUM>2) { 1, 0, 3, 2, 4, 7, 6, 5, 8, 9, 10, 12, 15, 14, 11, 13 }, { 0, 1, 7, 4, 2, 5, 6, 3, 9, 8, 10, 12, 11, 14, 13, 15 }, #endif }, { { 8, 9, 14, 15, 12, 13, 11, 10, 1, 0, 3, 2, 7, 6, 4, 5 }, #if (CHANNEL_NUM>1) { 9, 8, 13, 12, 15, 10, 11, 14, 0, 1, 3, 2, 4, 6, 5, 7 }, #endif #if (CHANNEL_NUM>2) { 0, 1, 6, 7, 4, 5, 3, 2, 9, 8, 11, 10, 15, 14, 12, 13 }, { 1, 0, 5, 4, 7, 2, 3, 6, 8, 9, 11, 10, 12, 14, 13, 15 }, #endif } }; { uiLPDDR_RDDQC_Mapping = (U8 *)uiLPDDR4_RDDQC_Mapping_POP[p->DRAMPinmux][p->channel]; } vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX1), P_Fld(uiLPDDR_RDDQC_Mapping[0], MRR_BIT_MUX1_MRR_BIT0_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[1], MRR_BIT_MUX1_MRR_BIT1_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[2], MRR_BIT_MUX1_MRR_BIT2_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[3], MRR_BIT_MUX1_MRR_BIT3_SEL)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX2), P_Fld(uiLPDDR_RDDQC_Mapping[4], MRR_BIT_MUX2_MRR_BIT4_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[5], MRR_BIT_MUX2_MRR_BIT5_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[6], MRR_BIT_MUX2_MRR_BIT6_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[7], MRR_BIT_MUX2_MRR_BIT7_SEL)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX3), P_Fld(uiLPDDR_RDDQC_Mapping[8], MRR_BIT_MUX3_MRR_BIT8_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[9], MRR_BIT_MUX3_MRR_BIT9_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[10], MRR_BIT_MUX3_MRR_BIT10_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[11], MRR_BIT_MUX3_MRR_BIT11_SEL)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX4), P_Fld(uiLPDDR_RDDQC_Mapping[12], MRR_BIT_MUX4_MRR_BIT12_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[13], MRR_BIT_MUX4_MRR_BIT13_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[14], MRR_BIT_MUX4_MRR_BIT14_SEL) | P_Fld(uiLPDDR_RDDQC_Mapping[15], MRR_BIT_MUX4_MRR_BIT15_SEL)); } #endif #define RDDQCGOLDEN_LP5_MR30_BIT_CTRL_LOWER RDDQCGOLDEN_MR15_GOLDEN #define RDDQCGOLDEN_LP5_MR31_BIT_CTRL_UPPER RDDQCGOLDEN_MR20_GOLDEN #define RDDQCGOLDEN_LP5_MR32_PATTERN_A RDDQCGOLDEN_MR32_GOLDEN #define RDDQCGOLDEN_LP5_MR33_PATTERN_B RDDQCGOLDEN_MR40_GOLDEN static U32 DramcRxWinRDDQCInit(DRAMC_CTX_T *p) { //int i; //U8 *uiLPDDR_O1_Mapping; //U16 temp_value = 0; U8 RDDQC_Bit_Ctrl_Lower = 0x55; U8 RDDQC_Bit_Ctrl_Upper = 0x55; U8 RDDQC_Pattern_A = 0x5A; U8 RDDQC_Pattern_B = 0x3C; #if FOR_DV_SIMULATION_USED == 1 cal_sv_rand_args_t *psra = get_psra(); if (psra) { RDDQC_Bit_Ctrl_Lower = psra->low_byte_invert_golden & 0xFF; RDDQC_Bit_Ctrl_Upper = psra->upper_byte_invert_golden & 0xFF; RDDQC_Pattern_A = psra->mr_dq_a_golden; RDDQC_Pattern_B = psra->mr_dq_b_golden; } #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ7), 0, SHU_B0_DQ7_R_DMDQMDBI_SHU_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ7), 0, SHU_B1_DQ7_R_DMDQMDBI_SHU_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0), u1GetRank(p), SWCMD_CTRL0_MRSRK); #if RDDQC_PINMUX_WORKAROUND RDDQCPinmuxWorkaround(p); #endif { DramcModeRegWriteByRank(p, p->rank, 15, RDDQC_Bit_Ctrl_Lower); DramcModeRegWriteByRank(p, p->rank, 20, RDDQC_Bit_Ctrl_Upper); DramcModeRegWriteByRank(p, p->rank, 32, RDDQC_Pattern_A); DramcModeRegWriteByRank(p, p->rank, 40, RDDQC_Pattern_B); } vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RDDQCGOLDEN), P_Fld(RDDQC_Bit_Ctrl_Lower, RDDQCGOLDEN_LP5_MR30_BIT_CTRL_LOWER) | P_Fld(RDDQC_Bit_Ctrl_Upper, RDDQCGOLDEN_LP5_MR31_BIT_CTRL_UPPER) | P_Fld(RDDQC_Pattern_A, RDDQCGOLDEN_LP5_MR32_PATTERN_A) | P_Fld(RDDQC_Pattern_B, RDDQCGOLDEN_LP5_MR33_PATTERN_B)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ8), P_Fld(1, SHU_B0_DQ8_R_DMRXDLY_CG_IG_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ8), P_Fld(1, SHU_B1_DQ8_R_DMRXDLY_CG_IG_B1)); return 0; } #if PRINT_CALIBRATION_SUMMARY_FASTK_CHECK static U32 DramcRxWinRDDQCEnd(DRAMC_CTX_T *p) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL0), 0, SWCMD_CTRL0_MRSRK); return 0; } #endif static void SetRxVref(DRAMC_CTX_T *p, U8 u1Vref_B0, U8 u1Vref_B1) { BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL), P_Fld(u1Vref_B0, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B0) | P_Fld(u1Vref_B0, SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B0)); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL), P_Fld(u1Vref_B1, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B1) | P_Fld(u1Vref_B1, SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_UB_B1)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_PHY_VREF_SEL), P_Fld(u1Vref_B1, SHU_CA_PHY_VREF_SEL_RG_RX_ARCA_VREF_SEL_LB) | P_Fld(u1Vref_B1, SHU_CA_PHY_VREF_SEL_RG_RX_ARCA_VREF_SEL_UB)); } } #if 0 static void SetRxDqDelay(DRAMC_CTX_T *p, U8 ii, S16 iDelay) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY0 + (ii * 4)), P_Fld(iDelay, SHU_R0_B0_RXDLY0_RX_ARDQ0_R_DLY_B0) | P_Fld(iDelay, SHU_R0_B0_RXDLY0_RX_ARDQ1_R_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY0 + (ii * 4)), P_Fld(iDelay, SHU_R0_B1_RXDLY0_RX_ARDQ0_R_DLY_B1) | P_Fld(iDelay, SHU_R0_B1_RXDLY0_RX_ARDQ1_R_DLY_B1)); } static void SetRxDqDqsDelay(DRAMC_CTX_T *p, S16 iDelay) { U8 ii; //u1ByteIdx //U32 u4value; if (iDelay <= 0) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY5), (-iDelay), SHU_R0_B0_RXDLY5_RX_ARDQS0_R_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY5), (-iDelay), SHU_R0_B1_RXDLY5_RX_ARDQS0_R_DLY_B1); //DramPhyReset(p); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4), iDelay, SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4), iDelay, SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1); //DramPhyReset(p); for (ii = 0; ii < 4; ii++) SetRxDqDelay(p, ii, iDelay); } } static U32 DramcRxWinRDDQCRun(DRAMC_CTX_T *p) { U32 u4Result = 0, u4TmpResult; DRAM_STATUS_T u4Response = DRAM_FAIL; vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_CTRL1), 1, SWCMD_CTRL1_RDDQC_LP_ENB); REG_TRANSFER_T TriggerReg = {DRAMC_REG_SWCMD_EN, SWCMD_EN_RDDQCEN}; REG_TRANSFER_T RepondsReg = {DRAMC_REG_SPCMDRESP, SPCMDRESP_RDDQC_RESPONSE}; u4Response = DramcTriggerAndWait(p, TriggerReg, RepondsReg); u4TmpResult = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_RDQC_CMP)); u4Result = (0xFFFF) & ((u4TmpResult) | (u4TmpResult >> 16)); #if (FEATURE_RDDQC_K_DMI == TRUE) u4TmpResult = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RDQC_DQM_CMP), RDQC_DQM_CMP_RDDQC_DQM_CMP0_ERR); u4TmpResult |= u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RDQC_DQM_CMP), RDQC_DQM_CMP_RDDQC_DQM_CMP1_ERR); u4Result |= (u4TmpResult << 16); #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SWCMD_EN), 0, SWCMD_EN_RDDQCEN); return u4Result; } #endif DRAM_STATUS_T DramcRxWindowPerbitCal(DRAMC_CTX_T *p, RX_PATTERN_OPTION_T u1UseTestEngine, U8 *u1AssignedVref, U8 isAutoK, U8 K_Type) { U8 u1BitIdx, u1ByteIdx; //ii //U32 u1vrefidx; //U8 ucbit_first, ucbit_last; //S16 iDelay = 0, S16DelayBegin = 0, u4DelayStep=1; //u16DelayEnd = 0 //U32 uiFinishCount; //U32 u4err_value, u4fail_bit, u4value; PASS_WIN_DATA_T FinalWinPerBit[DQ_DATA_WIDTH + RDDQC_ADD_DMI_NUM]; //WinPerBit[DQ_DATA_WIDTH + RDDQC_ADD_DMI_NUM] S32 iDQSDlyPerbyte[DQS_BYTE_NUMBER], iDQMDlyPerbyte[DQS_BYTE_NUMBER];//, iFinalDQSDly[DQS_NUMBER]; U8 u1VrefScanEnable = FALSE; //U16 u2TempWinSum[DQS_BYTE_NUMBER]={0}, u2rx_window_sum[DQS_BYTE_NUMBER]={0}, u2TmpDQMSum=0; U16 u2FinalVref [DQS_BYTE_NUMBER]= {0xe, 0xe}; //u2VrefLevel U16 u2VrefBegin, u2VrefEnd, u2VrefStep; //U32 u4fail_bit_R, u4fail_bit_F; U8 u1RXEyeScanEnable=(K_Type==NORMAL_K ? DISABLE : ENABLE); //U16 u1min_bit_by_vref[DQS_BYTE_NUMBER], u1min_winsize_by_vref[DQS_BYTE_NUMBER]; //U16 u1min_bit[DQS_BYTE_NUMBER], u1min_winsize[DQS_BYTE_NUMBER]={0}; //U32 u4PassFlags = 0xFFFF; U16 backup_RX_FinalVref_Value[DQS_BYTE_NUMBER]={0}; U32 backup_DQS_Dly_Value[DQS_BYTE_NUMBER]={0}; U32 backup_DQM_Dly_Value[DQS_BYTE_NUMBER]={0}; U32 backup_DQ_Dly_Value[DQ_DATA_WIDTH]={0}; #if ENABLE_EYESCAN_GRAPH U8 EyeScan_index[DQ_DATA_WIDTH + RDDQC_ADD_DMI_NUM] = {0}; U8 u1pass_in_this_vref_flag[DQ_DATA_WIDTH + RDDQC_ADD_DMI_NUM]; #endif U8 backup_rank, rank_i, u1KnownVref[2]={0xff, 0xff}; BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ10)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ10)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_AUTOK_CFG0)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_RX_AUTOK_CFG1)), #if RDDQC_PINMUX_WORKAROUND (DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX1)), (DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX2)), (DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX3)), (DRAMC_REG_ADDR(DRAMC_REG_MRR_BIT_MUX4)), #endif }; DramcBackupRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); #if (FEATURE_RDDQC_K_DMI == TRUE) if (u1UseTestEngine == PATTERN_RDDQC) { iDQMDlyPerbyte[0] = -0xFFFFFF; iDQMDlyPerbyte[1] = -0xFFFFFF; } else #endif { iDQMDlyPerbyte[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4), SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0); iDQMDlyPerbyte[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4), SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1); } if (u1RXEyeScanEnable) { backup_RX_FinalVref_Value[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_PHY_VREF_SEL), SHU_B0_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B0); if (!isLP4_DSC) backup_RX_FinalVref_Value[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_PHY_VREF_SEL), SHU_B1_PHY_VREF_SEL_RG_RX_ARDQ_VREF_SEL_LB_B1); else backup_RX_FinalVref_Value[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_PHY_VREF_SEL), SHU_CA_PHY_VREF_SEL_RG_RX_ARCA_VREF_SEL_LB); backup_DQS_Dly_Value[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY5), SHU_R0_B0_RXDLY5_RX_ARDQS0_R_DLY_B0); backup_DQS_Dly_Value[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY5), SHU_R0_B1_RXDLY5_RX_ARDQS0_R_DLY_B1); backup_DQM_Dly_Value[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4), SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0); backup_DQM_Dly_Value[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4), SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1); for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx += 2) { backup_DQ_Dly_Value[u1BitIdx ] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY0 + u1BitIdx * 2), SHU_R0_B0_RXDLY0_RX_ARDQ0_R_DLY_B0); backup_DQ_Dly_Value[u1BitIdx+1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY0 + u1BitIdx * 2), SHU_R0_B0_RXDLY0_RX_ARDQ1_R_DLY_B0); backup_DQ_Dly_Value[u1BitIdx+8] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY0 + u1BitIdx * 2), SHU_R0_B1_RXDLY0_RX_ARDQ0_R_DLY_B1); backup_DQ_Dly_Value[u1BitIdx+9] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY0 + u1BitIdx * 2), SHU_R0_B1_RXDLY0_RX_ARDQ1_R_DLY_B1); } #if ENABLE_EYESCAN_GRAPH if (u1UseTestEngine == PATTERN_TEST_ENGINE) { for(u1vrefidx=0; u1vrefidxrank, CKE_FIXON, TO_ONE_CHANNEL); backup_rank = u1GetRank(p); if (u1UseTestEngine == PATTERN_TEST_ENGINE) { if (u1RXEyeScanEnable == DISABLE) { vSetCalibrationResult(p, DRAM_CALIBRATION_RX_PERBIT, DRAM_FAIL); } if (isAutoK == TRUE) { DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_XTALK_PATTERN, 0, TE_NO_UI_SHIFT); } else { #if ENABLE_K_WITH_WORST_SI_UI_SHIFT DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern | 0x80, 0, TE_UI_SHIFT); #else DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0, TE_NO_UI_SHIFT); #endif } } else { if (u1RXEyeScanEnable == DISABLE) { vSetCalibrationResult(p, DRAM_CALIBRATION_RX_RDDQC, DRAM_FAIL); } DramcRxWinRDDQCInit(p); } u2VrefBegin = 0; u2VrefEnd = 0; u2VrefStep = 1; if (u1UseTestEngine == PATTERN_TEST_ENGINE) { #if (FOR_DV_SIMULATION_USED==0 && SW_CHANGE_FOR_SIMULATION==0) if ((p->rank==RANK_0) || (p->frequency >= RX_VREF_DUAL_RANK_K_FREQ) || (u1RXEyeScanEnable==1)) u1VrefScanEnable =1; #else u1VrefScanEnable =0; #endif } #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if (p->femmc_Ready == 1 && ((p->Bypass_RDDQC && u1UseTestEngine == PATTERN_RDDQC) || (p->Bypass_RXWINDOW && u1UseTestEngine == PATTERN_TEST_ENGINE))) { mcSHOW_DBG_MSG(("[FAST_K] Bypass RX Calibration\n")); } else #endif { //mcDUMP_REG_MSG(("\n[dumpRG] %s\n",u1UseTestEngine==PATTERN_RDDQC?"RDDQC":"DramcRxWindowPerbitCal")); #if VENDER_JV_LOG #if 0 if (u1UseTestEngine == 1) vPrintCalibrationBasicInfo_ForJV(p); #endif #else vPrintCalibrationBasicInfo(p); #endif //mcSHOW_DBG_MSG2(("Start DQ dly to find pass range UseTestEngine =%d\n", u1UseTestEngine)); } mcSHOW_DBG_MSG(("[RxWindowPerbitCal] UseTestEngine: %s, RX Vref Scan: %d, Autok:%d\n", u1UseTestEngine==PATTERN_RDDQC?"RDDQC":"DramcRxWindowPerbitCal", u1VrefScanEnable, isAutoK)); if (u1VrefScanEnable) { if ((Get_Vref_Calibration_OnOff(p) == VREF_CALI_OFF) && (u1RXEyeScanEnable == 0)) { u2VrefBegin = 0; u2VrefEnd = 0; u1KnownVref[0] = gFinalRXVrefDQForSpeedUp[p->channel][p->rank][p->odt_onoff][0]; u1KnownVref[1] = gFinalRXVrefDQForSpeedUp[p->channel][p->rank][p->odt_onoff][1]; if (u1UseTestEngine == PATTERN_TEST_ENGINE && ((u1KnownVref[0] == 0) || (u1KnownVref[1] == 0))) { // mcSHOW_ERR_MSG(("\nWrong frequency K order= %d\n")); #if __ETT__ while (1); #endif } } else if (u1AssignedVref != NULL) { u2VrefBegin = 0; u2VrefEnd = 0; u1KnownVref[0] = u1AssignedVref[0]; u1KnownVref[1] = u1AssignedVref[1]; } else { #if (SW_CHANGE_FOR_SIMULATION || FOR_DV_SIMULATION_USED) u2VrefBegin = RX_VREF_RANGE_BEGIN; #else if (u1RXEyeScanEnable == 0) { if (p->odt_onoff) { u2VrefBegin = RX_VREF_RANGE_BEGIN_ODT_ON; } else { u2VrefBegin = RX_VREF_RANGE_BEGIN_ODT_OFF; } u2VrefEnd = RX_VREF_RANGE_END-1; //mcSHOW_DBG_MSG(("\nSet Vref Range= %d -> %d\n",u2VrefBegin,u2VrefEnd)); } else { u2VrefBegin = 0; (void)u2VrefBegin; u2VrefEnd = EYESCAN_RX_VREF_RANGE_END-1; (void)u2VrefEnd; //mcSHOW_DBG_MSG(("\nSet Eyescan Vref Range= %d -> %d\n",u2VrefBegin,u2VrefEnd)); } #endif } if (u1RXEyeScanEnable == 0) { u2VrefStep = RX_VREF_RANGE_STEP; } else { u2VrefStep = EYESCAN_GRAPH_RX_VREF_STEP; } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0); if (!isLP4_DSC) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1); else vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD5), 1, CA_CMD5_RG_RX_ARCMD_VREF_EN); } else { u2VrefBegin = 0; u2VrefEnd = 0; u2VrefStep = 1; } (void)u2VrefStep; #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if (p->femmc_Ready == 1 && ((p->Bypass_RDDQC && u1UseTestEngine == PATTERN_RDDQC) || (p->Bypass_RXWINDOW && u1UseTestEngine == PATTERN_TEST_ENGINE))) { for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { if (u1VrefScanEnable) { #if ( SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL) u2FinalVref[u1ByteIdx] = p->pSavetimeData->u1RxWinPerbitVref_Save[p->channel][p->rank][u1ByteIdx]; #endif } iDQSDlyPerbyte[u1ByteIdx] = p->pSavetimeData->u1RxWinPerbit_DQS[p->channel][p->rank][u1ByteIdx]; iDQMDlyPerbyte[u1ByteIdx] = p->pSavetimeData->u1RxWinPerbit_DQM[p->channel][p->rank][u1ByteIdx]; } for (u1BitIdx = 0; u1BitIdx < 16; u1BitIdx++) { FinalWinPerBit[u1BitIdx].best_dqdly = p->pSavetimeData->u1RxWinPerbit_DQ[p->channel][p->rank][u1BitIdx]; } if (u1RXEyeScanEnable == DISABLE) { if (u1UseTestEngine == PATTERN_TEST_ENGINE) vSetCalibrationResult(p, DRAM_CALIBRATION_RX_PERBIT, DRAM_FAST_K); else vSetCalibrationResult(p, DRAM_CALIBRATION_RX_RDDQC, DRAM_FAST_K); } } #endif if (u1RXEyeScanEnable) { u2FinalVref[0] = backup_RX_FinalVref_Value[0]; u2FinalVref[1] = backup_RX_FinalVref_Value[1]; iDQSDlyPerbyte[0] = backup_DQS_Dly_Value[0]; iDQSDlyPerbyte[1] = backup_DQS_Dly_Value[1]; iDQMDlyPerbyte[0] = backup_DQM_Dly_Value[0]; iDQMDlyPerbyte[1] = backup_DQM_Dly_Value[1]; for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx += 2) { FinalWinPerBit[u1BitIdx ].best_dqdly = backup_DQ_Dly_Value[u1BitIdx ]; FinalWinPerBit[u1BitIdx + 1].best_dqdly = backup_DQ_Dly_Value[u1BitIdx+1]; FinalWinPerBit[u1BitIdx + 8].best_dqdly = backup_DQ_Dly_Value[u1BitIdx+8]; FinalWinPerBit[u1BitIdx + 9].best_dqdly = backup_DQ_Dly_Value[u1BitIdx+9]; } } if (u1VrefScanEnable == TRUE) { for (rank_i = p->rank; rank_i < p->support_rank_num; rank_i++) { vSetRank(p, rank_i); SetRxVref(p, u2FinalVref[0], u2FinalVref[1]); for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { mcSHOW_DBG_MSG(("\nFinal RX Vref Byte %d = %d to rank%d", u1ByteIdx, u2FinalVref[u1ByteIdx], rank_i)); //mcDUMP_REG_MSG(("\nFinal RX Vref Byte %d = %d to rank%d", u1ByteIdx, u2FinalVref[u1ByteIdx], rank_i)); gFinalRXVrefDQ[p->channel][rank_i][u1ByteIdx] = (U8) u2FinalVref[u1ByteIdx]; gFinalRXVrefDQForSpeedUp[p->channel][rank_i][p->odt_onoff][u1ByteIdx] = (U8) u2FinalVref[u1ByteIdx]; } } vSetRank(p, backup_rank); } mcSHOW_DBG_MSG(("\n")); #if DUMP_TA2_WINDOW_SIZE_RX_TX if (u1UseTestEngine == PATTERN_TEST_ENGINE) { U32 u4B0Tatal =0; U32 u4B1Tatal =0; mcSHOW_DBG_MSG(("RX window per bit CH[%d] Rank[%d] window size\n", p->channel, p->rank)); for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { mcSHOW_DBG_MSG(("DQ[%d] size = %d\n", u1BitIdx, gFinalRXPerbitWin[p->channel][p->rank][u1BitIdx])); if(u1BitIdx < 8) { u4B0Tatal += gFinalRXPerbitWin[p->channel][p->rank][u1BitIdx]; } else { u4B1Tatal += gFinalRXPerbitWin[p->channel][p->rank][u1BitIdx]; } } mcSHOW_DBG_MSG(("total rx window size B0: %d B1: %d\n", u4B0Tatal, u4B1Tatal)); } #endif vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY5), P_Fld((U32)iDQSDlyPerbyte[0], SHU_R0_B0_RXDLY5_RX_ARDQS0_R_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4), P_Fld((U32)iDQMDlyPerbyte[0], SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY5), P_Fld((U32)iDQSDlyPerbyte[1], SHU_R0_B1_RXDLY5_RX_ARDQS0_R_DLY_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4), P_Fld((U32)iDQMDlyPerbyte[1], SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1)); for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx += 2) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY0 + u1BitIdx * 2), P_Fld(((U32)FinalWinPerBit[u1BitIdx].best_dqdly), SHU_R0_B0_RXDLY0_RX_ARDQ0_R_DLY_B0) | P_Fld(((U32)FinalWinPerBit[u1BitIdx + 1].best_dqdly), SHU_R0_B0_RXDLY0_RX_ARDQ1_R_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY0 + u1BitIdx * 2), P_Fld((U32)FinalWinPerBit[u1BitIdx + 8].best_dqdly, SHU_R0_B1_RXDLY0_RX_ARDQ0_R_DLY_B1) | P_Fld((U32)FinalWinPerBit[u1BitIdx + 9].best_dqdly, SHU_R0_B1_RXDLY0_RX_ARDQ1_R_DLY_B1)); //mcSHOW_DBG_MSG(("u1BitId %d Addr 0x%2x = %2d %2d %2d %2d \n", u1BitIdx, DDRPHY_RXDQ1+u1BitIdx*2, // FinalWinPerBit[u1BitIdx].best_dqdly, FinalWinPerBit[u1BitIdx+1].best_dqdly, FinalWinPerBit[u1BitIdx+8].best_dqdly, FinalWinPerBit[u1BitIdx+9].best_dqdly)); } DramPhyReset(p); #if RDDQC_PINMUX_WORKAROUND DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); #endif vSetRank(p, backup_rank); //vPrintCalibrationBasicInfo(p); #ifdef ETT_PRINT_FORMAT mcSHOW_DBG_MSG(("\nDQS Delay:\nDQS0 = %d, DQS1 = %d\n" "DQM Delay:\nDQM0 = %d, DQM1 = %d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQMDlyPerbyte[0], iDQMDlyPerbyte[1])); /*mcDUMP_REG_MSG(("\nDQS Delay:\nDQS0 = %d, DQS1 = %d\n" "DQM Delay:\nDQM0 = %d, DQM1 = %d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQMDlyPerbyte[0], iDQMDlyPerbyte[1]));*/ #else mcSHOW_DBG_MSG(("\nDQS Delay:\nDQS0 = %2d, DQS1 = %2d\n" "DQM Delay:\nDQM0 = %2d, DQM1 = %2d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQMDlyPerbyte[0], iDQMDlyPerbyte[1])); /*mcDUMP_REG_MSG(("\nDQS Delay:\nDQS0 = %2d, DQS1 = %2d\n" "DQM Delay:\nDQM0 = %2d, DQM1 = %2d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQMDlyPerbyte[0], iDQMDlyPerbyte[1]));*/ #endif mcSHOW_DBG_MSG(("DQ Delay:\n")); //mcDUMP_REG_MSG(("DQ Delay:\n")); for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx = u1BitIdx + 4) { #ifdef ETT_PRINT_FORMAT mcSHOW_DBG_MSG(("DQ%d =%d, DQ%d =%d, DQ%d =%d, DQ%d =%d\n", u1BitIdx, FinalWinPerBit[u1BitIdx].best_dqdly, u1BitIdx+1, FinalWinPerBit[u1BitIdx+1].best_dqdly, u1BitIdx+2, FinalWinPerBit[u1BitIdx+2].best_dqdly, u1BitIdx+3, FinalWinPerBit[u1BitIdx+3].best_dqdly)); //mcDUMP_REG_MSG(("DQ%d =%d, DQ%d =%d, DQ%d =%d, DQ%d =%d\n", u1BitIdx, FinalWinPerBit[u1BitIdx].best_dqdly, u1BitIdx+1, FinalWinPerBit[u1BitIdx+1].best_dqdly, u1BitIdx+2, FinalWinPerBit[u1BitIdx+2].best_dqdly, u1BitIdx+3, FinalWinPerBit[u1BitIdx+3].best_dqdly)); #else mcSHOW_DBG_MSG(("DQ%2d =%2d, DQ%2d =%2d, DQ%2d =%2d, DQ%2d =%2d\n", u1BitIdx, FinalWinPerBit[u1BitIdx].best_dqdly, u1BitIdx+1, FinalWinPerBit[u1BitIdx+1].best_dqdly, u1BitIdx+2, FinalWinPerBit[u1BitIdx+2].best_dqdly, u1BitIdx+3, FinalWinPerBit[u1BitIdx+3].best_dqdly)); //mcDUMP_REG_MSG(("DQ%2d =%2d, DQ%2d =%2d, DQ%2d =%2d, DQ%2d =%2d\n", u1BitIdx, FinalWinPerBit[u1BitIdx].best_dqdly, u1BitIdx+1, FinalWinPerBit[u1BitIdx+1].best_dqdly, u1BitIdx+2, FinalWinPerBit[u1BitIdx+2].best_dqdly, u1BitIdx+3, FinalWinPerBit[u1BitIdx+3].best_dqdly)); #endif } mcSHOW_DBG_MSG(("\n")); mcSHOW_DBG_MSG4(("[DramcRxWindowPerbitCal] Done\n")); #if LP5_DDR4266_RDBI_WORKAROUND if((is_lp5_family(p)) && (p->frequency >= 2133)) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ7), 1, SHU_B0_DQ7_R_DMDQMDBI_SHU_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ7), 1, SHU_B1_DQ7_R_DMDQMDBI_SHU_B1); } #endif return DRAM_OK; } #if SIMULATION_RX_DVS static U8 DramcRxDVSCal(DRAMC_CTX_T *p, U8 u1byte) { U8 u1rising_lead, u1falling_lead, u1rising_lag, u1falling_lag, u1lead_lag; if (u1byte == 0) { u1rising_lead = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS0), MISC_FT_STATUS0_AD_RX_ARDQ_DVS_R_LEAD_B0); u1falling_lead = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS1), MISC_FT_STATUS1_AD_RX_ARDQ_DVS_F_LEAD_B0); u1rising_lag = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS0), MISC_FT_STATUS0_AD_RX_ARDQ_DVS_R_LAG_B0); u1falling_lag = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS1), MISC_FT_STATUS1_AD_RX_ARDQ_DVS_F_LAG_B0); } else { u1rising_lead = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS0), MISC_FT_STATUS0_AD_RX_ARDQ_DVS_R_LAG_B1); u1falling_lead = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS1), MISC_FT_STATUS1_AD_RX_ARDQ_DVS_F_LEAD_B1); u1rising_lag = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS0), MISC_FT_STATUS0_AD_RX_ARDQ_DVS_R_LAG_B1); u1falling_lag = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_FT_STATUS1), MISC_FT_STATUS1_AD_RX_ARDQ_DVS_F_LAG_B1); } mcSHOW_DBG_MSG2(("Byte%d | LEAD(%d %d) | LAG(%d %d)\n", u1byte, u1rising_lead, u1falling_lead, u1rising_lag, u1falling_lag)); u1lead_lag = (u1rising_lead | u1falling_lead | u1rising_lag | u1falling_lag); return u1lead_lag; } DRAM_STATUS_T DramcRxDVSWindowCal(DRAMC_CTX_T *p) { U8 ii, u1ByteIdx; S16 iDelay = 0, S16DelayBegin = 0; U16 u16DelayEnd = 0, u16DelayStep = 1; U32 u4err_value; U8 u1lead_lag, u1DVS_first_flag[DQS_BYTE_NUMBER]={0}, u1DVS_first_pass[DQS_BYTE_NUMBER]={0}, u1DVS_pass_window[DQS_BYTE_NUMBER]={0}, u1finish_flag[DQS_BYTE_NUMBER]={0}; U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY5)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY5)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4)), }; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } mcSHOW_DBG_MSG(("[RX DVS calibration]\n")); vAutoRefreshSwitch(p, DISABLE); //CKEFixOnOff(p, p->rank, CKE_FIXON, TO_ONE_CHANNEL); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), 1, SHU_B0_DQ11_RG_RX_ARDQ_DVS_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), 1, SHU_B1_DQ11_RG_RX_ARDQ_DVS_EN_B1); #if ENABLE_K_WITH_WORST_SI_UI_SHIFT DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern | 0x80, 0, TE_UI_SHIFT); #else DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_XTALK_PATTERN, 0, TE_NO_UI_SHIFT); #endif { u16DelayStep = 4; } S16DelayBegin = -80; u16DelayEnd = 100; mcSHOW_DBG_MSG2(("\nRX Delay %d -> %d, step: %d\n", S16DelayBegin, u16DelayEnd, u16DelayStep)); { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_RXDLY4), P_Fld(0, SHU_R0_B0_RXDLY4_RX_ARDQM0_R_DLY_B0) | P_Fld(0, SHU_R0_B0_RXDLY4_RX_ARDQM0_F_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_RXDLY4), P_Fld(0, SHU_R0_B1_RXDLY4_RX_ARDQM0_R_DLY_B1) | P_Fld(0, SHU_R0_B1_RXDLY4_RX_ARDQM0_F_DLY_B1)); for (ii = 0; ii < 4; ii++) SetRxDqDelay(p, ii, 0); { for (iDelay = S16DelayBegin; iDelay <= u16DelayEnd; iDelay += u16DelayStep) { SetRxDqDqsDelay(p, iDelay); u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern); mcSHOW_DBG_MSG2(("iDelay= %4d, err_value: 0x%x", iDelay, u4err_value)); for(u1ByteIdx=0; u1ByteIdx> (u1ByteIdx<<3)) & 0xff) == 0)) { u1DVS_first_pass[u1ByteIdx] = iDelay; u1DVS_first_flag[u1ByteIdx] = 1; mcSHOW_DBG_MSG2(("Byte%d find first pass delay\n")) } else if (((u1lead_lag == 1) || (((u4err_value >> (u1ByteIdx<<3)) & 0xff) != 0)) && (u1DVS_first_flag[u1ByteIdx] == 1) && (u1finish_flag[u1ByteIdx] == 0)) { u1DVS_pass_window[u1ByteIdx] = iDelay - u1DVS_first_pass[u1ByteIdx] - u16DelayStep; if (u1DVS_pass_window[u1ByteIdx] < 7) { u1DVS_pass_window[u1ByteIdx] = 0; u1DVS_first_flag[u1ByteIdx] = 0; mcSHOW_DBG_MSG2(("Byte%d find fake window\n")) } else { u1finish_flag[u1ByteIdx] = 1; mcSHOW_DBG_MSG2(("Byte%d find pass window\n")) } } } if ((u1finish_flag[0]==1) && (u1finish_flag[1]==1)) { mcSHOW_DBG_MSG2(("Two byte DVS window find, early break!\n")); break; } } } } DramcEngine2End(p); for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { u1DVS_increase[p->rank][u1ByteIdx] = (u1DVS_pass_window[u1ByteIdx] > 8)? ((u1DVS_pass_window[u1ByteIdx] - 8) >> 3): 0; mcSHOW_DBG_MSG(("\nByte %d final DVS window size(M) %d, DVS increase %d\n", u1ByteIdx, u1DVS_pass_window[u1ByteIdx], u1DVS_increase[p->rank][u1ByteIdx])); } DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); vAutoRefreshSwitch(p, ENABLE); DramPhyReset(p); vPrintCalibrationBasicInfo(p); mcSHOW_DBG_MSG(("\n\n")); mcSHOW_DBG_MSG4(("[DramcRxDVSWindowCal] Done\n")); return DRAM_OK; } void DramcDramcRxDVSCalPostProcess(DRAMC_CTX_T *p) { U8 rank_i, u1ByteIdx, u1DVS_increase_final, u1DVS_dly_final[DQS_BYTE_NUMBER]={0}; U8 backup_rank = p->rank; for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { if (p->support_rank_num == RANK_DUAL) u1DVS_increase_final = (u1DVS_increase[RANK_0][u1ByteIdx] < u1DVS_increase[RANK_1][u1ByteIdx])? u1DVS_increase[RANK_0][u1ByteIdx] : u1DVS_increase[RANK_1][u1ByteIdx]; else u1DVS_increase_final = u1DVS_increase[p->rank][u1ByteIdx]; if (u1ByteIdx == 0) { u1DVS_dly_final[u1ByteIdx] = u1DVS_increase_final + (u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), SHU_B0_DQ11_RG_RX_ARDQ_DVS_DLY_B0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), u1DVS_dly_final[u1ByteIdx], SHU_B0_DQ11_RG_RX_ARDQ_DVS_DLY_B0); } else { u1DVS_dly_final[u1ByteIdx] = u1DVS_increase_final + (u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), SHU_B1_DQ11_RG_RX_ARDQ_DVS_DLY_B1)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), u1DVS_dly_final[u1ByteIdx], SHU_B1_DQ11_RG_RX_ARDQ_DVS_DLY_B1); } mcSHOW_DBG_MSG(("Byte%d final DVS delay: %d\n", u1ByteIdx, u1DVS_dly_final[u1ByteIdx])); } for(rank_i=RANK_0; rank_i< p->support_rank_num; rank_i++) { vSetRank(p, rank_i); DramcRxWindowPerbitCal(p, PATTERN_TEST_ENGINE, DVS_CAL_KEEP_VREF, AUTOK_OFF, NORMAL_K); } if ((DramcRxDVSCal(p, 0) == 1) || (DramcRxDVSCal(p, 1) == 1)) { mcSHOW_ERR_MSG(("Final DVS delay is out of RX window\n")); for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { if (u1DVS_dly_final[u1ByteIdx] > 0) { u1DVS_dly_final[u1ByteIdx] -= 1; if (u1ByteIdx == 0) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), u1DVS_dly_final[u1ByteIdx], SHU_B0_DQ11_RG_RX_ARDQ_DVS_DLY_B0); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), u1DVS_dly_final[u1ByteIdx], SHU_B1_DQ11_RG_RX_ARDQ_DVS_DLY_B1); } } for(rank_i=RANK_0; rank_i< p->support_rank_num; rank_i++) { vSetRank(p, rank_i); DramcRxWindowPerbitCal(p, PATTERN_TEST_ENGINE, DVS_CAL_KEEP_VREF, AUTOK_OFF, NORMAL_K); } } } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11), 1, SHU_B0_DQ11_RG_RX_ARDQ_DVS_EN_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11), 1, SHU_B1_DQ11_RG_RX_ARDQ_DVS_EN_B1); vSetRank(p, backup_rank); } #endif #if SIMULATION_DATLAT static void dle_factor_handler(DRAMC_CTX_T *p, U8 curr_val) { U8 u1DATLAT_DSEL = 0; U8 u1DLECG_OptionEXT1 = 0; U8 u1DLECG_OptionEXT2 = 0; U8 u1DLECG_OptionEXT3 = 0; if (u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_RX_PIPE_CTRL), SHU_MISC_RX_PIPE_CTRL_RX_PIPE_BYPASS_EN)) { u1DATLAT_DSEL = curr_val; } else { if (curr_val < 1) u1DATLAT_DSEL = curr_val; else u1DATLAT_DSEL = curr_val - 1; } // mcSHOW_DBG_MSG(("DATLAT: %d, u1DATLAT_DSEL: %d\n", curr_val, u1DATLAT_DSEL)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RDAT), P_Fld(curr_val, MISC_SHU_RDAT_DATLAT) | P_Fld(u1DATLAT_DSEL, MISC_SHU_RDAT_DATLAT_DSEL) | P_Fld(u1DATLAT_DSEL, MISC_SHU_RDAT_DATLAT_DSEL_PHY)); u1DLECG_OptionEXT1 = (curr_val >= 8)? (1): (0); u1DLECG_OptionEXT2 = (curr_val >= 14)? (1): (0); u1DLECG_OptionEXT3 = (curr_val >= 19)? (1): (0); // mcSHOW_DBG_MSG(("u1DLECG_OptionEXT1: %d, 2 for %d, 3 for %d\n", u1DLECG_OptionEXT1, u1DLECG_OptionEXT2, u1DLECG_OptionEXT3)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_RX_CG_SET0), P_Fld(u1DLECG_OptionEXT1, SHU_RX_CG_SET0_READ_START_EXTEND1) | P_Fld(u1DLECG_OptionEXT1, SHU_RX_CG_SET0_DLE_LAST_EXTEND1) | P_Fld((u1DLECG_OptionEXT2), SHU_RX_CG_SET0_READ_START_EXTEND2) | P_Fld((u1DLECG_OptionEXT2), SHU_RX_CG_SET0_DLE_LAST_EXTEND2) | P_Fld((u1DLECG_OptionEXT3), SHU_RX_CG_SET0_READ_START_EXTEND3) | P_Fld((u1DLECG_OptionEXT3), SHU_RX_CG_SET0_DLE_LAST_EXTEND3)); DramPhyReset(p); } static U8 aru1RxDatlatResult[RANK_MAX]; DRAM_STATUS_T DramcRxdatlatCal(DRAMC_CTX_T *p) { //U8 ii, ucStartCalVal = 0; //U32 u4err_value = 0xffffffff; U8 ucbest_step; //ucpipe_num = 0; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } //mcDUMP_REG_MSG(("\n[dumpRG] DramcRxdatlatCal\n")); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif mcSHOW_DBG_MSG(("[RxdatlatCal]\n")); u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RDAT)); vSetCalibrationResult(p, DRAM_CALIBRATION_DATLAT, DRAM_FAIL); ucbest_step = (U8) u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_RDAT), MISC_SHU_RDAT_DATLAT); mcSHOW_DBG_MSG2(("DATLAT Default: 0x%x\n", ucbest_step)); //mcDUMP_REG_MSG(("DATLAT Default: 0x%x\n", ucbest_step)); DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern | 0x80, 0, TE_UI_SHIFT); #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_DATLAT) if (p->femmc_Ready == 1) { ucbest_step = p->pSavetimeData->u1RxDatlat_Save[p->channel][p->rank]; } #endif aru1RxDatlatResult[p->rank] = ucbest_step; mcSHOW_DBG_MSG(("best_step = %d\n\n", ucbest_step)); //mcDUMP_REG_MSG(("best_step=%d\n\n", ucbest_step)); #if __A60868_TO_BE_PORTING__ #if __ETT__ U8 _init_Datlat_value = vDramcACTimingGetDatLat(p); if ((_init_Datlat_value > (ucbest_step + 1)) || (_init_Datlat_value < (ucbest_step - 1))) { mcSHOW_DBG_MSG(("[WARNING!!] Datlat initial value(%d) = best_step(%d) %c %d, out of range!\n\n", _init_Datlat_value, ucbest_step, (ucbest_step > _init_Datlat_value)? '-': '+', abs(ucbest_step - _init_Datlat_value))); while (1); } #endif #endif #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_DATLAT) if (p->femmc_Ready == 1) { dle_factor_handler(p, ucbest_step); vSetCalibrationResult(p, DRAM_CALIBRATION_DATLAT, DRAM_FAST_K); } #endif mcSHOW_DBG_MSG4(("[DramcRxdatlatCal] Done\n")); return DRAM_OK; } DRAM_STATUS_T DramcDualRankRxdatlatCal(DRAMC_CTX_T *p) { U8 u1FinalDatlat, u1Datlat0, u1Datlat1; u1Datlat0 = aru1RxDatlatResult[0]; u1Datlat1 = aru1RxDatlatResult[1]; if (p->support_rank_num == RANK_DUAL) { if (u1Datlat0 > u1Datlat1) { u1FinalDatlat = u1Datlat0; } else { u1FinalDatlat = u1Datlat1; } } else { u1FinalDatlat = u1Datlat0; } #if ENABLE_READ_DBI if (p->DBI_R_onoff[p->dram_fsp]) { u1FinalDatlat++; } #endif dle_factor_handler(p, u1FinalDatlat); #if RDSEL_TRACKING_EN if(p->frequency >= RDSEL_TRACKING_TH) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_RDSEL_TRACK), u1FinalDatlat, SHU_MISC_RDSEL_TRACK_DMDATLAT_I); } #endif mcSHOW_DBG_MSG(("[DualRankRxdatlatCal] RK0: %d, RK1: %d, Final_Datlat %d\n", u1Datlat0, u1Datlat1, u1FinalDatlat)); //mcDUMP_REG_MSG(("[DualRankRxdatlatCal] RK0: %d, RK1: %d, Final_Datlat %d\n", u1Datlat0, u1Datlat1, u1FinalDatlat)); #if defined(FOR_HQA_TEST_USED) && defined(FOR_HQA_REPORT_USED) { U8 backup_rank, rank_index; backup_rank = u1GetRank(p); for(rank_index = RANK_0; rank_index < p->support_rank_num; rank_index++) { vSetRank(p, rank_index); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "DATLAT", "", 0, u1FinalDatlat, NULL); } vSetRank(p, backup_rank); } #endif return DRAM_OK; } #endif #if SIMULATION_TX_PERBIT #if (SW_CHANGE_FOR_SIMULATION || FOR_DV_SIMULATION_USED) #define TX_VREF_RANGE_BEGIN 0 #define TX_VREF_RANGE_END 2 #define TX_VREF_RANGE_STEP 2 #else #define TX_VREF_RANGE_BEGIN 16 #define TX_VREF_RANGE_END 50 #define TX_VREF_RANGE_STEP 2 #endif #define TX_DQ_UI_TO_PI_TAP 64 #define TX_PHASE_DQ_UI_TO_PI_TAP 32 #define LP4_TX_VREF_DATA_NUM 50 #define LP4_TX_VREF_PASS_CONDITION 0 #define TX_PASS_WIN_CRITERIA 7 #define LP4_TX_VREF_BOUNDARY_NOT_READY 0xff typedef struct _PASS_WIN_DATA_BY_VREF_T { U16 u2VrefUsed; U16 u2WinSum_byVref; U8 u1WorseBitWinSize_byVref; U8 u1WorseBitIdx_byVref; } PASS_WIN_DATA_BY_VREF_T; #if 0 static U16 WDQSMode2AcTxOEShift(DRAMC_CTX_T *p) { U16 u2TxDQOEShift = 0; switch (p->frequency) { case 1866: u2TxDQOEShift = 19; break; case 1600: case 1200: case 800: case 600: u2TxDQOEShift = 15; break; case 933: u2TxDQOEShift = 11; break; case 400: u2TxDQOEShift = 16; break; default: mcSHOW_ERR_MSG(("[WDQSMode2AcTxOEShift] frequency err!\n")); #if __ETT__ while (1); #endif } return u2TxDQOEShift; } #endif void TxWinTransferDelayToUIPI(DRAMC_CTX_T *p, U16 uiDelay, U8 u1AdjustPIToCenter, U8* pu1UILarge_DQ, U8* pu1UISmall_DQ, U8* pu1PI, U8* pu1UILarge_DQOE, U8* pu1UISmall_DQOE) { U8 u1Small_ui_to_large, u1PI = 0, u164PIto1UI, u1TxDQOEShift = 0; U16 u2TmpValue, u2DQOE_shift; DDR800_MODE_T eDdr800Mode = vGet_DDR_Loop_Mode(p); U8 u1PiTap = (u1IsPhaseMode(p) == TRUE) ? TX_PHASE_DQ_UI_TO_PI_TAP : TX_DQ_UI_TO_PI_TAP; u1Small_ui_to_large = u1MCK2UI_DivShift(p); #if ENABLE_WDQS_MODE_2 u1TxDQOEShift = WDQSMode2AcTxOEShift(p); #else u1TxDQOEShift = TX_DQ_OE_SHIFT_LP4; #endif if(pu1PI != NULL) { u1PI = uiDelay & (u1PiTap-1); *pu1PI =u1PI; } if (u1IsLP4Div4DDR800(p) || u1IsPhaseMode(p)) u164PIto1UI = 0; else u164PIto1UI = 1; u2TmpValue = (uiDelay /u1PiTap)<> 1; u2TmpValue --; } else if (u1PI > u1PiTap - 10) { u1PI -= (u1PiTap) >> 1; u2TmpValue ++; } *pu1PI = u1PI; } #if 0 *pu1UISmall_DQ = u2TmpValue % u1Small_ui_to_large; *pu1UILarge_DQ = u2TmpValue / u1Small_ui_to_large; #else *pu1UISmall_DQ = u2TmpValue - ((u2TmpValue >> u1Small_ui_to_large) << u1Small_ui_to_large); *pu1UILarge_DQ = (u2TmpValue >> u1Small_ui_to_large); #endif { u2TmpValue -= u1TxDQOEShift; } if(((u1MR03Value[p->dram_fsp]&0x80)>>7)==1) { if (vGet_Div_Mode(p) == DIV4_MODE) u2DQOE_shift = 4; else u2DQOE_shift = 8; u2TmpValue += u2DQOE_shift; } *pu1UISmall_DQOE = u2TmpValue - ((u2TmpValue >> u1Small_ui_to_large) << u1Small_ui_to_large); *pu1UILarge_DQOE = (u2TmpValue >> u1Small_ui_to_large); } #if 0 static void TxPrintWidnowInfo(DRAMC_CTX_T *p, PASS_WIN_DATA_T WinPerBitData[]) { U8 u1BitIdx; for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++) { #ifdef ETT_PRINT_FORMAT mcSHOW_DBG_MSG(("TX Bit%d (%d~%d) %d %d, Bit%d (%d~%d) %d %d,", \ u1BitIdx, WinPerBitData[u1BitIdx].first_pass, WinPerBitData[u1BitIdx].last_pass, WinPerBitData[u1BitIdx].win_size, WinPerBitData[u1BitIdx].win_center, \ u1BitIdx + 8, WinPerBitData[u1BitIdx + 8].first_pass, WinPerBitData[u1BitIdx + 8].last_pass, WinPerBitData[u1BitIdx + 8].win_size, WinPerBitData[u1BitIdx + 8].win_center)); #else mcSHOW_DBG_MSG(("TX Bit%2d (%2d~%2d) %2d %2d, Bit%2d (%2d~%2d) %2d %2d,", \ u1BitIdx, WinPerBitData[u1BitIdx].first_pass, WinPerBitData[u1BitIdx].last_pass, WinPerBitData[u1BitIdx].win_size, WinPerBitData[u1BitIdx].win_center, \ u1BitIdx + 8, WinPerBitData[u1BitIdx + 8].first_pass, WinPerBitData[u1BitIdx + 8].last_pass, WinPerBitData[u1BitIdx + 8].win_size, WinPerBitData[u1BitIdx + 8].win_center)); #endif #if PIN_CHECK_TOOL PINInfo_flashtool.DQ_TX_WIN_SIZE[p->channel][p->rank][u1BitIdx] = WinPerBitData[u1BitIdx].win_size; PINInfo_flashtool.DQ_TX_WIN_SIZE[p->channel][p->rank][u1BitIdx+8] = WinPerBitData[u1BitIdx+8].win_size; #endif mcSHOW_DBG_MSG(("\n")); } mcSHOW_DBG_MSG(("\n")); #if DUMP_TA2_WINDOW_SIZE_RX_TX { U32 u4B0Tatal=0; U32 u4B1Tatal=0; for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { if(u1BitIdx < 8) { u4B0Tatal += WinPerBitData[u1BitIdx].win_size; } else { u4B1Tatal += WinPerBitData[u1BitIdx].win_size; } } mcSHOW_DBG_MSG(("\ntotal tx window size B0: %d B1: %d\n", u4B0Tatal, u4B1Tatal)); } #endif } #endif static void TXPerbitCalibrationInit(DRAMC_CTX_T *p, U8 calType) { if (calType != TX_DQ_DQS_MOVE_DQM_ONLY) { #if 1 #if PINMUX_AUTO_TEST_PER_BIT_TX if(gTX_check_per_bit_flag == 1) { } else #endif { vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY0), 0); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY1), 0); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY0), 0); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY1), 0); } #else vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU_R0_B0_DQ0), P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0) | P_Fld(0x0, SHU_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU_R0_B1_DQ0), P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ7_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ6_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ5_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ4_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ3_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ2_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ1_DLY_B1) | P_Fld(0x0, SHU_R0_B1_DQ0_RK0_TX_ARDQ0_DLY_B1)); #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY3), 0x0, SHU_R0_B0_TXDLY3_TX_ARDQM0_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY3), 0x0, SHU_R0_B1_TXDLY3_TX_ARDQM0_DLY_B1); } } #define TX_TDQS2DQ_PRE_CAL 0 #if TX_TDQS2DQ_PRE_CAL U16 u2DQS2DQ_Pre_Cal[CHANNEL_NUM][RANK_MAX][2] = {0}; #endif static void TXScanRange_PI(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U16 *pu2Begin, U16 *pu2End) { U8 u1MCK2UI, u1UI2PI, u1ByteIdx; U32 u4RegValue_TXDLY, u4RegValue_dly; U8 ucdq_ui_large_bak[DQS_BYTE_NUMBER], ucdq_ui_small_bak[DQS_BYTE_NUMBER]; U16 u2TempVirtualDelay, u2SmallestVirtualDelay = 0xffff; U16 u2DQDelayBegin = 0, u2DQDelayEnd = 0; { u4RegValue_TXDLY = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS0)); u4RegValue_dly = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS1)); } u1MCK2UI = u1MCK2UI_DivShift(p); if (vGet_DDR_Loop_Mode(p) == DDR800_CLOSE_LOOP) u1UI2PI = 6; else u1UI2PI = 5; for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { ucdq_ui_large_bak[u1ByteIdx] = (u4RegValue_TXDLY >> (u1ByteIdx << 2)) & 0x7; ucdq_ui_small_bak[u1ByteIdx] = (u4RegValue_dly >> (u1ByteIdx << 2)) & 0x7; u2TempVirtualDelay = (((ucdq_ui_large_bak[u1ByteIdx] << u1MCK2UI) + ucdq_ui_small_bak[u1ByteIdx]) << u1UI2PI) + wrlevel_dqs_final_delay[p->rank][u1ByteIdx]; if (u2TempVirtualDelay < u2SmallestVirtualDelay) { u2SmallestVirtualDelay = u2TempVirtualDelay; } //mcSHOW_DBG_MSG2(("Original DQS_B%d VirtualDelay %d = (%d %d %d)\n", u1ByteIdx, u2TempVirtualDelay, // ucdq_ui_large_bak[u1ByteIdx], ucdq_ui_small_bak[u1ByteIdx], wrlevel_dqs_final_delay[p->rank][u1ByteIdx])); } u2DQDelayBegin = u2SmallestVirtualDelay; #if TX_TDQS2DQ_PRE_CAL if (u1IsLP4Div4DDR800(p) == FALSE) { if (u2DQS2DQ_Pre_Cal[p->channel][p->rank][vGet_Div_Mode(p)] > 0) { U16 u2TmpShift; mcSHOW_DBG_MSG(("TX_TDQS2DQ_PRE_CAL : change DQ begin %d -->", u2DQDelayBegin)); u2TmpShift = (u2DQS2DQ_Pre_Cal[p->channel][p->rank][vGet_Div_Mode(p)]* p->frequency) / 1000; if (u2TmpShift >= 15) u2TmpShift -= 15; else u2TmpShift = 0; u2DQDelayBegin += u2TmpShift; mcSHOW_DBG_MSG(("%d (+%d)\n", u2DQDelayBegin, u2TmpShift)); } } #endif #if TX_K_DQM_WITH_WDBI if (calType == TX_DQ_DQS_MOVE_DQM_ONLY) { u2DQDelayBegin -= (1 << (u1MCK2UI + 5)); } #endif u2DQDelayEnd = u2DQDelayBegin + ((1 << u1MCK2UI) << u1UI2PI); *pu2Begin = u2DQDelayBegin; *pu2End = u2DQDelayEnd; #if 0 mcSHOW_DBG_MSG(("TXScanRange_PI %d~%d\n", u2DQDelayBegin, u2DQDelayEnd)); #endif } static void TXScanRange_Vref(DRAMC_CTX_T *p, U8 u1VrefScanEnable, U16* pu2Range, U16 *pu2Begin, U16 *pu2End, U16 *pu2Setp) { U16 u2VrefBegin = 0, u2VrefEnd = 0; if (u1VrefScanEnable) { #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL) if (p->femmc_Ready == 1) { u2VrefBegin = p->pSavetimeData->u1TxWindowPerbitVref_Save[p->channel][p->rank]; u2VrefEnd = u2VrefBegin + 1; } #endif } else { u2VrefBegin = 0; u2VrefEnd = 0; } *pu2Range = (!p->odt_onoff); *pu2Begin = u2VrefBegin; *pu2End = u2VrefEnd; *pu2Setp = TX_VREF_RANGE_STEP; } static U16 TxChooseVref(DRAMC_CTX_T *p, PASS_WIN_DATA_BY_VREF_T pVrefInfo[], U8 u1VrefNum) { U8 u1VrefIdx, u1WorseBitIdx = 0, u1WinSizeOfWorseBit = 0; //U8 u1VrefPassBegin = LP4_TX_VREF_BOUNDARY_NOT_READY, u1VrefPassEnd = LP4_TX_VREF_BOUNDARY_NOT_READY, u1TempPassNum = 0, u1MaxVerfPassNum = 0; //U8 u1VrefPassBegin_Final = LP4_TX_VREF_BOUNDARY_NOT_READY, u1VrefPassEnd_Final = LP4_TX_VREF_BOUNDARY_NOT_READY; U16 u2MaxWinSum = 0; U16 u2FinalVref = 0; for (u1VrefIdx = 0; u1VrefIdx < u1VrefNum; u1VrefIdx++) { mcSHOW_DBG_MSG2(("TX Vref=%d, minBit %d, minWin=%d, winSum=%d\n", pVrefInfo[u1VrefIdx].u2VrefUsed, pVrefInfo[u1VrefIdx].u1WorseBitIdx_byVref, pVrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref, pVrefInfo[u1VrefIdx].u2WinSum_byVref)); #if LP4_TX_VREF_PASS_CONDITION if ((pVrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref > LP4_TX_VREF_PASS_CONDITION)) { if (u1VrefPassBegin == LP4_TX_VREF_BOUNDARY_NOT_READY) { u1VrefPassBegin = pVrefInfo[u1VrefIdx].u2VrefUsed; u1TempPassNum = 1; } else u1TempPassNum ++; if (u1VrefIdx == u1VrefNum - 1) { u1VrefPassEnd = pVrefInfo[u1VrefIdx].u2VrefUsed; if (u1TempPassNum > u1MaxVerfPassNum) { u1VrefPassBegin_Final = u1VrefPassBegin; u1VrefPassEnd_Final = u1VrefPassEnd; u1MaxVerfPassNum = u1TempPassNum; } } } else { if ((u1VrefPassBegin != LP4_TX_VREF_BOUNDARY_NOT_READY) && (u1VrefPassEnd == LP4_TX_VREF_BOUNDARY_NOT_READY)) { u1VrefPassEnd = pVrefInfo[u1VrefIdx].u2VrefUsed - TX_VREF_RANGE_STEP; if (u1TempPassNum > u1MaxVerfPassNum) { u1VrefPassBegin_Final = u1VrefPassBegin; u1VrefPassEnd_Final = u1VrefPassEnd; u1MaxVerfPassNum = u1TempPassNum; } u1VrefPassBegin = 0xff; u1VrefPassEnd = 0xff; u1TempPassNum = 0; } } #endif } #if LP4_TX_VREF_PASS_CONDITION //if((u1VrefPassBegin_Final !=LP4_TX_VREF_BOUNDARY_NOT_READY) && (u1VrefPassEnd_Final!=LP4_TX_VREF_BOUNDARY_NOT_READY)) if (u1MaxVerfPassNum > 0) { u2FinalVref = (u1VrefPassBegin_Final + u1VrefPassEnd_Final) >> 1; mcSHOW_DBG_MSG(("[TxChooseVref] Window > %d, Vref (%d~%d), Final Vref %d\n", LP4_TX_VREF_PASS_CONDITION, u1VrefPassBegin_Final, u1VrefPassEnd_Final, u2FinalVref)); } else #endif { for (u1VrefIdx = 0; u1VrefIdx < u1VrefNum; u1VrefIdx++) { if ((pVrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref > u1WinSizeOfWorseBit) || ((pVrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref == u1WinSizeOfWorseBit) && (pVrefInfo[u1VrefIdx].u2WinSum_byVref > u2MaxWinSum))) { u1WinSizeOfWorseBit = pVrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref; u1WorseBitIdx = pVrefInfo[u1VrefIdx].u1WorseBitIdx_byVref; u2MaxWinSum = pVrefInfo[u1VrefIdx].u2WinSum_byVref; u2FinalVref = pVrefInfo[u1VrefIdx].u2VrefUsed; } } mcSHOW_DBG_MSG(("[TxChooseVref] Worse bit %d, Min win %d, Win sum %d, Final Vref %d\n", u1WorseBitIdx, u1WinSizeOfWorseBit, u2MaxWinSum, u2FinalVref)); //mcDUMP_REG_MSG(("[TxChooseVref] Worse bit %d, Min win %d, Win sum %d, Final Vref %d\n", u1WorseBitIdx, u1WinSizeOfWorseBit, u2MaxWinSum, u2FinalVref)); } return u2FinalVref; } static void DramcTXSetVref(DRAMC_CTX_T *p, U8 u1VrefRange, U8 u1VrefValue) { U8 u1TempOPValue; u1TempOPValue = ((u1VrefValue & 0x3f) | (u1VrefRange << 6)); u1MR14Value[p->channel][p->rank][p->dram_fsp] = u1TempOPValue; DramcModeRegWriteByRank(p, p->rank, 14, u1TempOPValue); #if CALIBRATION_SPEED_UP_DEBUG mcSHOW_DBG_MSG2(("Yulia TX Vref : CH%d Rank%d, TX Range %d Vref %d\n\n", p->channel, p->rank, u1VrefRange, (u1VrefValue & 0x3f))); #endif } static void TXSetFinalVref(DRAMC_CTX_T *p, U16 u2FinalRange, U16 u2FinalVref) { DramcTXSetVref(p, u2FinalRange, u2FinalVref); #ifdef FOR_HQA_TEST_USED gFinalTXVrefDQ[p->channel][p->rank] = (U8) u2FinalVref; #endif #if VENDER_JV_LOG mcSHOW_DBG_MSG5(("\nFinal TX Range %d Vref %d\n\n", u2FinalRange, u2FinalVref)); #else mcSHOW_DBG_MSG(("\nFinal TX Range %d Vref %d\n\n", u2FinalRange, u2FinalVref)); #endif #if CALIBRATION_SPEED_UP_DEBUG mcSHOW_DBG_MSG2(("Yulia TX Vref Final: CH%d Rank%d, TX Range %d Vref %d\n\n", p->channel, p->rank, u2FinalRange, u2FinalVref)); #endif } #if ENABLE_TX_TRACKING #if !BYPASS_CALIBRATION static #endif void TXUpdateTXTracking(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U8 ucdq_pi[], U8 ucdqm_pi[]) { if (calType == TX_DQ_DQS_MOVE_DQ_ONLY || calType == TX_DQ_DQS_MOVE_DQM_ONLY) { if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_PI), P_Fld(ucdq_pi[0], SHURK_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_pi[1], SHURK_PI_RK0_ARPI_DQ_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_DQS2DQ_CAL1), P_Fld(ucdq_pi[1], SHURK_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ1) | P_Fld(ucdq_pi[0], SHURK_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_DQS2DQ_CAL2), P_Fld(ucdq_pi[1], SHURK_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ1) | P_Fld(ucdq_pi[0], SHURK_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ0)); } //if(calType ==TX_DQ_DQS_MOVE_DQM_ONLY || (calType ==TX_DQ_DQS_MOVE_DQ_ONLY)) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_PI), P_Fld(ucdqm_pi[0], SHURK_PI_RK0_ARPI_DQM_B0) | P_Fld(ucdqm_pi[1], SHURK_PI_RK0_ARPI_DQM_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_DQS2DQ_CAL5), P_Fld(ucdqm_pi[1], SHURK_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM1) | P_Fld(ucdqm_pi[0], SHURK_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM0)); } } #if 0 vIO32WriteFldMulti(DRAMC_REG_SHURK0_PI + (CHANNEL_A << POS_BANK_NUM), \ P_Fld(ucdq_final_pi[0], SHURK0_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_final_pi[1], SHURK0_PI_RK0_ARPI_DQ_B1)); vIO32WriteFldMulti(DRAMC_REG_SHURK0_PI + SHIFT_TO_CHB_ADDR, \ P_Fld(ucdq_final_pi[2], SHURK0_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_final_pi[3], SHURK0_PI_RK0_ARPI_DQ_B1)); #endif } #endif #if !BYPASS_CALIBRATION static #endif void TXSetDelayReg_DQ(DRAMC_CTX_T *p, U8 u1UpdateRegUI, U8 ucdq_ui_large[], U8 ucdq_oen_ui_large[], U8 ucdq_ui_small[], U8 ucdq_oen_ui_small[], U8 ucdql_pi[]) { if (u1UpdateRegUI) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0), \ P_Fld(ucdq_ui_large[0], SHURK_SELPH_DQ0_TXDLY_DQ0) | P_Fld(ucdq_ui_large[1], SHURK_SELPH_DQ0_TXDLY_DQ1) | P_Fld(ucdq_oen_ui_large[0], SHURK_SELPH_DQ0_TXDLY_OEN_DQ0) | P_Fld(ucdq_oen_ui_large[1], SHURK_SELPH_DQ0_TXDLY_OEN_DQ1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2), \ P_Fld(ucdq_ui_small[0], SHURK_SELPH_DQ2_DLY_DQ0) | P_Fld(ucdq_ui_small[1], SHURK_SELPH_DQ2_DLY_DQ1) | P_Fld(ucdq_oen_ui_small[0], SHURK_SELPH_DQ2_DLY_OEN_DQ0) | P_Fld(ucdq_oen_ui_small[1], SHURK_SELPH_DQ2_DLY_OEN_DQ1)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), ucdql_pi[0], SHU_R0_B0_DQ0_SW_ARPI_DQ_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), ucdql_pi[1], SHU_R0_B1_DQ0_SW_ARPI_DQ_B1); } #if !BYPASS_CALIBRATION static #endif void TXSetDelayReg_DQM(DRAMC_CTX_T *p, U8 u1UpdateRegUI, U8 ucdqm_ui_large[], U8 ucdqm_oen_ui_large[], U8 ucdqm_ui_small[], U8 ucdqm_oen_ui_small[], U8 ucdqm_pi[]) { if (u1UpdateRegUI) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1), P_Fld(ucdqm_ui_large[0], SHURK_SELPH_DQ1_TXDLY_DQM0) | P_Fld(ucdqm_ui_large[1], SHURK_SELPH_DQ1_TXDLY_DQM1) | P_Fld(ucdqm_oen_ui_large[0], SHURK_SELPH_DQ1_TXDLY_OEN_DQM0) | P_Fld(ucdqm_oen_ui_large[1], SHURK_SELPH_DQ1_TXDLY_OEN_DQM1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3), P_Fld(ucdqm_ui_small[0], SHURK_SELPH_DQ3_DLY_DQM0) | P_Fld(ucdqm_ui_small[1], SHURK_SELPH_DQ3_DLY_DQM1) | P_Fld(ucdqm_oen_ui_small[0], SHURK_SELPH_DQ3_DLY_OEN_DQM0) | P_Fld(ucdqm_oen_ui_small[1], SHURK_SELPH_DQ3_DLY_OEN_DQM1)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), ucdqm_pi[0], SHU_R0_B0_DQ0_SW_ARPI_DQM_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), ucdqm_pi[1], SHU_R0_B1_DQ0_SW_ARPI_DQM_B1); } #if TX_AUTO_K_SUPPORT static void Tx_Auto_K_Init(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U8 ucdq_pi, U8 u1PI_Len) { u8 pi_thrd = 0xa; //u8 early_break = 0x0; #if FOR_DV_SIMULATION_USED == 1 cal_sv_rand_args_t *psra = get_psra(); if (psra) { pi_thrd = psra->tx_atk_pass_pi_thrd & 0xFF; early_break = psra->tx_atk_early_break & 0xFF; } #endif #if ENABLE_PA_IMPRO_FOR_TX_AUTOK vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DCM_SUB_CTRL), 0x1, DCM_SUB_CTRL_SUBCLK_CTRL_TX_AUTOK); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_CG_SET0), 0x1, TX_CG_SET0_TX_ATK_CLKRUN); #endif if (calType == TX_DQ_DQS_MOVE_DQ_DQM) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), P_Fld(0x1, TX_ATK_SET1_TX_ATK_DQ_PI_EN) | P_Fld(0x1, TX_ATK_SET1_TX_ATK_DQM_PI_EN)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET0), P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQ_B0_PI_INIT) | P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQ_B1_PI_INIT) | P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQM_B0_PI_INIT) | P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQM_B1_PI_INIT)); } else if (calType == TX_DQ_DQS_MOVE_DQM_ONLY) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x1, TX_ATK_SET1_TX_ATK_DQM_PI_EN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET0), P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQM_B0_PI_INIT) | P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQM_B1_PI_INIT)); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x1, TX_ATK_SET1_TX_ATK_DQ_PI_EN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET0), P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQ_B0_PI_INIT) | P_Fld(ucdq_pi, TX_ATK_SET0_TX_ATK_DQ_B1_PI_INIT)); } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_CTRL1), 0, MISC_CTRL1_R_DMARPIDQ_SW); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), P_Fld(u1PI_Len, TX_ATK_SET1_TX_ATK_PI_LEN) | P_Fld(pi_thrd, TX_ATK_SET1_TX_ATK_PASS_PI_THRD)); #if (fcFOR_CHIP_ID == fcIPM) vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), early_break, TX_ATK_SET1_TX_ATK_EARLY_BREAK); #endif { vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_TX_SET0), P_Fld(0x3, SHU_TX_SET0_TXOEN_AUTOSET_OFFSET) | P_Fld(0x1, SHU_TX_SET0_TXOEN_AUTOSET_EN)); } #if TX_AUTO_K_DEBUG_ENABLE vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x1, TX_ATK_SET1_TX_ATK_DBG_EN); #endif } static void Tx_Auto_K_complete_check(DRAMC_CTX_T *p) { U32 u4loop_count = 0; while ((u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_RESULT8), TX_ATK_RESULT8_TX_ATK_DONE) != 0x1)) { mcDELAY_US(1); u4loop_count++; //mcSHOW_DBG_MSG(("Wait! TX auto K is not done!\n")); if (u4loop_count > 100000) { mcSHOW_ERR_MSG(("Error! TX auto K is not done!\n")); break; } } if ((u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_RESULT8), TX_ATK_RESULT8_TX_ATK_FIND_PW) == 0x1)) { vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_OK); mcSHOW_DBG_MSG(("Tx auto K, all bit find passs window\n")); } else { mcSHOW_ERR_MSG(("Error! TX auto K is fail!\n")); } } static void Tx_Auto_K_Clear(DRAMC_CTX_T *p) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x0, TX_ATK_SET1_TX_ATK_TRIG); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_TX_SET0), 0x0, SHU_TX_SET0_TXOEN_AUTOSET_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_CTRL1), 0x1, MISC_CTRL1_R_DMARPIDQ_SW); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x0, TX_ATK_SET1_TX_ATK_DBG_EN); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x1, TX_ATK_SET1_TX_ATK_CLR); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x0, TX_ATK_SET1_TX_ATK_CLR); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), P_Fld(0x0, TX_ATK_SET1_TX_ATK_PI_LEN) | P_Fld(0x0, TX_ATK_SET1_TX_ATK_DQ_PI_EN) | P_Fld(0x0, TX_ATK_SET1_TX_ATK_DQM_PI_EN)); #if ENABLE_PA_IMPRO_FOR_TX_AUTOK vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_CG_SET0), 0x0, TX_CG_SET0_TX_ATK_CLKRUN); #endif } #if TX_AUTO_K_WORKAROUND static void Tx_Auto_K_DQM_Workaround(DRAMC_CTX_T *p) { //U32 u4DQM_MCK, u4DQM_UI, u4DQM_PI_B0, u4DQM_PI_B1; vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1), u4DQM_MCK_RK1_backup); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3), u4DQM_UI_RK1_backup); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), u4DQM_PI_RK1_backup[0]); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), u4DQM_PI_RK1_backup[1]); } static void Tx_Auto_K_DQ_Workaround(DRAMC_CTX_T *p) { //U32 u4DQ_MCK, u4DQ_UI, u4DQ_PI_B0, u4DQ_PI_B1; vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0), u4DQ_MCK_RK1_backup); vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2), u4DQ_UI_RK1_backup); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), u4DQ_PI_RK1_backup[0]); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), u4DQ_PI_RK1_backup[1]); } #endif #if TX_AUTO_K_DEBUG_ENABLE static void Tx_Auto_K_Debug_Message(DRAMC_CTX_T *p, U8 u1PI_Len) { U8 u1bit_num = 0, u1BitIdx; U16 u2Length = 0, u2Length_max = 0; U32 u4status; U32 u4status_bit[4][DQ_DATA_WIDTH]; if (u1PI_Len == 0) u2Length_max = 48; else u2Length_max = 32 * (1 + u1PI_Len); for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), u1BitIdx, TX_ATK_SET1_TX_ATK_DBG_BIT_SEL); u4status_bit[0][u1BitIdx] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_DBG_BIT_STATUS1)); u4status_bit[1][u1BitIdx] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_DBG_BIT_STATUS2)); u4status_bit[2][u1BitIdx] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_DBG_BIT_STATUS3)); u4status_bit[3][u1BitIdx] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_DBG_BIT_STATUS4)); } mcSHOW_DBG_MSG2(("Debug TX DQ PASS/FAIL status:\n")); for (u2Length = 0; u2Length < u2Length_max; u2Length++) { mcSHOW_DBG_MSG2(("Delay=%3d ", u2Length)); for (u1bit_num = 0; u1bit_num < p->data_width; u1bit_num++) { u4status = ((u4status_bit[u2Length / 32][u1bit_num] >> (u2Length % 32)) & 0x1); if (u4status == 0) { mcSHOW_DBG_MSG2(("x")); } else { mcSHOW_DBG_MSG2(("o")); } if (u1bit_num == (p->data_width - 1)) { mcSHOW_DBG_MSG2((" \n")); } } } //mcSHOW_DBG_MSG(("Debug DQ PASS(1)/FAIL(0) bit: %d, STATUS1: 0x%x, STATUS2: 0x%x, STATUS3: 0x%x, STATUS4: 0x%x,\n",u1BitIdx,u4status_bit[0][u1BitIdx],u4status_bit[1][u1BitIdx],u4status_bit[2][u1BitIdx],u4status_bit[3][u1BitIdx])); } #endif #endif #if TX_K_DQM_WITH_WDBI void vSwitchWriteDBISettings(DRAMC_CTX_T *p, U8 u1OnOff) { S8 u1TXShiftMCK; u1TXShiftMCK = (u1OnOff)? -1: 1; DramcWriteShiftMCKForWriteDBI(p, u1TXShiftMCK); SetDramModeRegForWriteDBIOnOff(p, p->dram_fsp, u1OnOff); DramcWriteDBIOnOff(p, u1OnOff); #if (TX_AUTO_K_SUPPORT && TX_AUTO_K_WORKAROUND) if (p->rank == RANK_1) { u4DQ_MCK_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0)); u4DQ_UI_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2)); u4DQ_PI_RK1_backup[0] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0)); u4DQ_PI_RK1_backup[1] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0)); } #endif } #endif DRAM_STATUS_T DramcTxWindowPerbitCal(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U8 u1VrefScanEnable, u8 isAutoK) { U8 u1BitTemp, u1BitIdx, u1ByteIdx, u1RankIdx, backup_rank; U32 uiFinishCount; PASS_WIN_DATA_T WinPerBit[DQ_DATA_WIDTH], VrefWinPerBit[DQ_DATA_WIDTH], FinalWinPerBit[DQ_DATA_WIDTH]; U16 uiDelay, u2DQDelayBegin, u2DQDelayEnd, u2DQDelayStep = 1; U8 ucdq_pi, ucdq_ui_small, ucdq_ui_large, ucdq_oen_ui_small, ucdq_oen_ui_large; U8 ucdq_ui_small_reg_value, u1UpdateRegUI; U8 ucdq_reg_pi[DQS_BYTE_NUMBER], ucdq_reg_ui_large[DQS_BYTE_NUMBER], ucdq_reg_ui_small[DQS_BYTE_NUMBER]; U8 ucdq_reg_oen_ui_large[DQS_BYTE_NUMBER], ucdq_reg_oen_ui_small[DQS_BYTE_NUMBER]; U8 ucdq_reg_dqm_pi[DQS_BYTE_NUMBER] = {0}, ucdq_reg_dqm_ui_large[DQS_BYTE_NUMBER] = {0}, ucdq_reg_dqm_ui_small[DQS_BYTE_NUMBER] = {0}; U8 ucdq_reg_dqm_oen_ui_large[DQS_BYTE_NUMBER] = {0}, ucdq_reg_dqm_oen_ui_small[DQS_BYTE_NUMBER] = {0}; #if 1 U16 u2DQM_Delay; U16 u2Center_min[DQS_BYTE_NUMBER] = {0}, u2Center_max[DQS_BYTE_NUMBER] = {0}; #endif U8 u1EnableDelayCell = 0; U16 u2DelayCellOfst[DQ_DATA_WIDTH] = {0}; U32 u4err_value, u4fail_bit; U16 u2FinalRange = 0, u2FinalVref; U16 u2VrefLevel, u2VrefBegin = 0, u2VrefEnd = 0, u2VrefStep; U16 u2TempWinSum, u2MaxWindowSum = 0;//, u2tx_window_sum[LP4_TX_VREF_DATA_NUM]={0}; //U32 u4TempRegValue; U8 u1min_bit, u1min_winsize = 0; U8 u1VrefIdx = 0; U8 u1PIDiff; PASS_WIN_DATA_BY_VREF_T VrefInfo[LP4_TX_VREF_DATA_NUM]; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } #if TX_AUTO_K_SUPPORT U8 u1PI_Len, u1dq_shift; U32 PwMaxInitReg[4] = {DRAMC_REG_TX_ATK_RESULT0, DRAMC_REG_TX_ATK_RESULT1, DRAMC_REG_TX_ATK_RESULT2, DRAMC_REG_TX_ATK_RESULT3}; U32 PwMaxLenReg[4] = {DRAMC_REG_TX_ATK_RESULT4, DRAMC_REG_TX_ATK_RESULT5, DRAMC_REG_TX_ATK_RESULT6, DRAMC_REG_TX_ATK_RESULT7}; U32 u4Length = 0; #if TX_AUTO_K_WORKAROUND U8 u1backup_Rank = 0; #endif #if TX_AUTO_K_WORKAROUND U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3)), }; #endif #endif #if 0 if(0)//(p->channel==CHANNEL_D) { ucdq_reg_ui_large[0] = ucdq_reg_ui_large[1] = 2; ucdq_reg_ui_small[0] = ucdq_reg_ui_small[1] = 1; ucdq_reg_oen_ui_large[0] = ucdq_reg_oen_ui_large[1] = 1; ucdq_reg_oen_ui_small[0] = ucdq_reg_oen_ui_small[1] = 6; ucdq_reg_pi[0] = ucdq_reg_pi[1] = 20; ucdq_reg_dqm_ui_large[0] = ucdq_reg_dqm_ui_large[1] = 2; ucdq_reg_dqm_ui_small[0] = ucdq_reg_dqm_ui_small[1] = 1; ucdq_reg_dqm_oen_ui_large[0] = ucdq_reg_dqm_oen_ui_large[1] = 1; ucdq_reg_dqm_oen_ui_small[0] = ucdq_reg_dqm_oen_ui_small[1] = 6; ucdq_reg_dqm_pi[0] = ucdq_reg_dqm_pi[1] = 20; TXSetDelayReg_DQ(p, TRUE, ucdq_reg_ui_large, ucdq_reg_oen_ui_large, ucdq_reg_ui_small, ucdq_reg_oen_ui_small, ucdq_reg_pi); TXSetDelayReg_DQM(p, TRUE, ucdq_reg_dqm_ui_large, ucdq_reg_dqm_oen_ui_large, ucdq_reg_dqm_ui_small, ucdq_reg_dqm_oen_ui_small, ucdq_reg_dqm_pi); return; } #endif //mcDUMP_REG_MSG(("\n[dumpRG] DramcTxWindowPerbitCal\n")); #if VENDER_JV_LOG if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif mcSHOW_DBG_MSG(("[TxWindowPerbitCal] caltype:%d Autok:%d\n", calType, isAutoK)); backup_rank = u1GetRank(p); TXPerbitCalibrationInit(p, calType); TXScanRange_PI(p, calType, &u2DQDelayBegin, &u2DQDelayEnd); TXScanRange_Vref(p, u1VrefScanEnable, &u2FinalRange, &u2VrefBegin, &u2VrefEnd, &u2VrefStep); vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_FAIL); if (isAutoK) { #if TX_AUTO_K_SUPPORT //CKEFixOnOff(p, p->rank, CKE_FIXON, TO_ONE_CHANNEL); u1UpdateRegUI = 1; uiDelay = u2DQDelayBegin; u1PI_Len = 3; TxWinTransferDelayToUIPI(p, uiDelay, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { if (u1UpdateRegUI) { ucdq_reg_ui_large[u1ByteIdx] = ucdq_ui_large; ucdq_reg_ui_small[u1ByteIdx] = ucdq_ui_small; ucdq_reg_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large; ucdq_reg_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small; ucdq_reg_dqm_ui_large[u1ByteIdx] = ucdq_ui_large; ucdq_reg_dqm_ui_small[u1ByteIdx] = ucdq_ui_small; ucdq_reg_dqm_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large; ucdq_reg_dqm_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small; } ucdq_reg_pi[u1ByteIdx] = ucdq_pi; ucdq_reg_dqm_pi[u1ByteIdx] = ucdq_pi; } #if TX_AUTO_K_WORKAROUND if (p->rank == 1) { u1backup_Rank = 1; p->rank = 0; DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); } #endif if (calType == TX_DQ_DQS_MOVE_DQ_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { TXSetDelayReg_DQ(p, u1UpdateRegUI, ucdq_reg_ui_large, ucdq_reg_oen_ui_large, ucdq_reg_ui_small, ucdq_reg_oen_ui_small, ucdq_reg_pi); mcSHOW_DBG_MSG2(("TX Auto-K set begin delay DQ MCK: %d, UI: %d, PI: %d\n", ucdq_reg_ui_large[0], ucdq_reg_ui_small[0], ucdq_reg_pi[0])); #if TX_AUTO_K_WORKAROUND if ((calType == TX_DQ_DQS_MOVE_DQ_ONLY) && (u1backup_Rank == 1)) Tx_Auto_K_DQM_Workaround(p); #endif } if (calType == TX_DQ_DQS_MOVE_DQM_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { TXSetDelayReg_DQM(p, u1UpdateRegUI, ucdq_reg_dqm_ui_large, ucdq_reg_dqm_oen_ui_large, ucdq_reg_dqm_ui_small, ucdq_reg_dqm_oen_ui_small, ucdq_reg_dqm_pi); mcSHOW_DBG_MSG2(("TX Auto-K set begin delay DQM MCK: %d, UI: %d, PI: %d\n", ucdq_reg_dqm_ui_large[0], ucdq_reg_dqm_ui_small[0], ucdq_reg_dqm_pi[0])); #if TX_AUTO_K_WORKAROUND if ((calType == TX_DQ_DQS_MOVE_DQM_ONLY) && (u1backup_Rank == 1)) Tx_Auto_K_DQ_Workaround(p); #endif } #if TX_AUTO_K_WORKAROUND if (u1backup_Rank == 1) p->rank = 1; #endif #endif } else { if (vGet_DDR_Loop_Mode(p) == SEMI_OPEN_LOOP_MODE) u2DQDelayStep = (1 << 3); else if (vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE) u2DQDelayStep = (1 << 4); else if (calType == TX_DQ_DQS_MOVE_DQ_DQM) u2DQDelayStep = 2; else u2DQDelayStep = 1; #if (FOR_DV_SIMULATION_USED == 1) u2DQDelayStep = (vGet_DDR_Loop_Mode(p) == OPEN_LOOP_MODE) ? 16 : 8; #endif } #if 0 mcSHOW_DBG_MSG(("[TxWindowPerbitCal] calType=%d, VrefScanEnable %d (Range %d, VrefBegin %d, u2VrefEnd %d)\n" "\nBegin, DQ Scan Range %d~%d\n", calType, u1VrefScanEnable, u2FinalRange, u2VrefBegin, u2VrefEnd, u2DQDelayBegin, u2DQDelayEnd)); #endif #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if (p->femmc_Ready == 1 && (p->Bypass_TXWINDOW)) { for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { u2Center_min[u1ByteIdx] = p->pSavetimeData->u1TxCenter_min_Save[p->channel][p->rank][u1ByteIdx]; u2Center_max[u1ByteIdx] = p->pSavetimeData->u1TxCenter_max_Save[p->channel][p->rank][u1ByteIdx]; for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++) { u1BitTemp = u1ByteIdx * DQS_BIT_NUMBER + u1BitIdx; FinalWinPerBit[u1BitTemp].win_center = p->pSavetimeData->u1Txwin_center_Save[p->channel][p->rank][u1BitTemp]; } } vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_FAST_K); } else #endif { #if ENABLE_K_WITH_WORST_SI_UI_SHIFT DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern | 0x80, 0, TE_UI_SHIFT); #else DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_XTALK_PATTERN, 0, TE_NO_UI_SHIFT); #endif for (u2VrefLevel = u2VrefBegin; u2VrefLevel <= u2VrefEnd; u2VrefLevel += u2VrefStep) { if (u1VrefScanEnable) { #if (!REDUCE_LOG_FOR_PRELOADER) mcSHOW_DBG_MSG2(("\n\n\tLP4 TX VrefRange %d, VrefLevel=%d\n", u2FinalRange, u2VrefLevel)); #endif #if VENDER_JV_LOG if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) { mcSHOW_DBG_MSG5(("\n\tLP4 TX VrefRange %d, VrefLevel=%d\n", u2FinalRange, u2VrefLevel)); } #endif DramcTXSetVref(p, u2FinalRange, u2VrefLevel); } else { mcSHOW_DBG_MSG(("\n\tTX Vref Scan disable\n")); } uiFinishCount = 0; u2TempWinSum = 0; ucdq_ui_small_reg_value = 0xff; for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { WinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA; WinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA; VrefWinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA; VrefWinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA; } if (isAutoK) { #if TX_AUTO_K_SUPPORT Tx_Auto_K_Init(p, calType, ucdq_pi, u1PI_Len); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET1), 0x1, TX_ATK_SET1_TX_ATK_TRIG); #endif } else { for (uiDelay = u2DQDelayBegin; uiDelay < u2DQDelayEnd; uiDelay += u2DQDelayStep) { TxWinTransferDelayToUIPI(p, uiDelay, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); if (ucdq_ui_small_reg_value != ucdq_ui_small) { u1UpdateRegUI = 1; ucdq_ui_small_reg_value = ucdq_ui_small; } else u1UpdateRegUI = 0; for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { if (u1UpdateRegUI) { ucdq_reg_ui_large[u1ByteIdx] = ucdq_ui_large; ucdq_reg_ui_small[u1ByteIdx] = ucdq_ui_small; ucdq_reg_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large; ucdq_reg_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small; ucdq_reg_dqm_ui_large[u1ByteIdx] = ucdq_ui_large; ucdq_reg_dqm_ui_small[u1ByteIdx] = ucdq_ui_small; ucdq_reg_dqm_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large; ucdq_reg_dqm_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small; } ucdq_reg_pi[u1ByteIdx] = ucdq_pi; ucdq_reg_dqm_pi[u1ByteIdx] = ucdq_pi; } if (calType == TX_DQ_DQS_MOVE_DQ_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { TXSetDelayReg_DQ(p, u1UpdateRegUI, ucdq_reg_ui_large, ucdq_reg_oen_ui_large, ucdq_reg_ui_small, ucdq_reg_oen_ui_small, ucdq_reg_pi); } if (calType == TX_DQ_DQS_MOVE_DQM_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { TXSetDelayReg_DQM(p, u1UpdateRegUI, ucdq_reg_dqm_ui_large, ucdq_reg_dqm_oen_ui_large, ucdq_reg_dqm_ui_small, ucdq_reg_dqm_oen_ui_small, ucdq_reg_dqm_pi); } u4err_value = 0; #if ENABLE_K_WITH_WORST_SI_UI_SHIFT u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern); #else DramcEngine2SetPat(p, TEST_AUDIO_PATTERN, 0, 0, TE_NO_UI_SHIFT); u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_AUDIO_PATTERN); DramcEngine2SetPat(p, TEST_XTALK_PATTERN, 0, 1, TE_NO_UI_SHIFT); u4err_value |= DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_XTALK_PATTERN); #endif if (u1VrefScanEnable == 0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY)) { //mcSHOW_DBG_MSG(("Delay=%3d |%2d %2d %3d| %2d %2d| 0x%8x [0]",uiDelay, ucdq_ui_large,ucdq_ui_small, ucdq_pi, ucdq_oen_ui_large,ucdq_oen_ui_small, u4err_value)); #ifdef ETT_PRINT_FORMAT if (u4err_value != 0) { mcSHOW_DBG_MSG3(("%d |%d %d %d|[0]", uiDelay, ucdq_ui_large, ucdq_ui_small, ucdq_pi)); } #else mcSHOW_DBG_MSG3(("Delay=%3d |%2d %2d %3d| 0x%8x [0]", uiDelay, ucdq_ui_large, ucdq_ui_small, ucdq_pi, u4err_value)); #endif } for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { u4fail_bit = u4err_value & ((U32)1 << u1BitIdx); if (u1VrefScanEnable == 0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY)) { if(u4err_value != 0) { if (u1BitIdx % DQS_BIT_NUMBER == 0) { mcSHOW_DBG_MSG3((" ")); } if (u4fail_bit == 0) { mcSHOW_DBG_MSG3(("o")); } else { mcSHOW_DBG_MSG3(("x")); } } } if (WinPerBit[u1BitIdx].first_pass == PASS_RANGE_NA) { if (u4fail_bit == 0) { WinPerBit[u1BitIdx].first_pass = uiDelay; #if TX_TDQS2DQ_PRE_CAL if ((u1IsLP4Div4DDR800(p) == FALSE) && (calType == TX_DQ_DQS_MOVE_DQ_ONLY) && (u1VrefScanEnable == FALSE)) { if (u2DQS2DQ_Pre_Cal[p->channel][p->rank][vGet_Div_Mode(p)] == 0) { u2DQS2DQ_Pre_Cal[p->channel][p->rank][vGet_Div_Mode(p)] = ((uiDelay - u2DQDelayBegin)* 1000) / p->frequency; } if (uiDelay == u2DQDelayBegin) { mcSHOW_ERR_MSG(("TX_TDQS2DQ_PRE_CAL: Warning, possible miss TX window boundary\n")); #if __ETT__ while (1); #endif } } #endif } } else if (WinPerBit[u1BitIdx].last_pass == PASS_RANGE_NA) { if (u4fail_bit != 0) { WinPerBit[u1BitIdx].last_pass = uiDelay - u2DQDelayStep; } else if (uiDelay >= (u2DQDelayEnd - u2DQDelayStep)) { WinPerBit[u1BitIdx].last_pass = uiDelay; mcSHOW_ERR_MSG(("\nTx last pass not found!!\n")); #if __ETT__ while(1); #endif } if (WinPerBit[u1BitIdx].last_pass != PASS_RANGE_NA) { if ((WinPerBit[u1BitIdx].last_pass - WinPerBit[u1BitIdx].first_pass) >= (VrefWinPerBit[u1BitIdx].last_pass - VrefWinPerBit[u1BitIdx].first_pass)) { if ((VrefWinPerBit[u1BitIdx].last_pass != PASS_RANGE_NA) && (VrefWinPerBit[u1BitIdx].last_pass - VrefWinPerBit[u1BitIdx].first_pass) > 0) { mcSHOW_DBG_MSG2(("Bit[%d] Bigger window update %d > %d, window broken?\n", u1BitIdx, \ (WinPerBit[u1BitIdx].last_pass - WinPerBit[u1BitIdx].first_pass), (VrefWinPerBit[u1BitIdx].last_pass - VrefWinPerBit[u1BitIdx].first_pass))); } if (((WinPerBit[u1BitIdx].last_pass - WinPerBit[u1BitIdx].first_pass) > TX_PASS_WIN_CRITERIA) ||((u2DQDelayStep>=16) && (WinPerBit[u1BitIdx].first_pass!=PASS_RANGE_NA))) uiFinishCount |= (1 << u1BitIdx); VrefWinPerBit[u1BitIdx].first_pass = WinPerBit[u1BitIdx].first_pass; VrefWinPerBit[u1BitIdx].last_pass = WinPerBit[u1BitIdx].last_pass; } WinPerBit[u1BitIdx].first_pass = PASS_RANGE_NA; WinPerBit[u1BitIdx].last_pass = PASS_RANGE_NA; } } } if(u1VrefScanEnable==0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY)) { if(u4err_value != 0) { mcSHOW_DBG_MSG3((" [MSB]\n")); } } if (uiFinishCount == 0xffff) { vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_OK); #if !REDUCE_LOG_FOR_PRELOADER #ifdef ETT_PRINT_FORMAT mcSHOW_DBG_MSG3(("TX calibration finding left boundary early break. PI DQ delay=0x%B\n", uiDelay)); #else mcSHOW_DBG_MSG3(("TX calibration finding left boundary early break. PI DQ delay=0x%2x\n", uiDelay)); #endif #endif break; } } } if (isAutoK) { #if TX_AUTO_K_SUPPORT Tx_Auto_K_complete_check(p); #if TX_AUTO_K_DEBUG_ENABLE Tx_Auto_K_Debug_Message(p, u1PI_Len); #endif #endif } u1min_winsize = 0xff; u1min_bit = 0xff; for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { if (isAutoK) { #if TX_AUTO_K_SUPPORT u1dq_shift = ((u1BitIdx % 4) * 8); VrefWinPerBit[u1BitIdx].first_pass = u2DQDelayBegin - ucdq_pi + ((u4IO32Read4B(DRAMC_REG_ADDR(PwMaxInitReg[u1BitIdx / 4])) & (0xff << u1dq_shift)) >> u1dq_shift); VrefWinPerBit[u1BitIdx].last_pass = ((u4IO32Read4B(DRAMC_REG_ADDR(PwMaxLenReg[u1BitIdx / 4])) & (0xff << u1dq_shift)) >> u1dq_shift) + VrefWinPerBit[u1BitIdx].first_pass; VrefWinPerBit[u1BitIdx].win_size = ((u4IO32Read4B(DRAMC_REG_ADDR(PwMaxLenReg[u1BitIdx / 4])) & (0xff << u1dq_shift)) >> u1dq_shift); if (u1PI_Len == 0) u4Length = 48; else u4Length = 32 * (1 + u1PI_Len); if ((VrefWinPerBit[u1BitIdx].first_pass == (int)(u2DQDelayBegin - ucdq_pi)) || (VrefWinPerBit[u1BitIdx].last_pass == (int)(u2DQDelayBegin + u4Length))) { mcSHOW_ERR_MSG(("Error! Probably miss pass window!\n")); } mcSHOW_DBG_MSG(("TX DQ bit %d, first pass: %d, last pass: %d\n", u1BitIdx, VrefWinPerBit[u1BitIdx].first_pass, VrefWinPerBit[u1BitIdx].last_pass)); #else //if(VrefWinPerBit[u1BitIdx].last_pass == VrefWinPerBit[u1BitIdx].first_pass) if (VrefWinPerBit[u1BitIdx].first_pass == PASS_RANGE_NA) VrefWinPerBit[u1BitIdx].win_size = 0; else VrefWinPerBit[u1BitIdx].win_size = VrefWinPerBit[u1BitIdx].last_pass - VrefWinPerBit[u1BitIdx].first_pass + u2DQDelayStep; #endif } else { if (VrefWinPerBit[u1BitIdx].first_pass == PASS_RANGE_NA) VrefWinPerBit[u1BitIdx].win_size = 0; else VrefWinPerBit[u1BitIdx].win_size = VrefWinPerBit[u1BitIdx].last_pass - VrefWinPerBit[u1BitIdx].first_pass + u2DQDelayStep; } if (VrefWinPerBit[u1BitIdx].win_size < u1min_winsize) { u1min_bit = u1BitIdx; u1min_winsize = VrefWinPerBit[u1BitIdx].win_size; } u2TempWinSum += VrefWinPerBit[u1BitIdx].win_size; #if VENDER_JV_LOG if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) { mcSHOW_DBG_MSG5(("TX Bit%d, %d%%\n", u1BitIdx, (VrefWinPerBit[u1BitIdx].win_size * 100 + 31) / 32)); } #endif VrefWinPerBit[u1BitIdx].win_center = (VrefWinPerBit[u1BitIdx].first_pass + VrefWinPerBit[u1BitIdx].last_pass) >> 1; #if PINMUX_AUTO_TEST_PER_BIT_TX gFinalTXPerbitFirstPass[p->channel][u1BitIdx] = VrefWinPerBit[u1BitIdx].first_pass; #endif } #if (__ETT__ || PIN_CHECK_TOOL) if (u1VrefScanEnable == 0) { //mcSHOW_DBG_MSG(("\n\tCH=%d, VrefRange= %d, VrefLevel = %d\n", p->channel, u2FinalRange, u2VrefLevel)); TxPrintWidnowInfo(p, VrefWinPerBit); } #endif if (u1VrefScanEnable == 1) { if (u2TempWinSum > u2MaxWindowSum) u2MaxWindowSum = u2TempWinSum; VrefInfo[u1VrefIdx].u2VrefUsed = u2VrefLevel; VrefInfo[u1VrefIdx].u1WorseBitWinSize_byVref = u1min_winsize; VrefInfo[u1VrefIdx].u1WorseBitIdx_byVref = u1min_bit; VrefInfo[u1VrefIdx].u2WinSum_byVref = u2TempWinSum; u1VrefIdx ++; } #if TX_AUTO_K_SUPPORT if (isAutoK) Tx_Auto_K_Clear(p); #endif #if LP4_TX_VREF_PASS_CONDITION if (u1VrefScanEnable && (u2TempWinSum < (u2MaxWindowSum * 95 / 100)) && (u1min_winsize < LP4_TX_VREF_PASS_CONDITION)) #else if (u1VrefScanEnable && (u2TempWinSum < (u2MaxWindowSum * 95 / 100)) && (u1min_winsize > TX_PASS_WIN_CRITERIA)) #endif { mcSHOW_DBG_MSG(("\nTX Vref early break, caculate TX vref\n")); break; } #if TX_AUTO_K_SUPPORT Tx_Auto_K_Clear(p); #endif } DramcEngine2End(p); #if (TX_AUTO_K_SUPPORT && TX_AUTO_K_WORKAROUND) if ((isAutoK) && (p->rank == RANK_1)) { vSetRank(p, RANK_0); DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); vSetRank(p, backup_rank); } #endif if (u1VrefScanEnable == 0) { for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { #if 1 u2Center_min[u1ByteIdx] = 0xffff; u2Center_max[u1ByteIdx] = 0; #endif for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++) { u1BitTemp = u1ByteIdx * DQS_BIT_NUMBER + u1BitIdx; memcpy(FinalWinPerBit, VrefWinPerBit, sizeof(PASS_WIN_DATA_T) * DQ_DATA_WIDTH); if (FinalWinPerBit[u1BitTemp].win_center < u2Center_min[u1ByteIdx]) u2Center_min[u1ByteIdx] = FinalWinPerBit[u1BitTemp].win_center; if (FinalWinPerBit[u1BitTemp].win_center > u2Center_max[u1ByteIdx]) u2Center_max[u1ByteIdx] = FinalWinPerBit[u1BitTemp].win_center; #ifdef FOR_HQA_TEST_USED if ((calType == TX_DQ_DQS_MOVE_DQ_ONLY) && (u1VrefScanEnable == 0)) { gFinalTXPerbitWin[p->channel][p->rank][u1BitTemp] = FinalWinPerBit[u1BitTemp].win_size; } #endif } } } } if (u1VrefScanEnable) { #if SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL if (p->femmc_Ready == 1 && (p->Bypass_TXWINDOW)) { u2FinalVref = p->pSavetimeData->u1TxWindowPerbitVref_Save[p->channel][p->rank]; } else #endif { u2FinalVref = TxChooseVref(p, VrefInfo, u1VrefIdx); } TXSetFinalVref(p, u2FinalRange, u2FinalVref); return DRAM_OK; } #ifdef FOR_HQA_TEST_USED if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) { gFinalTXPerbitWin_min_max[p->channel][p->rank] = u1min_winsize; if(u1min_winsize<16) { mcSHOW_ERR_MSG(("[WARNING] Smaller TX win !!\n")); #if CHECK_HQA_CRITERIA while(1); #endif } } #endif if ((calType == TX_DQ_DQS_MOVE_DQ_ONLY) && (p->frequency >= 1333) && (p->u2DelayCellTimex100 != 0)) { u1EnableDelayCell = 1; mcSHOW_DBG_MSG(("[TX_PER_BIT_DELAY_CELL] DelayCellTimex100 =%d/100 ps\n", p->u2DelayCellTimex100)); //mcDUMP_REG_MSG(("[TX_PER_BIT_DELAY_CELL] DelayCellTimex100 =%d/100 ps\n", p->u2DelayCellTimex100)); } for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { mcSHOW_DBG_MSG((" == TX Byte %d ==\n", u1ByteIdx)); //mcDUMP_REG_MSG((" == TX Byte %d ==\n", u1ByteIdx)); u2DQM_Delay = ((u2Center_min[u1ByteIdx] + u2Center_max[u1ByteIdx]) >> 1); if (u1EnableDelayCell == 0) { uiDelay = u2DQM_Delay; } else { uiDelay = u2Center_min[u1ByteIdx]; for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++) { u1BitTemp = u1ByteIdx * DQS_BIT_NUMBER + u1BitIdx; u1PIDiff = FinalWinPerBit[u1BitTemp].win_center - u2Center_min[u1ByteIdx]; if (p->u2DelayCellTimex100 != 0) { u2DelayCellOfst[u1BitTemp] = (u1PIDiff * 100000000 / (DDRPhyGetRealFreq(p)<< 6)) / p->u2DelayCellTimex100; mcSHOW_DBG_MSG(("u2DelayCellOfst[%d]=%d cells (%d PI)\n", u1BitTemp, u2DelayCellOfst[u1BitTemp], u1PIDiff)); //mcDUMP_REG_MSG(("u2DelayCellOfst[%d]=%d cells (%d PI)\n", u1BitTemp, u2DelayCellOfst[u1BitTemp], u1PIDiff)); if(u2DelayCellOfst[u1BitTemp]>255) { mcSHOW_DBG_MSG(("[WARNING] TX DQ%d delay cell %d >255, adjust to 255 cell\n", u1BitIdx, u2DelayCellOfst[u1BitTemp])); u2DelayCellOfst[u1BitTemp] =255; } } else { mcSHOW_ERR_MSG(("Error: Cell time (p->u2DelayCellTimex100) is 0 \n")); break; } } } TxWinTransferDelayToUIPI(p, uiDelay, 1, &ucdq_reg_ui_large[u1ByteIdx], &ucdq_reg_ui_small[u1ByteIdx], &ucdq_reg_pi[u1ByteIdx], \ &ucdq_reg_oen_ui_large[u1ByteIdx], &ucdq_reg_oen_ui_small[u1ByteIdx]); TxWinTransferDelayToUIPI(p, u2DQM_Delay, 1, &ucdq_reg_dqm_ui_large[u1ByteIdx], &ucdq_reg_dqm_ui_small[u1ByteIdx], &ucdq_reg_dqm_pi[u1ByteIdx], \ &ucdq_reg_dqm_oen_ui_large[u1ByteIdx], &ucdq_reg_dqm_oen_ui_small[u1ByteIdx]); if (calType == TX_DQ_DQS_MOVE_DQ_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { mcSHOW_DBG_MSG(("Update DQ dly =%d (%d ,%d, %d) DQ OEN =(%d ,%d)\n", uiDelay, ucdq_reg_ui_large[u1ByteIdx], ucdq_reg_ui_small[u1ByteIdx], ucdq_reg_pi[u1ByteIdx], \ ucdq_reg_oen_ui_large[u1ByteIdx], ucdq_reg_oen_ui_small[u1ByteIdx])); /*mcDUMP_REG_MSG(("Update DQ dly =%d (%d ,%d, %d) DQ OEN =(%d ,%d)\n", uiDelay, ucdq_reg_ui_large[u1ByteIdx], ucdq_reg_ui_small[u1ByteIdx], ucdq_reg_pi[u1ByteIdx], \ ucdq_reg_oen_ui_large[u1ByteIdx], ucdq_reg_oen_ui_small[u1ByteIdx]));*/ } //if(calType ==TX_DQ_DQS_MOVE_DQM_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM) { mcSHOW_DBG_MSG(("Update DQM dly =%d (%d ,%d, %d) DQM OEN =(%d ,%d)\n", u2DQM_Delay, ucdq_reg_dqm_ui_large[u1ByteIdx], ucdq_reg_dqm_ui_small[u1ByteIdx], ucdq_reg_dqm_pi[u1ByteIdx], \ ucdq_reg_dqm_oen_ui_large[u1ByteIdx], ucdq_reg_dqm_oen_ui_small[u1ByteIdx])); /*mcDUMP_REG_MSG(("Update DQM dly =%d (%d ,%d, %d) DQM OEN =(%d ,%d)\n", u2DQM_Delay, ucdq_reg_dqm_ui_large[u1ByteIdx], ucdq_reg_dqm_ui_small[u1ByteIdx], ucdq_reg_dqm_pi[u1ByteIdx], \ ucdq_reg_dqm_oen_ui_large[u1ByteIdx], ucdq_reg_dqm_oen_ui_small[u1ByteIdx]));*/ } mcSHOW_DBG_MSG(("\n")); #ifdef FOR_HQA_REPORT_USED if (calType == TX_DQ_DQS_MOVE_DQ_ONLY) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "TX_Window_Center_", "BYTE", u1ByteIdx, uiDelay, NULL); for (u1BitIdx = u1ByteIdx*8; u1BitIdx < u1ByteIdx*8+8; u1BitIdx++) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "TX_Window_Center_", "DQ", u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, NULL); } } #if TX_K_DQM_WITH_WDBI if ((p->DBI_W_onoff[p->dram_fsp]!=DBI_ON)) { if (calType == TX_DQ_DQS_MOVE_DQ_ONLY && u1VrefScanEnable == FALSE) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_", "DQM", u1ByteIdx, u2DQM_Delay, NULL); } } else { if (calType == TX_DQ_DQS_MOVE_DQM_ONLY) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_", "DQM", u1ByteIdx, u2DQM_Delay, NULL); } } #else if (calType == TX_DQ_DQS_MOVE_DQ_ONLY && u1VrefScanEnable == FALSE) { HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_", "DQM", u1ByteIdx, u2DQM_Delay, NULL); } #endif #if 0 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "TX_Window_Center_", "LargeUI", u1ByteIdx, ucdq_reg_ui_large[u1ByteIdx], NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_", "SmallUI", u1ByteIdx, ucdq_reg_ui_small[u1ByteIdx], NULL); HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_", "PI", u1ByteIdx, ucdq_reg_pi[u1ByteIdx], NULL); #endif #endif } #if REG_ACCESS_PORTING_DGB RegLogEnable = 1; #endif for (u1RankIdx = p->rank; u1RankIdx < RANK_MAX; u1RankIdx++) { vSetRank(p, u1RankIdx); if (calType == TX_DQ_DQS_MOVE_DQ_ONLY || calType == TX_DQ_DQS_MOVE_DQ_DQM) { TXSetDelayReg_DQ(p, TRUE, ucdq_reg_ui_large, ucdq_reg_oen_ui_large, ucdq_reg_ui_small, ucdq_reg_oen_ui_small, ucdq_reg_pi); } TXSetDelayReg_DQM(p, TRUE, ucdq_reg_dqm_ui_large, ucdq_reg_dqm_oen_ui_large, ucdq_reg_dqm_ui_small, ucdq_reg_dqm_oen_ui_small, ucdq_reg_dqm_pi); if (u1EnableDelayCell) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY0), P_Fld(u2DelayCellOfst[3], SHU_R0_B0_TXDLY0_TX_ARDQ3_DLY_B0) | P_Fld(u2DelayCellOfst[2], SHU_R0_B0_TXDLY0_TX_ARDQ2_DLY_B0) | P_Fld(u2DelayCellOfst[1], SHU_R0_B0_TXDLY0_TX_ARDQ1_DLY_B0) | P_Fld(u2DelayCellOfst[0], SHU_R0_B0_TXDLY0_TX_ARDQ0_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_TXDLY1), P_Fld(u2DelayCellOfst[7], SHU_R0_B0_TXDLY1_TX_ARDQ7_DLY_B0) | P_Fld(u2DelayCellOfst[6], SHU_R0_B0_TXDLY1_TX_ARDQ6_DLY_B0) | P_Fld(u2DelayCellOfst[5], SHU_R0_B0_TXDLY1_TX_ARDQ5_DLY_B0) | P_Fld(u2DelayCellOfst[4], SHU_R0_B0_TXDLY1_TX_ARDQ4_DLY_B0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY0), P_Fld(u2DelayCellOfst[11], SHU_R0_B1_TXDLY0_TX_ARDQ3_DLY_B1) | P_Fld(u2DelayCellOfst[10], SHU_R0_B1_TXDLY0_TX_ARDQ2_DLY_B1) | P_Fld(u2DelayCellOfst[9], SHU_R0_B1_TXDLY0_TX_ARDQ1_DLY_B1) | P_Fld(u2DelayCellOfst[8], SHU_R0_B1_TXDLY0_TX_ARDQ0_DLY_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_TXDLY1), P_Fld(u2DelayCellOfst[15], SHU_R0_B1_TXDLY1_TX_ARDQ7_DLY_B1) | P_Fld(u2DelayCellOfst[14], SHU_R0_B1_TXDLY1_TX_ARDQ6_DLY_B1) | P_Fld(u2DelayCellOfst[13], SHU_R0_B1_TXDLY1_TX_ARDQ5_DLY_B1) | P_Fld(u2DelayCellOfst[12], SHU_R0_B1_TXDLY1_TX_ARDQ4_DLY_B1)); } #if ENABLE_TX_TRACKING TXUpdateTXTracking(p, calType, ucdq_reg_pi, ucdq_reg_dqm_pi); #endif } vSetRank(p, backup_rank); if (isAutoK) { #if TX_AUTO_K_SUPPORT #if TX_AUTO_K_WORKAROUND vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_TX_ATK_SET0), P_Fld(ucdq_reg_pi[0], TX_ATK_SET0_TX_ATK_DQ_B0_PI_INIT) | P_Fld(ucdq_reg_pi[1], TX_ATK_SET0_TX_ATK_DQ_B1_PI_INIT) | P_Fld(ucdq_reg_dqm_pi[0], TX_ATK_SET0_TX_ATK_DQM_B0_PI_INIT) | P_Fld(ucdq_reg_dqm_pi[1], TX_ATK_SET0_TX_ATK_DQM_B1_PI_INIT)); #endif #endif } #if REG_ACCESS_PORTING_DGB RegLogEnable = 0; #endif #if (TX_AUTO_K_SUPPORT && TX_AUTO_K_WORKAROUND) if ((isAutoK) && (p->rank == RANK_1) && (calType == TX_DQ_DQS_MOVE_DQ_DQM)) { u4DQM_MCK_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1)); u4DQM_UI_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3)); u4DQM_PI_RK1_backup[0] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0)); u4DQM_PI_RK1_backup[1] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0)); u4DQ_MCK_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0)); u4DQ_UI_RK1_backup = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2)); u4DQ_PI_RK1_backup[0] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0)); u4DQ_PI_RK1_backup[1] = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0)); } #endif mcSHOW_DBG_MSG4(("[TxWindowPerbitCal] Done\n\n")); #if 0 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_PADCTL4), 1, PADCTL4_CKEFIXON); #endif return DRAM_OK; } #endif #if ENABLE_EYESCAN_GRAPH void Dramc_K_TX_EyeScan_Log(DRAMC_CTX_T *p) { U8 ucindex, u1BitIdx, u1ByteIdx; U8 ii, backup_rank, u1PrintWinData, u1vrefidx; PASS_WIN_DATA_T WinPerBit[DQ_DATA_WIDTH], VrefWinPerBit[DQ_DATA_WIDTH], FinalWinPerBit[DQ_DATA_WIDTH]; U16 tx_pi_delay[4], tx_dqm_pi_delay[4]; U16 u2DQDelayBegin, uiDelay; U16 u2VrefLevel, u2VrefBegin, u2VrefEnd, u2VrefStep, u2VrefRange; U8 ucdq_pi, ucdq_ui_small, ucdq_ui_large,ucdq_oen_ui_small, ucdq_oen_ui_large; U32 uiFinishCount; U16 u2TempWinSum, u2tx_window_sum=0; U32 u4err_value, u4fail_bit; #if 1 U16 u2Center_min[DQS_BYTE_NUMBER],u2Center_max[DQS_BYTE_NUMBER]; #endif U16 TXPerbitWin_min_max = 0; U32 min_bit, min_winsize; U16 u2FinalVref=0xd; U16 u2FinalRange=0; U8 EyeScan_index[DQ_DATA_WIDTH]; U16 backup_u1MR14Value; U8 u1pass_in_this_vref_flag[DQ_DATA_WIDTH]; U8 u1MCK2UI, u1UI2PI; U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1)), (DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0)), }; //if (gTX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency != u2DFSGetHighestFreq(p)) return; DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32)); backup_u1MR14Value = u1MR14Value[p->channel][p->rank][p->dram_fsp]; if (gFinalTXVrefDQ[p->channel][p->rank] ==0) gFinalTXVrefDQ[p->channel][p->rank] = u1MR14Value[p->channel][p->rank][p->dram_fsp]; for(u1vrefidx=0; u1vrefidx<=VREF_VOLTAGE_TABLE_NUM_LP5-1;u1vrefidx++) { for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { for(ii=0; iidram_type==TYPE_LPDDR5?VREF_VOLTAGE_TABLE_NUM_LP5:VREF_VOLTAGE_TABLE_NUM_LP4)-1; u2VrefStep = EYESCAN_GRAPH_CATX_VREF_STEP; mcSHOW_DBG_MSG3(("\nTX Vref %d -> %d, step: %d\n", u2VrefBegin, u2VrefEnd, u2VrefStep)); #if ENABLE_K_WITH_WORST_SI_UI_SHIFT DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern | 0x80, 0, TE_UI_SHIFT); #else DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_XTALK_PATTERN, 0, TE_NO_UI_SHIFT); #endif for(u2VrefLevel = u2VrefBegin; u2VrefLevel <= u2VrefEnd; u2VrefLevel += u2VrefStep) { DramcTXSetVref(p, u2VrefRange, u2VrefLevel); mcSHOW_DBG_MSG3(("\n\n Set TX VrefRange %d, VrefLevel=%d\n", u2VrefRange, u2VrefLevel)); uiFinishCount = 0; u2TempWinSum =0; for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { WinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA; WinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA; VrefWinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA; VrefWinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA; gEyeScan_DelayCellPI[u1BitIdx] = 0; EyeScan_index[u1BitIdx] = 0; u1pass_in_this_vref_flag[u1BitIdx] = 0; } for (uiDelay=0; uiDelay<64; uiDelay+=(u1IsPhaseMode(p)==TRUE ? 8 : 1)) { TxWinTransferDelayToUIPI(p, tx_pi_delay[0]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0), \ P_Fld(ucdq_ui_large, SHURK_SELPH_DQ0_TXDLY_DQ0) | \ P_Fld(ucdq_oen_ui_large, SHURK_SELPH_DQ0_TXDLY_OEN_DQ0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2), \ P_Fld(ucdq_ui_small, SHURK_SELPH_DQ2_DLY_DQ0) | \ P_Fld(ucdq_oen_ui_small, SHURK_SELPH_DQ2_DLY_OEN_DQ0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), ucdq_pi, SHU_R0_B0_DQ0_SW_ARPI_DQ_B0); TxWinTransferDelayToUIPI(p, tx_pi_delay[1]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0), \ P_Fld(ucdq_ui_large, SHURK_SELPH_DQ0_TXDLY_DQ1) | \ P_Fld(ucdq_oen_ui_large, SHURK_SELPH_DQ0_TXDLY_OEN_DQ1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2), \ P_Fld(ucdq_ui_small, SHURK_SELPH_DQ2_DLY_DQ1) | \ P_Fld(ucdq_oen_ui_small, SHURK_SELPH_DQ2_DLY_OEN_DQ1)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), ucdq_pi, SHU_R0_B1_DQ0_SW_ARPI_DQ_B1); TxWinTransferDelayToUIPI(p, tx_dqm_pi_delay[0]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1), \ P_Fld(ucdq_ui_large, SHURK_SELPH_DQ1_TXDLY_DQM0) | \ P_Fld(ucdq_oen_ui_large, SHURK_SELPH_DQ1_TXDLY_OEN_DQM0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3), \ P_Fld(ucdq_ui_small, SHURK_SELPH_DQ3_DLY_DQM0) | \ P_Fld(ucdq_oen_ui_small, SHURK_SELPH_DQ3_DLY_OEN_DQM0)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B0_DQ0), ucdq_pi, SHU_R0_B0_DQ0_SW_ARPI_DQM_B0); TxWinTransferDelayToUIPI(p, tx_dqm_pi_delay[1]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1), \ P_Fld(ucdq_ui_large, SHURK_SELPH_DQ1_TXDLY_DQM1) | \ P_Fld(ucdq_oen_ui_large, SHURK_SELPH_DQ1_TXDLY_OEN_DQM1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3), \ P_Fld(ucdq_ui_small, SHURK_SELPH_DQ3_DLY_DQM1) | \ P_Fld(ucdq_oen_ui_small, SHURK_SELPH_DQ3_DLY_OEN_DQM1)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_R0_B1_DQ0), ucdq_pi, SHU_R0_B1_DQ0_SW_ARPI_DQM_B1); u4err_value=0; #if ENABLE_K_WITH_WORST_SI_UI_SHIFT //DramcEngine2SetPat(p, p->test_pattern, 0, 0, TE_UI_SHIFT); u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern); #else DramcEngine2SetPat(p, TEST_AUDIO_PATTERN, 0, 0, TE_NO_UI_SHIFT); u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_AUDIO_PATTERN); DramcEngine2SetPat(p, TEST_XTALK_PATTERN, 0, 1, TE_NO_UI_SHIFT); u4err_value |= DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_XTALK_PATTERN); #endif for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { u4fail_bit = u4err_value&((U32)1<=63) { WinPerBit[u1BitIdx].last_pass = 63; } if(WinPerBit[u1BitIdx].last_pass !=PASS_RANGE_NA) { if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >= (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass)) { if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >7) uiFinishCount |= (1<data_width; u1BitIdx++) { VrefWinPerBit[u1BitIdx].win_size = VrefWinPerBit[u1BitIdx].last_pass- VrefWinPerBit[u1BitIdx].first_pass +(VrefWinPerBit[u1BitIdx].last_pass==VrefWinPerBit[u1BitIdx].first_pass?0:1); if (VrefWinPerBit[u1BitIdx].win_size < min_winsize) { min_bit = u1BitIdx; min_winsize = VrefWinPerBit[u1BitIdx].win_size; } u2TempWinSum += VrefWinPerBit[u1BitIdx].win_size; gEyeScan_WinSize[(u2VrefLevel+u2VrefRange*30)/EYESCAN_GRAPH_CATX_VREF_STEP][u1BitIdx] = VrefWinPerBit[u1BitIdx].win_size; #ifdef FOR_HQA_TEST_USED if((((backup_u1MR14Value>>6)&1) == u2VrefRange) && ((backup_u1MR14Value&0x3f)==u2VrefLevel)) { gFinalTXPerbitWin[p->channel][p->rank][u1BitIdx] = VrefWinPerBit[u1BitIdx].win_size; } #endif } if ((min_winsize > TXPerbitWin_min_max) || ((min_winsize == TXPerbitWin_min_max) && (u2TempWinSum >u2tx_window_sum))) { TXPerbitWin_min_max = min_winsize; u2tx_window_sum =u2TempWinSum; u2FinalRange = u2VrefRange; u2FinalVref = u2VrefLevel; for (u1ByteIdx=0; u1ByteIdx> 1; if(FinalWinPerBit[ucindex].win_center < u2Center_min[u1ByteIdx]) u2Center_min[u1ByteIdx] = FinalWinPerBit[ucindex].win_center; if(FinalWinPerBit[ucindex].win_center > u2Center_max[u1ByteIdx]) u2Center_max[u1ByteIdx] = FinalWinPerBit[ucindex].win_center; } } } if(u2VrefRange==0 && u2VrefLevel ==50 && p->dram_type!=TYPE_LPDDR5) { u2VrefRange = 1; u2VrefLevel = 20; } for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++) { if (u1pass_in_this_vref_flag[u1BitIdx]) gEyeScan_ContinueVrefHeight[u1BitIdx]+=EYESCAN_GRAPH_CATX_VREF_STEP; } } DramcEngine2End(p); for (u1ByteIdx=0; u1ByteIdx>1); #if VENDER_JV_LOG || defined(RELEASE) gEyeScan_CaliDelay[u1ByteIdx] = uiDelay; #else gEyeScan_CaliDelay[u1ByteIdx] = uiDelay + tx_pi_delay[u1ByteIdx]-32; #endif } DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32)); { u2VrefRange = backup_u1MR14Value>>6; u2VrefLevel = backup_u1MR14Value & 0x3f; } DramcTXSetVref(p, u2VrefRange, u2VrefLevel); u1MR14Value[p->channel][p->rank][p->dram_fsp] = backup_u1MR14Value; } #endif #if TX_OE_CALIBATION #define TX_OE_PATTERN_USE_TA2 1 #define TX_OE_SCAN_FULL_RANGE 0 void DramcTxOECalibration(DRAMC_CTX_T *p) { U8 u1ByteIdx; //ucBegin[2] = {0xff, 0xff}, ucEnd[2] = {0xff, 0xff}, ucbest_step[2]; //U8 ucbegin=0xff, , ucfirst, ucsum, ucbest_step; //U32 u4RegValue_TXDLY, u4RegValue_dly, u4err_value; //U16 u2Delay, u2TempVirtualDelay, u2SmallestVirtualDelay = 0xffff; //U16 u2DQOEN_DelayBegin, u2DQEN_DelayEnd; //U8 ucdq_ui_large_bak[DQS_BYTE_NUMBER], ucdq_ui_small_bak[DQS_BYTE_NUMBER]; U8 ucdq_oen_ui_large[2] = {0}, ucdq_oen_ui_small[2] = {0}; //U8 ucdq_current_ui_large, ucdq_current_ui_small; //U8 ucdq_ui_large_reg_value=0xff, ucdq_ui_small_reg_value=0xff; //U8 ucdq_final_dqm_oen_ui_large[DQS_BYTE_NUMBER] = {0}, ucdq_final_dqm_oen_ui_small[DQS_BYTE_NUMBER] = {0}; //DRAM_STATUS_T KResult; //mcDUMP_REG_MSG(("\n[dumpRG] DramcTXOECalibration\n")); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif #if TX_OE_PATTERN_USE_TA2 mcSHOW_DBG_MSG(("\n[DramC_TX_OE_Calibration] TA2\n")); #else mcSHOW_DBG_MSG(("\n[DramC_TX_OE_Calibration] DMA\n")); #endif vSetCalibrationResult(p, DRAM_CALIBRATION_TX_OE, DRAM_FAIL); #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION) if (p->femmc_Ready == 1) { for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { ucdq_oen_ui_large[u1ByteIdx] = p->pSavetimeData->u1TX_OE_DQ_MCK[p->channel][p->rank][u1ByteIdx]; ucdq_oen_ui_small[u1ByteIdx] = p->pSavetimeData->u1TX_OE_DQ_UI[p->channel][p->rank][u1ByteIdx]; } vSetCalibrationResult(p, DRAM_CALIBRATION_TX_OE, DRAM_FAST_K); } #endif for (u1ByteIdx = 0; u1ByteIdx < DQS_BYTE_NUMBER; u1ByteIdx++) { mcSHOW_DBG_MSG(("Byte%d TX OE(2T, 0.5T) = (%d, %d)\n", u1ByteIdx, ucdq_oen_ui_large[u1ByteIdx], ucdq_oen_ui_small[u1ByteIdx])); //mcDUMP_REG_MSG(("Byte%d TX OE(2T, 0.5T) = (%d, %d)\n", u1ByteIdx, ucdq_oen_ui_large[u1ByteIdx], ucdq_oen_ui_small[u1ByteIdx])); } mcSHOW_DBG_MSG(("\n\n")); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ0), \ P_Fld(ucdq_oen_ui_large[0], SHURK_SELPH_DQ0_TXDLY_OEN_DQ0) | \ P_Fld(ucdq_oen_ui_large[1], SHURK_SELPH_DQ0_TXDLY_OEN_DQ1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ1), \ P_Fld(ucdq_oen_ui_large[0], SHURK_SELPH_DQ1_TXDLY_OEN_DQM0) | \ P_Fld(ucdq_oen_ui_large[1], SHURK_SELPH_DQ1_TXDLY_OEN_DQM1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ2), \ P_Fld(ucdq_oen_ui_small[0], SHURK_SELPH_DQ2_DLY_OEN_DQ0) | \ P_Fld(ucdq_oen_ui_small[1], SHURK_SELPH_DQ2_DLY_OEN_DQ1) ); vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK_SELPH_DQ3), \ P_Fld(ucdq_oen_ui_small[0], SHURK_SELPH_DQ3_DLY_OEN_DQM0) | \ P_Fld(ucdq_oen_ui_small[1], SHURK_SELPH_DQ3_DLY_OEN_DQM1)); } #endif #define fld_val(_reg, _fld) \ ((_reg & Fld2Msk32(_fld)) >> Fld_shft(_fld)) static void OECKCKE_Control(DRAMC_CTX_T *p, U32 option) { static U32 u4CA_CMD2_backup = 0; static U32 u4SHU_CA_CMD13_backup = 0; static U32 u4CS_CTRL_backup = 0; static U32 u4CKE_CTRL_backup = 0; static U32 u4backup_done = 0; BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; if (option == DISABLE) { if (u4backup_done == 1) { mcSHOW_ERR_MSG(("[%s] Backup OE again without restored??\n", __func__)); #if __ETT__ while (1); #else ASSERT(0); #endif } if (!isLP4_DSC) { u4CA_CMD2_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2)); u4SHU_CA_CMD13_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13)); u4CS_CTRL_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CA_TX_ARCS_CTRL)); } else { u4CA_CMD2_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2)); u4SHU_CA_CMD13_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13)); u4CKE_CTRL_backup = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_B1_TX_CKE_CTRL)); } u4backup_done = 1; if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld( 0, CA_CMD2_RG_TX_ARCS_OE_TIE_SEL_CA) \ | P_Fld( 1, CA_CMD2_RG_TX_ARCS_OE_TIE_EN_CA) \ | P_Fld( 0, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA) \ | P_Fld( 0xff, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_TX_ARCS_CTRL), P_Fld( 0, CA_TX_ARCS_CTRL_RG_TX_ARCS_OE_TIE_SEL_C0)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_TX_CKE_CTRL), P_Fld( 0, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_SEL_B1) \ | P_Fld( 1, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_EN_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld( 0, B1_DQ2_RG_TX_ARDQM_OE_TIE_SEL_B1) \ | P_Fld( 1, B1_DQ2_RG_TX_ARDQM_OE_TIE_EN_B1) \ | P_Fld( 0, B1_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B1) \ | P_Fld( 0xff, B1_DQ2_RG_TX_ARDQ_OE_TIE_EN_B1)); } mcDELAY_US(1); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld( 0, CA_CMD2_RG_TX_ARCLK_OE_TIE_SEL_CA) \ | P_Fld( 1, CA_CMD2_RG_TX_ARCLK_OE_TIE_EN_CA)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13), P_Fld( 0, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_SEL_CA) \ | P_Fld( 1, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_EN_CA)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld( 0, B1_DQ2_RG_TX_ARDQS_OE_TIE_SEL_B1) \ | P_Fld( 1, B1_DQ2_RG_TX_ARDQS_OE_TIE_EN_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13), P_Fld( 0, SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B1) \ | P_Fld( 1, SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B1)); } } else { U32 u4CKOE_TieSel, u4CKOE_TieEn; U32 u4CKBOE_TieSel, u4CKBOE_TieEn; U32 u4CSOE_TieSel, u4CSOE_TieEn; U32 u4CAOE_TieSel, u4CAOE_TieEn; U32 u4CKEOE_TieSel, u4CKEOE_TieEN; if (u4backup_done == 0) { mcSHOW_ERR_MSG(("[%s] Restore OE while not backup??\n", __func__)); #if __ETT__ while (1); #else ASSERT(0); #endif } u4CKOE_TieSel = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCLK_OE_TIE_SEL_CA); u4CKOE_TieEn = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCLK_OE_TIE_EN_CA); u4CKBOE_TieSel = fld_val(u4SHU_CA_CMD13_backup, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_SEL_CA); u4CKBOE_TieEn = fld_val(u4SHU_CA_CMD13_backup, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_EN_CA); u4CAOE_TieSel = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA); u4CAOE_TieEn = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA); if(!isLP4_DSC) { u4CSOE_TieSel = fld_val(u4CS_CTRL_backup, CA_TX_ARCS_CTRL_RG_TX_ARCS_OE_TIE_SEL_C0); u4CSOE_TieEn = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA); u4CKEOE_TieSel = fld_val(u4CA_CMD2_backup, CA_CMD2_RG_TX_ARCS_OE_TIE_SEL_CA); u4CKEOE_TieEN = u4CSOE_TieEn; } else { u4CSOE_TieSel = fld_val(u4CA_CMD2_backup, B1_DQ2_RG_TX_ARDQM_OE_TIE_SEL_B1); u4CSOE_TieEn = fld_val(u4CA_CMD2_backup, B1_DQ2_RG_TX_ARDQM_OE_TIE_EN_B1); u4CKEOE_TieSel = fld_val(u4CKE_CTRL_backup, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_SEL_B1); u4CKEOE_TieEN = fld_val(u4CKE_CTRL_backup, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_EN_B1); } if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld( u4CKOE_TieSel, CA_CMD2_RG_TX_ARCLK_OE_TIE_SEL_CA) \ | P_Fld( u4CKOE_TieEn, CA_CMD2_RG_TX_ARCLK_OE_TIE_EN_CA)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13), P_Fld( u4CKBOE_TieSel, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_SEL_CA ) \ | P_Fld( u4CKBOE_TieEn, SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_EN_CA)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld( u4CKOE_TieSel, B1_DQ2_RG_TX_ARDQS_OE_TIE_SEL_B1) \ | P_Fld( u4CKOE_TieEn, B1_DQ2_RG_TX_ARDQS_OE_TIE_EN_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13), P_Fld( u4CKBOE_TieSel, SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B1 ) \ | P_Fld( u4CKBOE_TieEn, SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B1)); } mcDELAY_US(1); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_TX_ARCS_CTRL), P_Fld( u4CSOE_TieSel, CA_TX_ARCS_CTRL_RG_TX_ARCS_OE_TIE_SEL_C0)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld( u4CKEOE_TieSel, CA_CMD2_RG_TX_ARCS_OE_TIE_SEL_CA) \ | P_Fld( u4CSOE_TieEn, CA_CMD2_RG_TX_ARCS_OE_TIE_EN_CA) \ | P_Fld( u4CAOE_TieSel, CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA) \ | P_Fld( u4CAOE_TieEn, CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA)); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld( u4CSOE_TieSel, B1_DQ2_RG_TX_ARDQM_OE_TIE_SEL_B1) \ | P_Fld( u4CSOE_TieEn, B1_DQ2_RG_TX_ARDQM_OE_TIE_EN_B1) \ | P_Fld( u4CAOE_TieSel, B1_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B1) \ | P_Fld( u4CAOE_TieEn, B1_DQ2_RG_TX_ARDQ_OE_TIE_EN_B1)); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_TX_CKE_CTRL), P_Fld( u4CKEOE_TieSel, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_SEL_B1) \ | P_Fld( u4CKEOE_TieEN, B1_TX_CKE_CTRL_RG_TX_ARCKE_OE_TIE_EN_B1)); } u4backup_done = 0; } } static void OEDisable(DRAMC_CTX_T *p) { BOOL isLP4_DSC = (p->DRAMPinmux == PINMUX_DSC)?1:0; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ2), P_Fld( 0 , B0_DQ2_RG_TX_ARDQS_OE_TIE_SEL_B0 ) \ | P_Fld( 1 , B0_DQ2_RG_TX_ARDQS_OE_TIE_EN_B0 ) \ | P_Fld( 0 , B0_DQ2_RG_TX_ARWCK_OE_TIE_SEL_B0 ) \ | P_Fld( 1 , B0_DQ2_RG_TX_ARWCK_OE_TIE_EN_B0 ) \ | P_Fld( 0 , B0_DQ2_RG_TX_ARWCKB_OE_TIE_SEL_B0 ) \ | P_Fld( 1 , B0_DQ2_RG_TX_ARWCKB_OE_TIE_EN_B0 ) \ | P_Fld( 0 , B0_DQ2_RG_TX_ARDQM_OE_TIE_SEL_B0 ) \ | P_Fld( 1 , B0_DQ2_RG_TX_ARDQM_OE_TIE_EN_B0 ) \ | P_Fld( 0 , B0_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B0 ) \ | P_Fld( 0xff , B0_DQ2_RG_TX_ARDQ_OE_TIE_EN_B0 ) ); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), P_Fld( 0 , B1_DQ2_RG_TX_ARDQS_OE_TIE_SEL_B1 ) \ | P_Fld( 1 , B1_DQ2_RG_TX_ARDQS_OE_TIE_EN_B1 ) \ | P_Fld( 0 , B1_DQ2_RG_TX_ARWCK_OE_TIE_SEL_B1 ) \ | P_Fld( 1 , B1_DQ2_RG_TX_ARWCK_OE_TIE_EN_B1 ) \ | P_Fld( 0 , B1_DQ2_RG_TX_ARWCKB_OE_TIE_SEL_B1 ) \ | P_Fld( 1 , B1_DQ2_RG_TX_ARWCKB_OE_TIE_EN_B1 ) \ | P_Fld( 0 , B1_DQ2_RG_TX_ARDQM_OE_TIE_SEL_B1 ) \ | P_Fld( 1 , B1_DQ2_RG_TX_ARDQM_OE_TIE_EN_B1 ) \ | P_Fld( 0 , B1_DQ2_RG_TX_ARDQ_OE_TIE_SEL_B1 ) \ | P_Fld( 0xff , B1_DQ2_RG_TX_ARDQ_OE_TIE_EN_B1) ); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), P_Fld( 0 , CA_CMD2_RG_TX_ARCLK_OE_TIE_SEL_CA ) \ | P_Fld( 1 , CA_CMD2_RG_TX_ARCLK_OE_TIE_EN_CA ) \ | P_Fld( 0 , CA_CMD2_RG_TX_ARCS_OE_TIE_SEL_CA ) \ | P_Fld( 1 , CA_CMD2_RG_TX_ARCS_OE_TIE_EN_CA ) \ | P_Fld( 0 , CA_CMD2_RG_TX_ARCA_OE_TIE_SEL_CA ) \ | P_Fld( 0xff , CA_CMD2_RG_TX_ARCA_OE_TIE_EN_CA) ); } OECKCKE_Control(p, DISABLE); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ13) , P_Fld( 0 , SHU_B0_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B0 ) \ | P_Fld( 1 , SHU_B0_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B0 )); if (!isLP4_DSC) { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13) , P_Fld( 0 , SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_SEL_B1 ) \ | P_Fld( 1 , SHU_B1_DQ13_RG_TX_ARDQSB_OE_TIE_EN_B1 )); } else { vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13) , P_Fld( 0 , SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_SEL_CA ) \ | P_Fld( 1 , SHU_CA_CMD13_RG_TX_ARCLKB_OE_TIE_EN_CA )); } } #ifdef FOR_HQA_TEST_USED VCORE_DELAYCELL_T gVcoreDelayCellTable[49]={ {500000, 512}, {506250, 496}, {512500, 482}, {518750, 469}, {525000, 457}, {531250, 445}, {537500, 434}, {543750, 423}, {550000, 412}, {556250, 402}, {562500, 393}, {568750, 384}, {575000, 377}, {581250, 369}, {587500, 362}, {593750, 355}, {600000, 348}, {606250, 341}, {612500, 335}, {618750, 328}, {625000, 322}, {631250, 317}, {637500, 312}, {643750, 307}, {650000, 302}, {656250, 297}, {662500, 292}, {668750, 288}, {675000, 284}, {681250, 280}, {687500, 276}, {693750, 272}, {700000, 269}, {706250, 265}, {712500, 262}, {718750, 258}, {725000, 255}, {731250, 252}, {737500, 249}, {743750, 246}, {750000, 243}, {756250, 241}, {762500, 238}, {768750, 236}, {775000, 233}, {781250, 231}, {787500, 229}, {793750, 227}, {800000, 225}, //{825000, 718}, //{831250, 717}, //{837500, 715}, //{843750, 713}, //{850000, 708}, //{856250, 705}, //{862500, 702}, //{868750, 700}, //{875000, 698} }; static U16 GetVcoreDelayCellTimeFromTable(DRAMC_CTX_T *p) { U32 i; U32 get_vcore = 0; U16 delay_cell_ps = 0; U8 u1delay_cell_cnt = 0; VCORE_DELAYCELL_T *pVcoreDelayCellTable; #if (defined(DRAM_HQA) || __ETT__) && (FOR_DV_SIMULATION_USED == 0) get_vcore = dramc_get_vcore_voltage(); #endif pVcoreDelayCellTable = (VCORE_DELAYCELL_T *)gVcoreDelayCellTable; u1delay_cell_cnt = sizeof(gVcoreDelayCellTable)/sizeof(gVcoreDelayCellTable[0]); for(i=0; iJmtrInfo[ucsearch_state].u1JmDelay = ucdqs_dly; pJmtrInfo->JmtrInfo[ucsearch_state].u1TransLevel = fgcurrent_value; ucsearch_state++; pJmtrInfo->u1TransCnt = ucsearch_state; if (ucsearch_state == CYCLE_1T) break; } } } } #endif #ifdef ENABLE_MIOCK_JMETER U16 GetVcoreDelayCellTime(DRAMC_CTX_T *p) { #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if(p->femmc_Ready==1) { mcSHOW_DBG_MSG(("[FAST_K] Freq=%d, DelayCellTimex100=%d\n", p->frequency, p->pSavetimeData->u2DelayCellTimex100)); return p->pSavetimeData->u2DelayCellTimex100; } #endif return 0; } void Get_RX_DelayCell(DRAMC_CTX_T *p) { #if defined(FOR_HQA_REPORT_USED) && (FOR_DV_SIMULATION_USED==0) && (SW_CHANGE_FOR_SIMULATION==0) #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if(p->femmc_Ready == 1) { return; } #endif if (gHQALOG_RX_delay_cell_ps_075V == 0) { #if __ETT__ mcSHOW_DBG_MSG(("RX delay cell calibration (%d):\n", hqa_vmddr_class)); switch (hqa_vmddr_class) { case 1: dramc_set_vcore_voltage(_SEL_PREFIX(VMDDR, HV, LP4)); break; case 2: dramc_set_vcore_voltage(_SEL_PREFIX(VMDDR, NV, LP4)); break; case 3: dramc_set_vcore_voltage(_SEL_PREFIX(VMDDR, LV, LP4)); break; } #else dramc_set_vcore_voltage(SEL_PREFIX_VMDDR); #endif gHQALOG_RX_delay_cell_ps_075V = GetVcoreDelayCellTime(p); vSetVcoreByFreq(p); } #endif } #endif DRAM_STATUS_T Dramc8PhaseCal(DRAMC_CTX_T *p) { #if ENABLE_8PHASE_CALIBRATION U8 u18Ph_dly_loop_break = 0; U8 u1DqsienPI = 0; U8 u18Phase_SM = DQS_8PH_DEGREE_0, u18Ph_dly_final = 0xff; U8 u18Ph_dly = 0, u18Ph_start = 0, u18Ph_end = 0; U16 u2R0 = 0xffff, u2R180 = 0xffff, u2R = 0xffff; U16 u2P = 0xffff, ucdqs_dly = 0; S16 s2Err_code = 0x7fff, s2Err_code_min = 0x7fff; U8 backup_rank, u1RankIdx, u18PhDlyBackup = 0; U8 u1loop_cnt = 0, u1early_break_cnt = 5; JMETER_T JmtrInfo; U8 u1JmtrPrintCnt = 0; U32 u4backup_broadcast= GetDramcBroadcast(); DRAM_STATUS_T eDRAMStatus = DRAM_OK; #ifdef DUMP_INIT_RG_LOG_TO_DE return DRAM_OK; #endif u1DqsienPI = 0x0; if (!p) { mcSHOW_ERR_MSG(("context NULL\n")); return DRAM_FAIL; } if (p->frequency < 1866) { //mcSHOW_ERR_MSG(("skip 8-Phase Calib Freq is %d < 1866 !!!\n", p->frequency)); return DRAM_OK; } //mcDUMP_REG_MSG(("\n[dumpRG] Dramc8PhaseCal\n")); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif mcSHOW_DBG_MSG(("[Dramc8PhaseCal]\n")); U32 u4RegBackupAddress[] = { (DRAMC_REG_ADDR(DDRPHY_REG_MISC_DUTYSCAN1)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ5)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ5)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ3)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ3)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_CTRL1)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_CTRL4)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_PHY2)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_PHY2)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DLL_ARPI2)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DLL_ARPI2)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ11)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ11)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD11)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_PI_DLY)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_PI_DLY + DDRPHY_AO_RANK_OFFSET)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_JMETER)), //(DRAMC_REG_ADDR(DDRPHY_REG_MISC_STBCAL2)), //(DRAMC_REG_ADDR(DDRPHY_REG_MISC_DVFSCTL2)), (DRAMC_REG_ADDR(DDRPHY_REG_MISC_SHU_STBCAL)), #if 0 (DRAMC_REG_ADDR(DDRPHY_REG_B0_DLL_ARPI0)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DLL_ARPI0)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_DLL_ARPI0)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ6)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD6)), #endif (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_DLL1)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DLL1)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DLL1)), (DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ2)), (DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2)), (DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ13)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13)), }; backup_rank = u1GetRank(p); memset(&JmtrInfo, 0, sizeof(JmtrInfo)); DramcBroadcastOnOff(DRAMC_BROADCAST_OFF); DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); DramcJmeterInit(p, FALSE); u18PhDlyBackup = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ1), SHU_B0_DQ1_RG_ARPI_MIDPI_8PH_DLY_B0); for (u18Phase_SM = DQS_8PH_DEGREE_0; u18Phase_SM < DQS_8PH_DEGREE_MAX; u18Phase_SM++) { switch (u18Phase_SM) { case DQS_8PH_DEGREE_0: u1DqsienPI = 16; u18Ph_start = 0; u18Ph_end = 1; break; case DQS_8PH_DEGREE_180: u1DqsienPI = 48; u18Ph_start = 0; u18Ph_end = 1; break; case DQS_8PH_DEGREE_45: u1DqsienPI = 24; u18Ph_start = 0; u18Ph_end = 32; break; default: mcSHOW_ERR_MSG(("u18Phase_SM err!\n")); #if __ETT__ while (1); #endif } mcSHOW_DBG_MSG2(("\n[Dramc8PhaseCal] 8-Phase SM_%d, 8PH_dly (%d~%d), DQSIEN PI = %d, 8PH_Dly = %d\n", u18Phase_SM, u18Ph_start, u18Ph_end, u1DqsienPI, u18PhDlyBackup)); for (u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++) { vSetRank(p, u1RankIdx); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_RK_B0_DQSIEN_PI_DLY), u1DqsienPI, SHU_RK_B0_DQSIEN_PI_DLY_DQSIEN_PI_B0); } vSetRank(p, backup_rank); for (u18Ph_dly = u18Ph_start; u18Ph_dly < u18Ph_end; u18Ph_dly++) { mcSHOW_DBG_MSG2(("8PH dly = %d\n", u18Ph_dly)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ1), u18Ph_dly, SHU_B0_DQ1_RG_ARPI_MIDPI_8PH_DLY_B0); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ1), u18Ph_dly, SHU_B1_DQ1_RG_ARPI_MIDPI_8PH_DLY_B1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD1), u18Ph_dly, SHU_CA_CMD1_RG_ARPI_MIDPI_8PH_DLY_CA); DramcJmeterCalib(p, &JmtrInfo, 1, FALSE); for (u1JmtrPrintCnt = 0; u1JmtrPrintCnt < JmtrInfo.u1TransCnt; u1JmtrPrintCnt++) { if (JmtrInfo.JmtrInfo[u1JmtrPrintCnt].u1TransLevel == 1) { ucdqs_dly = JmtrInfo.JmtrInfo[u1JmtrPrintCnt].u1JmDelay; if (u18Phase_SM == DQS_8PH_DEGREE_0) { u2R0 = ucdqs_dly; mcSHOW_DBG_MSG2(("R0 (H) = %d\n", u2R0)); break; } else if (u18Phase_SM == DQS_8PH_DEGREE_180) { u2R180 = ucdqs_dly; if (u2R180 > u2R0) { u2R = u2R0 + ((u2R180 - u2R0) >> 2); mcSHOW_DBG_MSG2(("R = %d, R180 (H) = %d\n", u2R, u2R180)); break; } } else if (u18Phase_SM == DQS_8PH_DEGREE_45) { u2P = ucdqs_dly; if (u2P > u2R0) { if (u2R > u2P) s2Err_code = u2R - u2P; else s2Err_code = u2P - u2R; if (s2Err_code == 0) { s2Err_code_min = s2Err_code; u18Ph_dly_final = u18Ph_dly; u18Ph_dly_loop_break = 1; } else if (s2Err_code < s2Err_code_min) { s2Err_code_min = s2Err_code; u18Ph_dly_final = u18Ph_dly; u1loop_cnt = 0; } else if (s2Err_code >= s2Err_code_min) { u1loop_cnt++; if (u1loop_cnt > u1early_break_cnt) u18Ph_dly_loop_break = 1; } mcSHOW_DBG_MSG2(("diff (P-R) = %d, min = %d, early break count = %d, R45 (H) = %d\n", s2Err_code, s2Err_code_min, u1loop_cnt, u2P)); break; } } else { mcSHOW_ERR_MSG(("u18Phase_SM err!\n")); #if __ETT__ while (1); #endif } } } if (JmtrInfo.u1TransCnt == u1JmtrPrintCnt) { u18Ph_dly_final = u18PhDlyBackup; eDRAMStatus = DRAM_FAIL; mcSHOW_ERR_MSG(("\n[Dramc8PhaseCal] 8-Phase SM_%d is fail (to Default) !!!\n", u18Phase_SM)); goto exit; } else if (u18Ph_dly_loop_break == 1) break; } } exit: mcSHOW_DBG_MSG(("\n[Dramc8PhaseCal] u18Ph_dly_final = %d\n\n", u18Ph_dly_final)); //mcDUMP_REG_MSG(("\n[Dramc8PhaseCal] u18Ph_dly_final = %d\n\n", u18Ph_dly_final)); vIO32WriteFldAlign_All(DDRPHY_REG_SHU_B0_DQ1, u18Ph_dly_final, SHU_B0_DQ1_RG_ARPI_MIDPI_8PH_DLY_B0); vIO32WriteFldAlign_All(DDRPHY_REG_SHU_B1_DQ1, u18Ph_dly_final, SHU_B1_DQ1_RG_ARPI_MIDPI_8PH_DLY_B1); vIO32WriteFldAlign_All(DDRPHY_REG_SHU_CA_CMD1, u18Ph_dly_final, SHU_CA_CMD1_RG_ARPI_MIDPI_8PH_DLY_CA); OECKCKE_Control(p, ENABLE); DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); DramcBroadcastOnOff(u4backup_broadcast); return eDRAMStatus; #endif } #if SIMULATION_SW_IMPED #if 0 static U32 SwImpedanceAdjust(U32 u4ImpVal, S8 s1StepCnt) { S32 S4ImpedanceTemp = (S32)u4ImpVal; S4ImpedanceTemp += s1StepCnt; if ((S4ImpedanceTemp > 15) && (S4ImpedanceTemp < 29)) { S4ImpedanceTemp = S4ImpedanceTemp - 16 + 29; } if (S4ImpedanceTemp > 31) { S4ImpedanceTemp = 31; } else if (S4ImpedanceTemp < 0) { S4ImpedanceTemp = 0; } return (U32)S4ImpedanceTemp; } #endif #define IMPCAL_STAGE_DRVP 0 #define IMPCAL_STAGE_DRVN 1 #define IMPCAL_STAGE_ODTP 2 #define IMPCAL_STAGE_ODTN 3 #define IMPCAL_STAGE_TRACKING 4 #define IMP_TRACK_LP4X_LOWFREQ_VREF_SEL 0x37 #define IMP_TRACK_LP4X_HIGHFREQ_VREF_SEL 0x3a #define IMP_TRACK_LP5_LOWFREQ_VREF_SEL 0x38 #define IMP_TRACK_LP5_HIGHFREQ_VREF_SEL 0x3a static const U8 ImpLP4VrefSel[IMP_VREF_MAX][IMP_DRV_MAX] = { {0x37, 0x33, 0x00, 0x37}, {0x3a, 0x33, 0x00, 0x3a}, {0x2a, 0x2a, 0x00, 0x3a} }; static const U8 ImpLP5VrefSel[IMP_VREF_MAX][IMP_DRV_MAX] = { {0x38, 0x33, 0x00, 0x38}, {0x3a, 0x33, 0x00, 0x3a}, {0x2a, 0x2a, 0x00, 0x3a} }; static void vImpCalVrefSel(DRAMC_CTX_T *p, DRAMC_IMP_T efreq_region, U8 u1ImpCalStage) { U8 u1RegTmpValue = 0; U32 u4DrvFld = 0; if (p->dram_type == TYPE_LPDDR4X) { if (u1ImpCalStage == IMPCAL_STAGE_TRACKING) u1RegTmpValue = (efreq_region == IMP_LOW_FREQ) ? IMP_TRACK_LP4X_LOWFREQ_VREF_SEL : IMP_TRACK_LP4X_HIGHFREQ_VREF_SEL; else u1RegTmpValue = ImpLP4VrefSel[efreq_region][u1ImpCalStage]; } else if (p->dram_type == TYPE_LPDDR5) { if (u1ImpCalStage == IMPCAL_STAGE_TRACKING) u1RegTmpValue = (efreq_region == IMP_LOW_FREQ) ? IMP_TRACK_LP5_LOWFREQ_VREF_SEL : IMP_TRACK_LP5_HIGHFREQ_VREF_SEL; else u1RegTmpValue = ImpLP5VrefSel[efreq_region][u1ImpCalStage]; } else { mcSHOW_ERR_MSG(("[vImpCalVrefSel] Warnning: Need confirm DRAM type for IMP_VREF_SEL !!!\n")); #if __ETT__ while(1); #endif } switch (u1ImpCalStage) { case IMPCAL_STAGE_DRVP: u4DrvFld = SHU_CA_CMD12_RG_RIMP_VREF_SEL_DRVP; break; case IMPCAL_STAGE_DRVN: u4DrvFld = SHU_CA_CMD12_RG_RIMP_VREF_SEL_DRVN; break; case IMPCAL_STAGE_ODTN: u4DrvFld = SHU_CA_CMD12_RG_RIMP_VREF_SEL_ODTN; break; case IMPCAL_STAGE_TRACKING: break; default: mcSHOW_ERR_MSG(("[vImpCalVrefSel] Warnning: Need confirm u1ImpCalStage for SW IMP Calibration !!!\n")); break; } mcSHOW_DBG_MSG3(("[vImpCalVrefSel] IMP_VREF_SEL 0x%x, IMPCAL stage:%u, freq_region:%u\n", u1RegTmpValue, u1ImpCalStage, efreq_region)); if (u1ImpCalStage == IMPCAL_STAGE_TRACKING) { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD12), u1RegTmpValue, SHU_CA_CMD12_RG_RIMP_VREF_SEL_DRVP); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD12), u1RegTmpValue, SHU_CA_CMD12_RG_RIMP_VREF_SEL_ODTN); } else { vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD12), u1RegTmpValue, u4DrvFld); } return; } void DramcSwImpedanceSaveRegister(DRAMC_CTX_T *p, U8 ca_freq_option, U8 dq_freq_option, U8 save_to_where) { U32 backup_broadcast; //U8 u1Hysteresis; backup_broadcast = GetDramcBroadcast(); DramcBroadcastOnOff(DRAMC_BROADCAST_ON); vImpCalVrefSel(p, dq_freq_option, IMPCAL_STAGE_TRACKING); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][DRVP], SHU_MISC_DRVING1_DQDRVP2) | P_Fld(gDramcImpedanceResult[dq_freq_option][DRVN], SHU_MISC_DRVING1_DQDRVN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING2 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][DRVP], SHU_MISC_DRVING2_DQDRVP1) | P_Fld(gDramcImpedanceResult[dq_freq_option][DRVN], SHU_MISC_DRVING2_DQDRVN1)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][ODTP], SHU_MISC_DRVING3_DQODTP2) | P_Fld(gDramcImpedanceResult[dq_freq_option][ODTN], SHU_MISC_DRVING3_DQODTN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING4 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][ODTP], SHU_MISC_DRVING4_DQODTP1) | P_Fld(gDramcImpedanceResult[dq_freq_option][ODTN], SHU_MISC_DRVING4_DQODTN1)); #if SUPPORT_HYNIX_RX_DQS_WEAK_PULL if (p->vendor_id == VENDOR_HYNIX) { U32 temp_value[4]; int i; for(i=0; i<4; i++) { temp_value[i] = SwImpedanceAdjust(gDramcImpedanceResult[dq_freq_option][i], 2); } vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(temp_value[0], SHU_MISC_DRVING1_DQSDRVP2) | P_Fld(temp_value[1], SHU_MISC_DRVING1_DQSDRVN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(temp_value[0], SHU_MISC_DRVING1_DQSDRVP1) | P_Fld(temp_value[1], SHU_MISC_DRVING1_DQSDRVN1)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(temp_value[2], SHU_MISC_DRVING3_DQSODTP2) | P_Fld(temp_value[3], SHU_MISC_DRVING3_DQSODTN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(temp_value[2], SHU_MISC_DRVING3_DQSODTP) | P_Fld(temp_value[3], SHU_MISC_DRVING3_DQSODTN)); } else #endif { vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][DRVP], SHU_MISC_DRVING1_DQSDRVP2) | P_Fld(gDramcImpedanceResult[dq_freq_option][DRVN], SHU_MISC_DRVING1_DQSDRVN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][DRVP], SHU_MISC_DRVING1_DQSDRVP1) | P_Fld(gDramcImpedanceResult[dq_freq_option][DRVN], SHU_MISC_DRVING1_DQSDRVN1)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][ODTP], SHU_MISC_DRVING3_DQSODTP2) | P_Fld(gDramcImpedanceResult[dq_freq_option][ODTN], SHU_MISC_DRVING3_DQSODTN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[dq_freq_option][ODTP], SHU_MISC_DRVING3_DQSODTP) | P_Fld(gDramcImpedanceResult[dq_freq_option][ODTN], SHU_MISC_DRVING3_DQSODTN)); } vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING2 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[ca_freq_option][DRVP], SHU_MISC_DRVING2_CMDDRVP2) | P_Fld(gDramcImpedanceResult[ca_freq_option][DRVN], SHU_MISC_DRVING2_CMDDRVN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING2 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[ca_freq_option][DRVP], SHU_MISC_DRVING2_CMDDRVP1) | P_Fld(gDramcImpedanceResult[ca_freq_option][DRVN], SHU_MISC_DRVING2_CMDDRVN1)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING4 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[ca_freq_option][ODTP], SHU_MISC_DRVING4_CMDODTP2) | P_Fld(gDramcImpedanceResult[ca_freq_option][ODTN], SHU_MISC_DRVING4_CMDODTN2)); vIO32WriteFldMulti((DDRPHY_REG_SHU_MISC_DRVING4 + save_to_where * SHU_GRP_DDRPHY_OFFSET), P_Fld(gDramcImpedanceResult[ca_freq_option][ODTP], SHU_MISC_DRVING4_CMDODTP1) | P_Fld(gDramcImpedanceResult[ca_freq_option][ODTN], SHU_MISC_DRVING4_CMDODTN1)); #if (fcFOR_CHIP_ID == fcA60868) vIO32WriteFldAlign((DDRPHY_REG_MISC_SHU_DRVING8 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 0xA, MISC_SHU_DRVING8_CS_DRVP); vIO32WriteFldAlign((DDRPHY_REG_MISC_SHU_DRVING8 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 0xA, MISC_SHU_DRVING8_CS_DRVN); #elif (fcFOR_CHIP_ID == fc8195) vIO32WriteFldAlign((DDRPHY_REG_MISC_SHU_DRVING8 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 0xF, MISC_SHU_DRVING8_CS_DRVP); vIO32WriteFldAlign((DDRPHY_REG_MISC_SHU_DRVING8 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 0x14, MISC_SHU_DRVING8_CS_DRVN); #endif DramcBroadcastOnOff(backup_broadcast); } #if IMPEDANCE_HW_CALIBRATION static void Dramc_Hw_ImpedanceCal(DRAMC_CTX_T *p, DRAMC_IMP_T freq_region) { U8 u1DrvType = 0; U32 u4DRVP_Result = 0xff, u4ODTN_Result = 0xff, u4DRVN_Result = 0xff; vAutoRefreshSwitch(p, ENABLE); vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF0), 0, SHU_CONF0_PBREFEN); for (u1DrvType = DRVP; u1DrvType < IMP_DRV_MAX; u1DrvType++) { if (u1DrvType == ODTP) continue; vImpCalVrefSel(p, freq_region, u1DrvType); } ImpedanceTracking_DisImpHw_Setting(p, DISABLE); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), P_Fld(4, SHU_MISC_IMPCAL1_IMPCALCNT) | P_Fld(1, SHU_MISC_IMPCAL1_IMPCAL_CHKCYCLE)); DramcImpedanceTrackingEnable(p); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), 0, MISC_IMPCAL_IMPCAL_ECO_OPT); mcDELAY_US(16); u4DRVN_Result = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL_STATUS3), MISC_IMPCAL_STATUS3_DRVNDQ_SAVE_1); u4DRVP_Result = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL_STATUS3), MISC_IMPCAL_STATUS3_DRVPDQ_SAVE_1); u4ODTN_Result = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL_STATUS3), MISC_IMPCAL_STATUS3_ODTNDQ_SAVE_1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), u4DRVP_Result, SHU_MISC_IMPCAL1_IMPDRVP); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), u4DRVN_Result, SHU_MISC_IMPCAL1_IMPDRVN); mcSHOW_DBG_MSG(("[HwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result)); gDramcImpedanceResult[freq_region][DRVP] = u4DRVP_Result; gDramcImpedanceResult[freq_region][DRVN] = u4DRVN_Result; gDramcImpedanceResult[freq_region][ODTP] = 0; gDramcImpedanceResult[freq_region][ODTN] = u4ODTN_Result; //vAutoRefreshSwitch(p, DISABLE); } #else static U32 DramcSwImpCalResult(DRAMC_CTX_T *p, const char *drvType, U32 u4Fld) { U32 u4ImpxDrv = 0, u4ImpCalResult = 0; U32 u4CheckImpChange = (u4Fld == SHU_MISC_IMPCAL1_IMPDRVP)? 1: 0; for (u4ImpxDrv = 0; u4ImpxDrv < 32; u4ImpxDrv++) { #if 0 if (u4ImpxDrv == 16) u4ImpxDrv = 29; #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), u4ImpxDrv, u4Fld); mcDELAY_US(1); u4ImpCalResult = u4IO32ReadFldAlign((DDRPHY_REG_MISC_PHY_RGS_CMD), MISC_PHY_RGS_CMD_RGS_RIMPCALOUT); mcSHOW_DBG_MSG2(("OCD %s=%d ,CALOUT=%d\n", drvType, u4ImpxDrv, u4ImpCalResult)); if (u4ImpCalResult == u4CheckImpChange) { mcSHOW_DBG_MSG2(("\nOCD %s calibration OK! %s=%d\n\n", drvType, drvType, u4ImpxDrv)); break; } } if (u4ImpxDrv == 32) { u4ImpxDrv = 31; mcSHOW_DBG_MSG2(("\nOCD %s calibration FAIL! %s=%d\n\n", drvType, drvType, u4ImpxDrv)); } return u4ImpxDrv; } static void Dramc_Sw_ImpedanceCal(DRAMC_CTX_T *p, DRAMC_IMP_T freq_region) { U8 u1DrvType = 0, u1CALI_ENP = 0, u1CALI_ENN = 0; U32 u4DRVP_Result = 0xff, u4ODTN_Result = 0xff, u4DRVN_Result = 0xff; U32 u4SwImpCalResult = 0, u4DrvFld = 0; const char *drvStr = "NULL"; vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), 1, MISC_IMPCAL_IMPCAL_CALI_EN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), P_Fld(0, SHU_MISC_IMPCAL1_IMPDRVN) | P_Fld(0, SHU_MISC_IMPCAL1_IMPDRVP)); for (u1DrvType = DRVP; u1DrvType < IMP_DRV_MAX; u1DrvType++) { if (u1DrvType == ODTP) continue; vImpCalVrefSel(p, freq_region, u1DrvType); switch (u1DrvType) { case DRVP: drvStr = "DRVP"; u1CALI_ENP = 0x1; u1CALI_ENN = 0x0; u4DrvFld = SHU_MISC_IMPCAL1_IMPDRVP; u4DRVP_Result = 0; break; case DRVN: case ODTN: drvStr = (u1DrvType == DRVN)? "DRVN" : "ODTN"; u1CALI_ENP = 0x0; u1CALI_ENN = (u1DrvType == DRVN)? 0x0: 0x1; u4DrvFld = SHU_MISC_IMPCAL1_IMPDRVN; break; default: mcSHOW_ERR_MSG(("[DramcSwImpedanceCal] Warnning: Need confirm u1DrvType for SW IMP Calibration !!!\n")); break; } vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), u1CALI_ENP, MISC_IMPCAL_IMPCAL_CALI_ENP); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), u1CALI_ENN, MISC_IMPCAL_IMPCAL_CALI_ENN); mcSHOW_DBG_MSG2(("\n\n\tK %s\n", drvStr)); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_IMPCAL1), u4DRVP_Result, SHU_MISC_IMPCAL1_IMPDRVP); u4SwImpCalResult = DramcSwImpCalResult(p, drvStr, u4DrvFld); switch (u1DrvType) { case DRVP: u4DRVP_Result = u4SwImpCalResult; break; case DRVN: u4DRVN_Result = u4SwImpCalResult; break; case ODTN: u4ODTN_Result = u4SwImpCalResult; break; default: mcSHOW_ERR_MSG(("[DramcSwImpedanceCal] Warnning: Need confirm u4SwImpCalResult for SW IMP Calibration !!!\n")); break; } } mcSHOW_DBG_MSG(("[SwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result)); gDramcImpedanceResult[freq_region][DRVP] = u4DRVP_Result; gDramcImpedanceResult[freq_region][DRVN] = u4DRVN_Result; gDramcImpedanceResult[freq_region][ODTP] = 0; gDramcImpedanceResult[freq_region][ODTN] = u4ODTN_Result; } #endif DRAM_STATUS_T DramcImpedanceCal(DRAMC_CTX_T *p, U8 u1Para, DRAMC_IMP_T freq_region) { //U32 u4BaklReg_DDRPHY_MISC_IMP_CTRL0, u4BaklReg_DDRPHY_MISC_IMP_CTRL1; //U32 u4BaklReg_DRAMC_REG_IMPCAL; U8 backup_channel; U32 backup_broadcast; U8 u1Drv05 = 0, u1DDR4 = 0; U32 u4RegBackupAddress[] = { (DDRPHY_REG_MISC_IMPCAL), #if IMPEDANCE_HW_CALIBRATION (DDRPHY_REG_MISC_IMPCAL + SHIFT_TO_CHB_ADDR), (DRAMC_REG_ADDR(DRAMC_REG_DDRCOMMON0)), (DRAMC_REG_DRAMC_PD_CTRL), (DRAMC_REG_DRAMC_PD_CTRL+ SHIFT_TO_CHB_ADDR), #if (CHANNEL_NUM > 2) (DDRPHY_REG_MISC_IMPCAL + SHIFT_TO_CHC_ADDR), (DDRPHY_REG_MISC_IMPCAL + SHIFT_TO_CHD_ADDR), #endif (DDRPHY_REG_MISC_CTRL0), (DDRPHY_REG_MISC_CTRL0 + SHIFT_TO_CHB_ADDR), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_DRVING1)), (DRAMC_REG_ADDR(DDRPHY_REG_SHU_MISC_DRVING2)), (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)), #endif }; backup_broadcast = GetDramcBroadcast(); DramcBroadcastOnOff(DRAMC_BROADCAST_OFF); vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_FAIL); #if VENDER_JV_LOG vPrintCalibrationBasicInfo_ForJV(p); #else vPrintCalibrationBasicInfo(p); #endif mcSHOW_DBG_MSG(("[DramcImpedenceCal]\n")); vIO32WriteFldMulti_All(DDRPHY_REG_MISC_LP_CTRL, P_Fld(0x0, MISC_LP_CTRL_RG_ARDMSUS_10) | \ P_Fld(0x0, MISC_LP_CTRL_RG_ARDMSUS_10_LP_SEL) | \ P_Fld(0x0, MISC_LP_CTRL_RG_RIMP_DMSUS_10) | \ P_Fld(0x0, MISC_LP_CTRL_RG_RIMP_DMSUS_10_LP_SEL)); vIO32WriteFldAlign_All(DDRPHY_REG_MISC_IMPCAL, 0, MISC_IMPCAL_IMPCAL_HW); backup_channel = p->channel; vSetPHY2ChannelMapping(p, CHANNEL_A); //u4BaklReg_DDRPHY_MISC_IMP_CTRL0 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL0)); //u4BaklReg_DDRPHY_MISC_IMP_CTRL1 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL1)); //u4BaklReg_DRAMC_REG_IMPCAL = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL)); DramcBackupRegisters(p, u4RegBackupAddress, ARRAY_SIZE(u4RegBackupAddress)); #if IMPEDANCE_HW_CALIBRATION vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDRCOMMON0), 1, DDRCOMMON0_LPDDR4EN); vIO32WriteFldMulti_All(DRAMC_REG_DRAMC_PD_CTRL, P_Fld(1, DRAMC_PD_CTRL_PHYCLKDYNGEN)\ | P_Fld(1, DRAMC_PD_CTRL_DCMEN)); #endif vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMP_CTRL1), 0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN); vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), P_Fld(0, MISC_IMPCAL_IMPCAL_CALI_ENN) | P_Fld(1, MISC_IMPCAL_IMPCAL_IMPPDP) | \ P_Fld(1, MISC_IMPCAL_IMPCAL_IMPPDN)); u1DDR4 = 1; vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMP_CTRL1), P_Fld(1, MISC_IMP_CTRL1_RG_IMP_EN) | \ P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_DDR3_SEL) | \ P_Fld(1, MISC_IMP_CTRL1_RG_RIMP_VREF_EN) | \ P_Fld(u1DDR4, MISC_IMP_CTRL1_RG_RIMP_DDR4_SEL)); mcDELAY_US(1); vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD12), u1Drv05, SHU_CA_CMD12_RG_RIMP_DRV05); #if IMPEDANCE_HW_CALIBRATION Dramc_Hw_ImpedanceCal(p, freq_region); #else Dramc_Sw_ImpedanceCal(p, freq_region); #endif DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress) / sizeof(U32)); //vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_MISC_IMPCAL), u4BaklReg_DRAMC_REG_IMPCAL); //vIO32Write4B((DDRPHY_MISC_IMP_CTRL0), u4BaklReg_DDRPHY_MISC_IMP_CTRL0); //vIO32Write4B((DDRPHY_MISC_IMP_CTRL1), u4BaklReg_DDRPHY_MISC_IMP_CTRL1); #if 0 if (u1Para) { u4ODTN_Result = ImpedanceAdjustment_Hynix(u4ODTN_Result, u1Para); } #endif #if RUNTIME_SHMOO_RELEATED_FUNCTION && SUPPORT_SAVE_TIME_FOR_CALIBRATION { U8 u1drv; { for (u1drv = 0; u1drv < 4; u1drv++) { { gDramcImpedanceResult[freq_region][u1drv] = p->pSavetimeData->u1SwImpedanceResule[freq_region][u1drv]; vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_FAST_K); } } } } #endif mcSHOW_DBG_MSG(("freq_region=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n", freq_region, gDramcImpedanceResult[freq_region][DRVP], gDramcImpedanceResult[freq_region][DRVN], gDramcImpedanceResult[freq_region][ODTN])); #if APPLY_SIGNAL_WAVEFORM_SETTINGS_ADJUST if ((p->dram_type == TYPE_LPDDR4) && (freq_region == 0)) { gDramcImpedanceResult[freq_region][DRVP] = SwImpedanceAdjust(gDramcImpedanceResult[freq_region][DRVP], gDramcSwImpedanceAdjust[freq_region][DRVP]); gDramcImpedanceResult[freq_region][DRVN] = SwImpedanceAdjust(gDramcImpedanceResult[freq_region][DRVN], gDramcSwImpedanceAdjust[freq_region][ODTN]); } else { gDramcImpedanceResult[freq_region][DRVP] = SwImpedanceAdjust(gDramcImpedanceResult[freq_region][DRVP], gDramcSwImpedanceAdjust[freq_region][DRVP]); gDramcImpedanceResult[freq_region][ODTN] = SwImpedanceAdjust(gDramcImpedanceResult[freq_region][ODTN], gDramcSwImpedanceAdjust[freq_region][ODTN]); } mcSHOW_DBG_MSG(("freq_region=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d (After Adjust)\n", freq_region, gDramcImpedanceResult[freq_region][DRVP], gDramcImpedanceResult[freq_region][DRVN], gDramcImpedanceResult[freq_region][ODTN])); #endif #if 0 if (gDramcSwImpedanceResult[freq_region][DRVP] >= 31 && (freq_region == 0) ) { mcSHOW_DBG_MSG(("SLT_BIN2\n")); while (1); } #else if (freq_region==0) { if (!(gDramcImpedanceResult[freq_region][DRVP] >= 1 && gDramcImpedanceResult[freq_region][DRVP] <= 0x16) || !(gDramcImpedanceResult[freq_region][DRVN] >= 10 && gDramcImpedanceResult[freq_region][DRVN] <= 23) || !(gDramcImpedanceResult[freq_region][ODTN] >= 3 && gDramcImpedanceResult[freq_region][ODTN] <= 0x13)) { #if defined(SLT) mcSHOW_ERR_MSG(("[DramcInit] SLT_BIN2\n")); while (1); #else mcSHOW_ERR_MSG(("[Warning] freq_region = %d, Unexpected value for impedance calibration\n", freq_region)); #if __ETT__ while (1); #endif #endif }else{ vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_OK); } } else { if (!(gDramcImpedanceResult[freq_region][DRVP] >= 1 && gDramcImpedanceResult[freq_region][DRVP] <= 24) || !(gDramcImpedanceResult[freq_region][DRVN] >= 10 && gDramcImpedanceResult[freq_region][DRVN] <= 30) || !(gDramcImpedanceResult[freq_region][ODTN] >= 3 && gDramcImpedanceResult[freq_region][ODTN] <= 12)) { #if defined(SLT) mcSHOW_ERR_MSG(("[DramcInit] SLT_BIN2\n")); while (1); #else mcSHOW_ERR_MSG(("[Warning] freq_region = %d, Unexpected value for impedance calibration\n", freq_region)); #if __ETT__ while (1); #endif #endif }else{ vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_OK); } } #endif #if PIN_CHECK_TOOL if((gDramcImpedanceResult[freq_region][ODTN] ==0)||(gDramcImpedanceResult[freq_region][ODTN] >=31)) { mcSHOW_DBG_MSG(("[WARNING] freq_region = %d, ODTN = %d ==> unexpect value\n", freq_region, gDramcImpedanceResult[freq_region][ODTN])); PINInfo_flashtool.IMP_ERR_FLAG |= (0x1<<(freq_region+ODTN)); } else if((gDramcImpedanceResult[freq_region][DRVP] ==0)||(gDramcImpedanceResult[freq_region][DRVP] >=31)) { mcSHOW_DBG_MSG(("[WARNING] freq_region = %d, DRVP = %d ==> unexpect value\n", freq_region, gDramcImpedanceResult[freq_region][DRVP])); PINInfo_flashtool.IMP_ERR_FLAG |= (0x1<<(freq_region+DRVP)); } else if((gDramcImpedanceResult[freq_region][DRVN] ==0)||(gDramcImpedanceResult[freq_region][DRVN] >=31)) { mcSHOW_DBG_MSG(("[WARNING] freq_region = %d, DRVN = %d ==> unexpect value\n", freq_region, gDramcImpedanceResult[freq_region][DRVN])); PINInfo_flashtool.IMP_ERR_FLAG |= (0x1<<(freq_region+DRVN)); } #endif mcSHOW_DBG_MSG4(("[DramcImpedanceCal] Done\n\n")); vSetPHY2ChannelMapping(p, backup_channel); DramcBroadcastOnOff(backup_broadcast); return DRAM_OK; } #endif #if ENABLE_WRITE_DBI || TX_K_DQM_WITH_WDBI void DramcWriteShiftMCKForWriteDBI(DRAMC_CTX_T *p, S8 iShiftMCK) { U8 ucDataRateDivShift = 0; S8 s1UIMove = 0; ucDataRateDivShift = u1MCK2UI_DivShift(p); s1UIMove = iShiftMCK * (S8)(1 << ucDataRateDivShift); ShiftDQUI(p, s1UIMove, ALL_BYTES); } #endif #if ENABLE_DUTY_SCAN_V2 #define DutyPrintAllLog 0 #define DUTY_OFFSET_START -28 #define DUTY_OFFSET_END 28 #define DUTY_OFFSET_STEP 4 #define CLOCK_PI_START 0 #define CLOCK_PI_END 63 #if FOR_DV_SIMULATION_USED #define CLOCK_PI_STEP 8 #else #define CLOCK_PI_STEP 2 #endif #define ClockDutyFailLowerBound 4500 #define ClockDutyFailUpperBound 5500 #define ClockDutyMiddleBound 5000 static U8 DramcDutyDelayRGSettingConvert(DRAMC_CTX_T *p, S8 scDutyDelay, U8 *tDly) { U8 tDelay; if (scDutyDelay < 0) { tDelay = -scDutyDelay; } else if (scDutyDelay > 0) { tDelay = scDutyDelay + (1 << 5); } else { tDelay = 0; } *tDly = tDelay; return tDelay; } static void DramcClockDutySetClkDelayCell(DRAMC_CTX_T *p, S8 *scDutyDelay) { U8 u1ShuffleIdx = 0; U32 save_offset; U8 tDelay; DramcDutyDelayRGSettingConvert(p, scDutyDelay[0], &tDelay); #if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ for(u1ShuffleIdx = 0; u1ShuffleIdxchannel, scDutyDelay[0])); // mcSHOW_DBG_MSG(("CH%d, Final DQS1 duty delay cell = %d\n", p->channel, scDutyDelay[1])); for(u1DQSIdx=0; u1DQSIdx<2; u1DQSIdx++) { DramcDutyDelayRGSettingConvert(p, scDutyDelay[u1DQSIdx], &(tDelay[u1DQSIdx])); } #if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ for(u1ShuffleIdx = 0; u1ShuffleIdxDRAMPinmux == PINMUX_DSC)?1:0; U32 backup_DDRPHY_REG_B0_DQ2=0, backup_DDRPHY_REG_B1_DQ2=0, backup_DDRPHY_REG_CA_CMD2=0; U32 backup_DDRPHY_REG_SHU_B0_DQ13=0, backup_DDRPHY_REG_SHU_B1_DQ13=0, backup_DDRPHY_REG_SHU_CA_CMD13=0; #if(DQS_DUTY_SLT_CONDITION_TEST) U16 u2TestCnt, u2FailCnt=0, u2TestCntTotal =20; U8 u1ByteIdx, u1PI_FB; U32 u4Variance; #endif u1backup_rank = u1GetRank(p); vSetRank(p, RANK_0); backup_DDRPHY_REG_B0_DQ2 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ2)); if (!isLP4_DSC) backup_DDRPHY_REG_B1_DQ2 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2)); else backup_DDRPHY_REG_CA_CMD2 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2)); backup_DDRPHY_REG_SHU_B0_DQ13 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ13)); if (!isLP4_DSC) backup_DDRPHY_REG_SHU_B1_DQ13 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13)); else backup_DDRPHY_REG_SHU_CA_CMD13 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13)); vSetCalibrationResult(p, DRAM_CALIBRATION_DUTY_SCAN, DRAM_FAIL); #if !FT_DSIM_USED #if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ if (p->frequency == u2DFSGetHighestFreq(p)) #else #endif #endif { U8 u1ChannelIdx; U8 u1backup_channel = vGetPHY2ChannelMapping(p); #if SUPPORT_SAVE_TIME_FOR_CALIBRATION if(p->femmc_Ready==1) { for(u1ChannelIdx=CHANNEL_A; u1ChannelIdxsupport_channel_num; u1ChannelIdx++){ vSetPHY2ChannelMapping(p, u1ChannelIdx); DramcClockDutySetClkDelayCell(p, p->pSavetimeData->s1ClockDuty_clk_delay_cell[p->channel]); DQSDutyScan_SetDqsDelayCell(p, p->pSavetimeData->s1DQSDuty_clk_delay_cell[p->channel]); #if APPLY_DQDQM_DUTY_CALIBRATION DQDQMDutyScan_SetDQDQMDelayCell(p, p->channel, p->pSavetimeData->s1DQMDuty_clk_delay_cell[p->channel], DutyScan_Calibration_K_DQM); DQDQMDutyScan_SetDQDQMDelayCell(p, p->channel, p->pSavetimeData->s1DQDuty_clk_delay_cell[p->channel], DutyScan_Calibration_K_DQ); #endif } vSetPHY2ChannelMapping(p, u1backup_channel); vSetCalibrationResult(p, DRAM_CALIBRATION_DUTY_SCAN, DRAM_FAST_K); return; } #endif } OECKCKE_Control(p, ENABLE); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_B0_DQ2), backup_DDRPHY_REG_B0_DQ2); if (!isLP4_DSC) vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_B1_DQ2), backup_DDRPHY_REG_B1_DQ2); else vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_CA_CMD2), backup_DDRPHY_REG_CA_CMD2); vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B0_DQ13), backup_DDRPHY_REG_SHU_B0_DQ13); if (!isLP4_DSC) vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_B1_DQ13), backup_DDRPHY_REG_SHU_B1_DQ13); else vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_REG_SHU_CA_CMD13), backup_DDRPHY_REG_SHU_CA_CMD13); vSetRank(p, u1backup_rank); } #endif