blob: a6df28fe9dbe200b78fcaf50f4902aca42d932ad [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*----------------------------------------------------------------------------*
2 * Copyright Statement: *
3 * *
4 * This software/firmware and related documentation ("MediaTek Software") *
5 * are protected under international and related jurisdictions'copyright laws *
6 * as unpublished works. The information contained herein is confidential and *
7 * proprietary to MediaTek Inc. Without the prior written permission of *
8 * MediaTek Inc., any reproduction, modification, use or disclosure of *
9 * MediaTek Software, and information contained herein, in whole or in part, *
10 * shall be strictly prohibited. *
11 * MediaTek Inc. Copyright (C) 2010. All rights reserved. *
12 * *
13 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND *
14 * AGREES TO THE FOLLOWING: *
15 * *
16 * 1)Any and all intellectual property rights (including without *
17 * limitation, patent, copyright, and trade secrets) in and to this *
18 * Software/firmware and related documentation ("MediaTek Software") shall *
19 * remain the exclusive property of MediaTek Inc. Any and all intellectual *
20 * property rights (including without limitation, patent, copyright, and *
21 * trade secrets) in and to any modifications and derivatives to MediaTek *
22 * Software, whoever made, shall also remain the exclusive property of *
23 * MediaTek Inc. Nothing herein shall be construed as any transfer of any *
24 * title to any intellectual property right in MediaTek Software to Receiver. *
25 * *
26 * 2)This MediaTek Software Receiver received from MediaTek Inc. and/or its *
27 * representatives is provided to Receiver on an "AS IS" basis only. *
28 * MediaTek Inc. expressly disclaims all warranties, expressed or implied, *
29 * including but not limited to any implied warranties of merchantability, *
30 * non-infringement and fitness for a particular purpose and any warranties *
31 * arising out of course of performance, course of dealing or usage of trade. *
32 * MediaTek Inc. does not provide any warranty whatsoever with respect to the *
33 * software of any third party which may be used by, incorporated in, or *
34 * supplied with the MediaTek Software, and Receiver agrees to look only to *
35 * such third parties for any warranty claim relating thereto. Receiver *
36 * expressly acknowledges that it is Receiver's sole responsibility to obtain *
37 * from any third party all proper licenses contained in or delivered with *
38 * MediaTek Software. MediaTek is not responsible for any MediaTek Software *
39 * releases made to Receiver's specifications or to conform to a particular *
40 * standard or open forum. *
41 * *
42 * 3)Receiver further acknowledge that Receiver may, either presently *
43 * and/or in the future, instruct MediaTek Inc. to assist it in the *
44 * development and the implementation, in accordance with Receiver's designs, *
45 * of certain softwares relating to Receiver's product(s) (the "Services"). *
46 * Except as may be otherwise agreed to in writing, no warranties of any *
47 * kind, whether express or implied, are given by MediaTek Inc. with respect *
48 * to the Services provided, and the Services are provided on an "AS IS" *
49 * basis. Receiver further acknowledges that the Services may contain errors *
50 * that testing is important and it is solely responsible for fully testing *
51 * the Services and/or derivatives thereof before they are used, sublicensed *
52 * or distributed. Should there be any third party action brought against *
53 * MediaTek Inc. arising out of or relating to the Services, Receiver agree *
54 * to fully indemnify and hold MediaTek Inc. harmless. If the parties *
55 * mutually agree to enter into or continue a business relationship or other *
56 * arrangement, the terms and conditions set forth herein shall remain *
57 * effective and, unless explicitly stated otherwise, shall prevail in the *
58 * event of a conflict in the terms in any agreements entered into between *
59 * the parties. *
60 * *
61 * 4)Receiver's sole and exclusive remedy and MediaTek Inc.'s entire and *
62 * cumulative liability with respect to MediaTek Software released hereunder *
63 * will be, at MediaTek Inc.'s sole discretion, to replace or revise the *
64 * MediaTek Software at issue. *
65 * *
66 * 5)The transaction contemplated hereunder shall be construed in *
67 * accordance with the laws of Singapore, excluding its conflict of laws *
68 * principles. Any disputes, controversies or claims arising thereof and *
69 * related thereto shall be settled via arbitration in Singapore, under the *
70 * then current rules of the International Chamber of Commerce (ICC). The *
71 * arbitration shall be conducted in English. The awards of the arbitration *
72 * shall be final and binding upon both parties and shall be entered and *
73 * enforceable in any court of competent jurisdiction. *
74 *---------------------------------------------------------------------------*/
75/*-----------------------------------------------------------------------------
76 *
77 * $Author: jc.wu $
78 * $Date: 2012/6/5 $
79 * $RCSfile: pi_calibration_api.c,v $
80 * $Revision: #5 $
81 *
82 *---------------------------------------------------------------------------*/
83
84/** @file pi_calibration_api.c
85 * Basic DRAMC calibration API implementation
86 */
87
88//-----------------------------------------------------------------------------
89// Include files
90//-----------------------------------------------------------------------------
91//#include "..\Common\pd_common.h"
92#include "dramc_common.h"
93#include "x_hal_io.h"
94#include "dramc_pi_api.h"
95//#include "DramC_reg.h"
96//#include "System_reg.h"
97
98#if 1//REG_ACCESS_PORTING_DGB
99U8 RegLogEnable=0;
100#endif
101
102#if REG_SHUFFLE_REG_CHECK
103U8 ShuffleRegCheck =0;
104#endif
105
106#define CATRAINING_NUM_LP3 10
107#define CATRAINING_NUM_LP4 6
108#define CATRAINING_NUM 10
109#define LP3_DIE_NUM_MAX 2
110
111#define MAX_CA_PI_DELAY 95 //63+32
112#define MAX_CS_PI_DELAY 63
113#define MAX_CLK_PI_DELAY 31
114
115#define PASS_RANGE_NA 0x7fff
116#define CATRAINING_PASS_RANGE_NA 0x7f
117
118
119#if (SW_CHANGE_FOR_SIMULATION ||FOR_DV_SIMULATION_USED)
120#define RX_VREF_RANGE_BEGIN 0
121#define RX_VREF_RANGE_END 2
122#define RX_VREF_RANGE_STEP 2
123#else
124#define RX_VREF_RANGE_BEGIN_ODT_OFF 16
125#define RX_VREF_RANGE_BEGIN_ODT_ON 6
126#define RX_VREF_RANGE_END 31 //bit5 useless (Justin) //field is 6 bit, but can only use 0~31
127#define RX_VREF_RANGE_STEP 1
128#endif
129
130//-----------------------------------------------------------------------------
131// Global variables
132//-----------------------------------------------------------------------------
133static U8 fgwrlevel_done = 0;
134
135#if defined(RELEASE)
136U8 gEye_Scan_color_flag = 0;
137U8 gCBT_EYE_Scan_flag = 0;
138U8 gCBT_EYE_Scan_only_higheset_freq_flag = 1;
139U8 gRX_EYE_Scan_flag = 0;
140U8 gRX_EYE_Scan_only_higheset_freq_flag = 1;
141U8 gTX_EYE_Scan_flag = 1;
142U8 gTX_EYE_Scan_only_higheset_freq_flag = 1;
143#else
144U8 gEye_Scan_color_flag = 1;
145U8 gCBT_EYE_Scan_flag = 0;
146U8 gCBT_EYE_Scan_only_higheset_freq_flag = 1;
147U8 gRX_EYE_Scan_flag = 0;
148U8 gRX_EYE_Scan_only_higheset_freq_flag = 1;
149U8 gTX_EYE_Scan_flag = 0;
150U8 gTX_EYE_Scan_only_higheset_freq_flag = 1;
151#endif
152
153#ifdef FOR_HQA_REPORT_USED
154U8 gHQALog_flag = 0;
155#endif
156
157U8 *u1ChannelSet;
158const U8 u1LP4Channel[] =
159{
160 CHANNEL_B
161}; //0:CHA, 1:CHB, 2:CHC, 3:CHD
162#if ENABLE_LP3_SW
163const U8 u1LP3Channel[] =
164{
165 CHANNEL_A
166}; //0:CHA, 1:CHB, 2:CHC, 3:CHD
167#endif
168
169U16 gu2MR0_Value[RANK_MAX] = {0xffff, 0xffff};
170U8 u1MR01Value[FSP_MAX];
171U8 u1MR02Value[FSP_MAX];
172U8 u1MR03Value[FSP_MAX];
173U8 u1MR13Value;
174
175U8 u1MR12Value[CHANNEL_NUM][RANK_MAX][FSP_MAX];
176U8 u1MR14Value[CHANNEL_NUM][RANK_MAX][FSP_MAX];
177
178#if MRW_CHECK_ONLY
179U16 u2MRRecord[CHANNEL_NUM][RANK_MAX][FSP_MAX][MR_NUM];
180#endif
181
182U8 gCBT_VREF_RANGE_SEL;
183U8 gCBT_VREF_RANGE_BEGIN;
184U8 gCBT_VREF_RANGE_END;
185U8 gCBT_VREF_RANGE_STEP;
186
187U8 gu1LP3DieNum[2]; // 2 rank may have different die number
188
189//U8 gu1MR23Done = FALSE; /* Not used starting from Vinson (all freqs use MR23=0x3F) */
190U8 gu1MR23[CHANNEL_NUM][RANK_MAX];
191/* DQSOSCTHRD_INC & _DEC are 12 bits (Starting from Vinson) */
192U16 gu2DQSOSCTHRD_INC[CHANNEL_NUM][RANK_MAX];
193U16 gu2DQSOSCTHRD_DEC[CHANNEL_NUM][RANK_MAX];
194U16 gu2MR18[CHANNEL_NUM][RANK_MAX]; /* Stores MRR MR18 (DQS ocillator count - MSB) */
195U16 gu2MR19[CHANNEL_NUM][RANK_MAX]; /* Stores MRR MR19 (DQS ocillator count - LSB) */
196U16 gu2DQSOSC[CHANNEL_NUM][RANK_MAX]; /* Stores tDQSOSC results */
197U16 gu2DQSOscCnt[CHANNEL_NUM][RANK_MAX][2];
198
199#define CBT_WORKAROUND_O1_SWAP 0 // set default clk and ca value
200
201static S32 CATrain_CmdDelay[CHANNEL_NUM][RANK_MAX];
202static U32 CATrain_CsDelay[CHANNEL_NUM][RANK_MAX];
203static S32 CATrain_ClkDelay[CHANNEL_NUM][RANK_MAX];
204static S32 wrlevel_dqs_final_delay[DQS_NUMBER]; // 3 is channel number
205static U16 u2rx_window_sum;
206static U8 ucg_num_dlycell_perT = 49; //from 60807
207U16 u2gdelay_cell_ps;
208U8 ucg_num_dlycell_perT_all[DRAM_DFS_SHUFFLE_MAX][CHANNEL_NUM];///TODO: to be removed by Francis
209U16 u2gdelay_cell_ps_all[DRAM_DFS_SHUFFLE_MAX][CHANNEL_NUM];///TODO: to be removed by Francis
210U32 u4gVcore[DRAM_DFS_SHUFFLE_MAX];
211
212U32 gDramcSwImpedanceResule[2][4]={{0,0,0,0},{0,0,0,0}};//ODT_ON/OFF x DRVP/DRVN/ODTP/ODTN
213#if APPLY_SIGNAL_WAVEFORM_SETTINGS_ADJUST
214S8 gDramcSwImpedanceAdjust[2][4]={{0,0,0,0},{0,0,0,0}};//ODT_ON/OFF x DRVP/DRVN/ODTP/ODTN
215S8 gDramcDqOdtRZQAdjust=-1;
216S8 gDramcMR03PDDSAdjust[FSP_MAX]={-1,-1};
217S8 gDramcMR22SoCODTAdjust[FSP_MAX]={-1,-1};
218#endif
219S8 iFirstCAPass[RANK_MAX][LP3_DIE_NUM_MAX][CATRAINING_NUM], iLastCAPass[RANK_MAX][LP3_DIE_NUM_MAX][CATRAINING_NUM]; // 2 die.
220
221S16 gu2RX_DQS_Duty_Offset[DQS_NUMBER][2];
222
223#ifdef FOR_HQA_TEST_USED
224U16 gFinalCBTVrefCA[CHANNEL_NUM][RANK_MAX];
225U16 gFinalCBTCA[CHANNEL_NUM][RANK_MAX][10];
226U16 gFinalRXPerbitWin[CHANNEL_NUM][RANK_MAX][DQ_DATA_WIDTH];
227U16 gFinalTXPerbitWin[CHANNEL_NUM][RANK_MAX][DQ_DATA_WIDTH];
228U16 gFinalTXPerbitWin_min_max[CHANNEL_NUM][RANK_MAX];
229U16 gFinalTXPerbitWin_min_margin[CHANNEL_NUM][RANK_MAX];
230U16 gFinalTXPerbitWin_min_margin_bit[CHANNEL_NUM][RANK_MAX];
231S8 gFinalClkDuty[CHANNEL_NUM];
232U32 gFinalClkDutyMinMax[CHANNEL_NUM][2];
233S8 gFinalDQSDuty[CHANNEL_NUM][DQS_NUMBER];
234U32 gFinalDQSDutyMinMax[CHANNEL_NUM][DQS_NUMBER][2];
235#endif
236U8 gFinalCBTVrefDQ[CHANNEL_NUM][RANK_MAX];
237U8 gFinalRXVrefDQ[CHANNEL_NUM][RANK_MAX];
238U8 gFinalTXVrefDQ[CHANNEL_NUM][RANK_MAX];
239
240#if EYESCAN_LOG
241#define VREF_TOTAL_NUM_WITH_RANGE 51+30 //range0 0~50 + range1 21~50
242#define EYESCAN_BROKEN_NUM 3
243#define EYESCAN_DATA_INVALID 0x7fff
244S16 gEyeScan_Min[VREF_TOTAL_NUM_WITH_RANGE][DQ_DATA_WIDTH_LP4][EYESCAN_BROKEN_NUM];
245S16 gEyeScan_Max[VREF_TOTAL_NUM_WITH_RANGE][DQ_DATA_WIDTH_LP4][EYESCAN_BROKEN_NUM];
246U16 gEyeScan_CaliDelay[DQS_NUMBER];
247U8 gEyeScan_WinSize[VREF_TOTAL_NUM_WITH_RANGE][DQ_DATA_WIDTH_LP4];
248S8 gEyeScan_DelayCellPI[DQ_DATA_WIDTH_LP4];
249U8 gEyeScan_ContinueVrefHeight[DQ_DATA_WIDTH_LP4];
250U16 gEyeScan_TotalPassCount[DQ_DATA_WIDTH_LP4];
251#endif
252
253#ifdef DEVIATION
254U8 gSetSpecificedVref_Enable[3]={0};
255U8 gSetSpecificedVref_Type=0;
256U8 gSetSpecificedVref_All_ChRk[3]={0};
257U8 gSetSpecificedVref_Channel[3]={0};
258U8 gSetSpecificedVref_Rank[3]={0};
259S8 gSetSpecificedVref_Vref_Offset[3]={0};
260#endif
261
262extern const U8 uiLPDDR4_MRR_Mapping_POP[CHANNEL_NUM][16];
263#if ENABLE_LP3_SW
264extern const U8 uiLPDDR3_O1_Mapping_POP[32];
265extern const U8 uiLPDDR3_O1_Mapping_POP_DLP3[32];
266#endif
267extern const U8 uiLPDDR4_O1_Mapping_POP[CHANNEL_NUM][16];
268
269extern DRAM_DFS_FREQUENCY_TABLE_T gFreqTbl[];
270extern DRAM_DFS_FREQUENCY_TABLE_T gFreqTbl_LP3[];
271
272extern const U16 gRXVref_Voltage_Table_LP4[RX_VREF_RANGE_END+1];
273extern const U16 gVref_Voltage_Table_LP4X[VREF_RANGE_MAX][VREF_VOLTAGE_TABLE_NUM];
274extern const U16 gVref_Voltage_Table_LP4[VREF_RANGE_MAX][VREF_VOLTAGE_TABLE_NUM];
275
276
277static void dle_factor_handler(DRAMC_CTX_T *p, U8 curr_val, U8 pip_num);
278U8 GetCmdBusTrainingVrefPinMuxRevertValue(DRAMC_CTX_T *p, U8 u1VrefLevel);
279U8 get_shuffleIndex_by_Freq(DRAMC_CTX_T *p); //Retrieve LP4's shuffle index from gFreqTbl
280
281void vInitGlobalVariablesByCondition(DRAM_DRAM_TYPE_T dram_type)
282{
283 U8 u1CHIdx, u1RankIdx, u1FSPIdx;
284#if MRW_CHECK_ONLY
285 U8 u1MRIdx;
286#endif
287 U8 u1Vref_Unterm;
288
289 u1MR01Value[FSP_0] = 0x26;
290 u1MR01Value[FSP_1] = 0x56;
291
292 if(dram_type==TYPE_LPDDR4)
293 u1Vref_Unterm = 0x4d; //LP4
294 else
295 u1Vref_Unterm = 0x5d; //LP4X
296
297 memset(u1MR12Value, u1Vref_Unterm, sizeof(u1MR12Value));
298
299 for(u1FSPIdx=0; u1FSPIdx<FSP_MAX; u1FSPIdx++)
300 {
301 u1MR02Value[u1FSPIdx]=0x1a;
302 u1MR03Value[u1FSPIdx]=0x31;
303 }
304
305 for(u1CHIdx=0; u1CHIdx<CHANNEL_NUM; u1CHIdx++)
306 for(u1RankIdx=0; u1RankIdx< RANK_MAX; u1RankIdx++)
307 for(u1FSPIdx=0; u1FSPIdx<FSP_MAX; u1FSPIdx++)
308 {
309 // MR14 default value, LP4 default 0x4d, LP4X 0x5d
310 u1MR14Value[u1CHIdx][u1RankIdx][u1FSPIdx] = (u1FSPIdx==FSP_0) ? u1Vref_Unterm : 0x10;
311 #if MRW_CHECK_ONLY
312 for(u1MRIdx=0; u1MRIdx<MR_NUM; u1MRIdx++)
313 u2MRRecord[u1CHIdx][u1RankIdx][u1FSPIdx][u1MRIdx] =0xffff;
314 #endif
315 }
316
317 memset(gu1MR23, 0x3F, sizeof(gu1MR23)); /* MR23 should be 0x3F for all freqs (Starting from Vinson) */
318 memset(gu2DQSOSCTHRD_INC, 0x6, sizeof(gu2DQSOSCTHRD_INC));
319 memset(gu2DQSOSCTHRD_DEC, 0x4, sizeof(gu2DQSOSCTHRD_DEC));
320 memset(gu2RX_DQS_Duty_Offset, 0, sizeof(gu2RX_DQS_Duty_Offset));
321
322
323}
324
325void vSetChannelNumber(DRAMC_CTX_T *p)
326{
327 if(u1IsLP4Family(p->dram_type))
328 {
329 u1ChannelSet = (U8 *)u1LP4Channel;
330 #if (!FOR_DV_SIMULATION_USED)
331 p->support_channel_num = sizeof(u1LP4Channel)/sizeof(U8); // 2 channel
332 #else
333 p->support_channel_num = CHANNEL_SINGLE;
334 #endif
335 }
336#if ENABLE_LP3_SW
337 else //LP3
338 {
339 u1ChannelSet = (U8 *)u1LP3Channel;
340 p->support_channel_num = sizeof(u1LP3Channel)/sizeof(U8);
341 }
342#endif /* ENABLE_LP3_SW */
343}
344
345void vSetRankNumber(DRAMC_CTX_T *p)
346{
347 if (u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RSTMASK), RSTMASK_RSV_DRAM_SUPPORT_RANK_NUM) == 0)
348 {
349 p->support_rank_num =RANK_DUAL;
350 }
351 else
352 {
353 p->support_rank_num =RANK_SINGLE;
354 }
355}
356
357void vSetPHY2ChannelMapping(DRAMC_CTX_T *p, U8 u1Channel)
358{
359 p->channel =u1Channel;
360}
361
362
363U8 vGetPHY2ChannelMapping(DRAMC_CTX_T *p)
364{
365 return p->channel;
366}
367
368void vSetRank(DRAMC_CTX_T *p, U8 ucRank)
369{
370 p->rank = ucRank;
371}
372
373U8 u1GetRank(DRAMC_CTX_T *p)
374{
375 return p->rank;
376}
377
378/* vGet_Dram_CBT_Mode
379 * Due to current HW design (both ranks share the same set of ACTiming regs), mixed
380 * mode LP4 now uses byte mode ACTiming settings. This means most calibration steps
381 * should use byte mode code flow.
382 * Note: The below items must have per-rank settings (Don't use this function)
383 * 1. CBT training 2. TX tracking
384 */
385DRAM_CBT_MODE_T vGet_Dram_CBT_Mode(DRAMC_CTX_T *p)
386{
387 if(p->dram_cbt_mode[RANK_0] == CBT_NORMAL_MODE && p->dram_cbt_mode[RANK_1] == CBT_NORMAL_MODE)
388 {
389 return CBT_NORMAL_MODE;
390 }
391 else // For Mixed mode & Byte mode LP4
392 {
393 return CBT_BYTE_MODE1;
394 }
395}
396
397#if PRINT_CALIBRATION_SUMMARY
398void vSetCalibrationResult(DRAMC_CTX_T *p, U8 ucCalType, U8 ucResult)
399{
400 p->aru4CalExecuteFlag[p->channel][p->rank] |= (1<<ucCalType); // ececution done
401 if (ucResult == DRAM_OK) // Calibration OK
402 {
403 p->aru4CalResultFlag[p->channel][p->rank] &= (~(1<<ucCalType));
404 }
405 else //Calibration fail
406 {
407 p->aru4CalResultFlag[p->channel][p->rank] |= (1<<ucCalType);
408 }
409}
410
411#if 0 //no use now, disable for saving code size.
412void vGetCalibrationResult_All(DRAMC_CTX_T *p, U8 u1Channel, U8 u1Rank, U8 u1FreqType, U32 *u4CalExecute, U32 *u4CalResult)
413{
414 *u4CalExecute = p->aru4CalExecuteFlag[u1Channel][u1Rank];
415 *u4CalResult = p->aru4CalResultFlag[u1Channel][u1Rank];
416}
417
418void vGetCalibrationResult(DRAMC_CTX_T *p, U8 ucCalType, U8 *ucCalExecute, U8 *ucCalResult)
419{
420 U32 ucCalResult_All, ucCalExecute_All;
421
422 ucCalExecute_All = p->aru4CalExecuteFlag[p->channel][p->rank];
423 ucCalResult_All = p->aru4CalResultFlag[p->channel][p->rank];
424
425 *ucCalExecute = (U8)((ucCalExecute_All >>ucCalType) & 0x1);
426 *ucCalResult = (U8)((ucCalResult_All >>ucCalType) & 0x1);
427}
428#endif
429
430const char *szCalibStatusName[DRAM_CALIBRATION_MAX]=
431{
432 "ZQ Calibration",
433 "SW Impedance",
434 "CA Training",
435 "Write leveling",
436 "RX DQS gating",
437 "RX DATLAT",
438 "RX DQ/DQS(RDDQC)",
439 "RX DQ/DQS(Engine)",
440 "TX DQ/DQS",
441};
442
443void vPrintCalibrationResult(DRAMC_CTX_T *p)
444{
445 U8 ucCHIdx, ucRankIdx, ucCalIdx;
446 U32 ucCalResult_All, ucCalExecute_All;
447 U8 ucCalResult, ucCalExecute;
448 U8 u1CalibrationFail;
449
450 mcSHOW_DBG_MSG(("\n\n[Calibration Summary] Freqency %d\n", p->frequency));
451
452 //for(ucFreqIdx=0; ucFreqIdx<DRAM_DFS_SHUFFLE_MAX; ucFreqIdx++)
453 {
454 //mcSHOW_DBG_MSG(("==Freqency = %d==\n", get_Freq_by_shuffleIndex(p,ucFreqIdx)));
455 for(ucCHIdx=0; ucCHIdx<p->support_channel_num; ucCHIdx++)
456 {
457 for(ucRankIdx=0; ucRankIdx<p->support_rank_num; ucRankIdx++)
458 {
459 u1CalibrationFail =0;
460 ucCalExecute_All = p->aru4CalExecuteFlag[u1ChannelSet[ucCHIdx]][ucRankIdx];
461 ucCalResult_All = p->aru4CalResultFlag[u1ChannelSet[ucCHIdx]][ucRankIdx];
462 mcSHOW_DBG_MSG(("CH %d, Rank %d\n", u1ChannelSet[ucCHIdx], ucRankIdx));
463 //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));
464
465 for(ucCalIdx =0; ucCalIdx<DRAM_CALIBRATION_MAX; ucCalIdx++)
466 {
467 ucCalExecute = (U8)((ucCalExecute_All >>ucCalIdx) & 0x1);
468 ucCalResult = (U8)((ucCalResult_All >>ucCalIdx) & 0x1);
469
470 if(ucCalExecute==1 && ucCalResult ==1) // excuted and fail
471 {
472 u1CalibrationFail =1;
473 mcSHOW_DBG_MSG(("%s: %s\n", szCalibStatusName[ucCalIdx], ((ucCalResult == 0) ? "OK" : "Fail")));
474 }
475 }
476
477 if(u1CalibrationFail ==0)
478 {
479 mcSHOW_DBG_MSG(("All Pass.\n"));
480 }
481 mcSHOW_DBG_MSG(("\n"));
482 }
483 }
484 }
485
486 memset(p->aru4CalResultFlag, 0, sizeof(p->aru4CalResultFlag));
487 memset(p->aru4CalExecuteFlag, 0, sizeof(p->aru4CalExecuteFlag));
488}
489#endif
490
491void vPrintCalibrationBasicInfo(DRAMC_CTX_T *p)
492{
493#if __ETT__
494 mcSHOW_DBG_MSG(("===============================================================================\n"
495 "Dram Type= %d, Freq= %u, FreqGroup= %u, CH_%d, rank %d\n"
496 "fsp= %d, odt_onoff= %d, Byte mode= %d\n"
497 "===============================================================================\n",
498 p->dram_type, DDRPhyFMeter(), p->freqGroup, p->channel, p->rank,
499 p->dram_fsp, p->odt_onoff, p->dram_cbt_mode[p->rank]));
500#else
501 mcSHOW_DBG_MSG(("===============================================================================\n"
502 "Dram Type= %d, Freq= %u, CH_%d, rank %d\n"
503 "fsp= %d, odt_onoff= %d, Byte mode= %d\n"
504 "===============================================================================\n",
505 p->dram_type, DDRPhyFMeter(), p->channel, p->rank,
506 p->dram_fsp, p->odt_onoff, p->dram_cbt_mode[p->rank]));
507#endif
508}
509
510#if VENDER_JV_LOG
511void vPrintCalibrationBasicInfo_ForJV(DRAMC_CTX_T *p)
512{
513 mcSHOW_DBG_MSG5(("\n\nDram type:"));
514
515 switch(p->dram_type)
516 {
517#if ENABLE_LP3_SW
518 case TYPE_LPDDR3:
519 mcSHOW_DBG_MSG5(("LPDDR3\t"));
520 break;
521#endif /* ENABLE_LP3_SW */
522 case TYPE_LPDDR4:
523 mcSHOW_DBG_MSG5(("LPDDR4\t"));
524 break;
525
526 case TYPE_LPDDR4X:
527 mcSHOW_DBG_MSG5(("LPDDR4X\t"));
528 break;
529
530 case TYPE_LPDDR4P:
531 mcSHOW_DBG_MSG5(("LPDDR4P\t"));
532 break;
533 }
534
535 mcSHOW_DBG_MSG5(("Freq: %d, FreqGroup %u, channel %d, rank %d\n"
536 "dram_fsp= %d, odt_onoff= %d, Byte mode= %d\n\n",
537 p->frequency, p->freqGroup, p->channel, p->rank,
538 p->dram_fsp, p->odt_onoff, p->dram_cbt_mode[p->rank]));
539
540 return;
541}
542#endif
543
544#ifdef DEVIATION
545void DeviationAddVrefOffset(U8 k_type, U16 *u2FinalRange, U16 *u2FinalVref, S8 Vref_Offset)
546{
547 S16 temp_vref_value;
548
549 if (k_type==1)
550 {
551 temp_vref_value = *u2FinalVref + Vref_Offset;
552 if (temp_vref_value < 0)
553 {
554 *u2FinalVref = 0;
555 }
556 else if (temp_vref_value < RX_VREF_RANGE_END)
557 {
558 *u2FinalVref = temp_vref_value;
559 }
560 else
561 {
562 *u2FinalVref = RX_VREF_RANGE_END;
563 }
564 }
565 else
566 {
567 temp_vref_value = (*u2FinalRange*30) + *u2FinalVref + Vref_Offset;
568 if (temp_vref_value < 0)
569 {
570 *u2FinalRange = 0;
571 *u2FinalVref = 0;
572 }
573 else if (temp_vref_value <=50)
574 {
575 *u2FinalRange = 0;
576 *u2FinalVref = temp_vref_value;
577 }
578 else if (temp_vref_value < 81)
579 {
580 *u2FinalRange = 1;
581 *u2FinalVref = temp_vref_value - 30;
582 }
583 else
584 {
585 *u2FinalRange = 1;
586 *u2FinalVref = 50;
587 }
588 }
589}
590#endif
591
592#if (__ETT__ || ENABLE_LP3_SW)
593//for LP3 read register in different byte
594U32 u4IO32ReadFldAlign_Phy_Byte2(DRAMC_CTX_T *p, U8 ucByteIdx, U32 reg32, U32 fld)
595{
596 U32 offset=0;
597 U32 except_offset=0;
598
599#if (fcFOR_CHIP_ID == fcLaurel)
600 if(reg32<Channel_A_PHY_AO_BASE_VIRTUAL)
601 {
602 mcSHOW_DBG_MSG(("\n[ReadFldAlign_Phy_Byte] wrong addr 0x%x\n", reg32));
603 #if (FOR_DV_SIMULATION_USED==0 && SW_CHANGE_FOR_SIMULATION==0)
604 ASSERT(0);
605 #endif
606 }
607
608 reg32 &= 0xffff;
609
610 if (reg32 >= (DDRPHY_SHU1_R0_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_R0_B1_DQ0-DDRPHY_AO_BASE_ADDR))
611 {
612 offset = 0x50;
613 ///TODO: BE CAREFUL. CLK (PHY) -> DQS (DRAM)
614 if (reg32 >= (DDRPHY_SHU1_R0_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_R0_B0_DQ6-DDRPHY_AO_BASE_ADDR))
615 {
616 except_offset = 0x0;
617 }
618 else
619 {
620 except_offset = 0x8;
621 }
622 }
623 else if (reg32 >= (DDRPHY_R0_B0_RXDVS0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_R0_B1_RXDVS0-DDRPHY_AO_BASE_ADDR))
624 {
625 offset = 0x80;
626 except_offset = 0;
627 }
628 else if (reg32 >= (DDRPHY_SHU1_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_B1_DQ0-DDRPHY_AO_BASE_ADDR))
629 {
630 offset = 0x80;
631 except_offset = 0;
632 }
633 else if (reg32 >= (DDRPHY_B0_DLL_ARPI0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_B1_DLL_ARPI0-DDRPHY_AO_BASE_ADDR))
634 {
635 offset = 0x80;
636 except_offset = 0;
637 }
638 else
639 {
640 offset = 0x0;
641 except_offset = 0;
642 }
643
644 switch(ucByteIdx)
645 {
646 case 0:
647 return u4IO32ReadFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL+offset, fld); //CHB_B1
648 break;
649 case 1:
650 if(reg32==(DDRPHY_SHU1_R0_B0_DQ7&0xffff) && fld==SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0)
651 {
652 fld=SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS;
653 }
654 return u4IO32ReadFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL+(offset<<1)+except_offset, fld); //CHB_CA
655 break;
656 case 2:
657 return u4IO32ReadFldAlign(reg32+Channel_A_PHY_AO_BASE_VIRTUAL+offset, fld); //CHA_B1
658 break;
659 case 3:
660 return u4IO32ReadFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL, fld); //CHB_B0
661 break;
662 default:
663 mcSHOW_DBG_MSG(("\n[ReadFldAlign_Phy_Byte] wrong index of ucByteIdx !!!\n"));
664 break;
665 }
666#endif
667
668 #if (FOR_DV_SIMULATION_USED==0 && SW_CHANGE_FOR_SIMULATION==0)
669 ASSERT(0);
670 #endif
671}
672#endif
673
674#if ENABLE_LP3_SW
675//for LP3 write register in different byte
676void vIO32WriteFldAlign_Phy_Byte2(DRAMC_CTX_T *p, U8 ucByteIdx, U32 reg32, U32 val32, U32 fld)
677{
678#if (fcFOR_PINMUX == fcLaurel)
679 U32 offset=0;
680 U32 except_offset=0;
681
682 if(reg32 < Channel_A_PHY_AO_BASE_VIRTUAL)
683 {
684 mcSHOW_DBG_MSG(("\n[WriteFldAlign_Phy_Byte] wrong addr 0x%x\n", reg32));
685 return;
686 }
687 reg32 &= 0xffff;
688 if (reg32 >= (DDRPHY_SHU1_R0_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_R0_B1_DQ0-DDRPHY_AO_BASE_ADDR))
689 {
690 offset = 0x50;
691 ///TODO: BE CAREFUL. CLK (PHY) -> DQS (DRAM)
692 if (reg32 >= (DDRPHY_SHU1_R0_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_R0_B0_DQ6-DDRPHY_AO_BASE_ADDR))
693 {
694 except_offset = 0x0;
695 }
696 else
697 {
698 except_offset = 0x8;
699 }
700 }
701 else if (reg32 >= (DDRPHY_R0_B0_RXDVS0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_R0_B1_RXDVS0-DDRPHY_AO_BASE_ADDR))
702 {
703 offset = 0x80;
704 except_offset = 0x0;
705 }
706 else if (reg32 >= (DDRPHY_SHU1_B0_DQ0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_SHU1_B1_DQ0-DDRPHY_AO_BASE_ADDR))
707 {
708 offset = 0x80;
709 except_offset = 0;
710 }
711 else if (reg32 >= (DDRPHY_B0_DLL_ARPI0-DDRPHY_AO_BASE_ADDR) && reg32 < (DDRPHY_B1_DLL_ARPI0-DDRPHY_AO_BASE_ADDR))
712 {
713 offset = 0x80;
714 except_offset = 0;
715 }
716 else
717 {
718 offset = 0x0;
719 except_offset = 0;
720 }
721
722 switch(ucByteIdx)
723 {
724 case 0:
725 vIO32WriteFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL+offset, val32, fld); //CHB_B1
726 break;
727 case 1:
728 if(reg32==(DDRPHY_SHU1_R0_B0_DQ7&0xffff) && fld==SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0)
729 {
730 fld=SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS;
731 }
732 vIO32WriteFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL+(offset<<1)+except_offset, val32, fld); //CHB_CA
733 break;
734 case 2:
735 vIO32WriteFldAlign(reg32+Channel_A_PHY_AO_BASE_VIRTUAL+offset, val32, fld); //CHA_B1
736 break;
737 case 3:
738 vIO32WriteFldAlign(reg32+Channel_B_PHY_AO_BASE_VIRTUAL, val32, fld); //CHB_B0
739 break;
740 default:
741 mcSHOW_DBG_MSG(("\n[WriteFldAlign_Phy_Byte] wrong index of ucByteIdx !!!\n"));
742#if (FOR_DV_SIMULATION_USED==0 && SW_CHANGE_FOR_SIMULATION==0)
743 ASSERT(0);
744#endif
745 break;
746 }
747#endif
748}
749#endif /* ENABLE_LP3_SW */
750
751// for LP3 to control all PHY of single channel
752void vIO32WriteFldAlign_Phy_All2(DRAMC_CTX_T *p, U32 reg32, U32 val32, U32 fld)
753{
754 U8 ucCHIdx;
755
756 if(reg32<Channel_A_PHY_AO_BASE_VIRTUAL)
757 {
758 mcSHOW_DBG_MSG(("\n[WriteFldAlign_Phy_All] wrong addr 0x%x\n", reg32));
759 return;
760 }
761
762 reg32 &= 0xffff;
763
764 for(ucCHIdx=0; ucCHIdx<CHANNEL_NUM; ucCHIdx++)
765 {
766 vIO32WriteFldAlign(reg32+Channel_A_PHY_AO_BASE_VIRTUAL+0x10000*ucCHIdx, val32, fld);
767 }
768}
769
770void vApplyConfigAfterCalibration(DRAMC_CTX_T *p)
771{
772 U8 shu_index;
773/*================================
774 PHY RX Settings
775==================================*/
776
777 if(u1IsLP4Family(p->dram_type))
778 {
779 vIO32WriteFldAlign_All(DDRPHY_MISC_CG_CTRL4, 0x11400000, MISC_CG_CTRL4_R_PHY_MCK_CG_CTRL);
780 vIO32WriteFldAlign_All(DRAMC_REG_REFCTRL1, 0x0, REFCTRL1_SREF_CG_OPT);
781 vIO32WriteFldAlign_All(DRAMC_REG_SHUCTRL, 0x0, SHUCTRL_DVFS_CG_OPT);
782
783 /* Burst mode settings are removed from here due to
784 * 1. Set in UpdateInitialSettings_LP4
785 * 2. DQS Gating ensures new burst mode is switched when to done
786 * (or doesn't switch gatingMode at all, depending on "LP4_GATING_OLD_BURST_MODE")
787 */
788
789 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x0, CA_CMD6_RG_RX_ARCMD_RES_BIAS_EN);
790#if 0
791 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x0, B0_DQ6_RG_TX_ARDQ_OE_EXT_DIS_B0);
792 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x0, B1_DQ6_RG_TX_ARDQ_OE_EXT_DIS_B1);
793 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x0, CA_CMD6_RG_TX_ARCMD_OE_EXT_DIS);
794#endif
795
796#if ENABLE_WRITE_DBI
797 EnableDRAMModeRegWriteDBIAfterCalibration(p);
798#endif
799
800#if ENABLE_READ_DBI
801 EnableDRAMModeRegReadDBIAfterCalibration(p);
802#endif
803
804 // Set VRCG{MR13[3]} to 0 both to DRAM and DVFS
805 SetMr13VrcgToNormalOperation(p);
806
807 }
808#if ENABLE_LP3_SW
809 else
810 { //pulse mode
811 vIO32WriteFldAlign_All(DDRPHY_B0_DQ9, 0x0, B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0);
812 vIO32WriteFldAlign_All(DDRPHY_B1_DQ9, 0x0, B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1);
813 vIO32WriteFldAlign_All(DDRPHY_CA_CMD10, 0x0, CA_CMD10_RG_RX_ARCLK_DQSIENMODE);
814
815 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x0, B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0);
816 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x0, B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1);
817 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x0, CA_CMD6_RG_RX_ARCMD_BIAS_VREF_SEL);
818
819#if 0
820 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x1, B0_DQ6_RG_TX_ARDQ_OE_EXT_DIS_B0);
821 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x1, B1_DQ6_RG_TX_ARDQ_OE_EXT_DIS_B1);
822 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x1, CA_CMD6_RG_TX_ARCMD_OE_EXT_DIS);
823#endif
824
825 }
826#endif /* ENABLE_LP3_SW */
827
828 //DA mode
829 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x0, B0_DQ6_RG_RX_ARDQ_BIAS_PS_B0);
830 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x0, B1_DQ6_RG_RX_ARDQ_BIAS_PS_B1);
831 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x0, CA_CMD6_RG_RX_ARCMD_BIAS_PS);
832
833 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x1, B0_DQ6_RG_RX_ARDQ_RPRE_TOG_EN_B0);
834 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x1, B1_DQ6_RG_RX_ARDQ_RPRE_TOG_EN_B1);
835 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x1, CA_CMD6_RG_RX_ARCMD_RPRE_TOG_EN);
836
837
838/*================================
839 IMPCAL Settings
840==================================*/
841 vIO32WriteFldMulti_All(DRAMC_REG_IMPCAL, P_Fld(0, IMPCAL_IMPCAL_IMPPDP) | P_Fld(0, IMPCAL_IMPCAL_IMPPDN)); //RG_RIMP_BIAS_EN and RG_RIMP_VREF_EN move to IMPPDP and IMPPDN
842 vIO32WriteFldAlign_All(DDRPHY_MISC_IMP_CTRL0, 0, MISC_IMP_CTRL0_RG_IMP_EN);
843
844/*================================
845 MR1
846==================================*/
847
848 //MR1 op[7]=0 already be setted at end of gating calibration, no need to set here again
849/*
850 u1MR01Value[p->dram_fsp] &= 0x7f;
851 DramcModeRegWrite(p, 1, u1MR01Value[p->dram_fsp]);
852*/
853 //Prevent M_CK OFF because of hardware auto-sync
854 vIO32WriteFldAlign_All(DDRPHY_MISC_CG_CTRL0, 0, Fld(4,0));
855
856 //DFS- fix Gating Tracking settings
857 vIO32WriteFldAlign_All(DDRPHY_MISC_CTRL0, 0, MISC_CTRL0_R_STBENCMP_DIV4CK_EN);
858 vIO32WriteFldAlign_All(DDRPHY_MISC_CTRL1, 0, MISC_CTRL1_R_DMSTBENCMP_RK_OPT);
859
860 ///TODO: Disable MR4 MR18/MR19, TxHWTracking, Dummy RD - for DFS workaround
861 vIO32WriteFldAlign_All(DRAMC_REG_SPCMDCTRL, 0x1, SPCMDCTRL_REFRDIS); //MR4 Disable
862 vIO32WriteFldAlign_All(DRAMC_REG_DQSOSCR, 0x1, DQSOSCR_DQSOSCRDIS); //MR18, MR19 Disable
863 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
864 vIO32WriteFldAlign_All(DRAMC_REG_SHU_SCINTV + SHU_GRP_DRAMC_OFFSET*shu_index, 0x1, SHU_SCINTV_DQSOSCENDIS);
865 //vIO32WriteFldAlign_All(DRAMC_REG_SHU_SCINTV, 0x1, SHU_SCINTV_DQSOSCENDIS);
866 //vIO32WriteFldAlign_All(DRAMC_REG_SHU2_SCINTV, 0x1, SHU2_SCINTV_DQSOSCENDIS);
867 //vIO32WriteFldAlign_All(DRAMC_REG_SHU3_SCINTV, 0x1, SHU3_SCINTV_DQSOSCENDIS);
868 vIO32WriteFldMulti_All(DRAMC_REG_DUMMY_RD, P_Fld(0x0, DUMMY_RD_DUMMY_RD_EN)
869 | P_Fld(0x1, DUMMY_RD_SREF_DMYRD_EN)
870 | P_Fld(0x0, DUMMY_RD_DQSG_DMYRD_EN)
871 | P_Fld(0x0, DUMMY_RD_DMY_RD_DBG));
872#if APPLY_LP4_POWER_INIT_SEQUENCE
873 //CKE dynamic
874#if ENABLE_TMRRI_NEW_MODE
875 CKEFixOnOff(p, CKE_WRITE_TO_ALL_RANK, CKE_DYNAMIC, CKE_WRITE_TO_ALL_CHANNEL);
876#else
877 CKEFixOnOff(p, RANK_0, CKE_DYNAMIC, CKE_WRITE_TO_ALL_CHANNEL);
878#endif
879
880 //// Enable HW MIOCK control to make CLK dynamic
881 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_MIOCKCTRLOFF);
882#endif
883
884 //close eyescan to save power
885 vIO32WriteFldMulti_All(DRAMC_REG_EYESCAN, P_Fld(0x0, EYESCAN_EYESCAN_DQS_SYNC_EN)
886 | P_Fld(0x0, EYESCAN_EYESCAN_NEW_DQ_SYNC_EN)
887 | P_Fld(0x0, EYESCAN_EYESCAN_DQ_SYNC_EN));
888
889 /* TESTAGENT2 */
890 vIO32WriteFldAlign_All(DRAMC_REG_TEST2_4, 4, TEST2_4_TESTAGENTRKSEL); // Rank selection is controlled by Test Agent
891}
892
893#if defined(LOOPBACK_TEST) || (EMI_LPBK_DRAM_USED==0)
894void DramcLoopbackTest_settings(DRAMC_CTX_T *p, U8 u1Type)
895{
896
897 //close DCM, or DQ no clock
898 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMDQSIENCG_EN);
899
900 if (u1Type==1) //external loop back
901 {
902 //IOBIAS settings
903 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 1, B0_DQ6_RG_RX_ARDQ_BIAS_PS_B0);
904 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 1, B1_DQ6_RG_RX_ARDQ_BIAS_PS_B1);
905 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 1, CA_CMD6_RG_RX_ARCMD_BIAS_PS);
906
907 //after initial, must set 0 of PHY registers
908 vIO32WriteFldMulti_All(DDRPHY_B0_DQ3, P_Fld(0, B0_DQ3_RG_RX_ARDQS0_SWAP_EN_B0) | P_Fld(0, B0_DQ3_RG_RX_ARDQ_OFFC_EN_B0) | P_Fld(0, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0));
909 vIO32WriteFldMulti_All(DDRPHY_B1_DQ3, P_Fld(0, B1_DQ3_RG_RX_ARDQS0_SWAP_EN_B1) | P_Fld(0, B1_DQ3_RG_RX_ARDQ_OFFC_EN_B1) | P_Fld(0, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1));
910 vIO32WriteFldMulti_All(DDRPHY_CA_CMD3, P_Fld(0, CA_CMD3_RG_RX_ARCLK_SWAP_EN) | P_Fld(0, CA_CMD3_RG_RX_ARCMD_OFFC_EN) | P_Fld(0, CA_CMD3_RG_RX_ARCMD_SMT_EN));
911
912 //after initial, must set 1 of PHY registers
913 vIO32WriteFldMulti_All(DDRPHY_B0_DQ3, P_Fld(1, B0_DQ3_RG_RX_ARDQ_STBENCMP_EN_B0) | P_Fld(1, B0_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B0) | P_Fld(1, B0_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B0) | P_Fld(1, B0_DQ3_RG_ARDQ_RESETB_B0));
914 vIO32WriteFldAlign_All(DDRPHY_B0_DQ9, 1, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0);
915 vIO32WriteFldAlign_All(DDRPHY_B0_DQ5, 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0);
916 vIO32WriteFldMulti_All(DDRPHY_B0_DQ6, P_Fld(1, B0_DQ6_RG_RX_ARDQ_BIAS_EN_B0) | P_Fld(1, B0_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B0));
917
918 vIO32WriteFldMulti_All(DDRPHY_B1_DQ3, P_Fld(1, B1_DQ3_RG_RX_ARDQ_STBENCMP_EN_B1) | P_Fld(1, B1_DQ3_RG_RX_ARDQ_IN_BUFF_EN_B1) | P_Fld(1, B1_DQ3_RG_RX_ARDQS0_IN_BUFF_EN_B1) | P_Fld(1, B1_DQ3_RG_ARDQ_RESETB_B1));
919 vIO32WriteFldAlign_All(DDRPHY_B1_DQ9, 1, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1);
920 vIO32WriteFldAlign_All(DDRPHY_B1_DQ5, 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1);
921 vIO32WriteFldMulti_All(DDRPHY_B1_DQ6, P_Fld(1, B1_DQ6_RG_RX_ARDQ_BIAS_EN_B1) | P_Fld(1, B1_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B1));
922
923 vIO32WriteFldMulti_All(DDRPHY_CA_CMD3, P_Fld(1, CA_CMD3_RG_RX_ARCMD_STBENCMP_EN) | P_Fld(1, CA_CMD3_RG_RX_ARCMD_IN_BUFF_EN) | P_Fld(1, CA_CMD3_RG_RX_ARCLK_IN_BUFF_EN) | P_Fld(1, CA_CMD3_RG_ARCMD_RESETB));
924 vIO32WriteFldAlign_All(DDRPHY_CA_CMD10, 1, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB);
925 vIO32WriteFldAlign_All(DDRPHY_CA_CMD5, 1, CA_CMD5_RG_RX_ARCMD_VREF_EN);
926 vIO32WriteFldMulti_All(DDRPHY_CA_CMD6, P_Fld(1, CA_CMD6_RG_RX_ARCMD_BIAS_EN) | P_Fld(1, CA_CMD6_RG_RX_ARCMD_RES_BIAS_EN));
927 }
928}
929#endif
930
931
932void vResetDelayChainBeforeCalibration(DRAMC_CTX_T *p)
933{
934 U8 u1RankIdx, u1RankIdxBak;
935
936 u1RankIdxBak = u1GetRank(p);
937
938 for(u1RankIdx=RANK_0; u1RankIdx<RANK_MAX; u1RankIdx++)
939 {
940 vSetRank(p, u1RankIdx);
941 vIO32WriteFldMulti_All(DDRPHY_SHU1_R0_CA_CMD0, P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY)
942 | P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY)
943 | P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY)
944 | P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY)
945 | P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY)
946 | P_Fld(0x0, SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY));
947 vIO32WriteFldMulti_All(DDRPHY_SHU1_R0_B0_DQ0, P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0)
948 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0)
949 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0)
950 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0)
951 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0)
952 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0)
953 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0)
954 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0));
955 vIO32WriteFldMulti_All(DDRPHY_SHU1_R0_B1_DQ0, P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ7_DLY_B1)
956 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ6_DLY_B1)
957 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ5_DLY_B1)
958 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ4_DLY_B1)
959 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ3_DLY_B1)
960 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ2_DLY_B1)
961 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ1_DLY_B1)
962 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ0_DLY_B1));
963 vIO32WriteFldAlign_All(DDRPHY_SHU1_R0_B0_DQ1, 0x0, SHU1_R0_B0_DQ1_RK0_TX_ARDQM0_DLY_B0);
964 vIO32WriteFldAlign_All(DDRPHY_SHU1_R0_B1_DQ1, 0x0, SHU1_R0_B1_DQ1_RK0_TX_ARDQM0_DLY_B1);
965 }
966
967 vSetRank(p, u1RankIdxBak);
968}
969
970
971void vApplyConfigBeforeCalibration(DRAMC_CTX_T *p)
972{
973 U8 shu_index;
974 U8 u1RankIdx, u1RankIdxBak;
975 u1RankIdxBak = u1GetRank(p);
976
977#if 0//ENABLE_LP3_SW
978 if(p->dram_type == TYPE_LPDDR3)
979 {
980 vIO32WriteFldAlign(DDRPHY_SHU1_B1_DLL0, 0x6, SHU1_B1_DLL0_RG_ARDLL_GAIN_B1);
981 vIO32WriteFldAlign(DDRPHY_SHU1_CA_DLL0+(SHIFT_TO_CHB_ADDR), 0x6, SHU1_CA_DLL0_RG_ARDLL_GAIN_CA);
982 vIO32WriteFldAlign(DDRPHY_SHU1_B0_DLL0+(SHIFT_TO_CHB_ADDR), 0x6, SHU1_B0_DLL0_RG_ARDLL_GAIN_B0);
983 vIO32WriteFldAlign(DDRPHY_SHU1_B1_DLL0+(SHIFT_TO_CHB_ADDR), 0x6, SHU1_B1_DLL0_RG_ARDLL_GAIN_B1);
984 }
985#endif
986
987 //Clk free run
988#if (SW_CHANGE_FOR_SIMULATION==0)
989 EnableDramcPhyDCM(p, 0);
990#endif
991
992 //Set LP3/LP4 Rank0/1 CA/TX delay chain to 0
993#if (FOR_DV_SIMULATION_USED==0)
994 //CA0~9 per bit delay line -> CHA_CA0 CHA_CA3 CHA_B0_DQ6 CHA_B0_DQ7 CHA_B0_DQ2 CHA_B0_DQ5 CHA_B0_DQ4 CHA_B0_DQ1 CHA_B0_DQ0 CHA_B0_DQ3
995 vResetDelayChainBeforeCalibration(p);
996#endif
997
998 //MR4 refresh cnt set to 0x1ff (2ms update)
999 vIO32WriteFldAlign_All(DRAMC_REG_SHU_CONF3, 0x1ff, SHU_CONF3_REFRCNT);
1000
1001 //The counter for Read MR4 cannot be reset after SREF if DRAMC no power down.
1002 vIO32WriteFldAlign_All(DRAMC_REG_SPCMDCTRL, 1, SPCMDCTRL_SRFMR4_CNTKEEP_B);
1003
1004 //---- ZQ CS init --------
1005 vIO32WriteFldAlign_All(DRAMC_REG_SHU_SCINTV, 0x1B, SHU_SCINTV_TZQLAT); //ZQ Calibration Time, unit: 38.46ns, tZQCAL min is 1 us. need to set larger than 0x1b
1006 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
1007 vIO32WriteFldAlign_All(DRAMC_REG_SHU_CONF3 + SHU_GRP_DRAMC_OFFSET*shu_index, 0x1ff, SHU_CONF3_ZQCSCNT); //Every refresh number to issue ZQCS commands, only for DDR3/LPDDR2/LPDDR3/LPDDR4
1008 //vIO32WriteFldAlign_All(DRAMC_REG_SHU_CONF3, 0x1ff, SHU_CONF3_ZQCSCNT); //Every refresh number to issue ZQCS commands, only for DDR3/LPDDR2/LPDDR3/LPDDR4
1009 //vIO32WriteFldAlign_All(DRAMC_REG_SHU2_CONF3, 0x1ff, SHU_CONF3_ZQCSCNT); //Every refresh number to issue ZQCS commands, only for DDR3/LPDDR2/LPDDR3/LPDDR4
1010 //vIO32WriteFldAlign_All(DRAMC_REG_SHU3_CONF3, 0x1ff, SHU_CONF3_ZQCSCNT); //Every refresh number to issue ZQCS commands, only for DDR3/LPDDR2/LPDDR3/LPDDR4
1011 vIO32WriteFldAlign_All(DRAMC_REG_DRAMCTRL, 0, DRAMCTRL_ZQCALL); // HW send ZQ command for both rank, disable it due to some dram only have 1 ZQ pin for two rank.
1012
1013 //Dual channel ZQCS interlace, 0: disable, 1: enable
1014 if(p->support_channel_num==CHANNEL_SINGLE)
1015 {
1016 //single channel, ZQCSDUAL=0, ZQCSMASK=0
1017 vIO32WriteFldMulti(DRAMC_REG_ZQCS, P_Fld(0, ZQCS_ZQCSDUAL)| P_Fld(0x0, ZQCS_ZQCSMASK));
1018 }
1019 else if(p->support_channel_num==CHANNEL_DUAL)
1020 {
1021 // HW ZQ command is channel interleaving since 2 channel share the same ZQ pin.
1022 #ifdef ZQCS_ENABLE_LP4
1023 // dual channel, ZQCSDUAL =1, and CHA ZQCSMASK=0, CHB ZQCSMASK=1
1024 vIO32WriteFldMulti_All(DRAMC_REG_ZQCS, P_Fld(1, ZQCS_ZQCSDUAL) | \
1025 P_Fld(0, ZQCS_ZQCSMASK_OPT) | \
1026 P_Fld(0, ZQCS_ZQMASK_CGAR) | \
1027 P_Fld(0, ZQCS_ZQCS_MASK_SEL_CGAR));
1028
1029 // DRAMC CHA(CHN0):ZQCSMASK=1, DRAMC CHB(CHN1):ZQCSMASK=0.
1030 // ZQCSMASK setting: (Ch A, Ch B) = (1,0) or (0,1)
1031 // if CHA.ZQCSMASK=1, and then set CHA.ZQCALDISB=1 first, else set CHB.ZQCALDISB=1 first
1032 vIO32WriteFldAlign(DRAMC_REG_ZQCS + (CHANNEL_A<< POS_BANK_NUM), 1, ZQCS_ZQCSMASK);
1033 vIO32WriteFldAlign(DRAMC_REG_ZQCS + SHIFT_TO_CHB_ADDR, 0, ZQCS_ZQCSMASK);
1034
1035 // DRAMC CHA(CHN0):ZQCS_ZQCS_MASK_SEL=0, DRAMC CHB(CHN1):ZQCS_ZQCS_MASK_SEL=0.
1036 vIO32WriteFldAlign_All(DRAMC_REG_ZQCS, 0, ZQCS_ZQCS_MASK_SEL);
1037 #endif
1038 }
1039
1040 // Disable LP3 HW ZQ
1041 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 0, SPCMDCTRL_ZQCSDISB); //LP3 ZQCSDISB=0
1042 // Disable LP4 HW ZQ
1043 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 0, SPCMDCTRL_ZQCALDISB); //LP4 ZQCALDISB=0
1044 // ---- End of ZQ CS init -----
1045
1046 #if ENABLE_TX_TRACKING
1047 vIO32WriteFldAlign_All(DRAMC_REG_DQSOSCR, p->dram_cbt_mode[RANK_0],DQSOSCR_RK0_BYTE_MODE);
1048 vIO32WriteFldAlign_All(DRAMC_REG_DQSOSCR, p->dram_cbt_mode[RANK_1],DQSOSCR_RK1_BYTE_MODE);
1049 #endif
1050 //Disable write-DBI of DRAMC (Avoids pre-defined data pattern being modified)
1051 DramcWriteDBIOnOff(p, DBI_OFF);
1052 //Disable read-DBI of DRAMC (Avoids pre-defined data pattern being modified)
1053 DramcReadDBIOnOff(p, DBI_OFF);
1054 //disable MR4 read, REFRDIS=1
1055 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 1, SPCMDCTRL_REFRDIS);
1056 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 0x1, DQSOSCR_DQSOSCRDIS); //MR18, MR19 Disable
1057 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
1058 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV) + SHU_GRP_DRAMC_OFFSET*shu_index, 0x1, SHU_SCINTV_DQSOSCENDIS);
1059 //vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 0x1, SHU_SCINTV_DQSOSCENDIS);
1060 //vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SHU2_SCINTV), 0x1, SHU2_SCINTV_DQSOSCENDIS);
1061 //vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_SHU3_SCINTV), 0x1, SHU3_SCINTV_DQSOSCENDIS);
1062 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DRAMC_REG_DUMMY_RD), P_Fld(0x0, DUMMY_RD_DUMMY_RD_EN)
1063 | P_Fld(0x0, DUMMY_RD_SREF_DMYRD_EN)
1064 | P_Fld(0x0, DUMMY_RD_DQSG_DMYRD_EN)
1065 | P_Fld(0x0, DUMMY_RD_DMY_RD_DBG));
1066
1067 // Disable HW gating tracking first, 0x1c0[31], need to disable both UI and PI tracking or the gating delay reg won't be valid.
1068 DramcHWGatingOnOff(p, 0);
1069
1070 // Disable gating debug
1071 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_STBCAL2), 0, STBCAL2_STB_GERRSTOP);
1072
1073 for(u1RankIdx=RANK_0; u1RankIdx<RANK_MAX; u1RankIdx++)
1074 {
1075 vSetRank(p, u1RankIdx);
1076
1077 // Disable RX delay tracking
1078 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B0);
1079 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B1);
1080
1081 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B0);
1082 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B1);
1083
1084 //RX delay mux, delay vlaue from reg.
1085 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x0, R0_B0_RXDVS2_R_RK0_DVS_MODE_B0);
1086 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x0, R0_B1_RXDVS2_R_RK0_DVS_MODE_B1);
1087 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_CA_RXDVS2), 0x0, R0_CA_RXDVS2_R_RK0_DVS_MODE_CA);
1088 }
1089 vSetRank(p, u1RankIdxBak);
1090
1091 // ARPI_DQ SW mode mux, TX DQ use 1: PHY Reg 0: DRAMC Reg
1092 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_DMARPIDQ_SW);
1093
1094 // Set to all-bank refresh
1095 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 0, REFCTRL0_PBREFEN);
1096
1097 // set MRSRK to 0, MPCRKEN always set 1 (Derping)
1098 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_MRS), 0, MRS_MRSRK);
1099 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN);
1100
1101 //RG mode
1102 vIO32WriteFldAlign_All(DDRPHY_B0_DQ6, 0x1, B0_DQ6_RG_RX_ARDQ_BIAS_PS_B0);
1103 vIO32WriteFldAlign_All(DDRPHY_B1_DQ6, 0x1, B1_DQ6_RG_RX_ARDQ_BIAS_PS_B1);
1104 vIO32WriteFldAlign_All(DDRPHY_CA_CMD6, 0x1, CA_CMD6_RG_RX_ARCMD_BIAS_PS);
1105
1106#if ENABLE_RX_TRACKING_LP4
1107 if(u1IsLP4Family(p->dram_type))
1108 {
1109 DramcRxInputDelayTrackingInit_byFreq(p);
1110 }
1111#endif
1112
1113#ifdef LOOPBACK_TEST
1114#ifdef LPBK_INTERNAL_EN
1115 DramcLoopbackTest_settings(p, 0); //0: internal loopback test 1: external loopback test
1116#else
1117 DramcLoopbackTest_settings(p, 1); //0: internal loopback test 1: external loopback test
1118#endif
1119#endif
1120
1121#if EMI_LPBK_DRAM_USED==0
1122 DramcLoopbackTest_settings(p, 0);
1123#endif
1124
1125#if ENABLE_TMRRI_NEW_MODE
1126 SetCKE2RankIndependent(p);
1127#endif
1128
1129#ifdef DUMMY_READ_FOR_TRACKING
1130 if (u1IsLP4Family(p->dram_type))
1131 {
1132 vIO32WriteFldAlign_All(DRAMC_REG_DUMMY_RD, 1, DUMMY_RD_DMY_RD_RX_TRACK);
1133 }
1134#endif
1135
1136 vIO32WriteFldAlign_All(DRAMC_REG_DRSCTRL, 1, DRSCTRL_DRSDIS);
1137
1138#ifdef IMPEDANCE_TRACKING_ENABLE
1139 if(u1IsLP4Family(p->dram_type))
1140 {
1141 // set correct setting to control IMPCAL HW Tracking in shuffle RG
1142 // if p->freq >= 1333, enable IMP HW tracking(SHU1_DRVING1_DIS_IMPCAL_HW=0), else SHU1_DRVING1_DIS_IMPCAL_HW = 1
1143 U8 u1DisImpHw;
1144
1145 u1DisImpHw = (p->frequency >= 1200)?0:1;
1146 vIO32WriteFldAlign_All(DRAMC_REG_SHU1_DRVING1, u1DisImpHw, SHU1_DRVING1_DIS_IMPCAL_HW);
1147 }
1148 else
1149 {
1150 vIO32WriteFldAlign_All(DRAMC_REG_SHU1_DRVING1, 1, SHU1_DRVING1_DIS_IMPCAL_HW);
1151 }
1152#else
1153 vIO32WriteFldAlign_All(DRAMC_REG_SHU1_DRVING1, 1, SHU1_DRVING1_DIS_IMPCAL_HW);
1154 vIO32WriteFldAlign_All(DRAMC_REG_SHU1_DRVING1, 1, SHU1_DRVING1_DIS_IMP_ODTN_TRACK);
1155#endif
1156}
1157
1158
1159//Reset PHY to prevent glitch when change DQS gating delay or RX DQS input delay
1160// [Lynx] Everest : cannot reset single channel. All DramC and All Phy have to reset together.
1161void DramPhyReset(DRAMC_CTX_T *p)
1162{
1163 // Everest change reset order : reset DQS before DQ, move PHY reset to final.
1164 if(u1IsLP4Family(p->dram_type))
1165 {
1166 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0), 1, DDRCONF0_RDATRST);// read data counter reset
1167 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_DMPHYRST);
1168
1169 //RG_ARCMD_RESETB & RG_ARDQ_RESETB_B0/1 only reset once at init, Justin Chan.
1170 ///TODO: need to confirm RG_ARCMD_RESETB & RG_ARDQ_RESETB_B0/1 is reset at mem.c
1171 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(0, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(0, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
1172 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(0, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) |P_Fld(0, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
1173 #ifdef LOOPBACK_TEST
1174 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(0, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(0, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1175 #endif
1176
1177#if EMI_LPBK_USE_LP3_PINMUX
1178vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(0, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(0, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1179vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(0, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(0, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB));
1180#endif
1181 mcDELAY_US(1);//delay 10ns
1182 #ifdef LOOPBACK_TEST
1183 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(1, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(1, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1184 #endif
1185
1186#if EMI_LPBK_USE_LP3_PINMUX
1187vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(1, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(1, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1188vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(1, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(1, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB));
1189#endif
1190 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(1, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) | P_Fld(1, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
1191 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(1, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(1, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
1192
1193 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMPHYRST);
1194 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0), 0, DDRCONF0_RDATRST);// read data counter reset
1195 }
1196#if ENABLE_LP3_SW
1197 else //LPDDR3
1198 {
1199 // Everest change : must reset all dramC and PHY together.
1200 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0), 1, DDRCONF0_RDATRST);// read data counter reset
1201 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_DMPHYRST);
1202
1203 //RG_ARCMD_RESETB & RG_ARDQ_RESETB_B0/1 only reset once at init, Justin Chan.
1204 ///TODO: need to confirm RG_ARCMD_RESETB & RG_ARDQ_RESETB_B0/1 is reset at mem.c
1205 //only in LP3 due to DQ pinmux to CA
1206 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(0, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) |P_Fld(0, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1207 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(0, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(0, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
1208 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(0, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) |P_Fld(0, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
1209 mcDELAY_US(1);//delay 10ns
1210 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(1, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) |P_Fld(1, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
1211 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(1, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(1, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
1212 //only in LP3 due to DQ pinmux to CA
1213 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(1, CA_CMD10_RG_RX_ARCLK_STBEN_RESETB) | P_Fld(1, CA_CMD10_RG_RX_ARCMD_STBEN_RESETB));
1214 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMPHYRST);
1215 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0), 0, DDRCONF0_RDATRST);// read data counter reset
1216 }
1217#endif
1218
1219}
1220
1221
1222void DramEyeStbenReset(DRAMC_CTX_T *p)
1223{
1224 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_GDDR3CTL1), 1, GDDR3CTL1_RDATRST);// read data counter reset
1225
1226 if(u1IsLP4Family(p->dram_type))
1227 {
1228 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 0, B0_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B0);
1229 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 0, B1_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B1);
1230
1231 mcDELAY_US(1);//delay 10ns
1232
1233 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B0);
1234 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B1);
1235 }
1236#if ENABLE_LP3_SW
1237 else //LPDDR3
1238 {
1239 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 0, B0_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B0);
1240 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 0, B1_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B1);
1241 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 0, CA_CMD5_RG_RX_ARCMD_EYE_STBEN_RESETB); //only in LP3 due to DQ pinmux to CA
1242
1243 mcDELAY_US(1);//delay 10ns
1244
1245 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B0);
1246 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_EYE_STBEN_RESETB_B1);
1247 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, CA_CMD5_RG_RX_ARCMD_EYE_STBEN_RESETB);//only in LP3 due to DQ pinmux to CA
1248 }
1249#endif
1250}
1251
1252#if 0
1253DRAM_STATUS_T DramcRankSwap(DRAMC_CTX_T *p, U8 u1Rank)
1254{
1255 U8 u1Multi;
1256
1257#if 0
1258 if (p->support_rank_num > 1)
1259 u1Multi = 1;
1260 else
1261 u1Multi = 0;
1262#else
1263 //RANK_DUAL or RANK_SINGLE, all set RKMODE to 1
1264 u1Multi = 1;
1265#endif
1266
1267 mcSHOW_DBG_MSG(("[RankSwap] Rank num %d, (Multi %d), Rank %d\n", p->support_rank_num, u1Multi, u1Rank));
1268 //mcFPRINTF((fp_A60501, "[DramcRankSwap] Rank number %d, (u1Multi %d), Rank %d\n", p->support_rank_num, u1Multi, u1Rank));
1269
1270 //Set to non-zero for multi-rank
1271 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), u1Multi, RKCFG_RKMODE);
1272 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), u1Rank, RKCFG_RKSWAP);
1273
1274 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), u1Rank, RKCFG_TXRANK); //use other rank's setting //TXRANK should be set before TXRANKFIX
1275
1276 if (u1Rank == 0)
1277 {
1278 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANKFIX);
1279 }
1280 else
1281 {
1282 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX);
1283 }
1284
1285 return DRAM_OK;
1286}
1287#endif
1288
1289DRAM_STATUS_T DramcStartDQSOSC(DRAMC_CTX_T *p)
1290{
1291 U32 u4Response;
1292 U32 u4TimeCnt;
1293
1294 u4TimeCnt = TIME_OUT_CNT;
1295 mcSHOW_DBG_MSG(("[DQSOSC]\n"));
1296
1297 //R_DMDQSOSCENEN, 0x1E4[10]=1 for DQSOSC Start
1298 //Wait dqsoscen_response=1 (dramc_conf_nao, 0x3b8[29])
1299 //R_DMDQSOSCENEN, 0x1E4[10]=0
1300 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_DQSOSCENEN);
1301 do
1302 {
1303 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_DQSOSCEN_RESPONSE);
1304 u4TimeCnt --;
1305 mcDELAY_US(1);
1306 }while((u4Response==0) &&(u4TimeCnt>0));
1307
1308 if(u4TimeCnt==0)//time out
1309 {
1310 mcSHOW_DBG_MSG(("Start fail (time out)\n"));
1311 //mcFPRINTF((fp_A60501, "[DramcStartDQSOSC] Start fail (time out)\n"));
1312 return DRAM_FAIL;
1313 }
1314 else
1315 {
1316 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_DQSOSCENEN);
1317 }
1318
1319 return DRAM_OK;
1320}
1321
1322
1323DRAM_STATUS_T DramcDQSOSCAuto(DRAMC_CTX_T *p)
1324{
1325 U8 u1MR23 = gu1MR23[p->channel][p->rank], shu_index;
1326 U16 u2MR18, u2MR19;
1327 U16 u2DQSCnt;
1328 U16 u2DQSOsc[2];
1329 U32 u4RegBak[3];
1330
1331#if MRW_CHECK_ONLY
1332 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
1333#endif
1334
1335 u4RegBak[0] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_MRS));
1336 u4RegBak[1] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL));
1337 u4RegBak[2] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL));
1338
1339 //!!R_DMMRSRK(R_DMMPCRKEN=1) specify rank0 or rank1
1340 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_DQSOSC2RK);
1341 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
1342 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN);
1343
1344 //LPDDR4-3200, PI resolution = tCK/64 =9.76ps
1345 //Only if MR23>=16, then error < PI resolution.
1346 //Set MR23 == 0x3f, stop after 63*16 clock
1347 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
1348 DramcModeRegWrite(p, 23, u1MR23);
1349
1350 //SW mode
1351 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
1352 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV) + SHU_GRP_DRAMC_OFFSET*shu_index, 1, SHU_SCINTV_DQSOSCENDIS);
1353 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 1, SHU_SCINTV_DQSOSCENDIS);
1354 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU2_SCINTV), 1, SHU2_SCINTV_DQSOSCENDIS);
1355 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU3_SCINTV), 1, SHU3_SCINTV_DQSOSCENDIS);
1356
1357 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF); //MIOCKCTRLOFF=1
1358
1359 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
1360
1361 DramcStartDQSOSC(p);
1362 mcDELAY_US(1);
1363#if ENABLE_TMRRI_NEW_MODE
1364 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
1365#else
1366 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRRRK);
1367#endif
1368 DramcModeRegRead(p, 18, &u2MR18);
1369 DramcModeRegRead(p, 19, &u2MR19);
1370
1371
1372#if (SW_CHANGE_FOR_SIMULATION==0)
1373 //B0
1374 u2DQSCnt = (u2MR18 & 0x00FF) | ((u2MR19 & 0x00FF) <<8);
1375 if(u2DQSCnt !=0)
1376 u2DQSOsc[0] = u1MR23*16*1000000/(2 * u2DQSCnt * p->frequency); //tDQSOSC = 16*MR23*tCK/2*count
1377 else
1378 u2DQSOsc[0] = 0;
1379
1380 //B1
1381 u2DQSCnt = (u2MR18 >> 8) | ((u2MR19 & 0xFF00));
1382 if(u2DQSCnt !=0)
1383 u2DQSOsc[1] = u1MR23*16*1000000/(2 * u2DQSCnt * p->frequency); //tDQSOSC = 16*MR23*tCK/2*count
1384 else
1385 u2DQSOsc[1] = 0;
1386 mcSHOW_DBG_MSG(("[DQSOSCAuto] RK%d, (LSB)MR18= 0x%x, (MSB)MR19= 0x%x, tDQSOscB0 = %d ps tDQSOscB1 = %d ps\n", u1GetRank(p), u2MR18, u2MR19, u2DQSOsc[0], u2DQSOsc[1]));
1387#endif
1388
1389 gu2MR18[p->channel][p->rank] = u2MR18;
1390 gu2MR19[p->channel][p->rank] = u2MR19;
1391 gu2DQSOSC[p->channel][p->rank] = u2DQSOsc[0];
1392
1393 if(u2DQSOsc[1]!=0 && u2DQSOsc[1]<u2DQSOsc[0])
1394 gu2DQSOSC[p->channel][p->rank] = u2DQSOsc[1];
1395
1396 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_MRS), u4RegBak[0]);
1397 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), u4RegBak[1]);
1398 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), u4RegBak[2]);
1399
1400 /* Starting from Vinson, MR23 should be 0x3F for all case ("HW tracking modify" DVT)
1401 * -> Value is already set in during gu1MR23 array init
1402 * The below code snippet is used for KIBO/Alaska/Whitney E2 projects
1403 * (Adjusts MR23 according to freq, since back then _INC _DEC bit's weren't sufficient)
1404 */
1405#if 0
1406 if(gu1MR23Done==FALSE)
1407 {
1408 DRAM_CHANNEL_T chIdx = CHANNEL_A;
1409 DRAM_RANK_T rankIdx = RANK_0;
1410 if(gu2DQSOSC[p->channel][p->rank]>500)
1411 {
1412 u1MR23 = 0x30;
1413 }
1414 else if(gu2DQSOSC[p->channel][p->rank]>350)
1415 {
1416 u1MR23 = 0x20;
1417 }
1418 else
1419 {
1420 u1MR23 = 0x10;
1421 }
1422 for(chIdx=CHANNEL_A; chIdx<p->support_channel_num; chIdx++)
1423 {
1424 for(rankIdx=RANK_0; rankIdx<RANK_MAX; rankIdx++)
1425 {
1426 gu1MR23[chIdx][rankIdx] = u1MR23;
1427 }
1428 }
1429 mcSHOW_DBG_MSG(("Update MR23=%d\n", u1MR23));
1430 gu1MR23Done = TRUE;
1431 }
1432#endif
1433
1434 return DRAM_OK;
1435}
1436
1437#if 1
1438/* Using gu2DQSOSC results calculated from DramcDQSOSCAuto
1439 * -> calculate DQSOSCTHRD_INC, DQSOSCTHRD_DEC
1440 * _INC, _DEC formulas are extracted from "Verification plan of Vinson LPDDR4 HW TX Tracking" doc
1441 */
1442DRAM_STATUS_T DramcDQSOSCMR23(DRAMC_CTX_T *p)
1443{
1444#if (SW_CHANGE_FOR_SIMULATION==0)
1445#if 1
1446 /* Preloader doesn't support floating point numbers -> Manually expand/simpify _INC, _DEC formula */
1447 U8 u1MR23 = gu1MR23[p->channel][p->rank];
1448 U16 u2DQSOSC = gu2DQSOSC[p->channel][p->rank];
1449 U32 u4tCK = 1000000 / p->frequency;
1450
1451 if(u2DQSOSC !=0)
1452 {
1453 gu2DQSOSCTHRD_INC[p->channel][p->rank] = (3 * u1MR23 * u4tCK * u4tCK) / (u2DQSOSC * u2DQSOSC * 20);
1454 gu2DQSOSCTHRD_DEC[p->channel][p->rank] = (u1MR23 * u4tCK * u4tCK) / (u2DQSOSC * u2DQSOSC * 10);
1455 }
1456#else
1457 /* Formulas implemented directly as mentioned (using floating point numbers) */
1458 #define DQSOSC_ALPHA 0.2
1459 /*
1460 * actualAlpha, tickTime, goldenMR23 formulas are extracted from
1461 * "Vinson HW TX Tracking Modify" DVT document's excel file
1462 */
1463 float actualAlpha = DQSOSC_ALPHA/((1600/(float)p->frequency)*(1600/(float)p->frequency)); //DDR3200's alpha = 0.2, use it as base
1464 float tickTime = (1/(float)p->frequency)*1000000;
1465 float goldenMR23 = (2*4/DQSOSC_ALPHA)*(((float)u2DQSOSC/tickTime)*((float)u2DQSOSC/tickTime));
1466
1467 /* (Floating point + 0.5) and truncated into unsigned integer -> roundup floating point number */
1468 gu2DQSOSCTHRD_INC[p->channel][p->rank] = (5*1.2*((float)u4MR23/goldenMR23)+0.5);
1469 gu2DQSOSCTHRD_DEC[p->channel][p->rank] = (5*0.8*((float)u4MR23/goldenMR23)+0.5);
1470#endif
1471 mcSHOW_DBG_MSG(("CH%d_RK%d: MR19=0x%X, MR18=0x%X, DQSOSC=%d, MR23=%u, INC=%u, DEC=%u\n", p->channel, p->rank,
1472 gu2MR19[p->channel][p->rank], gu2MR18[p->channel][p->rank], gu2DQSOSC[p->channel][p->rank],
1473 u1MR23, gu2DQSOSCTHRD_INC[p->channel][p->rank], gu2DQSOSCTHRD_DEC[p->channel][p->rank]));
1474#endif
1475 return DRAM_OK;
1476}
1477#else
1478/* Used for previous projects (before Vinson) */
1479DRAM_STATUS_T DramcDQSOSCMR23(DRAMC_CTX_T *p)
1480{
1481#if (SW_CHANGE_FOR_SIMULATION==0)
1482 U16 u2DQSOSC = gu2DQSOSC[p->channel][p->rank];
1483 U32 u4tCK = 1000000/p->frequency;
1484 U32 u4RunTime = (32*4*5*(u2DQSOSC*u2DQSOSC)/(u4tCK*u4tCK))+1;
1485 //U32 u4MR23 = (u4RunTime/16)+1;
1486 U32 u4MR23 = gu1MR23[p->channel][p->rank];
1487
1488 gu2DQSOSCTHRD_INC[p->channel][p->rank] = (6*u4MR23*16)/(u4RunTime);
1489 gu2DQSOSCTHRD_DEC[p->channel][p->rank] = (4*u4MR23*16)/(u4RunTime);
1490 mcSHOW_DBG_MSG(("CH%d_RK%d: MR19=%X, MR18=%X, DQSOSC=%d, Runtime=%d, MR23=%d, INC=%d, DEC=%d\n",
1491 p->channel, p->rank, gu2MR19[p->channel][p->rank], gu2MR18[p->channel][p->rank], gu2DQSOSC[p->channel][p->rank],
1492 u4RunTime,u4MR23, gu2DQSOSCTHRD_INC[p->channel][p->rank], gu2DQSOSCTHRD_DEC[p->channel][p->rank]));
1493#endif
1494 return DRAM_OK;
1495}
1496#endif
1497
1498/* Sets DQSOSC_BASE for specified rank/byte */
1499DRAM_STATUS_T DramcDQSOSCSetMR18MR19(DRAMC_CTX_T *p)
1500{
1501 U16 u2DQSOscCnt[2];
1502 DramcDQSOSCAuto(p);
1503
1504 //B0
1505 gu2DQSOscCnt[p->channel][p->rank][0] = u2DQSOscCnt[0] = (gu2MR18[p->channel][p->rank] & 0x00FF) | ((gu2MR19[p->channel][p->rank] & 0x00FF) <<8);
1506 //B1
1507 gu2DQSOscCnt[p->channel][p->rank][1] = u2DQSOscCnt[1] = (gu2MR18[p->channel][p->rank] >> 8) | ((gu2MR19[p->channel][p->rank] & 0xFF00));
1508
1509 if((p->dram_cbt_mode[p->rank]==CBT_NORMAL_MODE) && (gu2DQSOscCnt[p->channel][p->rank][1]==0))
1510 {
1511 gu2DQSOscCnt[p->channel][p->rank][1] = u2DQSOscCnt[1] = u2DQSOscCnt[0];
1512 }
1513
1514 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQSOSC), P_Fld(u2DQSOscCnt[0], SHU1RK0_DQSOSC_DQSOSC_BASE_RK0)| P_Fld(u2DQSOscCnt[1], SHU1RK0_DQSOSC_DQSOSC_BASE_RK0_B1));
1515
1516 mcSHOW_DBG_MSG(("CH%d RK%d: MR19=%X, MR18=%X\n", p->channel, p->rank, gu2MR19[p->channel][p->rank], gu2MR18[p->channel][p->rank]));
1517 return DRAM_OK;
1518}
1519
1520DRAM_STATUS_T DramcDQSOSCShuSettings(DRAMC_CTX_T *p)
1521{
1522 U16 u2PRDCNT = 0x3FF;
1523 U16 u2DQSOSCENCNT = 0x1FF;
1524 U16 u2Thrd_inc, u2Thrd_dec;
1525 U8 u1FILT_PITHRD = 0;
1526 U8 u1W2R_SEL = 0;
1527
1528 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 0x0, SHU_SCINTV_DQS2DQ_SHU_PITHRD);
1529 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK0_DQSOSC), 0x0, RK0_DQSOSC_R_DMDQS2DQ_FILT_OPT);
1530 if(p->frequency<=400)
1531 {
1532 u1FILT_PITHRD = 0x4;
1533 u1W2R_SEL = 0x5;
1534 }
1535 else if(p->frequency<=600)
1536 {
1537 u1FILT_PITHRD = 0x6;
1538 u1W2R_SEL = 0x5;
1539 }
1540 else if(p->frequency<=800)
1541 {
1542 u1FILT_PITHRD = 0x7;
1543 u1W2R_SEL = 0x5;
1544 }
1545 else if(p->frequency<=1200)
1546 {
1547 u1FILT_PITHRD = 0xb;
1548 u1W2R_SEL = 0x2;
1549 }
1550 else if(p->frequency<=1333)
1551 {
1552 u1FILT_PITHRD = 0xc;
1553 u1W2R_SEL = 0x2;
1554 }
1555 else if(p->frequency<=1600)
1556 {
1557 u1FILT_PITHRD = 0xE;
1558 u1W2R_SEL = 0x2;
1559 }
1560 else if(p->frequency<=1866)
1561 {
1562 u1FILT_PITHRD = 0x12;
1563 u1W2R_SEL = 0x2;
1564 }
1565 else //4266
1566 {
1567 u1FILT_PITHRD = 0x15;
1568 u1W2R_SEL = 0x2;
1569 }
1570
1571 u2PRDCNT = (gu1MR23[p->channel][RANK_0]/4)+3;
1572 if (p->support_rank_num==RANK_DUAL)
1573 {
1574 if(gu1MR23[p->channel][RANK_0]>gu1MR23[p->channel][RANK_1])
1575 u2PRDCNT = (gu1MR23[p->channel][RANK_0]/4)+3;
1576 else
1577 u2PRDCNT = (gu1MR23[p->channel][RANK_1]/4)+3;
1578 }
1579
1580 //Don't power down dram during DQS interval timer run time, (MR23[7:0] /4) + (tOSCO/MCK unit/16)
1581 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DQSOSC_PRD), u2PRDCNT, SHU1_DQSOSC_PRD_DQSOSC_PRDCNT);
1582
1583 //set tOSCO constraint to read MR18/MR19, should be > 40ns/MCK
1584 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCR), ((p->frequency-1)/100)+1, SHU_DQSOSCR_DQSOSCRCNT);//unit: MCK to meet spec. tOSCO
1585 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), u1FILT_PITHRD, SHU_SCINTV_DQS2DQ_FILT_PITHRD);
1586 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1_WODT), P_Fld(u1W2R_SEL, SHU1_WODT_TXUPD_W2R_SEL) | P_Fld(0x0, SHU1_WODT_TXUPD_SEL));
1587
1588 /* Starting from Vinson, DQSOSCTHRD_INC & _DEC is split into RK0 and RK1 */
1589 //Rank 0
1590 u2Thrd_inc = gu2DQSOSCTHRD_INC[p->channel][RANK_0];
1591 u2Thrd_dec = gu2DQSOSCTHRD_DEC[p->channel][RANK_0];
1592 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD), u2Thrd_inc, SHU_DQSOSCTHRD_DQSOSCTHRD_INC_RK0);
1593 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD), u2Thrd_dec, SHU_DQSOSCTHRD_DQSOSCTHRD_DEC_RK0);
1594
1595 //Rank 1
1596 u2Thrd_inc = gu2DQSOSCTHRD_INC[p->channel][RANK_1];
1597 u2Thrd_dec = gu2DQSOSCTHRD_DEC[p->channel][RANK_1];
1598 /* DQSOSCTHRD_INC_RK1 is split into 2 register fields (starting from Vinson) */
1599 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD), (u2Thrd_inc & 0x0FF), SHU_DQSOSCTHRD_DQSOSCTHRD_INC_RK1_7TO0);
1600 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DQSOSC_PRD), ((u2Thrd_inc & 0xF00) >> 8), SHU1_DQSOSC_PRD_DQSOSCTHRD_INC_RK1_11TO8);
1601
1602 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DQSOSC_PRD), u2Thrd_dec, SHU1_DQSOSC_PRD_DQSOSCTHRD_DEC_RK1);
1603
1604 //set interval to do MPC(start DQSOSC) command, and dramc send DQSOSC start to rank0/1/2 at the same time
1605 //TX tracking period unit: 3.9us
1606 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCR2), u2DQSOSCENCNT, SHU_DQSOSCR2_DQSOSCENCNT);
1607
1608 return DRAM_OK;
1609}
1610
1611void DramcHwDQSOSCSetFreqRatio(DRAMC_CTX_T *p)
1612{
1613#if 0
1614 //for SHUFFLE_1
1615 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), P_Fld((U16)(gFreqTbl[1].frequency*8/gFreqTbl[0].frequency), RK2_DQSOSC_FREQ_RATIO_TX_0)
1616 | P_Fld((U16)(gFreqTbl[2].frequency*8/gFreqTbl[0].frequency), RK2_DQSOSC_FREQ_RATIO_TX_1));
1617 //for SHUFFLE_2
1618 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), P_Fld((U16)(gFreqTbl[0].frequency*8/gFreqTbl[1].frequency), RK2_DQSOSC_FREQ_RATIO_TX_3)
1619 | P_Fld((U16)(gFreqTbl[2].frequency*8/gFreqTbl[1].frequency), RK2_DQSOSC_FREQ_RATIO_TX_4));
1620 //for SHUFFLE_3
1621 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RK2_DUMMY_RD_BK), P_Fld((U16)(gFreqTbl[0].frequency*8/gFreqTbl[2].frequency), RK2_DUMMY_RD_BK_FREQ_RATIO_TX_6)
1622 | P_Fld((U16)(gFreqTbl[1].frequency*8/gFreqTbl[2].frequency), RK2_DUMMY_RD_BK_FREQ_RATIO_TX_7));
1623
1624 //for SHUFFLE_4
1625 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_PRE_TDQSCK1), P_Fld(1, PRE_TDQSCK1_SHU_PRELOAD_TX_HW)
1626 | P_Fld(0, PRE_TDQSCK1_SHU_PRELOAD_TX_START)
1627 | P_Fld(0, PRE_TDQSCK1_SW_UP_TX_NOW_CASE));
1628
1629#endif
1630 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_0=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_0)));
1631 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_1=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_1)));
1632 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_2=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_2)));
1633 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_3=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_3)));
1634 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_4=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_4)));
1635 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_5=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_5)));
1636 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_6=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DUMMY_RD_BK), RK2_DUMMY_RD_BK_FREQ_RATIO_TX_6)));
1637 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_7=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DUMMY_RD_BK), RK2_DUMMY_RD_BK_FREQ_RATIO_TX_7)));
1638 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_8=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DUMMY_RD_BK), RK2_DUMMY_RD_BK_FREQ_RATIO_TX_8)));
1639 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_9=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK2_DQSOSC), RK2_DQSOSC_FREQ_RATIO_TX_0)));
1640 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_9=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PRE_TDQSCK1), PRE_TDQSCK1_FREQ_RATIO_TX_9)));
1641 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_10=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PRE_TDQSCK1), PRE_TDQSCK1_FREQ_RATIO_TX_10)));
1642 mcSHOW_DBG_MSG3(("TX_FREQ_RATIO_11=%d\n", u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PRE_TDQSCK1), PRE_TDQSCK1_FREQ_RATIO_TX_11)));
1643}
1644
1645void DramcHwDQSOSC(DRAMC_CTX_T *p)
1646{
1647 U8 shu_index;
1648 DRAM_RANK_T rank_bak = u1GetRank(p);
1649 DRAM_CHANNEL_T ch_bak = p->channel;
1650
1651 DramcHwDQSOSCSetFreqRatio(p);
1652
1653 //DQSOSC MPC command violation
1654#if ENABLE_TMRRI_NEW_MODE
1655 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPC_BLOCKALE_OPT);
1656#else
1657 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 0, MPC_OPTION_MPC_BLOCKALE_OPT);
1658#endif
1659
1660 //DQS2DQ UI/PI setting controlled by HW
1661 #if ENABLE_SW_TX_TRACKING
1662 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_DMARPIDQ_SW);
1663 #else
1664 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMARPIDQ_SW);
1665 #endif
1666 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_ARUIDQ_SW);
1667
1668 //Set dqsosc oscillator run time by MRW
1669 //write RK0 MR23
1670 #if 0
1671 U8 u1MR23 = 0x3F;
1672 vSetRank(p, RANK_0);
1673 vSetPHY2ChannelMapping(p, CHANNEL_A);
1674 DramcModeRegWrite(p, 23, u1MR23);
1675 vSetPHY2ChannelMapping(p, CHANNEL_B);
1676 DramcModeRegWrite(p, 23, u1MR23);
1677 //write RK1 MR23
1678 vSetRank(p, RANK_1);
1679 vSetPHY2ChannelMapping(p, CHANNEL_A);
1680 DramcModeRegWrite(p, 23, u1MR23);
1681 vSetPHY2ChannelMapping(p, CHANNEL_B);
1682 DramcModeRegWrite(p, 23, u1MR23);
1683 #endif
1684
1685 //Enable HW read MR18/MR19 for each rank
1686 #if ENABLE_SW_TX_TRACKING
1687 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_DQSOSCRDIS);
1688 #else
1689 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 0, DQSOSCR_DQSOSCRDIS);
1690 #endif
1691
1692 vSetRank(p, RANK_0);
1693 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK0_DQSOSC), 1, RK0_DQSOSC_DQSOSCR_RK0EN);
1694 if (p->support_rank_num == RANK_DUAL)
1695 {
1696 vSetRank(p, RANK_1);
1697 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RK1_DQSOSC), 1, RK1_DQSOSC_DQSOSCR_RK1EN);
1698 }
1699
1700 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRSCTRL), 1, DRSCTRL_DRSCLR_RK0_EN); //Set as 1 to fix issue of single rank, dual rank can also be enable
1701
1702 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_DQSOSC_CALEN);
1703
1704 //enable DQSOSC HW mode
1705 #if ENABLE_SW_TX_TRACKING
1706 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
1707 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV) + SHU_GRP_DRAMC_OFFSET*shu_index, 1, SHU_SCINTV_DQSOSCENDIS);
1708 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 1, SHU_SCINTV_DQSOSCENDIS);
1709 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU2_SCINTV), 1, SHU2_SCINTV_DQSOSCENDIS);
1710 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU3_SCINTV), 1, SHU3_SCINTV_DQSOSCENDIS);
1711 #else
1712 for(shu_index = DRAM_DFS_SHUFFLE_1; shu_index < DRAM_DFS_SHUFFLE_MAX; shu_index++)
1713 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV) + SHU_GRP_DRAMC_OFFSET*shu_index, 0, SHU_SCINTV_DQSOSCENDIS);
1714 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 0, SHU_SCINTV_DQSOSCENDIS);
1715 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU2_SCINTV), 0, SHU2_SCINTV_DQSOSCENDIS);
1716 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU3_SCINTV), 0, SHU3_SCINTV_DQSOSCENDIS);
1717 #endif
1718
1719 vSetRank(p, rank_bak);
1720 vSetPHY2ChannelMapping(p, ch_bak);
1721}
1722
1723#if ENABLE_SW_TX_TRACKING & __ETT__
1724void DramcSWTxTracking(DRAMC_CTX_T *p)
1725{
1726 U8 u1MR4OnOff = 1;
1727 U8 rankIdx = RANK_0;
1728 U8 u1ShuLevel = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHUSTATUS), SHUSTATUS_SHUFFLE_LEVEL);
1729 U16 u2DramcOffset = SHU_GRP_DRAMC_OFFSET * u1ShuLevel;
1730 U16 u2MR1819_Base[CHANNEL_NUM][RANK_MAX][2];
1731 U16 u2MR1819_Runtime[CHANNEL_NUM][RANK_MAX][2];
1732 U16 u2DQSOSC_INC[RANK_MAX] = {6}, u2DQSOSC_DEC[RANK_MAX] = {4};
1733 U8 u1AdjPI[RANK_MAX][2];
1734 U8 u1OriginalPI_DQ[DRAM_DFS_SHUFFLE_MAX][RANK_MAX][2];
1735 U8 u1UpdatedPI_DQ[DRAM_DFS_SHUFFLE_MAX][RANK_MAX][2];
1736 U8 u1OriginalPI_DQM[DRAM_DFS_SHUFFLE_MAX][RANK_MAX][2];
1737 U8 u1UpdatedPI_DQM[DRAM_DFS_SHUFFLE_MAX][RANK_MAX][2];
1738 U8 u1FreqRatioTX[DRAM_DFS_SHUFFLE_MAX];
1739 U8 shuIdx=0;
1740
1741 for(shuIdx=0; shuIdx<DRAM_DFS_SHUFFLE_MAX; shuIdx++)
1742 {
1743 u1FreqRatioTX[shuIdx] = (gFreqTbl[shuIdx].frequency*8/gFreqTbl[u1ShuLevel].frequency);
1744 mcSHOW_DBG_MSG(("[SWTxTracking] ShuLevel=%d, Ratio[%d]=%d", u1ShuLevel, shuIdx, u1FreqRatioTX[shuIdx]));
1745 }
1746
1747 vSetRank(p, RANK_0);
1748
1749 /* Starting from Vinson, DQSOSCTHRD_INC & _DEC is split into RK0 and RK1 */
1750 //Rank 0
1751 u2DQSOSC_INC[RANK_0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD) + u2DramcOffset, SHU_DQSOSCTHRD_DQSOSCTHRD_INC_RK0);
1752 u2DQSOSC_DEC[RANK_0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD) + u2DramcOffset, SHU_DQSOSCTHRD_DQSOSCTHRD_DEC_RK0);
1753
1754
1755 /* DQSOSCTHRD_INC_RK1 is split into 2 register fields (starting from Vinson) */
1756 //Rank 1
1757 u2DQSOSC_INC[RANK_1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DQSOSC_PRD) + u2DramcOffset, SHU1_DQSOSC_PRD_DQSOSCTHRD_INC_RK1_11TO8);
1758 u2DQSOSC_INC[RANK_1] = u2DQSOSC_INC[RANK_1] << 8; /* Shift [3:0] to correct position [11:8] */
1759 u2DQSOSC_INC[RANK_1] = u2DQSOSC_INC[RANK_1] | u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_DQSOSCTHRD) + u2DramcOffset, SHU_DQSOSCTHRD_DQSOSCTHRD_INC_RK1_7TO0);
1760
1761 u2DQSOSC_DEC[RANK_1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DQSOSC_PRD) + u2DramcOffset, SHU1_DQSOSC_PRD_DQSOSCTHRD_DEC_RK1);
1762
1763 for(shuIdx=0; shuIdx<DRAM_DFS_SHUFFLE_MAX; shuIdx++)
1764 {
1765 u1OriginalPI_DQ[shuIdx][RANK_0][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK0_PI_RK0_ARPI_DQ_B0);
1766 u1OriginalPI_DQ[shuIdx][RANK_0][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK0_PI_RK0_ARPI_DQ_B1);
1767 u1OriginalPI_DQ[shuIdx][RANK_1][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK1_PI_RK1_ARPI_DQ_B0);
1768 u1OriginalPI_DQ[shuIdx][RANK_1][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK1_PI_RK1_ARPI_DQ_B1);
1769
1770 u1OriginalPI_DQM[shuIdx][RANK_0][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK0_PI_RK0_ARPI_DQM_B0);
1771 u1OriginalPI_DQM[shuIdx][RANK_0][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK0_PI_RK0_ARPI_DQM_B1);
1772 u1OriginalPI_DQM[shuIdx][RANK_1][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK1_PI_RK1_ARPI_DQM_B0);
1773 u1OriginalPI_DQM[shuIdx][RANK_1][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_PI)+(SHU_GRP_DRAMC_OFFSET * shuIdx), SHU1RK1_PI_RK1_ARPI_DQM_B1);
1774 }
1775
1776 u2MR1819_Base[p->channel][RANK_0][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQSOSC)+u2DramcOffset, SHU1RK0_DQSOSC_DQSOSC_BASE_RK0);
1777 u2MR1819_Base[p->channel][RANK_0][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQSOSC)+u2DramcOffset, SHU1RK0_DQSOSC_DQSOSC_BASE_RK0_B1);
1778 u2MR1819_Base[p->channel][RANK_1][0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_DQSOSC)+u2DramcOffset, SHU1RK1_DQSOSC_DQSOSC_BASE_RK1);
1779 u2MR1819_Base[p->channel][RANK_1][1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK1_DQSOSC)+u2DramcOffset, SHU1RK1_DQSOSC_DQSOSC_BASE_RK1_B1);
1780
1781 u1MR4OnOff = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), SPCMDCTRL_REFRDIS);
1782
1783 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 1, SPCMDCTRL_REFRDIS);
1784 for(rankIdx=RANK_0; rankIdx<p->support_rank_num; rankIdx++)
1785 {
1786 U8 byteIdx=0;
1787
1788 vSetRank(p, rankIdx);
1789 DramcDQSOSCAuto(p);
1790 u2MR1819_Runtime[p->channel][p->rank][0] = (gu2MR18[p->channel][p->rank] & 0x00FF) | ((gu2MR19[p->channel][p->rank] & 0x00FF) <<8);
1791 if(p->dram_cbt_mode[p->rank]==CBT_BYTE_MODE1)
1792 {
1793 u2MR1819_Runtime[p->channel][p->rank][1] = (gu2MR18[p->channel][p->rank] >> 8) | ((gu2MR19[p->channel][p->rank] & 0xFF00));
1794 }
1795 else
1796 {
1797 u2MR1819_Runtime[p->channel][p->rank][1] = u2MR1819_Runtime[p->channel][p->rank][0];
1798 }
1799 //INC : MR1819>base. PI-
1800 //DEC : MR1819<base. PI+
1801 for(byteIdx=0; byteIdx<2; byteIdx++)
1802 {
1803 U16 deltaMR1819=0;
1804
1805 if(u2MR1819_Runtime[p->channel][p->rank][byteIdx] >= u2MR1819_Base[p->channel][p->rank][byteIdx])
1806 {
1807 deltaMR1819 = u2MR1819_Runtime[p->channel][p->rank][byteIdx] - u2MR1819_Base[p->channel][p->rank][byteIdx];
1808 u1AdjPI[rankIdx][byteIdx] = deltaMR1819/u2DQSOSC_INC[rankIdx];
1809 for(shuIdx=0; shuIdx<DRAM_DFS_SHUFFLE_MAX; shuIdx++)
1810 {
1811 u1UpdatedPI_DQ[shuIdx][rankIdx][byteIdx] = u1OriginalPI_DQ[shuIdx][rankIdx][byteIdx] - (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]);
1812 u1UpdatedPI_DQM[shuIdx][rankIdx][byteIdx] = u1OriginalPI_DQM[shuIdx][rankIdx][byteIdx] - (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]);
1813 mcSHOW_DBG_MSG(("SHU%u CH%d RK%d B%d, Base=%X Runtime=%X delta=%d INC=%d PI=0x%B Adj=%d newPI=0x%B\n", shuIdx, p->channel, u1GetRank(p), byteIdx
1814 , u2MR1819_Base[p->channel][p->rank][byteIdx], u2MR1819_Runtime[p->channel][p->rank][byteIdx], deltaMR1819, u2DQSOSC_INC[rankIdx]
1815 , u1OriginalPI_DQ[shuIdx][rankIdx][byteIdx], (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]), u1UpdatedPI_DQ[shuIdx][rankIdx][byteIdx]));
1816 }
1817 }
1818 else
1819 {
1820 deltaMR1819 = u2MR1819_Base[p->channel][p->rank][byteIdx] - u2MR1819_Runtime[p->channel][p->rank][byteIdx];
1821 u1AdjPI[rankIdx][byteIdx] = deltaMR1819/u2DQSOSC_DEC[rankIdx];
1822 for(shuIdx=0; shuIdx<DRAM_DFS_SHUFFLE_MAX; shuIdx++)
1823 {
1824 u1UpdatedPI_DQ[shuIdx][rankIdx][byteIdx] = u1OriginalPI_DQ[shuIdx][rankIdx][byteIdx] + (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]);
1825 u1UpdatedPI_DQM[shuIdx][rankIdx][byteIdx] = u1OriginalPI_DQM[shuIdx][rankIdx][byteIdx] + (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]);
1826 mcSHOW_DBG_MSG(("SHU%u CH%d RK%d B%d, Base=%X Runtime=%X delta=%d DEC=%d PI=0x%B Adj=%d newPI=0x%B\n", shuIdx, p->channel,u1GetRank(p), byteIdx
1827 , u2MR1819_Base[p->channel][p->rank][byteIdx], u2MR1819_Runtime[p->channel][p->rank][byteIdx], deltaMR1819, u2DQSOSC_DEC[rankIdx]
1828 , u1OriginalPI_DQ[shuIdx][rankIdx][byteIdx], (u1AdjPI[rankIdx][byteIdx]*u1FreqRatioTX[shuIdx]/u1FreqRatioTX[u1ShuLevel]), u1UpdatedPI_DQ[shuIdx][rankIdx][byteIdx]));
1829 }
1830 }
1831 }
1832 }
1833
1834 vSetRank(p, RANK_0);
1835 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_TXUPDMODE);
1836 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_MANUTXUPD);
1837
1838 for(shuIdx=0; shuIdx<DRAM_DFS_SHUFFLE_MAX; shuIdx++)
1839 {
1840 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7)+(SHU_GRP_DDRPHY_OFFSET * shuIdx), P_Fld(u1UpdatedPI_DQ[shuIdx][RANK_0][0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0)
1841 | P_Fld(u1UpdatedPI_DQM[shuIdx][RANK_0][0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0));
1842
1843 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7)+(SHU_GRP_DDRPHY_OFFSET * shuIdx), P_Fld(u1UpdatedPI_DQ[shuIdx][RANK_0][1], SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1)
1844 | P_Fld(u1UpdatedPI_DQM[shuIdx][RANK_0][1], SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1));
1845
1846 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R1_B0_DQ7)+(SHU_GRP_DDRPHY_OFFSET * shuIdx), P_Fld(u1UpdatedPI_DQ[shuIdx][RANK_1][0], SHU1_R1_B0_DQ7_RK1_ARPI_DQ_B0)
1847 | P_Fld(u1UpdatedPI_DQM[shuIdx][RANK_1][0], SHU1_R1_B0_DQ7_RK1_ARPI_DQM_B0));
1848
1849 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R1_B1_DQ7)+(SHU_GRP_DDRPHY_OFFSET * shuIdx), P_Fld(u1UpdatedPI_DQ[shuIdx][RANK_1][1], SHU1_R1_B1_DQ7_RK1_ARPI_DQ_B1)
1850 | P_Fld(u1UpdatedPI_DQM[shuIdx][RANK_1][1], SHU1_R1_B1_DQ7_RK1_ARPI_DQM_B1));
1851 }
1852
1853 while(u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MISC_STATUSA),MISC_STATUSA_MANUTXUPD_DONE)!=1)
1854 {
1855 mcDELAY_US(1);
1856 }
1857
1858 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 0, DQSOSCR_TXUPDMODE);
1859 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 0, DQSOSCR_MANUTXUPD);
1860
1861 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), u1MR4OnOff, SPCMDCTRL_REFRDIS);
1862}
1863#endif
1864
1865#if ENABLE_RX_TRACKING_LP4
1866void DramcRxInputDelayTrackingInit_Common(DRAMC_CTX_T *p)
1867{
1868 U8 ii, backup_rank;
1869
1870 backup_rank = u1GetRank(p);
1871
1872 //Enable RX_FIFO macro DIV4 clock CG
1873 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CG_CTRL1), 0xffffffff, MISC_CG_CTRL1_R_DVS_DIV4_CG_CTRL);
1874
1875 //DVS mode to RG mode
1876 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2),0x0, R0_B0_RXDVS2_R_RK0_DVS_MODE_B0);
1877 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2),0x0, R0_B1_RXDVS2_R_RK0_DVS_MODE_B1);
1878
1879 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R1_B0_RXDVS2),0x0, R1_B0_RXDVS2_R_RK1_DVS_MODE_B0);
1880 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R1_B1_RXDVS2),0x0, R1_B1_RXDVS2_R_RK1_DVS_MODE_B1);
1881
1882 //Tracking lead/lag counter >> Rx DLY adjustment fixed to 1
1883 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0),0x0, B0_RXDVS0_R_DMRXDVS_CNTCMP_OPT_B0);
1884 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0),0x0, B1_RXDVS0_R_DMRXDVS_CNTCMP_OPT_B1);
1885
1886 //DQIEN pre-state option to block update for RX ASVA 1-2
1887 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0),0x1, B0_RXDVS0_R_DMRXDVS_DQIENPRE_OPT_B0);
1888 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0),0x1, B1_RXDVS0_R_DMRXDVS_DQIENPRE_OPT_B1);
1889
1890 //Turn off F_DLY individual calibration option (CTO_AGENT_RDAT cannot separate DR/DF error)
1891 //tracking rising and update rising/falling together
1892 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2),0x0, R0_B0_RXDVS2_R_RK0_DVS_FDLY_MODE_B0);
1893 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2),0x0, R0_B1_RXDVS2_R_RK0_DVS_FDLY_MODE_B1);
1894
1895 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R1_B0_RXDVS2),0x0, R1_B0_RXDVS2_R_RK1_DVS_FDLY_MODE_B0);
1896 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R1_B1_RXDVS2),0x0, R1_B1_RXDVS2_R_RK1_DVS_FDLY_MODE_B1);
1897
1898 for(ii=RANK_0; ii<RANK_MAX; ii++)
1899 {
1900 vSetRank(p, ii);
1901
1902 //DQ/DQM/DQS DLY MAX/MIN value under Tracking mode
1903 /* Byte 0 */
1904#if (fcFOR_CHIP_ID == fcLaurel)
1905 /* DQS, DQ, DQM (DQ, DQM are tied together now) -> controlled using DQM MAX_MIN */
1906 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS7), P_Fld(0x0, R0_B0_RXDVS7_RG_RK0_ARDQ_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS7_RG_RK0_ARDQ_MAX_DLY_B0)
1907 | P_Fld(0x0, R0_B0_RXDVS7_RG_RK0_ARDQS0_MIN_DLY_B0) | P_Fld(0x7f, R0_B0_RXDVS7_RG_RK0_ARDQS0_MAX_DLY_B0));
1908#else
1909 /* Previous design DQ, DQM MAX/MIN are controlled using different register fields */
1910 /* DQM, DQS */
1911 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS7), P_Fld(0x0, R0_B0_RXDVS7_RG_RK0_ARDQ_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS7_RG_RK0_ARDQ_MAX_DLY_B0)
1912 | P_Fld(0x0, R0_B0_RXDVS7_RG_RK0_ARDQS0_MIN_DLY_B0) | P_Fld(0x7f, R0_B0_RXDVS7_RG_RK0_ARDQS0_MAX_DLY_B0));
1913 /* DQ */
1914 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS3), P_Fld(0x0, R0_B0_RXDVS3_RG_RK0_ARDQ0_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS3_RG_RK0_ARDQ0_MAX_DLY_B0));
1915 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS3), P_Fld(0x0, R0_B0_RXDVS3_RG_RK0_ARDQ1_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS3_RG_RK0_ARDQ1_MAX_DLY_B0));
1916 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS4), P_Fld(0x0, R0_B0_RXDVS4_RG_RK0_ARDQ2_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS4_RG_RK0_ARDQ2_MAX_DLY_B0));
1917 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS4), P_Fld(0x0, R0_B0_RXDVS4_RG_RK0_ARDQ3_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS4_RG_RK0_ARDQ3_MAX_DLY_B0));
1918 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS5), P_Fld(0x0, R0_B0_RXDVS5_RG_RK0_ARDQ4_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS5_RG_RK0_ARDQ4_MAX_DLY_B0));
1919 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS5), P_Fld(0x0, R0_B0_RXDVS5_RG_RK0_ARDQ5_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS5_RG_RK0_ARDQ5_MAX_DLY_B0));
1920 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS6), P_Fld(0x0, R0_B0_RXDVS6_RG_RK0_ARDQ6_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS6_RG_RK0_ARDQ6_MAX_DLY_B0));
1921 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS6), P_Fld(0x0, R0_B0_RXDVS6_RG_RK0_ARDQ7_MIN_DLY_B0) | P_Fld(0x3f, R0_B0_RXDVS6_RG_RK0_ARDQ7_MAX_DLY_B0));
1922#endif
1923
1924 /* Byte 1 */
1925#if (fcFOR_CHIP_ID == fcLaurel)
1926 /* DQS, DQ, DQM (DQ, DQM are tied together now) -> controlled using DQM MAX_MIN */
1927 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS7), P_Fld(0x0, R0_B1_RXDVS7_RG_RK0_ARDQ_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS7_RG_RK0_ARDQ_MAX_DLY_B1)
1928 | P_Fld(0x0, R0_B1_RXDVS7_RG_RK0_ARDQS0_MIN_DLY_B1) | P_Fld(0x7f, R0_B1_RXDVS7_RG_RK0_ARDQS0_MAX_DLY_B1));
1929#else
1930 /* Previous design DQ, DQM MAX/MIN are controlled using different register fields */
1931 /* DQM, DQS */
1932 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS7), P_Fld(0x0, R0_B1_RXDVS7_RG_RK0_ARDQ_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS7_RG_RK0_ARDQ_MAX_DLY_B1)
1933 | P_Fld(0x0, R0_B1_RXDVS7_RG_RK0_ARDQS0_MIN_DLY_B1) | P_Fld(0x7f, R0_B1_RXDVS7_RG_RK0_ARDQS0_MAX_DLY_B1));
1934 /* DQ */
1935 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS3), P_Fld(0x0, R0_B1_RXDVS3_RG_RK0_ARDQ0_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS3_RG_RK0_ARDQ0_MAX_DLY_B1));
1936 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS3), P_Fld(0x0, R0_B1_RXDVS3_RG_RK0_ARDQ1_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS3_RG_RK0_ARDQ1_MAX_DLY_B1));
1937 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS4), P_Fld(0x0, R0_B1_RXDVS4_RG_RK0_ARDQ2_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS4_RG_RK0_ARDQ2_MAX_DLY_B1));
1938 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS4), P_Fld(0x0, R0_B1_RXDVS4_RG_RK0_ARDQ3_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS4_RG_RK0_ARDQ3_MAX_DLY_B1));
1939 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS5), P_Fld(0x0, R0_B1_RXDVS5_RG_RK0_ARDQ4_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS5_RG_RK0_ARDQ4_MAX_DLY_B1));
1940 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS5), P_Fld(0x0, R0_B1_RXDVS5_RG_RK0_ARDQ5_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS5_RG_RK0_ARDQ5_MAX_DLY_B1));
1941 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS6), P_Fld(0x0, R0_B1_RXDVS6_RG_RK0_ARDQ6_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS6_RG_RK0_ARDQ6_MAX_DLY_B1));
1942 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS6), P_Fld(0x0, R0_B1_RXDVS6_RG_RK0_ARDQ7_MIN_DLY_B1) | P_Fld(0x3f, R0_B1_RXDVS6_RG_RK0_ARDQ7_MAX_DLY_B1));
1943#endif
1944
1945 //Threshold for LEAD/LAG filter
1946 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS1), P_Fld(0x2, R0_B0_RXDVS1_R_RK0_B0_DVS_TH_LEAD) | P_Fld(0x2, R0_B0_RXDVS1_R_RK0_B0_DVS_TH_LAG));
1947 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS1), P_Fld(0x2, R0_B1_RXDVS1_R_RK0_B1_DVS_TH_LEAD) | P_Fld(0x2, R0_B1_RXDVS1_R_RK0_B1_DVS_TH_LAG));
1948
1949 //DQ/DQS Rx DLY adjustment for tracking mode
1950 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), P_Fld(0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_RIS_DQ_SCALE_B0) | P_Fld(0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_RIS_DQS_SCALE_B0));
1951 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), P_Fld(0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_RIS_DQ_SCALE_B1) | P_Fld(0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_RIS_DQS_SCALE_B1));
1952
1953 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), P_Fld(0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_FAL_DQ_SCALE_B0) | P_Fld(0x0, R0_B0_RXDVS2_R_RK0_RX_DLY_FAL_DQS_SCALE_B0));
1954 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), P_Fld(0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_FAL_DQ_SCALE_B1) | P_Fld(0x0, R0_B1_RXDVS2_R_RK0_RX_DLY_FAL_DQS_SCALE_B1));
1955 }
1956
1957 vSetRank(p, backup_rank);
1958}
1959#endif
1960
1961void DramcRxInputDelayTrackingInit_byFreq(DRAMC_CTX_T *p)
1962{
1963 U8 u1DVS_Delay;
1964 //Monitor window size setting
1965 //DDRPHY.SHU*_B*_DQ5.RG_RX_ARDQS0_DVS_DLY_B* (suggested value from A-PHY owner)
1966//WHITNEY_TO_BE_PORTING
1967#if (fcFOR_CHIP_ID == fcLaurel)
1968 // Speed Voltage DVS_DLY
1969 //======================================
1970 //SHU1 3200 0.8V 3
1971 //SHU2 2667 0.8V-0.7V 4
1972 //SHU3 1600 0.7V-0.65V 5
1973 if(p->freqGroup == 2132)
1974 {
1975 u1DVS_Delay =2;
1976 }
1977 else
1978 if(p->freqGroup == 1866)
1979 {
1980 u1DVS_Delay =3;
1981 }
1982 else
1983 if(p->freqGroup == 1600)
1984 {
1985 u1DVS_Delay =3;
1986 }
1987 else if(p->freqGroup == 1333 || p->freqGroup == 1200)
1988 {
1989 u1DVS_Delay =4;
1990 }
1991 else// if(p->freqGroup == 800)
1992 {
1993 u1DVS_Delay =5;
1994 }
1995#endif
1996
1997 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), u1DVS_Delay, SHU1_B0_DQ5_RG_RX_ARDQS0_DVS_DLY_B0);
1998 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), u1DVS_Delay, SHU1_B1_DQ5_RG_RX_ARDQS0_DVS_DLY_B1);
1999
2000 /* Bianco HW design issue: run-time PBYTE flag will lose it's function and become per-bit -> set to 0 */
2001 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), P_Fld(0x0, SHU1_B0_DQ7_R_DMRXDVS_PBYTE_FLAG_OPT_B0)
2002 | P_Fld(0x0, SHU1_B0_DQ7_R_DMRXDVS_PBYTE_DQM_EN_B0));
2003 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7), P_Fld(0x0, SHU1_B1_DQ7_R_DMRXDVS_PBYTE_FLAG_OPT_B1)
2004 | P_Fld(0x0, SHU1_B1_DQ7_R_DMRXDVS_PBYTE_DQM_EN_B1));
2005}
2006
2007#if ENABLE_RX_TRACKING_LP4
2008void DramcRxInputDelayTrackingHW(DRAMC_CTX_T *p)
2009{
2010 DRAM_CHANNEL_T channel_bak = p->channel;
2011 //UINT8 updateDone=0;
2012 //U16 u2DVS_TH=0x0;
2013 //U16 u2MinDly=0x14;
2014 //U16 u2MaxDly=0x30;
2015 U8 ii, backup_rank;
2016
2017 vSetPHY2ChannelMapping(p, CHANNEL_A);
2018 backup_rank = u1GetRank(p);
2019
2020 //Rx DLY tracking setting (Static)
2021 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0),
2022 P_Fld(1, B0_RXDVS0_R_RX_DLY_TRACK_SPM_CTRL_B0) |
2023 P_Fld(0, B0_RXDVS0_R_RX_RANKINCTL_B0)|
2024 P_Fld(1, B0_RXDVS0_R_RX_RANKINSEL_B0));
2025
2026 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0),
2027 P_Fld(1, B1_RXDVS0_R_RX_DLY_TRACK_SPM_CTRL_B1) |
2028 P_Fld(0, B1_RXDVS0_R_RX_RANKINCTL_B1)|
2029 P_Fld(1, B1_RXDVS0_R_RX_RANKINSEL_B1));
2030
2031#if (fcFOR_CHIP_ID == fcLaurel)
2032 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(0x1, B0_DQ9_R_DMRXDVS_RDSEL_LAT_B0 | P_Fld(0, B0_DQ9_R_DMRXDVS_VALID_LAT_B0)));
2033 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(0x1, B1_DQ9_R_DMRXDVS_RDSEL_LAT_B1) | P_Fld(0, B1_DQ9_R_DMRXDVS_VALID_LAT_B1));
2034 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD10), P_Fld(0,CA_CMD10_R_DMRXDVS_RDSEL_LAT_CA) | P_Fld(0, CA_CMD10_R_DMRXDVS_VALID_LAT_CA));
2035
2036 /* DMRXTRACK_DQM_B* (rxdly_track SM DQM enable) -> need to be set to 1 if R_DBI is on
2037 * They are shuffle regs -> move setting to DramcSetting_Olympus_LP4_ByteMode()
2038 */
2039
2040 //Enable A-PHY DVS LEAD/LAG
2041 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 0x1, B0_DQ5_RG_RX_ARDQS0_DVS_EN_B0);
2042 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 0x1, B1_DQ5_RG_RX_ARDQS0_DVS_EN_B1);
2043#else
2044 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_MISC_RXDVS2), P_Fld(0x1, MISC_RXDVS2_R_RXDVS_RDSEL_TOG_LAT)
2045 | P_Fld(0x2, MISC_RXDVS2_R_RXDVS_RDSEL_BUS_LAT));
2046 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0x0, MISC_CTRL1_R_DMDQMDBI);
2047
2048 //Enable A-PHY DVS LEAD/LAG
2049 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 0x1, B0_DQ5_RG_RX_ARDQS0_DVS_EN_B0);
2050 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 0x1, B1_DQ5_RG_RX_ARDQS0_DVS_EN_B1);
2051#endif
2052
2053 //Rx DLY tracking function CG enable
2054 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0), 0x1, B0_RXDVS0_R_RX_DLY_TRACK_CG_EN_B0);
2055 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0), 0x1, B1_RXDVS0_R_RX_DLY_TRACK_CG_EN_B1);
2056
2057 //Rx DLY tracking lead/lag counter enable
2058 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0), 0x1, B0_RXDVS0_R_RX_DLY_TRACK_ENA_B0);
2059 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0), 0x1, B1_RXDVS0_R_RX_DLY_TRACK_ENA_B1);
2060
2061 for(ii=RANK_0; ii<RANK_MAX; ii++)
2062 {
2063 vSetRank(p, ii);
2064
2065 //Rx DLY tracking update enable (HW mode)
2066 #if 0
2067 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x2, R0_B0_RXDVS2_R_RK0_DVS_MODE_B0);
2068 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x2, R0_B1_RXDVS2_R_RK0_DVS_MODE_B1);
2069
2070 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x1, R0_B0_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B0);
2071 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x1, R0_B1_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B1);
2072
2073 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2), 0x1, R0_B0_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B0);
2074 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2), 0x1, R0_B1_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B1);
2075 #else
2076 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B0_RXDVS2),
2077 P_Fld(2, R0_B0_RXDVS2_R_RK0_DVS_MODE_B0) |
2078 P_Fld(1, R0_B0_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B0)|
2079 P_Fld(1, R0_B0_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B0));
2080
2081 vIO32WriteFldMulti_All(DRAMC_REG_ADDR(DDRPHY_R0_B1_RXDVS2),
2082 P_Fld(2, R0_B1_RXDVS2_R_RK0_DVS_MODE_B1) |
2083 P_Fld(1, R0_B1_RXDVS2_R_RK0_RX_DLY_RIS_TRACK_GATE_ENA_B1)|
2084 P_Fld(1, R0_B1_RXDVS2_R_RK0_RX_DLY_FAL_TRACK_GATE_ENA_B1));
2085 #endif
2086 }
2087
2088 vSetRank(p, backup_rank);
2089
2090#if 0
2091 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_RXDVS0),0x1, B0_RXDVS0_R_RX_DLY_RK_OPT_B0);
2092 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_RXDVS0),0x1, B1_RXDVS0_R_RX_DLY_RK_OPT_B1);
2093
2094 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_HWSAVE_MODE_ENA);
2095#endif
2096
2097 vSetPHY2ChannelMapping(p, channel_bak);
2098}
2099#endif
2100
2101
2102#if SIMULATION_LP4_ZQ
2103//-------------------------------------------------------------------------
2104/** DramcZQCalibration
2105 * start Dram ZQ calibration.
2106 * @param p Pointer of context created by DramcCtxCreate.
2107 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
2108 */
2109//-------------------------------------------------------------------------
2110DRAM_STATUS_T DramcZQCalibration(DRAMC_CTX_T *p)
2111{
2112 U32 u4Response;
2113 U32 u4TimeCnt = TIME_OUT_CNT;
2114 U32 u4RegBackupAddress[] = {DRAMC_REG_ADDR(DRAMC_REG_MRS), DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)};
2115
2116 // Backup rank, CKE fix on/off, HW MIOCK control settings
2117 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
2118
2119 mcSHOW_DBG_MSG3(("[ZQCalibration]\n"));
2120 mcFPRINTF((fp_A60501, "[ZQCalibration]\n"));
2121
2122 // Disable HW MIOCK control to make CLK always on
2123 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF);
2124 mcDELAY_US(1);
2125
2126 //if CKE2RANK=1, only need to set CKEFIXON, it will apply to both rank.
2127 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
2128
2129 //Use rank swap or MRSRK to select rank
2130 //DramcRankSwap(p, p->rank);
2131 //!!R_DMMRSRK(R_DMMPCRKEN=1) specify rank0 or rank1
2132 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
2133 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN);
2134
2135 //ZQCAL Start
2136 //R_DMZQCEN, 0x1E4[4]=1 for ZQCal Start
2137 //Wait zqc_response=1 (dramc_conf_nao, 0x3b8[4])
2138 //R_DMZQCEN, 0x1E4[4]=0
2139 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_ZQCEN);
2140 do
2141 {
2142 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_ZQC_RESPONSE);
2143 u4TimeCnt --;
2144 mcDELAY_US(1); // Wait tZQCAL(min) 1us or wait next polling
2145
2146 mcSHOW_DBG_MSG3(("%d- ", u4TimeCnt));
2147 mcFPRINTF((fp_A60501, "%d- ", u4TimeCnt));
2148 }while((u4Response==0) &&(u4TimeCnt>0));
2149
2150 if(u4TimeCnt==0)//time out
2151 {
2152 vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL);
2153 mcSHOW_DBG_MSG(("ZQCAL Start fail (time out)\n"));
2154 mcFPRINTF((fp_A60501, "ZQCAL Start fail (time out)\n"));
2155 return DRAM_FAIL;
2156 }
2157 else
2158 {
2159 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_ZQCEN);
2160 }
2161
2162 // [JC] delay tZQCAL
2163 mcDELAY_US(1);
2164 u4TimeCnt = TIME_OUT_CNT;
2165
2166 //ZQCAL Latch
2167 //R_DMZQLATEN, 0x1E4[6]=1 for ZQCal latch
2168 //Wait zqlat_response=1 (dramc_conf_nao, 0x3b8[28])
2169 //R_DMZQLATEN, 0x1E4[6]=0
2170 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_ZQLATEN);
2171 do
2172 {
2173 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_ZQLAT_RESPONSE);
2174 u4TimeCnt --;
2175 mcDELAY_US(1);// Wait tZQLAT 30ns or wait next polling
2176
2177 mcSHOW_DBG_MSG3(("%d=", u4TimeCnt));
2178 mcFPRINTF((fp_A60501, "%d= ", u4TimeCnt));
2179 }while((u4Response==0) &&(u4TimeCnt>0));
2180
2181 if(u4TimeCnt==0)//time out
2182 {
2183 vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_FAIL);
2184 mcSHOW_DBG_MSG(("ZQCAL Latch fail (time out)\n"));
2185 mcFPRINTF((fp_A60501, "ZQCAL Latch fail (time out)\n"));
2186 return DRAM_FAIL;
2187 }
2188 else
2189 {
2190 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_ZQLATEN);
2191 }
2192
2193 // [JC] delay tZQLAT
2194 mcDELAY_US(1);
2195
2196 // Restore rank, CKE fix on, HW MIOCK control settings
2197 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
2198
2199 vSetCalibrationResult(p, DRAM_CALIBRATION_ZQ, DRAM_OK);
2200 mcSHOW_DBG_MSG3(("\n[DramcZQCalibration] Done\n\n"));
2201 mcFPRINTF((fp_A60501, "\n[DramcZQCalibration] Done\n\n"));
2202
2203 return DRAM_OK;
2204}
2205#endif
2206
2207#if SIMULATION_RX_INPUT_BUF
2208//-------------------------------------------------------------------------
2209/** DramcSwImpedanceCal
2210 * start TX OCD impedance calibration.
2211 * @param p Pointer of context created by DramcCtxCreate.
2212 * @param apply (U8): 0 don't apply the register we set 1 apply the register we set ,default don't apply.
2213 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
2214 */
2215//-------------------------------------------------------------------------
2216static U8 RXInputBuf_DelayExchange(S8 iOfst)
2217{
2218 U8 u1Value;
2219
2220 if(iOfst <0)
2221 {
2222 u1Value = 0x8 | (-iOfst);
2223 }
2224 else
2225 {
2226 u1Value = iOfst;
2227 }
2228
2229 return u1Value;
2230}
2231
2232// cannot be simulated in DV or DSim, it's analog feature.
2233DRAM_STATUS_T DramcRXInputBufferOffsetCal(DRAMC_CTX_T *p)
2234{
2235 U16 u2RXVrefDefault;
2236 U32 u4RegBackupAddress[] =
2237 {
2238 (DRAMC_REG_ADDR(DDRPHY_B0_DQ5)),
2239 (DRAMC_REG_ADDR(DDRPHY_B1_DQ5)),
2240 (DRAMC_REG_ADDR(DDRPHY_B0_DQ6)),
2241 (DRAMC_REG_ADDR(DDRPHY_B1_DQ6)),
2242 (DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5)),
2243 (DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5)),
2244 (DRAMC_REG_ADDR(DDRPHY_B0_DQ3)),
2245 (DRAMC_REG_ADDR(DDRPHY_B1_DQ3)),
2246 (DRAMC_REG_ADDR(DRAMC_REG_PADCTRL)),
2247 };
2248 S8 iOffset, iDQFlagChange[16], iDQMFlagChange[2];
2249 U32 u4Value, u4RestltDQ[2], u4RestltDQM[2];
2250 U8 u1BitIdx, u1ByteIdx, u1FinishCount, u1DQFinalFlagChange[16], u1DQMFinalFlagChange[2];
2251
2252 mcSHOW_DBG_MSG(("\n[RXInputBufferOffsetCal]\n"));
2253 mcFPRINTF((fp_A60501, "\n[RXInputBufferOffsetCal] \n"));
2254
2255 if(!u1IsLP4Family(p->dram_type))
2256 {
2257 //RX offset calibration(LP4 only)
2258 mcSHOW_ERR_MSG(("LP3 no need\n"));
2259 return DRAM_FAIL;
2260 }
2261
2262 //Back up dramC register
2263 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
2264
2265 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0xf, PADCTRL_FIXDQIEN);
2266
2267 //Enable BIAS (RG_RX_*RDQ*_RES_BIAS_EN_B), RG_RX_*_BIAS_PS* = 2'b01(RG mode)
2268 //Select VREF, for LPDDR4 set RG_RX_*DQ_DDR4_SEL_* =1, RG_RX_*DQ_DDR3_SEL_* =0
2269 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ6),
2270 P_Fld(1, B0_DQ6_RG_RX_ARDQ_BIAS_PS_B0) |
2271 P_Fld(1, B0_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B0) |
2272 P_Fld(0, B0_DQ6_RG_RX_ARDQ_DDR3_SEL_B0) |
2273 P_Fld(1, B0_DQ6_RG_RX_ARDQ_DDR4_SEL_B0));
2274 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ6),
2275 P_Fld(1, B1_DQ6_RG_RX_ARDQ_BIAS_PS_B1) |
2276 P_Fld(1, B1_DQ6_RG_RX_ARDQ_RES_BIAS_EN_B1) |
2277 P_Fld(0, B1_DQ6_RG_TX_ARDQ_DDR3_SEL_B1) |
2278 P_Fld(1, B1_DQ6_RG_TX_ARDQ_DDR4_SEL_B1));
2279
2280 //Enable VREF, (RG_RX_*DQ_VREF_EN_* =1)
2281 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0);
2282 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1);
2283
2284 //Set Vref voltage: LP4 with termination SEL[4:0] = 01110 (0xe) (refer to Vref default table)
2285 //Only need to set Vref with term, only K rx input offset at highest freq.
2286 //Need to set according to ODT on/off.
2287 u2RXVrefDefault = vGetRXVrefDefault(p);
2288 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), u2RXVrefDefault, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0); // LP4 and LP4x with term: 0xe
2289 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), u2RXVrefDefault, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1); // LP4 and LP4x with term: 0xe
2290
2291 // Wait 1us.
2292 mcDELAY_US(1);
2293
2294 //Enable RX input buffer (RG_RX_*DQ_IN_BUFF_EN_* =1, DA_RX_*DQ_IN_GATE_EN_* =1)
2295 //Enable RX input buffer offset calibration (RG_RX_*DQ_OFFC_EN_*=1)
2296 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0xf, PADCTRL_FIXDQIEN); // same as DA_RX_*DQ_IN_GATE_EN_*=1, Keep DQ input always ON. ==> Note: Do not enable again.
2297 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_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));
2298 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_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));
2299
2300 // SW parameter initialization
2301 u1FinishCount =0;
2302 iDQMFlagChange[0] = 0x7f;
2303 iDQMFlagChange[1] = 0x7f;
2304
2305 for(u1BitIdx=0; u1BitIdx< 16; u1BitIdx++)
2306 {
2307 iDQFlagChange[u1BitIdx] = 0x7f; //initial as invalid
2308 }
2309
2310 //Sweep RX offset calibration code (RG_RX_*DQ*_OFFC<3:0>), the MSB is sign bit, sweep the code from -7(1111) to +7(0111)
2311 for(iOffset=-7; iOffset<7; iOffset++)
2312 {
2313 u4Value = RXInputBuf_DelayExchange(iOffset);
2314
2315 #ifdef ETT_PRINT_FORMAT
2316 mcSHOW_DBG_MSG(("iOffset= %d, u4Value=%d,", iOffset, u4Value));
2317 #else
2318 mcSHOW_DBG_MSG(("iOffset= %2d, u4Value=%2d,", iOffset, u4Value));
2319 #endif
2320 mcFPRINTF((fp_A60501, "iOffset= %2d, u4Value=%2d,", iOffset, u4Value));
2321
2322 //Delay of DQM0.
2323 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ1), u4Value, B0_DQ1_RG_RX_ARDQM0_OFFC_B0);
2324 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ1), u4Value, B1_DQ1_RG_RX_ARDQM0_OFFC_B1);
2325
2326 //Delay of DQ0~DQ7.
2327 u4Value = u4Value |(u4Value<<4) |(u4Value<<8) |(u4Value<<12) |(u4Value<<16) |(u4Value<<20) |(u4Value<<24) |(u4Value<<28);
2328 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_B0_DQ0), u4Value);
2329 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_B1_DQ0), u4Value);
2330
2331 //For each code sweep, wait 0.1us to check the flag.
2332 mcDELAY_US(1);
2333
2334 //Check offset flag of DQ (RGS_*DQ*_OFFSET_FLAG_*), the value will be from 1(-7) to 0(+7). Record the value when the flag becomes "0".
2335 //Flag bit0 is for DQ0, Flag bit15 for DQ15
2336 u4RestltDQ[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_DQ), MISC_PHY_RGS_DQ_RGS_ARDQ_OFFSET_FLAG_B0);
2337 u4RestltDQ[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_DQ), MISC_PHY_RGS_DQ_RGS_ARDQ_OFFSET_FLAG_B1);
2338 u4RestltDQ[0] |= (u4RestltDQ[1] <<8);
2339
2340 mcSHOW_DBG_MSG(("RestltDQ (B1)0x%x (B0)0x%x, ", u4RestltDQ[1], u4RestltDQ[0]));
2341 mcFPRINTF((fp_A60501, "RestltDQ (B1)0x%x (B0)0x%x, ", u4RestltDQ[1], u4RestltDQ[0]));
2342
2343 for(u1BitIdx= 0; u1BitIdx <16; u1BitIdx++)
2344 {
2345 if(iDQFlagChange[u1BitIdx] == 0x7f) //invalid
2346 {
2347 u4Value = (u4RestltDQ[0] >> u1BitIdx) & 0x1;
2348
2349 if(u4Value ==0) // 1 -> 0
2350 {
2351 iDQFlagChange[u1BitIdx] = iOffset;
2352 u1FinishCount ++;
2353 }
2354 }
2355 }
2356
2357 //Check offset flag of DQM (RGS_*DQ*_OFFSET_FLAG_*), the value will be from 1(-7) to 0(+7). Record the value when the flag becomes "0".
2358 u4RestltDQM[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_DQ), MISC_PHY_RGS_DQ_RGS_ARDQM0_OFFSET_FLAG_B0);
2359 u4RestltDQM[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_DQ), MISC_PHY_RGS_DQ_RGS_ARDQM0_OFFSET_FLAG_B1);
2360
2361 mcSHOW_DBG_MSG(("RestltDQM (B1)= 0x%x, (B0)= 0x%x\n", u4RestltDQM[1], u4RestltDQM[0]));
2362 mcFPRINTF((fp_A60501, "RestltDQM (B1)= 0x%x, (B0)= 0x%x\n", u4RestltDQM[1], u4RestltDQM[0]));
2363
2364 for(u1ByteIdx= 0; u1ByteIdx <2; u1ByteIdx++)
2365 {
2366 if(iDQMFlagChange[u1ByteIdx]== 0x7f) //invalid
2367 {
2368 if(u4RestltDQM[u1ByteIdx]==0)// 1 -> 0
2369 {
2370 iDQMFlagChange[u1ByteIdx]= iOffset;
2371 u1FinishCount++;
2372 }
2373 }
2374 }
2375
2376 if(u1FinishCount==18) // (DQ8 bits, DQM 1bit, total 9 bits.) x2 bytes
2377 {
2378 break; //all bits done, early break
2379 }
2380 }
2381
2382 mcSHOW_DBG_MSG(("\nResult DQ\n"
2383 "\t0\t1\t2\t3\t4\t5\t6\t7\n"
2384 "Byte 0\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n"
2385 "Byte 1\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n"
2386 "Result DQM [0] %d, [1] %d\n",
2387 iDQFlagChange[0], iDQFlagChange[1], iDQFlagChange[2], iDQFlagChange[3],
2388 iDQFlagChange[4], iDQFlagChange[5], iDQFlagChange[6], iDQFlagChange[7],
2389 iDQFlagChange[8], iDQFlagChange[9], iDQFlagChange[10], iDQFlagChange[11],
2390 iDQFlagChange[12], iDQFlagChange[13], iDQFlagChange[14],iDQFlagChange[15],
2391 iDQMFlagChange[0], iDQMFlagChange[1]));
2392
2393 mcFPRINTF((fp_A60501,"Result DQ [0]%d [1]%d [2]%d [3]%d [4]%d [5]%d [6]%d [7]%d\n", \
2394 iDQFlagChange[0], iDQFlagChange[1], iDQFlagChange[2], iDQFlagChange[3], \
2395 iDQFlagChange[4], iDQFlagChange[5], iDQFlagChange[6],iDQFlagChange[7]));
2396
2397 mcFPRINTF((fp_A60501, "Result DQ Byte 1 [0]%d [1]%d [2]%d [3]%d [4]%d [5]%d [6]%d [7]%d\n", \
2398 iDQFlagChange[8], iDQFlagChange[9], iDQFlagChange[10], iDQFlagChange[11], \
2399 iDQFlagChange[12], iDQFlagChange[13], iDQFlagChange[14],iDQFlagChange[15]));
2400
2401 mcFPRINTF((fp_A60501, "Result DQM[0] %d, Result DQM[1] %d,\n", iDQMFlagChange[0], iDQMFlagChange[1]));
2402
2403 //Restore setting registers
2404 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
2405
2406 // Change the offset value according to register format
2407 for(u1BitIdx= 0; u1BitIdx <16; u1BitIdx++)
2408 {
2409 u1DQFinalFlagChange[u1BitIdx] = RXInputBuf_DelayExchange(iDQFlagChange[u1BitIdx]);
2410 }
2411 u1DQMFinalFlagChange[0]= RXInputBuf_DelayExchange(iDQMFlagChange[0]);
2412 u1DQMFinalFlagChange[1]= RXInputBuf_DelayExchange(iDQMFlagChange[1]);
2413
2414 //Apply the code recorded.
2415 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ1), u1DQMFinalFlagChange[0], B0_DQ1_RG_RX_ARDQM0_OFFC_B0);
2416 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ1), u1DQMFinalFlagChange[1], B1_DQ1_RG_RX_ARDQM0_OFFC_B1);
2417
2418 u4Value = u1DQFinalFlagChange[0] |(u1DQFinalFlagChange[1]<<4) |(u1DQFinalFlagChange[2]<<8) |(u1DQFinalFlagChange[3]<<12) | \
2419 (u1DQFinalFlagChange[4]<<16) |(u1DQFinalFlagChange[5]<<20) |(u1DQFinalFlagChange[6]<<24) |(u1DQFinalFlagChange[7]<<28);
2420 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_B0_DQ0), u4Value);
2421
2422 u4Value = u1DQFinalFlagChange[8] |(u1DQFinalFlagChange[9]<<4) |(u1DQFinalFlagChange[10]<<8) |(u1DQFinalFlagChange[11]<<12) | \
2423 (u1DQFinalFlagChange[12]<<16) |(u1DQFinalFlagChange[13]<<20) |(u1DQFinalFlagChange[14]<<24) |(u1DQFinalFlagChange[15]<<28);
2424 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_B1_DQ0), u4Value);
2425
2426 // Disable RX input buffer offset calibration (RG_RX_*DQ_OFFC_EN_*=0)
2427 //U32 u4AddrOfst = 0x50;
2428 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_TXDQ3+u4AddrOfst), 0, TXDQ3_RG_RX_ARDQ_OFFC_EN_B0);
2429
2430 #if 0
2431 mcSHOW_DBG_MSG(("Register DQ [0]%d [1]%d [2]%d [3]%d [4]%d [5]%d [6]%d [7]%d\n", \
2432 u1DQFinalFlagChange[0], u1DQFinalFlagChange[1], u1DQFinalFlagChange[2], u1DQFinalFlagChange[3], \
2433 u1DQFinalFlagChange[4], u1DQFinalFlagChange[5], u1DQFinalFlagChange[6],u1DQFinalFlagChange[7]));
2434 mcFPRINTF((fp_A60501,"Register DQ [0]%d [1]%d [2]%d [3]%d [4]%d [5]%d [6]%d [7]%d\n", \
2435 u1DQFinalFlagChange[0], u1DQFinalFlagChange[1], u1DQFinalFlagChange[2], u1DQFinalFlagChange[3], \
2436 u1DQFinalFlagChange[4], u1DQFinalFlagChange[5], u1DQFinalFlagChange[6],u1DQFinalFlagChange[7]));
2437 mcSHOW_DBG_MSG(("Register DQM %d\n", u1DQMFinalFlagChange));
2438 mcFPRINTF((fp_A60501, "Register DQM %d\n", u1DQMFinalFlagChange));
2439 #endif
2440 mcSHOW_DBG_MSG3(("[DramcRXInputBufferOffsetCal] Done\n"));
2441 mcFPRINTF((fp_A60501, "[DramcRXInputBufferOffsetCal] Done\n"));
2442
2443 return DRAM_OK;
2444}
2445#endif
2446
2447//-------------------------------------------------------------------------
2448/** DramcSwImpedanceCal
2449 * start TX OCD impedance calibration.
2450 * @param p Pointer of context created by DramcCtxCreate.
2451 * @param apply (U8): 0 don't apply the register we set 1 apply the register we set ,default don't apply.
2452 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
2453 */
2454//-------------------------------------------------------------------------
2455#define HYNIX_IMPX_ADJUST 0
2456#if HYNIX_IMPX_ADJUST
2457U32 ImpedanceAdjustment_Hynix(U32 u4OriValue, U8 u1Div)
2458{
2459 U32 u4RODT;
2460 U32 u4AdjustValue;
2461
2462 if(u1Div >0)
2463 {
2464 u4RODT = 240/u1Div;
2465 u4AdjustValue = 60 *(u4OriValue+2)/u4RODT -2;
2466 }
2467 else
2468 {
2469 u4RODT =0;
2470 u4AdjustValue = u4OriValue;
2471 }
2472
2473 mcSHOW_DBG_MSG(("ODTN Change by Tool, 240 div %d =%d, After adjustment ODTN=%d\n\n", u1Div, u4RODT, u4AdjustValue));
2474
2475 return u4AdjustValue;
2476}
2477#endif
2478
2479/* Impedance have a total of 19 steps, but the HW value mapping to hardware is 0~15, 29~31
2480* This function adjusts passed value u1ImpVal by adjust step count "u1AdjStepCnt"
2481* After adjustment, if value is 1. Too large (val > 31) -> set to max 31
2482* 2. Too small (val < 0) -> set to min 0
2483* 3. Value is between 15 & 29, adjust accordingly ( 15 < value < 29 )
2484* returns: Impedance value after adjustment
2485*/
2486static U32 SwImpedanceAdjust(U32 u4ImpVal, S8 s1StepCnt)
2487{
2488 S32 S4ImpedanceTemp = (S32)u4ImpVal;
2489
2490 // Perform impedance value adjustment
2491 S4ImpedanceTemp += s1StepCnt;
2492 /* After adjustment, if value is 1. Too large (val > 31) -> set to max 31
2493 * 2. Too small (val < 0) -> set to min 0
2494 * 3. Value is between 15 & 29, adjust accordingly ( 15 < value < 29 )
2495 */
2496 if ((S4ImpedanceTemp > 15) && (S4ImpedanceTemp < 29)) //Value is between 15 & 29 ( 15 < value < 29)
2497 {
2498 S4ImpedanceTemp = S4ImpedanceTemp - 16 + 29;
2499 }
2500
2501 if (S4ImpedanceTemp > 31) //Value after adjustment too large -> set to max 31
2502 {
2503 S4ImpedanceTemp = 31;
2504 }
2505 else if (S4ImpedanceTemp < 0) //Value after adjustment too small -> set to min 0
2506 {
2507 S4ImpedanceTemp = 0;
2508 }
2509
2510 return (U32)S4ImpedanceTemp;
2511}
2512
2513#if SIMULATION_SW_IMPED
2514void DramcSwImpedanceSaveRegister(DRAMC_CTX_T *p, U8 ca_term_option, U8 dq_term_option, U8 save_to_where)
2515{
2516 U8 backup_broadcast;
2517
2518 backup_broadcast = GetDramcBroadcast();
2519
2520 if(u1IsLP4Family(p->dram_type))
2521 {
2522 DramcBroadcastOnOff(DRAMC_BROADCAST_ON);
2523 //DQ
2524 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQDRVP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQDRVN2));
2525 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING2_DQDRVP1) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING2_DQDRVN1) | P_Fld((!dq_term_option), SHU1_DRVING2_DIS_IMPCAL_ODT_EN));
2526 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING3 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTP], SHU1_DRVING3_DQODTP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTN], SHU1_DRVING3_DQODTN2));
2527 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING4 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTP], SHU1_DRVING4_DQODTP1) | P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTN], SHU1_DRVING4_DQODTN1));
2528
2529 //DQS
2530 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQSDRVP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQSDRVN2));
2531 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQSDRVP1) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQSDRVN1));
2532 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING3 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTP], SHU1_DRVING3_DQSODTP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTN], SHU1_DRVING3_DQSODTN2));
2533 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING3 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTP], SHU1_DRVING3_DQSODTP) | P_Fld(gDramcSwImpedanceResule[dq_term_option][ODTN], SHU1_DRVING3_DQSODTN));
2534
2535 //CMD & CLK
2536 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVP], SHU1_DRVING2_CMDDRVP2) | P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVN], SHU1_DRVING2_CMDDRVN2));
2537 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVP], SHU1_DRVING2_CMDDRVP1) | P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVN], SHU1_DRVING2_CMDDRVN1));
2538 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING4 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][ODTP], SHU1_DRVING4_CMDODTP2) | P_Fld(gDramcSwImpedanceResule[ca_term_option][ODTN], SHU1_DRVING4_CMDODTN2));
2539 vIO32WriteFldMulti((DRAMC_REG_SHU1_DRVING4 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][ODTP], SHU1_DRVING4_CMDODTP1) | P_Fld(gDramcSwImpedanceResule[ca_term_option][ODTN], SHU1_DRVING4_CMDODTN1));
2540
2541 //RG_TX_*RCKE_DRVP/RG_TX_*RCKE_DRVN doesn't set, so set 0xA first
2542 vIO32WriteFldAlign((DDRPHY_SHU1_CA_CMD11 + save_to_where * SHU_GRP_DDRPHY_OFFSET), gDramcSwImpedanceResule[ca_term_option][DRVP], SHU1_CA_CMD11_RG_TX_ARCKE_DRVP);
2543 vIO32WriteFldAlign((DDRPHY_SHU1_CA_CMD11 + save_to_where * SHU_GRP_DDRPHY_OFFSET), gDramcSwImpedanceResule[ca_term_option][DRVN], SHU1_CA_CMD11_RG_TX_ARCKE_DRVN);
2544
2545 //CKE
2546 // CKE is full swing.
2547 // LP4/LP4X set DRVP/DRVN as LP3's default value
2548 // DRVP=8
2549 // DRVN=9
2550 //DRVP[4:0] = RG_TX_ARCMD_PU_PRE<1:0>, RG_TX_ARCLK_DRVN_PRE<2:0>
2551 vIO32WriteFldAlign((DDRPHY_SHU1_CA_CMD3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), (8>>3)&0x3, SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE);
2552 vIO32WriteFldAlign((DDRPHY_SHU1_CA_CMD0 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 8&0x7, SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE);
2553 //DRVN[4:0] = RG_ARCMD_REV<12:8>
2554 #if (fcFOR_CHIP_ID == fcLaurel)
2555 DramcBroadcastOnOff(DRAMC_BROADCAST_OFF);
2556 vIO32WriteFldAlign_All((DDRPHY_SHU1_CA_DLL1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), 9, RG_ARCMD_REV_BIT_1208_TX_CKE_DRVN);
2557 DramcBroadcastOnOff(DRAMC_BROADCAST_ON);
2558 #endif
2559
2560 }
2561#if ENABLE_LP3_SW
2562 else
2563 {
2564 //DQ
2565 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQDRVP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQDRVN2));
2566 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING2_DQDRVP1) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING2_DQDRVN1) | P_Fld((!dq_term_option), SHU1_DRVING2_DIS_IMPCAL_ODT_EN));
2567
2568 //DQS
2569 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQSDRVP2) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQSDRVN2));
2570 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING1 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVP], SHU1_DRVING1_DQSDRVP1) | P_Fld(gDramcSwImpedanceResule[dq_term_option][DRVN], SHU1_DRVING1_DQSDRVN1));
2571
2572 //CMD & CLK
2573 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVP], SHU1_DRVING2_CMDDRVP2) | P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVN], SHU1_DRVING2_CMDDRVN2));
2574 vIO32WriteFldMulti_All((DRAMC_REG_SHU1_DRVING2 + save_to_where * SHU_GRP_DRAMC_OFFSET), P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVP], SHU1_DRVING2_CMDDRVP1) | P_Fld(gDramcSwImpedanceResule[ca_term_option][DRVN], SHU1_DRVING2_CMDDRVN1));
2575
2576
2577 //CKE
2578 // CKE is full swing.
2579 // LP3 CKE DRVP/DRVN is same above
2580 //DRVP[4:0] = RG_TX_ARCMD_PU_PRE<1:0>, RG_TX_ARCLK_DRVN_PRE<2:0>
2581 vIO32WriteFldAlign_All((DDRPHY_SHU1_CA_CMD3 + save_to_where * SHU_GRP_DDRPHY_OFFSET), (gDramcSwImpedanceResule[dq_term_option][DRVP]>>3)&0x3, SHU1_CA_CMD3_RG_TX_ARCMD_PU_PRE);
2582 vIO32WriteFldAlign_All((DDRPHY_SHU1_CA_CMD0 + save_to_where * SHU_GRP_DDRPHY_OFFSET), gDramcSwImpedanceResule[dq_term_option][DRVP]&0x7, SHU1_CA_CMD0_RG_TX_ARCLK_DRVN_PRE);
2583 //DRVN[4:0] = RG_ARCMD_REV<12:8>
2584 #if (fcFOR_CHIP_ID == fcLaurel)
2585 vIO32WriteFldAlign_All((DDRPHY_SHU1_CA_DLL1 + save_to_where * SHU_GRP_DDRPHY_OFFSET), gDramcSwImpedanceResule[dq_term_option][DRVN], RG_ARCMD_REV_BIT_1208_TX_CKE_DRVN);
2586 #endif
2587 }
2588#endif /* ENABLE_LP3_SW */
2589 DramcBroadcastOnOff(backup_broadcast);
2590}
2591
2592//-------------------------------------------------------------------------
2593/** vImpCalVrefSel
2594 * Set IMP_VREF_SEL for DRVP, DRVN, Run-time/Tracking
2595 * (Refer to "IMPCAL Settings" document register "RG_RIMP_VREF_SEL" settings)
2596 * @param p Pointer of context created by DramcCtxCreate.
2597 * @param term_option (U8): pass term_option (odt_on/off) for LP4X
2598 * @param u1ImpCalStage (U8): During DRVP, DRVN, run-time/tracking stages
2599 * some vref_sel values are different
2600 */
2601//-------------------------------------------------------------------------
2602/* Definitions to make IMPCAL_VREF_SEL function more readable */
2603#define IMPCAL_STAGE_DRVP 1
2604#define IMPCAL_STAGE_DRVN 2
2605#define IMPCAL_STAGE_TRACKING 3
2606
2607/* LP3 IMP_VREF_SEL ============================== */
2608#define IMP_LP3_VREF_SEL 0x2b
2609
2610/* LP4 IMP_VREF_SEL ============================== */
2611#define IMP_LP4_VREF_SEL 0x1b
2612
2613/* LP4X IMP_VREF_SEL ============================== */
2614#define IMP_LP4X_TERM_VREF_SEL 0x1b
2615
2616/* LP4X IMP_VREF_SEL w/o term ==== */
2617#if (ENABLE_DQ3200_UNTERM == 1)
2618 #define IMP_DRVP_LP4X_UNTERM_VREF_SEL 0x3a
2619 #define IMP_DRVN_LP4X_UNTERM_VREF_SEL 0x2a
2620 #define IMP_TRACK_LP4X_UNTERM_VREF_SEL 0x3a
2621#else
2622 #define IMP_DRVP_LP4X_UNTERM_VREF_SEL 0x1a
2623 #define IMP_DRVN_LP4X_UNTERM_VREF_SEL 0x16
2624 #define IMP_TRACK_LP4X_UNTERM_VREF_SEL 0x1a
2625#endif
2626
2627/* LP4P IMP_VREF_SEL ============================== */
2628#define IMP_DRVP_LP4P_VREF_SEL 0x13
2629#define IMP_DRVN_LP4P_VREF_SEL 0xf
2630#define IMP_TRACK_LP4P_VREF_SEL 0x13
2631
2632/* Refer to "IMPCAL Settings" document register "RG_RIMP_VREF_SEL" settings */
2633static void vImpCalVrefSel(DRAMC_CTX_T *p, U8 term_option, U8 u1ImpCalStage)
2634{
2635 U8 u1RegTmpValue = 0;
2636
2637 if (p->dram_type == TYPE_LPDDR4)
2638 {
2639 u1RegTmpValue = IMP_LP4_VREF_SEL;
2640 }
2641 else if (p->dram_type == TYPE_LPDDR4X)
2642 {
2643 if (term_option == 1) // w/i term
2644 {
2645 u1RegTmpValue = IMP_LP4X_TERM_VREF_SEL;
2646 }
2647 else // w/o term
2648 {
2649 if (u1ImpCalStage == IMPCAL_STAGE_DRVP) // OCDP
2650 {
2651 u1RegTmpValue = IMP_DRVP_LP4X_UNTERM_VREF_SEL;
2652 }
2653 else if (u1ImpCalStage == IMPCAL_STAGE_DRVN) // ODTN
2654 {
2655 u1RegTmpValue = IMP_DRVN_LP4X_UNTERM_VREF_SEL;
2656 }
2657 else // IMPCAL_STAGE_TRACKING (Tracking)
2658 {
2659 u1RegTmpValue = IMP_TRACK_LP4X_UNTERM_VREF_SEL;
2660 }
2661 }
2662 }
2663 else if (p->dram_type == TYPE_LPDDR4P)
2664 {
2665 if (u1ImpCalStage == IMPCAL_STAGE_DRVP) // OCDP
2666 {
2667 u1RegTmpValue = IMP_DRVP_LP4P_VREF_SEL;
2668 }
2669 else if (u1ImpCalStage == IMPCAL_STAGE_DRVN) // OCDN
2670 {
2671 u1RegTmpValue = IMP_DRVN_LP4P_VREF_SEL;
2672 }
2673 else // IMPCAL_STAGE_TRACKING (Tracking)
2674 {
2675 u1RegTmpValue = IMP_TRACK_LP4P_VREF_SEL;
2676 }
2677 }
2678 else // TYPE_LPDDR3
2679 {
2680 u1RegTmpValue = IMP_LP3_VREF_SEL;
2681 }
2682
2683 // dbg msg after vref_sel selection
2684 mcSHOW_DBG_MSG3(("[vImpCalVrefSel] IMP_VREF_SEL 0x%x, IMPCAL stage:%u, term_option:%u\n",
2685 u1RegTmpValue, u1ImpCalStage, term_option));
2686
2687 /* Set IMP_VREF_SEL register field's value */
2688 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD11), u1RegTmpValue, SHU1_CA_CMD11_RG_RIMP_VREF_SEL); /*fra : fix single channel b */
2689
2690 return;
2691}
2692
2693DRAM_STATUS_T DramcSwImpedanceCal(DRAMC_CTX_T *p, U8 u1Para, U8 term_option)
2694{
2695 U32 u4ImpxDrv, u4ImpCalResult;
2696 U32 u4DRVP_Result =0xff,u4ODTN_Result =0xff, u4DRVN_Result =0xff;
2697 U32 u4BaklReg_DRAMC_REG_IMPCAL;
2698 U8 u1RegTmpValue;
2699 U8 backup_channel;
2700 U8 backup_broadcast;
2701
2702 backup_broadcast = GetDramcBroadcast();
2703
2704 DramcBroadcastOnOff(DRAMC_BROADCAST_OFF);
2705
2706 // Darren
2707 vIO32WriteFldMulti_All(DDRPHY_MISC_SPM_CTRL1, P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10) | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_B0)
2708 | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_B1) | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_CA));
2709
2710 vIO32WriteFldAlign_All(DDRPHY_MISC_SPM_CTRL2, 0x0, MISC_SPM_CTRL2_PHY_SPM_CTL2);
2711 vIO32WriteFldAlign_All(DDRPHY_MISC_SPM_CTRL0, 0x0, MISC_SPM_CTRL0_PHY_SPM_CTL0);
2712
2713 //Disable IMP HW Tracking
2714 //Hw Imp tracking disable for all channels Because SwImpCal will be K again when resume from DDR reserved mode
2715 vIO32WriteFldAlign_All(DRAMC_REG_IMPCAL, 0, IMPCAL_IMPCAL_HW);
2716
2717 backup_channel = p->channel;
2718
2719#if (fcFOR_PINMUX == fcLaurel)
2720 if(u1IsLP4Family(p->dram_type))
2721 {
2722 vSetPHY2ChannelMapping(p, CHANNEL_B);
2723 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL0), 0x1, MISC_CTRL0_IMPCAL_CHAB_EN);//switch to CHB
2724 }
2725 else //LP3
2726 {
2727 vSetPHY2ChannelMapping(p, CHANNEL_A);
2728 }
2729#endif
2730
2731 //Register backup
2732 //u4BaklReg_DDRPHY_MISC_IMP_CTRL0 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL0));
2733 //u4BaklReg_DDRPHY_MISC_IMP_CTRL1 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL1));
2734 u4BaklReg_DRAMC_REG_IMPCAL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL));
2735
2736 /* Set IMP_VREF_SEL value for DRVP */
2737 vImpCalVrefSel(p, term_option, IMPCAL_STAGE_DRVP);
2738
2739 if(u1IsLP4Family(p->dram_type))
2740 {
2741 //RG_IMPCAL_VREF_SEL (now set in vImpCalVrefSel())
2742 //RG_IMPCAL_LP3_EN=0, RG_IMPCAL_LP4_EN=1
2743#if 0
2744 vIO32WriteFldMulti( (DDRPHY_MISC_IMP_CTRL1), P_Fld(1, MISC_IMP_CTRL1_RG_RIMP_BIAS_EN) | \
2745 P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN) | P_Fld(1, MISC_IMP_CTRL1_RG_RIMP_VREF_EN));
2746#else
2747 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN));
2748 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), P_Fld(0, IMPCAL_IMPCAL_CALI_ENN) | P_Fld(1, IMPCAL_IMPCAL_IMPPDP) | \
2749 P_Fld(1, IMPCAL_IMPCAL_IMPPDN)); //RG_RIMP_BIAS_EN and RG_RIMP_VREF_EN move to IMPPDP and IMPPDN
2750#endif
2751 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), P_Fld(1, MISC_IMP_CTRL0_RG_IMP_EN) | \
2752 P_Fld(0, MISC_IMP_CTRL0_RG_RIMP_DDR3_SEL) | P_Fld(1, MISC_IMP_CTRL0_RG_RIMP_DDR4_SEL));
2753 }
2754#if ENABLE_LP3_SW
2755 else //LPDDR3
2756 {
2757 //RG_IMPCAL_VREF_SEL (now set in vImpCalVrefSel())
2758 //RG_IMPCAL_LP3_EN=0, RG_IMPCAL_LP4_EN=1
2759 //RG_IMPCAL_ODT_EN=0
2760#if 0
2761 vIO32WriteFldMulti((DDRPHY_MISC_IMP_CTRL1), P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_ODT_EN)| P_Fld(1, MISC_IMP_CTRL1_RG_RIMP_BIAS_EN) | \
2762 P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN) | P_Fld(1, MISC_IMP_CTRL1_RG_RIMP_VREF_EN));
2763#else
2764 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), P_Fld(0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN));
2765 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), P_Fld(0, IMPCAL_IMPCAL_CALI_ENN) | P_Fld(1, IMPCAL_IMPCAL_IMPPDP) | \
2766 P_Fld(1, IMPCAL_IMPCAL_IMPPDN)); //RG_RIMP_BIAS_EN and RG_RIMP_VREF_EN move to IMPPDP and IMPPDN, ODT_EN move to CALI_ENN
2767#endif
2768 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), P_Fld(1, MISC_IMP_CTRL0_RG_IMP_EN) | \
2769 P_Fld(1, MISC_IMP_CTRL0_RG_RIMP_DDR3_SEL) | P_Fld(0, MISC_IMP_CTRL0_RG_RIMP_DDR4_SEL));
2770
2771 #ifdef ETT_PRINT_FORMAT
2772 mcSHOW_DBG_MSG2(("0x%X=0x%X\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1))));
2773 mcSHOW_DBG_MSG2(("0x%X=0x%X\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0))));
2774 #else
2775 mcSHOW_DBG_MSG2(("0x%8x=0x%8x\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1))));
2776 mcSHOW_DBG_MSG2(("0x%8x=0x%8x\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0))));
2777 #endif
2778 }
2779#endif
2780 mcDELAY_US(1);
2781
2782 // K pull up
2783 mcSHOW_DBG_MSG2(("\n\tK DRVP\n"));
2784 mcFPRINTF((fp_A60501, "\n\tK DRVP\n"));
2785 //PUCMP_EN=1
2786 //ODT_EN=0
2787 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 1, IMPCAL_IMPCAL_CALI_EN);
2788 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 1, IMPCAL_IMPCAL_CALI_ENP); //PUCMP_EN move to CALI_ENP
2789 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 0, IMPCAL_IMPCAL_CALI_ENN); //ODT_EN move to CALI_ENN
2790 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), P_Fld(0, SHU_IMPCAL1_IMPDRVN)|P_Fld(0, SHU_IMPCAL1_IMPDRVP));
2791
2792 //DRVP=0
2793 //DRV05=1
2794#if (fcFOR_CHIP_ID == fcLaurel)
2795 if(p->dram_type == TYPE_LPDDR4)
2796 {
2797 u1RegTmpValue = 1;//LP4P_EN=0, DRV05=1
2798 }
2799 else //TYPE_LPDDR4X || TYPE_LPDDR4P
2800 {
2801 u1RegTmpValue = 0;//LP4P_EN=1, DRV05=1
2802 }
2803#endif
2804 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD11), u1RegTmpValue, SHU1_CA_CMD11_RG_RIMP_REV); /* fra : fix single channel b */
2805
2806 //OCDP Flow
2807 //If RGS_TX_OCD_IMPCALOUTX=0
2808 //RG_IMPX_DRVP++;
2809 //Else save and keep RG_IMPX_DRVP value, and assign to DRVP
2810 for(u4ImpxDrv=0; u4ImpxDrv<32; u4ImpxDrv++)
2811 {
2812 if(u4ImpxDrv==16) //0~15, 29~31
2813 u4ImpxDrv = 29;
2814 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), u4ImpxDrv, SHU_IMPCAL1_IMPDRVP);
2815 mcDELAY_US(1);
2816 u4ImpCalResult = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_CMD), MISC_PHY_RGS_CMD_RGS_RIMPCALOUT);
2817 mcSHOW_DBG_MSG2(("1. OCD DRVP=%d CALOUT=%d\n", u4ImpxDrv, u4ImpCalResult));
2818 mcFPRINTF((fp_A60501, "1. OCD DRVP=%d CALOUT=%d\n", u4ImpxDrv, u4ImpCalResult));
2819
2820 if((u4ImpCalResult ==1) && (u4DRVP_Result == 0xff))//first found
2821 {
2822 u4DRVP_Result = u4ImpxDrv;
2823 mcSHOW_DBG_MSG2(("\n1. OCD DRVP calibration OK! DRVP=%d\n\n", u4DRVP_Result));
2824 mcFPRINTF((fp_A60501, "\n1. OCD DRVP calibration OK! DRVP=%d\n\n", u4DRVP_Result));
2825 break;
2826 }
2827 }
2828
2829 //LP4: ODTN calibration, LP3: DRVN calibration
2830 mcSHOW_DBG_MSG2(("\n\n\tK ODTN\n"));
2831 mcFPRINTF((fp_A60501, "\n\tK ODTN\n"));
2832
2833
2834 /* Set IMP_VREF_SEL value for DRVN */
2835 vImpCalVrefSel(p, term_option, IMPCAL_STAGE_DRVN);
2836
2837 //PUCMP_EN=0
2838 //LPDDR4 : ODT_EN=1
2839 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 0, IMPCAL_IMPCAL_CALI_ENP); //PUCMP_EN move to CALI_ENP
2840
2841 if(p->dram_type == TYPE_LPDDR4 || p->dram_type == TYPE_LPDDR4X)
2842 {
2843 if (term_option == 1)
2844 {
2845 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 1, IMPCAL_IMPCAL_CALI_ENN); //ODT_EN move to CALI_ENN
2846 }
2847 }
2848
2849 //DRVP=DRVP_FINAL
2850 //DRVN=0
2851 //DRV05=1
2852 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), P_Fld(u4DRVP_Result, SHU_IMPCAL1_IMPDRVP) | P_Fld(0, SHU_IMPCAL1_IMPDRVN));
2853
2854#if (fcFOR_CHIP_ID == fcLaurel)
2855 if(p->dram_type == TYPE_LPDDR4)
2856 {
2857 u1RegTmpValue = 1;//LP4P_EN=0, DRV05=1
2858 }
2859 else //TYPE_LPDDR4X || TYPE_LPDDR4P
2860 {
2861 u1RegTmpValue = 3;//LP4P_EN=1, DRV05=3
2862 }
2863#endif
2864 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD11), u1RegTmpValue, SHU1_CA_CMD11_RG_RIMP_REV); /*Fra : A, B write same value to avoid dram init A broadcast to B when single CHB */
2865
2866
2867
2868 //If RGS_TX_OCD_IMPCALOUTX=1
2869 //RG_IMPX_DRVN++;
2870 //Else save RG_IMPX_DRVN value and assign to DRVN
2871 for(u4ImpxDrv=0; u4ImpxDrv<32 ; u4ImpxDrv++)
2872 {
2873 if(u4ImpxDrv==16) //0~15, 29~31
2874 u4ImpxDrv = 29;
2875
2876 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), u4ImpxDrv, SHU_IMPCAL1_IMPDRVN);
2877 mcDELAY_US(1);
2878 u4ImpCalResult = u4IO32ReadFldAlign((DDRPHY_MISC_PHY_RGS_CMD), MISC_PHY_RGS_CMD_RGS_RIMPCALOUT);
2879 mcSHOW_DBG_MSG2(("3. OCD ODTN=%d ,CALOUT=%d\n", u4ImpxDrv, u4ImpCalResult));
2880 mcFPRINTF((fp_A60501, "3. OCD ODTN=%d ,CALOUT=%d\n", u4ImpxDrv, u4ImpCalResult));
2881
2882 if((u4ImpCalResult ==0) &&(u4ODTN_Result == 0xff))//first found
2883 {
2884 u4ODTN_Result = u4ImpxDrv;
2885 mcSHOW_DBG_MSG2(("\n3. OCD ODTN calibration OK! ODTN=%d\n\n", u4ODTN_Result));
2886 mcFPRINTF((fp_A60501, "\n3. OCD ODTN calibration OK! ODTN=%d\n\n", u4ODTN_Result));
2887 break;
2888 }
2889 }
2890
2891 //Register Restore
2892 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), u4BaklReg_DRAMC_REG_IMPCAL);
2893 //vIO32Write4B((DDRPHY_MISC_IMP_CTRL0), u4BaklReg_DDRPHY_MISC_IMP_CTRL0);
2894 //vIO32Write4B((DDRPHY_MISC_IMP_CTRL1), u4BaklReg_DDRPHY_MISC_IMP_CTRL1);
2895
2896
2897/*** default value if K fail
2898 LP3: DRVP=8, DRVN=9
2899 LP4: DRVP=6, DRVN=9, ODTN=14
2900 LP4X(UT): DRVP=12, DRVN=9
2901 LP4X(T): DRVP=5, DRVN=9, ODTN=14
2902 LP4P: DRVP=8, DRVN=10
2903***/
2904 if(u1IsLP4Family(p->dram_type))
2905 {
2906#if (fcFOR_CHIP_ID == fcLaurel)
2907 u4DRVN_Result = 9; //fixed value from DE YingMin Liao
2908#endif
2909
2910 if(u4DRVP_Result==0xff)
2911 {
2912 mcFPRINTF((fp_A60501, "\n[CHIP_SCAN]1. OCD DRVP calibration FAIL! \n\n"));
2913#if (fcFOR_CHIP_ID == fcLaurel)
2914 u4DRVP_Result = 31;
2915#endif
2916 }
2917 if(u4ODTN_Result==0xff || u4DRVP_Result==0xff)
2918 {
2919 mcFPRINTF((fp_A60501, "\n[CHIP_SCAN]3. OCD ODTN calibration FAIL! \n\n"));
2920#if (fcFOR_CHIP_ID == fcLaurel)
2921 u4ODTN_Result = 31;
2922#endif
2923 }
2924
2925 mcSHOW_DBG_MSG(("[SwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result));
2926 mcFPRINTF((fp_A60501, "[SwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result));
2927
2928 #if 0//HYNIX_IMPX_ADJUST
2929 if(u1Para)
2930 {
2931 u4ODTN_Result= ImpedanceAdjustment_Hynix(u4ODTN_Result, u1Para);
2932 }
2933 #endif
2934
2935 if((p->dram_type == TYPE_LPDDR4X || p->dram_type == TYPE_LPDDR4P) && (term_option ==0))
2936 {
2937 gDramcSwImpedanceResule[term_option][DRVP] = u4DRVP_Result;
2938 gDramcSwImpedanceResule[term_option][DRVN] = u4ODTN_Result; //Justin : LP4X unterm DRVN is ODTN * 2
2939 gDramcSwImpedanceResule[term_option][ODTP] = 0;
2940 gDramcSwImpedanceResule[term_option][ODTN] = 15; //Justin : LP4X unterm, ODTN is useless
2941 }
2942 else
2943 {
2944 gDramcSwImpedanceResule[term_option][DRVP] = (u4DRVP_Result<=3) ? (u4DRVP_Result * 3) : u4DRVP_Result;
2945 gDramcSwImpedanceResule[term_option][DRVN] = (u4DRVN_Result<=3) ? (u4DRVN_Result * 3) : u4DRVN_Result;
2946 gDramcSwImpedanceResule[term_option][ODTP] = 0;
2947 gDramcSwImpedanceResule[term_option][ODTN] = (u4ODTN_Result<=3) ? (u4ODTN_Result * 3) : u4ODTN_Result;
2948 }
2949 }
2950#if ENABLE_LP3_SW
2951 else //LPDDR3
2952 {
2953 u4DRVN_Result = u4ODTN_Result;
2954 if(u4DRVN_Result==0xff || u4DRVP_Result==0xff)
2955 {
2956 u4DRVP_Result = 8;
2957 u4DRVN_Result = 9;
2958 }
2959
2960 gDramcSwImpedanceResule[term_option][DRVP] = (u4DRVP_Result<=3) ? (u4DRVP_Result * 3) : u4DRVP_Result;
2961 gDramcSwImpedanceResule[term_option][DRVN] = (u4DRVN_Result<=3) ? (u4DRVN_Result * 3) : u4DRVN_Result;
2962 gDramcSwImpedanceResule[term_option][ODTP] = 0;
2963 gDramcSwImpedanceResule[term_option][ODTN] = (u4ODTN_Result<=3) ? (u4ODTN_Result * 3) : u4ODTN_Result;
2964 }
2965#endif
2966
2967 /* Set IMP_VREF_SEL value for TRACKING/RUN-TIME */
2968 vImpCalVrefSel(p, term_option, IMPCAL_STAGE_TRACKING);
2969
2970#if RUNTIME_SHMOO_RELEATED_FUNCTION && SUPPORT_SAVE_TIME_FOR_CALIBRATION
2971 {
2972 U8 u1drv;
2973 {
2974 for (u1drv=0; u1drv<4; u1drv++)
2975 {
2976 if(p->femmc_Ready==0)
2977 p->pSavetimeData->u1SwImpedanceResule[term_option][u1drv] = gDramcSwImpedanceResule[term_option][u1drv];
2978 else
2979 gDramcSwImpedanceResule[term_option][u1drv] = p->pSavetimeData->u1SwImpedanceResule[term_option][u1drv];
2980 }
2981 }
2982 }
2983#endif
2984 mcSHOW_DBG_MSG(("term_option=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n", term_option, gDramcSwImpedanceResule[term_option][DRVP],
2985 gDramcSwImpedanceResule[term_option][DRVN], gDramcSwImpedanceResule[term_option][ODTN]));
2986
2987#if APPLY_SIGNAL_WAVEFORM_SETTINGS_ADJUST
2988 if((p->dram_type == TYPE_LPDDR4X || p->dram_type == TYPE_LPDDR4P) && (term_option ==0))
2989 {
2990 gDramcSwImpedanceResule[term_option][DRVP] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVP], gDramcSwImpedanceAdjust[term_option][DRVP]);
2991 gDramcSwImpedanceResule[term_option][DRVN] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVN], gDramcSwImpedanceAdjust[term_option][ODTN]);
2992 }
2993 else
2994 {
2995 gDramcSwImpedanceResule[term_option][DRVP] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVP], gDramcSwImpedanceAdjust[term_option][DRVP]);
2996 gDramcSwImpedanceResule[term_option][ODTN] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][ODTN], gDramcSwImpedanceAdjust[term_option][ODTN]);
2997 }
2998
2999 mcSHOW_DBG_MSG(("term_option=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d (After Adjust)\n", term_option, gDramcSwImpedanceResule[term_option][DRVP],
3000 gDramcSwImpedanceResule[term_option][DRVN], gDramcSwImpedanceResule[term_option][ODTN]));
3001#endif
3002
3003#if SIMULATION_SW_IMPED && ENABLE_LP3_SW
3004 //LP3 updates impedance parameters to shuffle "SaveRegister" here, un-term only
3005 if(p->dram_type == TYPE_LPDDR3)
3006 DramcSwImpedanceSaveRegister(p, term_option, term_option, DRAM_DFS_SHUFFLE_1);
3007#endif
3008
3009
3010#if defined(SLT)
3011 if (gDramcSwImpedanceResule[term_option][DRVP] >= 31 && (term_option ==1) ) {
3012 mcSHOW_DBG_MSG(("SLT_BIN2\n"));
3013 while(1);
3014 }
3015#endif
3016
3017
3018 vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_OK);
3019 mcSHOW_DBG_MSG3(("[DramcSwImpedanceCal] Done\n\n"));
3020 mcFPRINTF((fp_A60501, "[DramcSwImpedanceCal] Done\n\n"));
3021
3022 vSetPHY2ChannelMapping(p, backup_channel);
3023 DramcBroadcastOnOff(backup_broadcast);
3024
3025 return DRAM_OK;
3026}
3027#endif //SIMULATION_SW_IMPED
3028
3029void DramcUpdateImpedanceTerm2UnTerm(DRAMC_CTX_T *p)
3030{
3031 gDramcSwImpedanceResule[ODT_OFF][ODTP] = gDramcSwImpedanceResule[ODT_ON][ODTP];
3032 gDramcSwImpedanceResule[ODT_OFF][ODTN] = gDramcSwImpedanceResule[ODT_ON][ODTN];
3033}
3034
3035#ifdef ENABLE_HW_IMPCAL
3036DRAM_STATUS_T DramcHwImpedanceCal(DRAMC_CTX_T *p, U8 u1Para, U8 term_option)
3037{
3038 U32 u4ImpxDrv, u4ImpCalResult;
3039 U32 u4DRVP_Result =0xff,u4ODTN_Result =0xff, u4DRVN_Result =0xff;
3040 U32 u4BaklReg_DDRPHY_MISC_IMP_CTRL0, u4BaklReg_DDRPHY_MISC_IMP_CTRL1, u4BaklReg_DRAMC_REG_IMPCAL;
3041 U32 u4BaklReg_DRAMC_REG_REFCTRL0;
3042 U8 u1ByteIdx, u1RegTmpValue;
3043 U8 backup_channel;
3044 U8 backup_broadcast;
3045
3046 backup_broadcast = GetDramcBroadcast();
3047
3048 DramcBroadcastOnOff(DRAMC_BROADCAST_OFF);
3049
3050 // Darren
3051 vIO32WriteFldMulti_All(DDRPHY_MISC_SPM_CTRL1, P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10) | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_B0)
3052 | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_B1) | P_Fld(0x0, MISC_SPM_CTRL1_RG_ARDMSUS_10_CA));
3053
3054 vIO32WriteFldAlign_All(DDRPHY_MISC_SPM_CTRL2, 0x0, MISC_SPM_CTRL2_PHY_SPM_CTL2);
3055 vIO32WriteFldAlign_All(DDRPHY_MISC_SPM_CTRL0, 0x0, MISC_SPM_CTRL0_PHY_SPM_CTL0);
3056
3057 //Disable IMP HW Tracking
3058 vIO32WriteFldAlign_All(DRAMC_REG_IMPCAL, 0, IMPCAL_IMPCAL_HW);
3059
3060 backup_channel = p->channel;
3061 vSetPHY2ChannelMapping(p, CHANNEL_A);
3062
3063 //Register backup
3064 //u4BaklReg_DDRPHY_MISC_IMP_CTRL0 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL0));
3065 //u4BaklReg_DDRPHY_MISC_IMP_CTRL1 = u4IO32Read4B((DDRPHY_MISC_IMP_CTRL1));
3066 u4BaklReg_DRAMC_REG_IMPCAL = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL));
3067 u4BaklReg_DRAMC_REG_REFCTRL0 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0));
3068
3069 //enable autorefresh
3070 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 0, REFCTRL0_REFDIS); //REFDIS=0, enable autorefresh
3071
3072 //Basic setup
3073 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA2), 0x7, SHU_SELPH_CA2_TXDLY_CMD);
3074
3075 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), 0, MISC_IMP_CTRL1_RG_RIMP_PRE_EN);
3076 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), P_Fld(0, IMPCAL_IMPCAL_IMPPDP) |
3077 P_Fld(0, IMPCAL_IMPCAL_IMPPDN) |
3078 P_Fld(0, IMPCAL_IMPCAL_CALI_ENP) |
3079 P_Fld(0, IMPCAL_IMPCAL_CALI_ENN) |
3080 P_Fld(0, IMPCAL_IMPCAL_CALI_EN) |
3081 //P_Fld(0, IMPCAL_IMPCAL_DRVUPOPT) | // for Cannon project
3082 P_Fld(1, IMPCAL_IMPCAL_NEW_OLD_SL) | //Impedance tracking form, 0: old, 1:new.
3083 P_Fld(1, IMPCAL_IMPCAL_SWVALUE_EN)); //Impedance tracking DRVP, DRVN initial value from SW setting
3084
3085 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), P_Fld(0, SHU_IMPCAL1_IMPDRVP) | //Set SW calibration value & HW initial calibration value for OCDP
3086 P_Fld(3, SHU_IMPCAL1_IMPCALCNT) | //hw impcal interval (unit: the number of refresh)
3087 P_Fld(7, SHU_IMPCAL1_IMPCAL_CHKCYCLE)); //hw impcal calibration to check CMPOOUT
3088
3089 /* Set IMP_VREF_SEL value for DRVP */
3090 vImpCalVrefSel(p, term_option, IMPCAL_STAGE_DRVP);
3091
3092#if (fcFOR_CHIP_ID == fcLaurel)
3093 if(p->dram_type == TYPE_LPDDR4)
3094 {
3095 u1RegTmpValue = 1;//LP4P_EN=0, DRV05=1
3096 }
3097 else //TYPE_LPDDR4X || TYPE_LPDDR4P
3098 {
3099 u1RegTmpValue = 0;//LP4P_EN=1, DRV05=1
3100 }
3101#endif
3102 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD11), u1RegTmpValue, SHU1_CA_CMD11_RG_RIMP_REV);
3103
3104 if(u1IsLP4Family(p->dram_type))
3105 {
3106 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), P_Fld(0, MISC_IMP_CTRL0_RG_IMP_EN) | \
3107 P_Fld(0, MISC_IMP_CTRL0_RG_RIMP_DDR3_SEL) | \
3108 P_Fld(1, MISC_IMP_CTRL0_RG_RIMP_DDR4_SEL));
3109 }
3110#if ENABLE_LP3_SW
3111 else //LPDDR3
3112 {
3113 //enable auto refresh process for LP3
3114 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 1, REFCTRL0_REFDIS);
3115 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_DCMREF_OPT);
3116 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), 1, CKECTRL_CKEFIXON);
3117 //mcDELAY_US(1);
3118 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CKECTRL), 0, CKECTRL_CKEFIXON);
3119 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 1, REFCTRL0_REFFRERUN);
3120 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ACTIM3), 0x70, SHU_ACTIM3_REFCNT);
3121 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 0, REFCTRL0_REFDIS);
3122
3123 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_IMPCAL1), 0x1F, SHU_IMPCAL1_IMPDRVN);
3124 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DRVING2), 1, SHU1_DRVING2_DIS_IMPCAL_ODT_EN);
3125 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU1_DRVING1), 0x1, SHU1_DRVING1_DIS_IMP_ODTN_TRACK);
3126
3127 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), P_Fld(0, MISC_IMP_CTRL0_RG_IMP_EN) | \
3128 P_Fld(1, MISC_IMP_CTRL0_RG_RIMP_DDR3_SEL) | \
3129 P_Fld(0, MISC_IMP_CTRL0_RG_RIMP_DDR4_SEL));
3130
3131 #ifdef ETT_PRINT_FORMAT
3132 mcSHOW_DBG_MSG2(("0x%X=0x%X\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1))));
3133 mcSHOW_DBG_MSG2(("0x%X=0x%X\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0))));
3134 #else
3135 mcSHOW_DBG_MSG2(("0x%8x=0x%8x\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL1))));
3136 mcSHOW_DBG_MSG2(("0x%8x=0x%8x\n", DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_IMP_CTRL0))));
3137 #endif
3138 }
3139#endif
3140
3141 //Enable HW Imp tracking for calibration (SW impcal switch, 0: SW. 1:HW.)
3142 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 1, IMPCAL_IMPCAL_HW);
3143#if ENABLE_LP3_SW
3144 if(p->dram_type == TYPE_LPDDR3)
3145 {
3146 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), 1, IMPCAL_IMPCAL_EN); //lp3 needed
3147 }
3148#endif
3149
3150 {
3151 U8 DQ_DRVP,DQ_ODTN;
3152 int u1Dly_cnt = 0;
3153
3154 while (2000>(u1Dly_cnt++))
3155 {
3156 if(u1IsLP4Family(p->dram_type))
3157 {
3158 DQ_DRVP = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL_STATUS2), IMPCAL_STATUS2_DRVPDQ_SAVE1);
3159 DQ_ODTN = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL_STATUS2), IMPCAL_STATUS2_DRVNDQ_SAVE1);
3160 }
3161#if ENABLE_LP3_SW
3162 else
3163 {
3164 DQ_DRVP = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CMDDRV_STATUS), CMDDRV_STATUS_DRVPDQ_1);
3165 DQ_ODTN = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CMDDRV_STATUS), CMDDRV_STATUS_DRVNDQ_1);
3166 }
3167#endif
3168 if (DQ_DRVP!=0 && DQ_ODTN!=0)
3169 {
3170 u4DRVP_Result = DQ_DRVP;
3171 u4ODTN_Result = DQ_ODTN;
3172 break;
3173 }
3174 mcDELAY_US(1);
3175 }
3176 }
3177
3178 //Register Restore
3179 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_IMPCAL), u4BaklReg_DRAMC_REG_IMPCAL);
3180 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), u4BaklReg_DRAMC_REG_REFCTRL0);
3181
3182
3183/*** default value if K fail
3184 LP3: DRVP=8, DRVN=9
3185 LP4: DRVP=6, DRVN=9, ODTN=14
3186 LP4X(UT): DRVP=12, DRVN=9
3187 LP4X(T): DRVP=5, DRVN=9, ODTN=14
3188 LP4P: DRVP=8, DRVN=10
3189***/
3190 if(u1IsLP4Family(p->dram_type))
3191 {
3192#if (fcFOR_CHIP_ID == fcLaurel)
3193 u4DRVN_Result = 9; //fixed value from DE YingMin Liao
3194#endif
3195
3196 if(u4DRVP_Result==0xff)
3197 {
3198 mcFPRINTF((fp_A60501, "\n[CHIP_SCAN]1. OCD DRVP calibration FAIL! \n\n"));
3199#if (fcFOR_CHIP_ID == fcLaurel)
3200 u4DRVP_Result = 31;
3201#endif
3202 }
3203 if(u4ODTN_Result==0xff || u4DRVP_Result==0xff)
3204 {
3205 mcFPRINTF((fp_A60501, "\n[CHIP_SCAN]3. OCD ODTN calibration FAIL! \n\n"));
3206#if (fcFOR_CHIP_ID == fcLaurel)
3207 u4ODTN_Result = 31;
3208#endif
3209 }
3210
3211 mcSHOW_DBG_MSG(("[HwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result));
3212 mcFPRINTF((fp_A60501, "[HwImpedanceCal] DRVP=%d, DRVN=%d, ODTN=%d\n", u4DRVP_Result, u4DRVN_Result, u4ODTN_Result));
3213
3214 #if 0//HYNIX_IMPX_ADJUST
3215 if(u1Para)
3216 {
3217 u4ODTN_Result= ImpedanceAdjustment_Hynix(u4ODTN_Result, u1Para);
3218 }
3219 #endif
3220
3221 if((p->dram_type == TYPE_LPDDR4X || p->dram_type == TYPE_LPDDR4P) && (term_option ==0))
3222 {
3223 gDramcSwImpedanceResule[term_option][DRVP] = u4DRVP_Result;
3224 gDramcSwImpedanceResule[term_option][DRVN] = u4ODTN_Result; //Justin : LP4X unterm DRVN is ODTN * 2
3225 gDramcSwImpedanceResule[term_option][ODTP] = 0;
3226 gDramcSwImpedanceResule[term_option][ODTN] = 15; //Justin : LP4X unterm, ODTN is useless
3227 }
3228 else
3229 {
3230 gDramcSwImpedanceResule[term_option][DRVP] = (u4DRVP_Result<=3) ? (u4DRVP_Result * 3) : u4DRVP_Result;
3231 gDramcSwImpedanceResule[term_option][DRVN] = (u4DRVN_Result<=3) ? (u4DRVN_Result * 3) : u4DRVN_Result;
3232 gDramcSwImpedanceResule[term_option][ODTP] = 0;
3233 gDramcSwImpedanceResule[term_option][ODTN] = (u4ODTN_Result<=3) ? (u4ODTN_Result * 3) : u4ODTN_Result;
3234 }
3235 }
3236#if ENABLE_LP3_SW
3237 else //LPDDR3
3238 {
3239 u4DRVN_Result = u4ODTN_Result;
3240 if(u4DRVN_Result==0xff || u4DRVP_Result==0xff)
3241 {
3242 u4DRVP_Result = 8;
3243 u4DRVN_Result = 9;
3244 }
3245
3246 gDramcSwImpedanceResule[term_option][DRVP] = (u4DRVP_Result<=3) ? (u4DRVP_Result * 3) : u4DRVP_Result;
3247 gDramcSwImpedanceResule[term_option][DRVN] = (u4DRVN_Result<=3) ? (u4DRVN_Result * 3) : u4DRVN_Result;
3248 gDramcSwImpedanceResule[term_option][ODTP] = 0;
3249 gDramcSwImpedanceResule[term_option][ODTN] = (u4ODTN_Result<=3) ? (u4ODTN_Result * 3) : u4ODTN_Result;
3250 }
3251#endif
3252
3253 /* Set IMP_VREF_SEL value for TRACKING/RUN-TIME */
3254 vImpCalVrefSel(p, term_option, IMPCAL_STAGE_TRACKING);
3255
3256#if RUNTIME_SHMOO_RELEATED_FUNCTION && SUPPORT_SAVE_TIME_FOR_CALIBRATION
3257 {
3258 U8 u1drv;
3259 {
3260 for (u1drv=0; u1drv<4; u1drv++)
3261 {
3262 if(p->femmc_Ready==0)
3263 p->pSavetimeData->u1SwImpedanceResule[term_option][u1drv] = gDramcSwImpedanceResule[term_option][u1drv];
3264 else
3265 gDramcSwImpedanceResule[term_option][u1drv] = p->pSavetimeData->u1SwImpedanceResule[term_option][u1drv];
3266 }
3267 }
3268 }
3269#endif
3270 mcSHOW_DBG_MSG(("term_option=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d\n", term_option, gDramcSwImpedanceResule[term_option][0],
3271 gDramcSwImpedanceResule[term_option][1], gDramcSwImpedanceResule[term_option][ODTN]));
3272
3273#if APPLY_SIGNAL_WAVEFORM_SETTINGS_ADJUST
3274 if((p->dram_type == TYPE_LPDDR4X || p->dram_type == TYPE_LPDDR4P) && (term_option ==0))
3275 {
3276 gDramcSwImpedanceResule[term_option][DRVP] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVP], gDramcSwImpedanceAdjust[term_option][DRVP]);
3277 gDramcSwImpedanceResule[term_option][DRVN] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVN], gDramcSwImpedanceAdjust[term_option][ODTN]);
3278 }
3279 else
3280 {
3281 gDramcSwImpedanceResule[term_option][DRVP] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][DRVP], gDramcSwImpedanceAdjust[term_option][DRVP]);
3282 gDramcSwImpedanceResule[term_option][ODTN] = SwImpedanceAdjust(gDramcSwImpedanceResule[term_option][ODTN], gDramcSwImpedanceAdjust[term_option][ODTN]);
3283 }
3284
3285 mcSHOW_DBG_MSG(("term_option=%d, Reg: DRVP=%d, DRVN=%d, ODTN=%d (After Adjust)\n", term_option, gDramcSwImpedanceResule[term_option][DRVP],
3286 gDramcSwImpedanceResule[term_option][DRVN], gDramcSwImpedanceResule[term_option][ODTN]));
3287#endif
3288
3289#if SIMULATION_SW_IMPED && ENABLE_LP3_SW
3290 //LP3 updates impedance parameters to shuffle "SaveRegister" here, un-term only
3291 if(p->dram_type == TYPE_LPDDR3)
3292 DramcSwImpedanceSaveRegister(p, term_option, term_option, DRAM_DFS_SHUFFLE_1);
3293#endif
3294
3295
3296#if defined(SLT)
3297 if (gDramcSwImpedanceResule[term_option][DRVP] >= 31 && (term_option ==1) ) {
3298 mcSHOW_DBG_MSG(("SLT_BIN2\n"));
3299 while(1);
3300 }
3301#endif
3302
3303 vSetCalibrationResult(p, DRAM_CALIBRATION_SW_IMPEDANCE, DRAM_OK);
3304 mcSHOW_DBG_MSG3(("[DramcSwImpedanceCal] Done\n\n"));
3305 mcFPRINTF((fp_A60501, "[DramcSwImpedanceCal] Done\n\n"));
3306
3307 vSetPHY2ChannelMapping(p, backup_channel);
3308 DramcBroadcastOnOff(backup_broadcast);
3309
3310 return DRAM_OK;
3311}
3312#endif
3313
3314#if 0
3315void Dram_Reset(DRAMC_CTX_T *p)
3316{
3317 // This function is implemented based on DE's bring up flow for DRAMC
3318 #if !SW_CHANGE_FOR_SIMULATION
3319 if(p->dram_type == TYPE_LPDDR3)
3320 DramcModeRegInit_LP3(p);
3321 else
3322 DramcModeRegInit_LP4(p);
3323 #endif
3324
3325 ///TODO: update MR2(WL& RL) from AC timing table
3326}
3327#endif
3328
3329
3330void O1PathOnOff(DRAMC_CTX_T *p, U8 u1OnOff)
3331{
3332 U8 u1FixDQIEN = 0;
3333
3334 if (u1IsLP4Family(p->dram_type))
3335 {
3336 u1FixDQIEN = (u1OnOff == ENABLE) ? 3 : 0;
3337 vIO32WriteFldAlign_All(DRAMC_REG_PADCTRL, u1FixDQIEN, PADCTRL_FIXDQIEN);
3338
3339 vIO32WriteFldAlign_All(DDRPHY_B0_DQ5, u1OnOff, B0_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B0);
3340 vIO32WriteFldAlign_All(DDRPHY_B1_DQ5, u1OnOff, B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1);
3341 vIO32WriteFldAlign_All(DDRPHY_B0_DQ3, u1OnOff, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0);
3342 vIO32WriteFldAlign_All(DDRPHY_B1_DQ3, u1OnOff, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1);
3343 }
3344 #if ENABLE_LP3_SW
3345 else
3346 {
3347 u1FixDQIEN = (u1OnOff == ENABLE) ? 15 : 0;
3348 vIO32WriteFldAlign_All(DRAMC_REG_PADCTRL, u1FixDQIEN, PADCTRL_FIXDQIEN);
3349
3350 vIO32WriteFldAlign(DDRPHY_B1_DQ5, u1OnOff, B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1); //CHA B1
3351 vIO32WriteFldAlign(DDRPHY_B0_DQ5 + SHIFT_TO_CHB_ADDR, u1OnOff, B0_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B0); //CHB B0
3352 vIO32WriteFldAlign(DDRPHY_CA_CMD5 + SHIFT_TO_CHB_ADDR, u1OnOff, CA_CMD5_RG_RX_ARCMD_EYE_VREF_EN); //CHB CA
3353 vIO32WriteFldAlign(DDRPHY_B1_DQ5 + SHIFT_TO_CHB_ADDR, u1OnOff, B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1); //CHB B1
3354
3355 vIO32WriteFldAlign(DDRPHY_B1_DQ3, u1OnOff, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1); //CHA B1
3356 vIO32WriteFldAlign(DDRPHY_B0_DQ3 + SHIFT_TO_CHB_ADDR, u1OnOff, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0); //CHB B0
3357 vIO32WriteFldAlign(DDRPHY_CA_CMD3 + SHIFT_TO_CHB_ADDR, u1OnOff, CA_CMD3_RG_RX_ARCMD_SMT_EN); //CHB CA
3358 vIO32WriteFldAlign(DDRPHY_B1_DQ3 + SHIFT_TO_CHB_ADDR, u1OnOff, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1); //CHB B1
3359 }
3360 #endif
3361 mcDELAY_US(1);
3362}
3363
3364void CATrainingPosCal(DRAMC_CTX_T *p, U8* pu1LP3DieNum, S8* ps1CAMacroDelay, S8 *ps1CACenterDiff)
3365{
3366 U8 u1RankIdx, u1DieIdx, u1CAIdx, u1MacroIdx, u1MacroNum;
3367 S8 s1Intersect_min_byMacro[2], s1Intersect_max_byMacro[2];
3368 S8 s1Intersect_min_byBit[CATRAINING_NUM], s1Intersect_max_byBit[CATRAINING_NUM], s1CACenter_min[2];//, s1CACenter[CATRAINING_NUM];
3369 S8 s1TempFirstPass, s1TempLastPass;
3370 U8 u1PerBitDelayCellEnable =0, u1CABitNum=0;
3371 S8 s1CACenter[CATRAINING_NUM];
3372
3373 if (!u1IsLP4Family(p->dram_type))
3374 {
3375#if LP3_CA_PER_BIT
3376 u1PerBitDelayCellEnable =1;
3377#endif
3378 u1CABitNum = 10;
3379 }
3380
3381 if (u1IsLP4Family(p->dram_type))
3382 {
3383#if CA_PER_BIT_DELAY_CELL
3384 u1PerBitDelayCellEnable =1;
3385#endif
3386 u1CABitNum =6;
3387 }
3388
3389 mcSHOW_DBG_MSG(("\n[CATrainingPosCal] consider %d rank data\n", p->rank +1));
3390
3391 for(u1MacroIdx =0; u1MacroIdx <2; u1MacroIdx++)
3392 {
3393 s1Intersect_min_byMacro[u1MacroIdx] = -127; // 127
3394 s1Intersect_max_byMacro[u1MacroIdx] = 127; //-127
3395 s1CACenter_min[u1MacroIdx] = 0x7f;
3396 }
3397
3398 for(u1CAIdx=0; u1CAIdx < u1CABitNum; u1CAIdx++)
3399 {
3400 s1Intersect_min_byBit[u1CAIdx] = -127; // 127
3401 s1Intersect_max_byBit[u1CAIdx] = 127; //-127
3402
3403 if (u1IsLP4Family(p->dram_type))
3404 {
3405 u1MacroIdx=0;
3406 }
3407 else //LP3
3408 {
3409 if(u1CAIdx==0 || u1CAIdx==1)
3410 {
3411 u1MacroIdx=0;
3412 }
3413 else
3414 u1MacroIdx=1;
3415 }
3416
3417 for(u1RankIdx=RANK_0; u1RankIdx<(p->rank+1); u1RankIdx++)
3418 {
3419 for(u1DieIdx=0; u1DieIdx< pu1LP3DieNum[u1RankIdx]; u1DieIdx++)
3420 {
3421 s1TempFirstPass = iFirstCAPass[u1RankIdx][u1DieIdx][u1CAIdx];
3422 s1TempLastPass = iLastCAPass[u1RankIdx][u1DieIdx][u1CAIdx];
3423 //mcSHOW_DBG_MSG(("RK%d, Die%d ,CA%d,iFirstCAPass = %d, iLastCAPass=%d \n",u1RankIdx, u1DieIdx, u1CAIdx, s1TempFirstPass, s1TempLastPass));
3424
3425 // Intersection by Macro
3426 if(s1TempFirstPass > s1Intersect_min_byMacro[u1MacroIdx])
3427 s1Intersect_min_byMacro[u1MacroIdx] = s1TempFirstPass;
3428
3429 if(s1TempLastPass < s1Intersect_max_byMacro[u1MacroIdx])
3430 s1Intersect_max_byMacro[u1MacroIdx] = s1TempLastPass;
3431
3432 // intersection by CA bit
3433 if(s1TempFirstPass > s1Intersect_min_byBit[u1CAIdx])
3434 s1Intersect_min_byBit[u1CAIdx] = s1TempFirstPass;
3435
3436 if(s1TempLastPass < s1Intersect_max_byBit[u1CAIdx])
3437 s1Intersect_max_byBit[u1CAIdx] = s1TempLastPass;
3438 }
3439 }
3440
3441 s1CACenter[u1CAIdx] = (s1Intersect_min_byBit[u1CAIdx] +s1Intersect_max_byBit[u1CAIdx])/2;
3442
3443 if(s1CACenter[u1CAIdx] < s1CACenter_min[u1MacroIdx])
3444 s1CACenter_min[u1MacroIdx] = s1CACenter[u1CAIdx];
3445 }
3446
3447 // If CA perbit, choose min CA PI of all bits.
3448 // If CA perbyte, choose middle position of intersenction range of all bits.
3449 if(u1IsLP4Family(p->dram_type))
3450 {
3451 u1MacroNum=1;
3452 }
3453 else //LP3
3454 {
3455 u1MacroNum=2;
3456 }
3457
3458 // CA perbit enable
3459 if(u1PerBitDelayCellEnable && (p->u2DelayCellTimex100 !=0))
3460 {
3461 for(u1MacroIdx =0; u1MacroIdx<u1MacroNum; u1MacroIdx++)
3462 {
3463 #if LP3_CATRAING_SHIFT_CLK_PI
3464 if(u1IsLP4Family(p->dram_type))
3465 #endif
3466 {
3467 if(s1CACenter_min[u1MacroIdx] <0) //don't move clk
3468 {
3469 //mcSHOW_DBG_MSG(("warning : Macro%d minimum CA PI delay is %d(<0) and changed to 0\n", u1MacroIdx, s1CACenter_min[u1MacroIdx]));
3470 s1CACenter_min[u1MacroIdx] =0;
3471 }
3472 }
3473
3474 ps1CAMacroDelay[u1MacroIdx] = s1CACenter_min[u1MacroIdx];
3475 }
3476
3477 mcSHOW_DBG_MSG(("u2DelayCellTimex100 = %d/100 ps\n", p->u2DelayCellTimex100));
3478
3479 for(u1CAIdx=0; u1CAIdx < u1CABitNum; u1CAIdx++)
3480 {
3481 if(u1IsLP4Family(p->dram_type))
3482 {
3483 u1MacroIdx=0;
3484 }
3485 else //LP3
3486 {
3487 if(u1CAIdx==0 || u1CAIdx==1)
3488 {
3489 u1MacroIdx=0;
3490 }
3491 else
3492 u1MacroIdx=1;
3493 }
3494
3495
3496 #if LP3_CATRAING_SHIFT_CLK_PI
3497 if(u1IsLP4Family(p->dram_type) && s1CACenter[u1CAIdx] <0) //don't move clk
3498 #else
3499 if(s1CACenter[u1CAIdx] <0) //don't move clk
3500 #endif
3501 {
3502 s1CACenter[u1CAIdx] =0;
3503 ps1CACenterDiff[u1CAIdx]=0;
3504 }
3505 else
3506 {
3507 ps1CACenterDiff[u1CAIdx] = s1CACenter[u1CAIdx] - s1CACenter_min[u1MacroIdx];
3508 }
3509
3510 mcSHOW_DBG_MSG(("CA%d delay=%d (%d~%d),", u1CAIdx, s1CACenter[u1CAIdx], s1Intersect_min_byBit[u1CAIdx], s1Intersect_max_byBit[u1CAIdx]));
3511 mcSHOW_DBG_MSG(("Diff = %d PI ", ps1CACenterDiff[u1CAIdx]));
3512 ps1CACenterDiff[u1CAIdx] = (ps1CACenterDiff[u1CAIdx]*100000000/(p->frequency<<6))/p->u2DelayCellTimex100;
3513 mcSHOW_DBG_MSG(("(%d cell)", ps1CACenterDiff[u1CAIdx]));
3514
3515 if(ps1CACenterDiff[u1CAIdx]>15)
3516 {
3517 mcSHOW_DBG_MSG(("[WARNING] CA%d delay cell %d >15, adjust to 15 cell", u1CAIdx, ps1CACenterDiff[u1CAIdx]));
3518 ps1CACenterDiff[u1CAIdx] =15;
3519 }
3520
3521 mcSHOW_DBG_MSG(("\n"));
3522 }
3523
3524 for(u1MacroIdx =0; u1MacroIdx < u1MacroNum; u1MacroIdx++)
3525 {
3526 mcSHOW_DBG_MSG(("\nCA PerBit enable=%d, Macro%d, CA PI delay=%d\n", u1PerBitDelayCellEnable, u1MacroIdx, ps1CAMacroDelay[u1MacroIdx]));
3527 }
3528 }
3529 else //CA perbyte
3530 {
3531 for(u1MacroIdx =0; u1MacroIdx < u1MacroNum; u1MacroIdx++)
3532 {
3533 ps1CAMacroDelay[u1MacroIdx] = (s1Intersect_min_byMacro[u1MacroIdx] +s1Intersect_max_byMacro[u1MacroIdx])/2;
3534
3535 if(ps1CAMacroDelay[u1MacroIdx] <0)//don't move clk
3536 {
3537 //mcSHOW_DBG_MSG(("warning : CA PI delay is %d(<0) and changed to 0\n", ps1CAMacroDelay[u1MacroIdx]));
3538 ps1CAMacroDelay[u1MacroIdx] =0;
3539 }
3540 mcSHOW_DBG_MSG(("CA PerBit enable=%d, Macro%d, CA PI delay=%d (%d~%d)\n", u1PerBitDelayCellEnable, u1MacroIdx, ps1CAMacroDelay[u1MacroIdx], s1Intersect_min_byMacro[u1MacroIdx], s1Intersect_max_byMacro[u1MacroIdx]));
3541 }
3542 }
3543}
3544
3545#if PINMUX_AUTO_TEST_PER_BIT_CA
3546void CheckCADelayCell(DRAMC_CTX_T *p)
3547{
3548 DRAM_CHANNEL_T channel_bak = p->channel;
3549 DRAM_RANK_T rank_bak = p->rank;
3550
3551 vSetPHY2ChannelMapping(p, CHANNEL_A);
3552 vSetRank(p, RANK_0);
3553 mcSHOW_DBG_MSG(("CA_delay_cell CHA R0[%X] CHB R0[%X] CHA R1[%X] CHB R1[%X]\n",
3554 u4IO32Read4B(DDRPHY_SHU1_R0_CA_CMD0),
3555 u4IO32Read4B(DDRPHY_SHU1_R0_CA_CMD0 + SHIFT_TO_CHB_ADDR),
3556 u4IO32Read4B(DDRPHY_SHU1_R0_CA_CMD0 + 0x100),
3557 u4IO32Read4B(DDRPHY_SHU1_R0_CA_CMD0 + SHIFT_TO_CHB_ADDR + 0x100)));
3558 vSetPHY2ChannelMapping(p, channel_bak);
3559 vSetRank(p, rank_bak);
3560
3561 return;
3562}
3563
3564U16 gFinalCAPerbitFirstPass[CHANNEL_NUM][RANK_MAX][CATRAINING_NUM_LP4];
3565void CheckCAPinMux(DRAMC_CTX_T *p)
3566{
3567 U8 u1CAIndex[CATRAINING_NUM_LP4] = {0};
3568 U8 u1CAdelay[CATRAINING_NUM_LP4] = {0};
3569 int i = 0;
3570 int j = 0;
3571 U8 u1Min = 0xff;
3572 U8 u1MinIdx = 0;
3573
3574 for(i = 0; i<CATRAINING_NUM_LP4; i++)
3575 {
3576 memset(u1CAdelay, 0, sizeof(u1CAdelay));
3577 u1CAdelay[i] = 0xf;
3578
3579 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), p->rank, RKCFG_TXRANK);
3580 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX);
3581
3582 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(u1CAdelay[5], SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY)
3583 | P_Fld(u1CAdelay[4], SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY)
3584 | P_Fld(u1CAdelay[3], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY)
3585 | P_Fld(u1CAdelay[2], SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY)
3586 | P_Fld(u1CAdelay[1], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY)
3587 | P_Fld(u1CAdelay[0], SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY));
3588 CmdBusTrainingLP4(p);
3589
3590 u1Min = 0xff;
3591 for(j = 0; j<CATRAINING_NUM_LP4; j++)
3592 {
3593 if(gFinalCAPerbitFirstPass[p->channel][p->rank][j] <= u1Min)
3594 {
3595 u1Min = gFinalCAPerbitFirstPass[p->channel][p->rank][j];
3596 u1MinIdx = j;
3597 }
3598 }
3599 u1CAIndex[i] = u1MinIdx;
3600 }
3601 for(i = 0; i<CATRAINING_NUM_LP4; i++)
3602 {
3603 mcSHOW_DBG_MSG(("CH[%d] Rank[%d] APHY_CA[%d]-->DRAM(->MRR->DRAMC)[%d]\n", p->channel, p->rank, i, u1CAIndex[i]));
3604 if(u1CAIndex[i] != uiLPDDR4_CA_Mapping_POP[p->channel][i])
3605 {
3606 mcSHOW_DBG_MSG(("!Not mapping with CA mapping table\n"));
3607 while(1);
3608 }
3609 }
3610 memset(u1CAdelay, 0, sizeof(u1CAdelay));
3611 vIO32WriteFldMulti_All(DDRPHY_SHU1_R0_CA_CMD0, P_Fld(u1CAdelay[5], SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY)
3612 | P_Fld(u1CAdelay[4], SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY)
3613 | P_Fld(u1CAdelay[3], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY)
3614 | P_Fld(u1CAdelay[2], SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY)
3615 | P_Fld(u1CAdelay[1], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY)
3616 | P_Fld(u1CAdelay[0], SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY));
3617 return;
3618}
3619
3620#if ENABLE_LP3_SW
3621DRAM_STATUS_T CATrainingLP3(DRAMC_CTX_T *p);
3622int gFinalCAPerbitFirstPass_LP3[RANK_MAX][CATRAINING_NUM_LP3];
3623void CheckCAPinMux_LP3(DRAMC_CTX_T *p)
3624{
3625 U8 u1CAIndex[CATRAINING_NUM_LP3] = {0};
3626 U8 u1CAdelay[CATRAINING_NUM_LP3] = {0};
3627 int i = 0;
3628 int j = 0;
3629 int iMin = 0xff;
3630 U8 u1MinIdx = 0;
3631 int iOriFirstPass[CATRAINING_NUM_LP3] = {0};
3632
3633 CATrainingLP3(p);
3634 for(j = 0; j < CATRAINING_NUM_LP3; j++)
3635 {
3636 iOriFirstPass[j] = gFinalCAPerbitFirstPass_LP3[p->rank][j];
3637 mcSHOW_DBG_MSG(("### Ori first pass %d = [%d]\n", j, iOriFirstPass[j]));
3638 }
3639
3640 for(i = 0; i < CATRAINING_NUM_LP3; i++)
3641 {
3642 memset(u1CAdelay, 0, sizeof(u1CAdelay));
3643 u1CAdelay[i] = 0xf;
3644 mcSHOW_DBG_MSG(("### Set delay cell of CA[%d]\n", i));
3645
3646 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(u1CAdelay[0], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY) |
3647 P_Fld(u1CAdelay[1], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY));
3648 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), P_Fld(u1CAdelay[2], SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0) |
3649 P_Fld(u1CAdelay[3], SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0) |
3650 P_Fld(u1CAdelay[4], SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0) |
3651 P_Fld(u1CAdelay[5], SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0) |
3652 P_Fld(u1CAdelay[6], SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0) |
3653 P_Fld(u1CAdelay[7], SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0) |
3654 P_Fld(u1CAdelay[8], SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0) |
3655 P_Fld(u1CAdelay[9], SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0));
3656
3657 CATrainingLP3(p);
3658
3659 iMin = 0xff;
3660 for(j = 0; j < CATRAINING_NUM_LP3; j++)
3661 {
3662 //mcSHOW_DBG_MSG(("###CA[%d] ori=[%d] first_pass=[%d]\n", j, iOriFirstPass[j], gFinalCAPerbitFirstPass[p->rank][j]));
3663 if((gFinalCAPerbitFirstPass_LP3[p->rank][j] - iOriFirstPass[j]) <= iMin)
3664 {
3665 iMin = gFinalCAPerbitFirstPass_LP3[p->rank][j] - iOriFirstPass[j];
3666 u1MinIdx = j;
3667 mcSHOW_DBG_MSG(( "[%d]enter %d %d \n", j, (gFinalCAPerbitFirstPass_LP3[p->rank][j] - iOriFirstPass[j]), iMin));
3668 }
3669 }
3670 u1CAIndex[i] = u1MinIdx;
3671 //mcSHOW_DBG_MSG(("### u1CAIndex = %d\n", u1CAIndex[i]));
3672 }
3673
3674 for(i = 0; i < CATRAINING_NUM_LP3; i++)
3675 {
3676 mcSHOW_DBG_MSG(("CH[%d] Rank[%d] APHY_CA[%d]-->DRAM(->O1)[%d]\n", p->channel, p->rank, i, u1CAIndex[i]));
3677 if(u1CAIndex[i] != i)
3678 {
3679 mcSHOW_DBG_MSG(("!Not mapping with CA mapping table\n"));
3680 while(1);
3681 }
3682 }
3683
3684 memset(u1CAdelay, 0, sizeof(u1CAdelay));
3685 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(u1CAdelay[0], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY) |
3686 P_Fld(u1CAdelay[1], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY));
3687 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), P_Fld(u1CAdelay[2], SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0) |
3688 P_Fld(u1CAdelay[3], SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0) |
3689 P_Fld(u1CAdelay[4], SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0) |
3690 P_Fld(u1CAdelay[5], SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0) |
3691 P_Fld(u1CAdelay[6], SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0) |
3692 P_Fld(u1CAdelay[7], SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0) |
3693 P_Fld(u1CAdelay[8], SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0) |
3694 P_Fld(u1CAdelay[9], SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0));
3695 return;
3696}
3697#endif
3698#endif
3699
3700#if PINMUX_AUTO_TEST_PER_BIT_RX
3701U8 gRX_check_per_bit_flag = 0;
3702U8 gRX_Check_per_bit_idx = 0;
3703U16 gFinalRXPerbitWinSiz[CHANNEL_NUM][DQ_DATA_WIDTH];
3704void CheckRXDelayCell(DRAMC_CTX_T *p)
3705{
3706 int ii;
3707 for (ii = 0; ii < 4; ii++)
3708 {
3709 mcSHOW_DBG_MSG2(("#### B0[%x] B1[%x]", u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2 + ii*4)), u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2 + ii*4))));
3710 }
3711}
3712
3713
3714void SetRxPerBitDelayCellForPinMuxCheck(DRAMC_CTX_T *p, U8 U1bitIdx)
3715{
3716 U32 u4delay = 0x3f;
3717 switch(U1bitIdx)
3718 {
3719 case 0:
3720 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2),
3721 P_Fld(u4delay, SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_R_DLY_B0) |
3722 P_Fld(u4delay, SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_F_DLY_B0));//bit0
3723 break;
3724 case 1:
3725 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2),
3726 P_Fld(u4delay, SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_R_DLY_B0) |
3727 P_Fld(u4delay, SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_F_DLY_B0));//bit1
3728 break;
3729 case 2:
3730 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ3),
3731 P_Fld(u4delay, SHU1_R0_B0_DQ3_RK0_RX_ARDQ2_R_DLY_B0) |
3732 P_Fld(u4delay, SHU1_R0_B0_DQ3_RK0_RX_ARDQ2_F_DLY_B0)); //bit2
3733 break;
3734 case 3:
3735 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ3),
3736 P_Fld(u4delay, SHU1_R0_B0_DQ3_RK0_RX_ARDQ3_R_DLY_B0) |
3737 P_Fld(u4delay, SHU1_R0_B0_DQ3_RK0_RX_ARDQ3_F_DLY_B0)); //bit3
3738 break;
3739 case 4:
3740 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ4),
3741 P_Fld(0x3f, SHU1_R0_B0_DQ4_RK0_RX_ARDQ4_R_DLY_B0) |
3742 P_Fld(0x3f, SHU1_R0_B0_DQ4_RK0_RX_ARDQ4_F_DLY_B0)); //bit4
3743 break;
3744 case 5:
3745 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ4),
3746 P_Fld(u4delay, SHU1_R0_B0_DQ4_RK0_RX_ARDQ5_R_DLY_B0) |
3747 P_Fld(u4delay, SHU1_R0_B0_DQ4_RK0_RX_ARDQ5_F_DLY_B0)); //bit5
3748 break;
3749 case 6:
3750 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ5),
3751 P_Fld(u4delay, SHU1_R0_B0_DQ5_RK0_RX_ARDQ6_R_DLY_B0) |
3752 P_Fld(u4delay, SHU1_R0_B0_DQ5_RK0_RX_ARDQ6_F_DLY_B0)); //bit6
3753 break;
3754 case 7:
3755 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ5),
3756 P_Fld(u4delay, SHU1_R0_B0_DQ5_RK0_RX_ARDQ7_R_DLY_B0) |
3757 P_Fld(u4delay, SHU1_R0_B0_DQ5_RK0_RX_ARDQ7_F_DLY_B0)); //bit7
3758 break;
3759 case 8:
3760 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2),
3761 P_Fld(u4delay, SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_R_DLY_B1) |
3762 P_Fld(u4delay, SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_F_DLY_B1)); //bit8
3763 break;
3764 case 9:
3765 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2),
3766 P_Fld(u4delay, SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_R_DLY_B1) |
3767 P_Fld(u4delay, SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_F_DLY_B1)); //bit9
3768 break;
3769 case 10:
3770 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ3),
3771 P_Fld(u4delay, SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_R_DLY_B1) |
3772 P_Fld(u4delay, SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_F_DLY_B1)); //bit10
3773 break;
3774 case 11:
3775 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ3),
3776 P_Fld(u4delay, SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_R_DLY_B1) |
3777 P_Fld(u4delay, SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_F_DLY_B1)); //bit 11
3778 break;
3779 case 12:
3780 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ4),
3781 P_Fld(u4delay, SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_R_DLY_B1) |
3782 P_Fld(u4delay, SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_F_DLY_B1)); //bit 12
3783 break;
3784 case 13:
3785 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ4),
3786 P_Fld(u4delay, SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_R_DLY_B1) |
3787 P_Fld(u4delay, SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_F_DLY_B1)); //bit 13
3788 break;
3789 case 14:
3790 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ5),
3791 P_Fld(u4delay, SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_R_DLY_B1) |
3792 P_Fld(u4delay, SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_F_DLY_B1)); //bit 14
3793 break;
3794 case 15:
3795 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ5),
3796 P_Fld(u4delay, SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_R_DLY_B1) |
3797 P_Fld(u4delay, SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_F_DLY_B1)); //bit 15
3798 break;
3799 default:
3800 mcSHOW_DBG_MSG(("Not assign correct index\n"));
3801 }
3802}
3803
3804void CheckRxPinMux(DRAMC_CTX_T *p)//By view of DRAM in LP4
3805{
3806 U8 u1RxIndex[DQ_DATA_WIDTH_LP4] = {0};
3807 int i = 0;
3808 int j = 0;
3809 gRX_check_per_bit_flag = 1;
3810
3811 U16 u2Min = 0xffff;
3812 U8 u1MinIdx = 0;
3813
3814 for (i=0; i < DQ_DATA_WIDTH_LP4; i+=1)
3815 {
3816 gRX_Check_per_bit_idx = i;
3817
3818 DramcRxWindowPerbitCal(p, 0);//RDDQC
3819
3820 u2Min = 0xffff;
3821 for(j = 0; j < DQ_DATA_WIDTH_LP4; j++)
3822 {
3823 if(gFinalRXPerbitWinSiz[p->channel][j] <= u2Min)
3824 {
3825 u2Min = gFinalRXPerbitWinSiz[p->channel][j];
3826 u1MinIdx = j;
3827 }
3828 }
3829 u1RxIndex[i] = u1MinIdx;
3830 }
3831
3832 for(i = 0; i < DQ_DATA_WIDTH_LP4; i++)
3833 {
3834 mcSHOW_DBG_MSG(("CH[%d] Rank[%d] APHY_RX[%d]-->DRAMC(-->RDDQC-->O1)[%d]\n", p->channel, p->rank, i, u1RxIndex[i]));
3835 if(u1RxIndex[i] != i)
3836 {
3837 mcSHOW_DBG_MSG(("!RX APHY DRAMC DQ is not mapping directly\n"));
3838 while(1);
3839 }
3840 }
3841 gRX_check_per_bit_flag = 0;
3842 return;
3843}
3844#endif
3845
3846#if PINMUX_AUTO_TEST_PER_BIT_RX_LP3
3847U8 gRX_check_per_bit_flag = 0;
3848U8 gRX_Check_per_bit_idx = 0;
3849U16 gFinalRXPerbitWinSiz[CHANNEL_NUM][DQ_DATA_WIDTH];
3850void Set_RX_DQ_DelayLine_Phy_Byte(DRAMC_CTX_T *p, U8 u1ByteIdx, U8 value[8]);
3851void SetRxPerBitDelayCellForPinMuxCheckLp3(DRAMC_CTX_T *p, U8 U1bitIdx, S16 iDelay)
3852{
3853 DRAM_CHANNEL_T backup_channel;
3854 backup_channel = p->channel;
3855 S8 dl_value[8] = {0};
3856 U8 u1ByteIdx = U1bitIdx / 8;
3857 U8 u1BitIdxInByte = U1bitIdx % 8;
3858 int i = 0;
3859
3860 mcSHOW_DBG_MSG(("get gRX_Check_per_bit_idx: %d ==> ByteIdx: %d, BitIdx: %d\n", U1bitIdx, u1ByteIdx, u1BitIdxInByte));
3861
3862 for(i=0; i < 8; i++)
3863 {
3864 dl_value[i] = (i != u1BitIdxInByte) ? iDelay : 0x3f;//Set delay cell of specific bit to max, others keep original value
3865 }
3866
3867 Set_RX_DQ_DelayLine_Phy_Byte(p, u1ByteIdx, dl_value);//View of DRAMC
3868
3869 p->channel = backup_channel;
3870 return;
3871}
3872
3873void CheckRxPinMux(DRAMC_CTX_T *p)//By view of DRAMC in LP3
3874{
3875 U8 u1RxIndex[DQ_DATA_WIDTH] = {0};
3876 int i = 0;
3877 int j = 0;
3878 gRX_check_per_bit_flag = 1;
3879 U16 u2Min = 0xffff;
3880 U8 u1MinIdx = 0;
3881
3882 for (i=0; i < DQ_DATA_WIDTH; i+=1)
3883 {
3884 gRX_Check_per_bit_idx = i;
3885
3886 mcSHOW_DBG_MSG(("Set DQ[%d] delay cell to max\n", i));
3887 DramcRxWindowPerbitCal(p, 1);//LP3 only for TA2
3888
3889 u2Min = 0xffff;
3890 for(j = 0; j < DQ_DATA_WIDTH; j++)
3891 {
3892 if(u2Min >= gFinalRXPerbitWinSiz[p->channel][j])
3893 {
3894 u2Min = gFinalRXPerbitWinSiz[p->channel][j];
3895 u1MinIdx = j;
3896 }
3897 }
3898 u1RxIndex[i] = u1MinIdx;
3899 }
3900
3901 mcSHOW_DBG_MSG(("CH[%d] Rank[%d]\n", p->channel, p->rank));
3902 bool is_wrong = false;
3903 for(i = 0; i < DQ_DATA_WIDTH; i++)
3904 {
3905 mcSHOW_DBG_MSG(("APHY_RX[%d] by DRAMC order-->DRAMC(-->TA2)[%d] TA2_answer[%d]\n", i, u1RxIndex[i], i));
3906 if(u1RxIndex[i] != i)
3907 {
3908 if((u1GetRank(p) == RANK_0) && ((i == 9) || (i == 12)))//check pinmux table, DRAMC DQ9 = MCP DQ10; DRAMC DQ12 = MCP DQ12
3909 {
3910 mcSHOW_DBG_MSG(("!Rank0 BRCKE0 of APHY will effect DQ10 && DQ12 of MCP\n"));
3911 }
3912 else
3913 {
3914 mcSHOW_DBG_MSG(("!RX APHY DRAMC DQ is not mapping directly\n"));
3915 is_wrong = true;
3916 //Since BRCKE0 of APHY will effect DQ10 && DQ12 of MCP
3917 }
3918 }
3919
3920 }
3921 if (is_wrong == true)
3922 {
3923 while(1);
3924 }
3925
3926 gRX_check_per_bit_flag = 0;
3927 return;
3928}
3929#endif // PINMUX_AUTO_TEST_PER_BIT_RX_LP3
3930
3931#if PINMUX_AUTO_TEST_PER_BIT_TX
3932U8 gTX_check_per_bit_flag = 0;
3933U16 gFinalTXPerbitFirstPass[CHANNEL_NUM][DQ_DATA_WIDTH];
3934void CheckTxPinMux(DRAMC_CTX_T *p)
3935{
3936 U8 u1Txdelay[16] = {0};
3937 U8 u1TxIndex[16] = {0};
3938 int i = 0;
3939 int j = 0;
3940 gTX_check_per_bit_flag = 1;
3941 U16 u2Min = 0xffff;
3942 U8 u1MinIdx = 0;
3943
3944 for(i = 0; i < DQ_DATA_WIDTH_LP4; i++)
3945 {
3946 memset(u1Txdelay, 0, sizeof(u1Txdelay));
3947 u1Txdelay[i] = 0xf;
3948 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), P_Fld(u1Txdelay[7], SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0)
3949 | P_Fld(u1Txdelay[6], SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0)
3950 | P_Fld(u1Txdelay[5], SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0)
3951 | P_Fld(u1Txdelay[4], SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0)
3952 | P_Fld(u1Txdelay[3], SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0)
3953 | P_Fld(u1Txdelay[2], SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0)
3954 | P_Fld(u1Txdelay[1], SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0)
3955 | P_Fld(u1Txdelay[0], SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0));
3956 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ0), P_Fld(u1Txdelay[15], SHU1_R0_B1_DQ0_RK0_TX_ARDQ7_DLY_B1)
3957 | P_Fld(u1Txdelay[14], SHU1_R0_B1_DQ0_RK0_TX_ARDQ6_DLY_B1)
3958 | P_Fld(u1Txdelay[13], SHU1_R0_B1_DQ0_RK0_TX_ARDQ5_DLY_B1)
3959 | P_Fld(u1Txdelay[12], SHU1_R0_B1_DQ0_RK0_TX_ARDQ4_DLY_B1)
3960 | P_Fld(u1Txdelay[11], SHU1_R0_B1_DQ0_RK0_TX_ARDQ3_DLY_B1)
3961 | P_Fld(u1Txdelay[10], SHU1_R0_B1_DQ0_RK0_TX_ARDQ2_DLY_B1)
3962 | P_Fld(u1Txdelay[9], SHU1_R0_B1_DQ0_RK0_TX_ARDQ1_DLY_B1)
3963 | P_Fld(u1Txdelay[8], SHU1_R0_B1_DQ0_RK0_TX_ARDQ0_DLY_B1));
3964 DramcTxWindowPerbitCal(p, TX_DQ_DQS_MOVE_DQ_ONLY, FALSE);
3965 mcSHOW_DBG_MSG(("set 1 ranks set:0xf\n"));
3966
3967 u2Min = 0xffff;
3968 for(j = 0; j < DQ_DATA_WIDTH_LP4; j++)
3969 {
3970 if(gFinalTXPerbitFirstPass[p->channel][j] <= u2Min)
3971 {
3972 u2Min = gFinalTXPerbitFirstPass[p->channel][j];
3973 u1MinIdx = j;
3974 }
3975 }
3976 u1TxIndex[i] = u1MinIdx;
3977 }
3978
3979 for(i = 0; i < DQ_DATA_WIDTH_LP4; i++)
3980 {
3981 mcSHOW_DBG_MSG(("CH[%d] Rank[%d] APHY_TX[%d]-->DRAMC(->TA2->)[%d]\n", p->channel, p->rank, i, u1TxIndex[i]));
3982 if(u1TxIndex[i] != i)
3983 {
3984 mcSHOW_DBG_MSG(("!TX APHY DRAMC DQ is not mapping directly\n"));
3985 while(1);
3986 }
3987 }
3988 gTX_check_per_bit_flag = 0;
3989 return;
3990}
3991#endif
3992
3993void CATrainingSetPerBitDelayCell(DRAMC_CTX_T *p, S8 *ps1CACenterDiff)
3994{
3995 // Need to porting for each project according to LP3 pinmux table
3996 #if (fcFOR_CHIP_ID == fcLaurel)
3997 #if LP3_CA_PER_BIT
3998 if(!u1IsLP4Family(p->dram_type))
3999 {
4000 //DRAM CA0/1 delay cell
4001 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(ps1CACenterDiff[0], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY)|
4002 P_Fld(ps1CACenterDiff[1], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY));
4003
4004 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), P_Fld(ps1CACenterDiff[2], SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0)|
4005 P_Fld(ps1CACenterDiff[3], SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0)|
4006 P_Fld(ps1CACenterDiff[4], SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0)|
4007 P_Fld(ps1CACenterDiff[5], SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0)|
4008 P_Fld(ps1CACenterDiff[6], SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0)|
4009 P_Fld(ps1CACenterDiff[7], SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0)|
4010 P_Fld(ps1CACenterDiff[8], SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0)|
4011 P_Fld(ps1CACenterDiff[9], SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0));
4012 }
4013 #endif// end of LP3_CA_PER_BIT
4014
4015 #if CA_PER_BIT_DELAY_CELL
4016 U8 uiCA;
4017 U8 *uiLPDDR_CA_Mapping = (U8 *)uiLPDDR4_CA_Mapping_POP[p->channel];
4018
4019 if(u1IsLP4Family(p->dram_type))
4020 {
4021 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
4022 {
4023 //mcSHOW_DBG_MSG(("CA%d dly line = %d cells \n", uiLPDDR_CA_Mapping[uiCA], ps1CACenterDiff[uiCA]));
4024 #if EYESCAN_LOG
4025 gEyeScan_DelayCellPI[uiCA] = (S8) ps1CACenterDiff[uiCA];
4026 #endif
4027 }
4028
4029 // Set CA perbit delay line calibration results
4030 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[0]], SHU1_R0_CA_CMD0_RK0_TX_ARCA0_DLY) | \
4031 P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[1]], SHU1_R0_CA_CMD0_RK0_TX_ARCA1_DLY) | \
4032 P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[2]], SHU1_R0_CA_CMD0_RK0_TX_ARCA2_DLY) | \
4033 P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[3]], SHU1_R0_CA_CMD0_RK0_TX_ARCA3_DLY) | \
4034 P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[4]], SHU1_R0_CA_CMD0_RK0_TX_ARCA4_DLY) | \
4035 P_Fld(ps1CACenterDiff[uiLPDDR_CA_Mapping[5]], SHU1_R0_CA_CMD0_RK0_TX_ARCA5_DLY) );
4036 }
4037 #endif
4038 #endif
4039}
4040
4041#if ENABLE_LP3_SW
4042#if SIMULATION_LP3_CA_TRAINING
4043//-------------------------------------------------------------------------
4044/** DramcCATraining
4045 * start the calibrate the skew between Clk pin and CAx pins.
4046 * @param p Pointer of context created by DramcCtxCreate.
4047 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
4048 */
4049//-------------------------------------------------------------------------
4050#define MAX_CLKO_DELAY 31
4051
4052static DRAM_STATUS_T CATrainingEntry(DRAMC_CTX_T *p, U32 uiMR41, U32 u4GoldenPattern)
4053{
4054 //CA_TRAINING_BEGIN:
4055
4056 // CS extent enable (need DRAM to support)
4057 // for testing
4058#if CA_TRAINING_K_RANK1_ENABLE
4059 if(p->rank == RANK_1)
4060 {
4061 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), p->rank, MRS_MRSRK);
4062
4063 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), P_Fld(0, RKCFG_CS0FORCE)|P_Fld(0, RKCFG_CS2RANK)); //cannot enable before any MRW command
4064 }
4065#endif
4066
4067#if (FOR_DV_SIMULATION_USED==0)
4068 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_CATRAINCSEXT);
4069#endif
4070
4071 // CKE high, CKE must be driven HIGH prior to issuance of the MRW41 and MRW48 command
4072 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
4073
4074 // Hold the CA bus stable for at least one cycle.
4075 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_CATRAINMRS);
4076
4077 mcDELAY_US(1);
4078
4079 // Enter MR 41/MR48
4080 // Set MA & OP.
4081 if (uiMR41)
4082 {
4083 DramcModeRegWrite(p, 41, 0xa4); //MR41=0xa4 CA Training Mode enable
4084 }
4085 else
4086 {
4087 DramcModeRegWrite(p, 48, 0xc0); //MR48=0xc0 CA Training Mode enable
4088 }
4089
4090 // Disable CA bus stable.
4091 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_CATRAINMRS);
4092
4093 // Wait tCACKEL(10 tck) before CKE low
4094 mcDELAY_US(1);
4095
4096 // CKE low
4097 CKEFixOnOff(p, p->rank, CKE_FIXOFF, CKE_WRITE_TO_ONE_CHANNEL);
4098
4099 // Set CA0~CA3, CA5~CA8 rising/falling golden value.
4100 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING2), u4GoldenPattern);
4101
4102#if CA_TRAINING_K_RANK1_ENABLE
4103 if(p->rank == RANK_1)
4104 {
4105 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), P_Fld(1, RKCFG_CS0FORCE)| P_Fld(1, RKCFG_CS2RANK)); //enable to force CS switch to rank1
4106 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANK); //TXRANKFIX should be write after TXRANK or the rank will be fix at rank 1
4107 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX); //enable to switch to rank1
4108 }
4109#endif
4110
4111
4112 // Wait tCAENT(10 tck) before pattern output
4113 mcDELAY_US(1);
4114
4115 return DRAM_OK;
4116}
4117
4118
4119static S32 CheckCATrainingTransition(U32 uiCA, U32 capattern, U32 uiRisingEdge, U32 uiFallingEdge)
4120{
4121 S32 iPass=0;
4122 U32 iii;
4123
4124 if (capattern == 0x55555555)
4125 {
4126 if ((uiRisingEdge!=0) && (uiFallingEdge==0))
4127 {
4128 iPass = 1;
4129 }
4130 else
4131 {
4132 iPass = 0;
4133 }
4134 }
4135 else if (capattern == 0xaaaaaaaa)
4136 {
4137 if ((uiRisingEdge==0) && (uiFallingEdge!=0))
4138 {
4139 iPass = 1;
4140 }
4141 else
4142 {
4143 iPass = 0;
4144 }
4145 }
4146 else if (capattern == 0x99999999)
4147 {
4148 iii = uiCA;
4149 if (iii>=5) iii-=5;
4150
4151 if ((iii & 1) == 0)
4152 {
4153 if ((uiRisingEdge!=0) && (uiFallingEdge==0))
4154 {
4155 iPass = 1;
4156 }
4157 else
4158 {
4159 iPass = 0;
4160 }
4161 }
4162 else
4163 {
4164 if ((uiRisingEdge==0) && (uiFallingEdge!=0))
4165 {
4166 iPass = 1;
4167 }
4168 else
4169 {
4170 iPass = 0;
4171 }
4172 }
4173 }
4174 else if (capattern == 0x66666666)
4175 {
4176 iii = uiCA;
4177 if (iii>=5) iii-=5;
4178
4179 if ((iii & 1) == 0)
4180 {
4181 if ((uiRisingEdge==0) && (uiFallingEdge!=0))
4182 {
4183 iPass = 1;
4184 }
4185 else
4186 {
4187 iPass = 0;
4188 }
4189 }
4190 else
4191 {
4192 if ((uiRisingEdge!=0) && (uiFallingEdge==0))
4193 {
4194 iPass = 1;
4195 }
4196 else
4197 {
4198 iPass = 0;
4199 }
4200 }
4201 }
4202
4203 return iPass;
4204}
4205
4206
4207static void CATrainingExit(DRAMC_CTX_T *p)
4208{
4209#if CA_TRAINING_K_RANK1_ENABLE
4210 if(p->rank == RANK_1) //disable setting of CS and TX rank sel switch to rank1 before leaving CA training
4211 {
4212 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), P_Fld(0, RKCFG_CS0FORCE)| P_Fld(0, RKCFG_CS2RANK));
4213 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANK); //TXRANKFIX should be write after TXRANK or the rank will be fix at rank 1
4214 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANKFIX); //enable to switch to rank1
4215 }
4216#endif
4217
4218 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
4219 mcDELAY_US(1);
4220
4221 // CS extent enable
4222 // for testing
4223#if (FOR_DV_SIMULATION_USED==0)
4224 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_CATRAINCSEXT);
4225#endif
4226
4227 // Hold the CA bus stable for at least one cycle.
4228 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_CATRAINMRS);
4229
4230 mcDELAY_US(1);
4231
4232 // MR42 to leave CA training.
4233 DramcModeRegWrite(p, 42, 0xa8); //MR42=0xa8 CA Training Mode disable
4234
4235 // Disable the hold the CA bus stable for at least one cycle.
4236 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_CATRAINMRS);
4237
4238 // CS extent disable
4239 // for testing
4240#if (FOR_DV_SIMULATION_USED==0)
4241 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_CATRAINCSEXT);
4242#endif
4243}
4244
4245void CATrainingDelayCompare(DRAMC_CTX_T *p, U32 uiMR41, U32 u4GoldenPattern, U8 u1LP3DieNum, U32 delayinecompare_flag)
4246{
4247 U8 *uiLPDDR_O1_Mapping = NULL, u1DieIdx;
4248// U32 u4O1Data[DQS_NUMBER];
4249 U8 u1Offset;
4250 U32 uiTemp, uiCA, uiRisingEdge, uiFallingEdge, uiFinishCount;
4251 S32 iPass, iDelay, iDelay_Start, iDelay_End;
4252
4253 S32 iCenter[LP3_DIE_NUM_MAX][CATRAINING_NUM] = {0};
4254
4255 #if (fcFOR_CHIP_ID == fcLaurel)
4256 if(p->bDLP3)
4257 {
4258 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR3_O1_Mapping_POP_DLP3;
4259 }
4260 else
4261 #endif
4262 {
4263 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR3_O1_Mapping_POP;
4264 }
4265
4266 // Calculate the middle range & max middle.
4267 mcSHOW_DBG_MSG(("\n[CA Training]\n"));
4268 vPrintCalibrationBasicInfo(p);
4269
4270 mcFPRINTF((fp_A60501, "\n1. CA training window before adjustment.\n"));
4271 mcFPRINTF((fp_A60501, "x=Pass window CA(max~min) Clk(min~max) center. \n"));
4272 if(uiMR41)
4273 {
4274 mcSHOW_DBG_MSG(("y=CA0~CA3, CA5~8\n\n"));
4275 mcFPRINTF((fp_A60501, "y=CA0~CA3, CA5~8\n\n"));
4276 }
4277 else//MR48
4278 {
4279 mcSHOW_DBG_MSG(("y=CA4 CA9\n\n"));
4280 mcFPRINTF((fp_A60501, "y=CA4 CA9\n\n"));
4281 }
4282
4283 uiFinishCount = 0;
4284
4285 for (u1DieIdx=0; u1DieIdx<LP3_DIE_NUM_MAX; u1DieIdx++)
4286 {
4287 for (uiCA=0; uiCA<CATRAINING_NUM; uiCA++)
4288 {
4289 if(uiMR41 && ((uiCA==4) || (uiCA==9))) // MR41 is for CA0~3, CA5~8
4290 {
4291 continue;
4292 }
4293 else if((uiMR41==0) && ((uiCA!=4) && (uiCA!=9)))// MR48 is for CA4, CA9
4294 {
4295 continue;
4296 }
4297
4298 iLastCAPass[p->rank][u1DieIdx][uiCA] = CATRAINING_PASS_RANGE_NA;
4299 iFirstCAPass[p->rank][u1DieIdx][uiCA] = CATRAINING_PASS_RANGE_NA;
4300 }
4301 }
4302
4303 if (delayinecompare_flag == 0)
4304 {
4305#if (fcFOR_PINMUX == fcLaurel)
4306 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), 0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD); //CA0~1 CA_PI_Delay
4307 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0); //CA2~9 CA_PI_Delay
4308#endif
4309 }
4310
4311 if (delayinecompare_flag == 0)
4312 {
4313 iDelay_Start = -(MAX_CLK_PI_DELAY/2);
4314 /* [Justin May 19, 2017 7:13 PM]SW modification is required if the final CMD/CS PI code=32~63
4315 HW bug: LP3 CA/CS delay cannot >31 PI. if larger than 31PI, use UI instead.
4316 The problem will be fixed in Cannon and can change iDelay_End back to 63 */
4317 iDelay_End = MAX_CA_PI_DELAY;
4318 }
4319 else
4320 {
4321 iDelay_Start = 0;
4322 iDelay_End = MAX_CLK_PI_DELAY;
4323 }
4324
4325 // Delay clock output delay to do CA training in order to get the pass window.
4326 for (iDelay= iDelay_Start; iDelay <= iDelay_End; iDelay++)
4327 {
4328 if (delayinecompare_flag == 0)
4329 {
4330 if(iDelay <=0)
4331 { //Set CLK delay
4332 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), -iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK); //clock_PI_Delay
4333 }
4334 else
4335 { // Set CA output delay
4336#if (fcFOR_PINMUX == fcLaurel)
4337 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD); //CA0~1 CA_PI_Delay
4338 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), iDelay, SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0); //CA2~9 CA_PI_Delay
4339#endif
4340 }
4341 }
4342 else
4343 {
4344 // set CLK PI value
4345 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK); //clock_PI_Delay
4346 }
4347
4348 // CA training pattern output enable
4349 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_CATRAINEN);
4350 // delay 2 DRAM clock cycle
4351 mcDELAY_US(1);
4352 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_CATRAINEN);
4353
4354
4355 // Wait tADR(20ns) before CA sampled values available in DQ.
4356 mcDELAY_US(1);
4357
4358 // Get DQ value.
4359 uiTemp = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_DQO1));
4360
4361 #ifdef ETT_PRINT_FORMAT
4362 mcSHOW_DBG_MSG3(("%d, DQ_O1 0x%x| ", iDelay, uiTemp));
4363 #else
4364 mcSHOW_DBG_MSG3(("delay %3d, DQ_O1 0x%8x| Pass ", iDelay, uiTemp));
4365 #endif
4366 mcFPRINTF((fp_A60501, "delay %3d, DQ_O1 0x%8x| Pass ", iDelay, uiTemp));
4367
4368 // Compare with golden value.
4369 for (u1DieIdx=0; u1DieIdx<u1LP3DieNum; u1DieIdx++)
4370 {
4371 if(u1LP3DieNum>1)
4372 {
4373 mcSHOW_DBG_MSG3(("|D%d ",u1DieIdx));
4374 }
4375
4376 for (uiCA=0; uiCA<CATRAINING_NUM; uiCA++)
4377 {
4378 if(uiMR41 && ((uiCA==4) || (uiCA==9))) // MR41 is for CA0~3, CA5~8
4379 {
4380 continue;
4381 }
4382 else if((uiMR41==0) && ((uiCA!=4) && (uiCA!=9)))// MR48 is for CA4, CA8
4383 {
4384 continue;
4385 }
4386
4387 u1Offset = 16 * u1DieIdx;
4388 //if ( (iFirstCAPass[p->rank][u1DieIdx][uiCA]==CATRAINING_PASS_RANGE_NA) || (iLastCAPass[p->rank][u1DieIdx][uiCA]==CATRAINING_PASS_RANGE_NA)) //marked fo debug
4389 {
4390 if (uiCA<4) //CA0~3
4391 {
4392 uiRisingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[(uiCA << 1) + u1Offset]));
4393 uiFallingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[(uiCA << 1) + 1 + u1Offset]));
4394 }
4395 else if((uiCA==4) || (uiCA==9))
4396 {
4397 uiRisingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[(uiCA == 4) ? 0 + u1Offset: 8 + u1Offset]));
4398 uiFallingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[(uiCA == 4) ? 1 + u1Offset : 9 + u1Offset]));
4399 }
4400 else//CA5~8
4401 {
4402 uiRisingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[((uiCA - 1) << 1) + u1Offset]));
4403 uiFallingEdge = uiTemp & ((0x01 << uiLPDDR_O1_Mapping[((uiCA - 1) << 1) + 1 + u1Offset]));
4404 }
4405
4406 iPass = CheckCATrainingTransition(uiCA, u4GoldenPattern, uiRisingEdge, uiFallingEdge);
4407 mcSHOW_DBG_MSG3(("%d ", iPass));
4408 mcFPRINTF((fp_A60501, "%d ", iPass));
4409
4410 if (iFirstCAPass[p->rank][u1DieIdx][uiCA]==CATRAINING_PASS_RANGE_NA)
4411 {
4412 if (iPass == 1)
4413 {
4414 iFirstCAPass[p->rank][u1DieIdx][uiCA] = iDelay;
4415 }
4416 }
4417 else
4418 {
4419 if (iLastCAPass[p->rank][u1DieIdx][uiCA]==CATRAINING_PASS_RANGE_NA)
4420 {
4421 if (iPass == 0)
4422 {
4423 if((iDelay-iFirstCAPass[p->rank][u1DieIdx][uiCA]) < 8) // prevent glitch
4424 {
4425 iFirstCAPass[p->rank][u1DieIdx][uiCA]=CATRAINING_PASS_RANGE_NA;
4426 continue;
4427 }
4428
4429 uiFinishCount++;
4430 iLastCAPass[p->rank][u1DieIdx][uiCA] = iDelay-1;
4431
4432 iCenter[u1DieIdx][uiCA] = (iLastCAPass[p->rank][u1DieIdx][uiCA] + iFirstCAPass[p->rank][u1DieIdx][uiCA]) >>1;
4433 }
4434 else
4435 {
4436 if (iDelay==MAX_CA_PI_DELAY)
4437 {
4438 uiFinishCount++;
4439 iLastCAPass[p->rank][u1DieIdx][uiCA] = iDelay;
4440
4441 iCenter[u1DieIdx][uiCA] = (iLastCAPass[p->rank][u1DieIdx][uiCA] + iFirstCAPass[p->rank][u1DieIdx][uiCA]) >>1;
4442 }
4443 }
4444 }
4445 }
4446 }
4447 }
4448 }
4449
4450 // Wait tCACD(22clk) before output CA pattern to DDR again..
4451 mcDELAY_US(1);
4452
4453 mcSHOW_DBG_MSG3(("\n"));
4454 mcFPRINTF((fp_A60501, "\n"));
4455
4456 if((uiMR41 && (uiFinishCount==(8*u1LP3DieNum))) || ((uiMR41==0) && (uiFinishCount==(2*u1LP3DieNum))))
4457 {
4458 mcSHOW_DBG_MSG(("Early break, MR41=%d FinishCount=%d\n", uiMR41, uiFinishCount));
4459 mcFPRINTF((fp_A60501, "Early break, uiMR41=%d\n", uiMR41));
4460 break;
4461 }
4462 }
4463
4464
4465 vSetCalibrationResult(p, DRAM_CALIBRATION_CA_TRAIN, DRAM_OK); // set default result OK, udpate status when per bit fail
4466
4467 if (delayinecompare_flag == 1)
4468 {
4469 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), 0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK);
4470 }
4471
4472 for(u1DieIdx=0; u1DieIdx<u1LP3DieNum; u1DieIdx++)
4473 {
4474 for (uiCA=0; uiCA<CATRAINING_NUM; uiCA++)
4475 {
4476 if(uiMR41 && ((uiCA==4) || (uiCA==9))) // MR41 is for CA0~3, CA5~8
4477 {
4478 continue;
4479 }
4480 else if((uiMR41==0) && ((uiCA!=4) && (uiCA!=9)))// MR48 is for CA4, CA9
4481 {
4482 continue;
4483 }
4484
4485 #ifdef FOR_HQA_TEST_USED
4486 gFinalCBTCA[p->channel][p->rank][uiCA] = (iLastCAPass[p->rank][u1DieIdx][uiCA] - iFirstCAPass[p->rank][u1DieIdx][uiCA])+(iLastCAPass[p->rank][u1DieIdx][uiCA]==iFirstCAPass[p->rank][u1DieIdx][uiCA]?0:1);
4487 #endif
4488 #if PINMUX_AUTO_TEST_PER_BIT_CA
4489 gFinalCAPerbitFirstPass_LP3[p->rank][uiCA] = iFirstCAPass[p->rank][0][uiCA];//only use die0
4490 #endif
4491
4492 if(u1LP3DieNum ==1)
4493 {
4494 #ifdef ETT_PRINT_FORMAT
4495 mcSHOW_DBG_MSG(("CA%d (%d~%d) %d,\n", uiCA, iFirstCAPass[p->rank][u1DieIdx][uiCA], iLastCAPass[p->rank][u1DieIdx][uiCA], iCenter[u1DieIdx][uiCA]));
4496 #else
4497 mcSHOW_DBG_MSG(("CA%3d Pass(%3d~%3d) Center %3d,\n", uiCA, iFirstCAPass[p->rank][u1DieIdx][uiCA], iLastCAPass[p->rank][u1DieIdx][uiCA], iCenter[u1DieIdx][uiCA]));
4498 #endif
4499 mcFPRINTF((fp_A60501, "CA%4d Pass(%3d~%3d) Center %3d,\n", uiCA, iFirstCAPass[p->rank][u1DieIdx][uiCA], iLastCAPass[p->rank][u1DieIdx][uiCA], iCenter[u1DieIdx][uiCA]));
4500 }
4501
4502 if(iLastCAPass[p->rank][u1DieIdx][uiCA]==CATRAINING_PASS_RANGE_NA) // no CA window found
4503 {
4504 vSetCalibrationResult(p, DRAM_CALIBRATION_CA_TRAIN, DRAM_FAIL);
4505 }
4506 }
4507 }
4508
4509
4510 if(u1LP3DieNum>1)
4511 {
4512 for (uiCA=0; uiCA<CATRAINING_NUM; uiCA++)
4513 {
4514 if(uiMR41 && ((uiCA==4) || (uiCA==9))) // MR41 is for CA0~3, CA5~8
4515 {
4516 continue;
4517 }
4518 else if((uiMR41==0) && ((uiCA!=4) && (uiCA!=9)))// MR48 is for CA4, CA9
4519 {
4520 continue;
4521 }
4522
4523 mcSHOW_DBG_MSG(("CA%d |D0 (%d~%d) %d |D1 (%d~%d) %d\n", uiCA, iFirstCAPass[p->rank][0][uiCA], iLastCAPass[p->rank][0][uiCA], iCenter[0][uiCA], \
4524 iFirstCAPass[p->rank][1][uiCA], iLastCAPass[p->rank][1][uiCA], iCenter[1][uiCA]));
4525 }
4526 }
4527
4528 // CS extent disable
4529 // for testing
4530#if (FOR_DV_SIMULATION_USED==0)
4531 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_CATRAINCSEXT);
4532#endif
4533
4534 // Wait tCACKEN (10ck)
4535 mcDELAY_US(1);
4536
4537 if((uiMR41 && (uiFinishCount<8)) || ((uiMR41==0) && (uiFinishCount<2)))
4538 {
4539 mcSHOW_DBG_MSG(("Error: some bits have abnormal window, uiMR41=%d, FinishCount=%d\n", uiMR41, uiFinishCount));
4540 mcFPRINTF((fp_A60501, "Error: some bits have abnormal window, uiMR41=%d, FinishCount=%d\n", uiMR41, uiFinishCount));
4541 }
4542}
4543
4544DRAM_STATUS_T CATrainingLP3(DRAMC_CTX_T *p)
4545{
4546 U32 uiMR41;
4547 U32 u4RegBackupAddress[] =
4548 {
4549 (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)),
4550 (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)),
4551 (DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL)),
4552 (DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)),
4553 (DRAMC_REG_ADDR(DRAMC_REG_MRS)),
4554 };
4555 S8 iFinalCACLK[2];
4556 S8 s1CACenterDiff[CATRAINING_NUM]={0}; //for LP3_CA_PER_BIT
4557 U32 module_i;
4558 U8 backup_rank, rank_i;
4559
4560#if LP3_CATRAING_SHIFT_CLK_PI
4561 U8 u1CLK_Shift_PI = 0;
4562#endif
4563
4564 // 01010101b -> 10101010b : Golden value = 1001100110011001b=0x9999
4565 // 11111111b -> 00000000b : Golden value = 0101010101010101b=0x5555
4566 U32 u4GoldenPattern =0x55555555;
4567 //U32 u4GoldenPattern =0xA6AAA6AA;
4568
4569 backup_rank = u1GetRank(p);
4570
4571 mcSHOW_DBG_MSG(("\n[CATrainingLP3]\n"));
4572 mcFPRINTF((fp_A60501, "\n[CATrainingLP3]\n"));
4573 #if MRW_CHECK_ONLY
4574 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
4575 #endif
4576
4577 if(p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
4578 gu1LP3DieNum[p->rank] =2;
4579 else
4580 gu1LP3DieNum[p->rank] =1;
4581
4582 // Fix ODT off. A60501 disable ODT in the init code. So no need to do the following code.
4583 //uiReg54h=u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WODT), WODT_WODTFIXOFF);
4584 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WODT), 1, WODT_WODTFIXOFF);// According to Derping, should set to 1 to disable ODT.
4585
4586 // Let MIO_CK always ON.
4587 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
4588
4589 vAutoRefreshSwitch(p, DISABLE); //When doing CA training, should make sure that auto refresh is disable
4590
4591 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF); //MIOCKCTRLOFF=1
4592 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_PHYCLKDYNGEN); // set R_DMPHYCLKDYNGEN=0
4593
4594
4595#ifdef CA_LAG_CK
4596 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA2) - 1, SHU_SELPH_CA7_DLY_RA2);
4597 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA3) - 1, SHU_SELPH_CA7_DLY_RA3);
4598 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA4) - 1, SHU_SELPH_CA7_DLY_RA4);
4599 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA5) - 1, SHU_SELPH_CA7_DLY_RA5);
4600 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA6) - 1, SHU_SELPH_CA7_DLY_RA6);
4601 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA7), SHU_SELPH_CA7_DLY_RA7) - 1, SHU_SELPH_CA7_DLY_RA7);
4602 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA8), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA8), SHU_SELPH_CA8_DLY_RA8) - 1, SHU_SELPH_CA8_DLY_RA8);
4603 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA8), u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_CA8), SHU_SELPH_CA8_DLY_RA9) - 1, SHU_SELPH_CA8_DLY_RA9);
4604#endif
4605
4606#if LP3_CA_PER_BIT
4607 CATrainingSetPerBitDelayCell(p, s1CACenterDiff); //reset delay to 0
4608#endif
4609
4610
4611 // Step 1.1 : let IO to O1 path valid
4612 O1PathOnOff(p, 1);
4613
4614 // ----- MR41, CA0~3, CA5~8 -------
4615 uiMR41 = 1;
4616 CATrainingEntry(p, uiMR41, u4GoldenPattern); //MR41
4617 CATrainingDelayCompare(p, uiMR41, u4GoldenPattern, gu1LP3DieNum[p->rank], 0);
4618
4619 // ----- MR48, CA4 and 9 -------
4620 uiMR41 = 0;
4621 CATrainingEntry(p, uiMR41, u4GoldenPattern); //MR48
4622 CATrainingDelayCompare(p, uiMR41, u4GoldenPattern, gu1LP3DieNum[p->rank], 0);
4623
4624 CATrainingPosCal(p, gu1LP3DieNum, iFinalCACLK, s1CACenterDiff);
4625
4626#if LP3_CATRAING_SHIFT_CLK_PI
4627 if((iFinalCACLK[0] <-LP3_CATRAING_SHIFT_CLK_PI) || (iFinalCACLK[1] <-LP3_CATRAING_SHIFT_CLK_PI))
4628 {
4629 u1CLK_Shift_PI = LP3_CATRAING_SHIFT_CLK_PI <<1; // if delay <-8, CLK += 16
4630 }
4631 else if((iFinalCACLK[0] <0) || (iFinalCACLK[1] <0))
4632 {
4633 u1CLK_Shift_PI = LP3_CATRAING_SHIFT_CLK_PI ; // if delay <0, CLK += 8
4634 }
4635 else
4636 u1CLK_Shift_PI = 0;
4637
4638
4639 if(u1CLK_Shift_PI >0)
4640 {
4641 mcSHOW_ERR_MSG(("\n\n[WARNING] CA Center < 0, CLK shif +%d PI\n", u1CLK_Shift_PI));
4642 mcSHOW_ERR_MSG(("Origin CA min0 = %d, CA min1 = %d\n\n", iFinalCACLK[0], iFinalCACLK[1]));
4643
4644 iFinalCACLK[0] += u1CLK_Shift_PI;
4645 iFinalCACLK[1] += u1CLK_Shift_PI;
4646
4647 mcSHOW_ERR_MSG(("Updated min0 = %d, CA min1 = %d\n\n", iFinalCACLK[0], iFinalCACLK[1]));
4648 }
4649#endif
4650
4651 for(module_i=0; module_i<2; module_i++)
4652 {
4653 if(iFinalCACLK[module_i] <0) //don't move clk
4654 {
4655 mcSHOW_DBG_MSG(("warning : Macro%d minimum CA PI delay is %d(<0) and changed to 0\n", module_i, iFinalCACLK[module_i]));
4656 iFinalCACLK[module_i] =0;
4657 }
4658 }
4659
4660
4661 #ifdef ETT_PRINT_FORMAT
4662 mcSHOW_DBG_MSG(("\nGoldenPattern 0x%X\n", u4GoldenPattern));
4663 #else
4664 mcSHOW_DBG_MSG(("\nGoldenPattern 0x%x\n", u4GoldenPattern));
4665 #endif
4666
4667 #if REG_SHUFFLE_REG_CHECK
4668 ShuffleRegCheck =1;
4669 #endif
4670
4671 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
4672 for(rank_i=RANK_0; rank_i<backup_rank+1; rank_i++)
4673 {
4674 // no need to enter self refresh before setting CLK under CA training mode
4675 #if LP3_CATRAING_SHIFT_CLK_PI
4676 CATrain_ClkDelay[p->channel][rank_i] = u1CLK_Shift_PI;
4677 CATrain_CsDelay[p->channel][rank_i] = u1CLK_Shift_PI;
4678 #else
4679 CATrain_ClkDelay[p->channel][rank_i] = 0;
4680 CATrain_CsDelay[p->channel][rank_i] = 0;
4681 #endif
4682
4683 vSetRank(p, rank_i);
4684 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), iFinalCACLK[0], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD);
4685 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), iFinalCACLK[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
4686
4687 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), CATrain_ClkDelay[p->channel][rank_i] , SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK);
4688 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), CATrain_CsDelay[p->channel][rank_i] , SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
4689
4690 for(module_i=0; module_i<2; module_i++)
4691 {
4692 mcSHOW_DBG_MSG(("Rank%d, Macro%d Clk dly: %d, CA dly: %d, CS dly: %d\n", rank_i, module_i, CATrain_ClkDelay[p->channel][rank_i], iFinalCACLK[module_i], CATrain_CsDelay[p->channel][rank_i]));
4693 mcFPRINTF((fp_A60501, "Rank%d, Macro%d Clk dly: %d, CA dly: %d, CS dly: %d\n\n", rank_i, module_i, CATrain_ClkDelay[p->channel][rank_i], iFinalCACLK[module_i], CATrain_CsDelay[p->channel][rank_i]));
4694 }
4695
4696 #if LP3_CA_PER_BIT
4697 CATrainingSetPerBitDelayCell(p, s1CACenterDiff);
4698 #endif
4699 }
4700 vSetRank(p, backup_rank);
4701
4702 #if REG_SHUFFLE_REG_CHECK
4703 ShuffleRegCheck =0;
4704 #endif
4705
4706 CATrainingExit(p);
4707
4708 // Disable fix DQ input enable. Disable IO to O1 path
4709 O1PathOnOff(p, 0);
4710
4711 // NO need to disable CKE high and back to dynamic when calibration
4712 //CKEFixOnOff(p, CKE_DYNAMIC, CKE_WRITE_TO_ONE_CHANNEL);
4713
4714 // Restore the registers' values.
4715 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
4716 mcSHOW_DBG_MSG(("\n\n"));
4717
4718 return DRAM_OK;
4719}
4720#endif
4721#endif //SIMULATION_LP3_CA_TRAINING
4722
4723
4724#if SIMUILATION_LP4_CBT
4725//-------------------------------------------------------------------------
4726/** CmdBusTrainingLP4
4727 * start the calibrate the skew between (1) Clk pin and CAx pins. (2) Clk and CS pin (3)Vref(ca) driving
4728 * @param p Pointer of context created by DramcCtxCreate.
4729 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
4730 */
4731//-------------------------------------------------------------------------
4732static void insertionSort(S32 a[], S32 array_size)
4733{
4734 S32 i, j, index;
4735 for (i = 1; i < array_size; ++i)
4736 {
4737 index = a[i];
4738 for (j = i; j > 0 && a[j-1] > index; j--)
4739 a[j] = a[j-1];
4740
4741 a[j] = index;
4742 }
4743}
4744
4745void CBT_Switch_Freq(DRAMC_CTX_T *p, U8 freq)
4746{
4747#if DUAL_FREQ_K
4748#if (fcFOR_CHIP_ID == fcLaurel)
4749 if(freq==CBT_LOW_FREQ)
4750 {
4751 CBT_DramcDFSDirectJump(p, (DRAM_DFS_SHUFFLE_MAX-1));
4752 }
4753 else
4754 {
4755 CBT_DramcDFSDirectJump(p, DRAM_DFS_SHUFFLE_1);
4756 }
4757#else
4758 #error Need check of the DRAM_DFS_SHUFFLE_X for your chip !!!
4759#endif
4760 //DDRPhyFreqMeter();
4761#endif
4762}
4763
4764static void vSetDramMRCBTOnOff(DRAMC_CTX_T *p, U8 u1OnOff, U8 operating_fsp)
4765{
4766 if(u1OnOff)
4767 {
4768 u1MR13Value |= 0x1; //MR13 OP[0]=1, enable CBT
4769
4770 // op[7] = !(p->dram_fsp), dram will switch to another FSP_OP automatically
4771 if(operating_fsp)
4772 u1MR13Value &= 0x7f; // OP[7] =0;
4773 else
4774 u1MR13Value |= 0x80; // OP[7] =1;
4775
4776 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
4777 {
4778 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_BYTEMODECBTEN); //BYTEMODECBTEN=1
4779 }
4780 }
4781 else
4782 {
4783 u1MR13Value &= 0xfe; //MR13 OP[0]=0, disable CBT
4784
4785 if(operating_fsp)
4786 u1MR13Value |= 0x80; // OP[7] =1;
4787 else
4788 u1MR13Value &= 0x7f; // OP[7] =0;
4789 }
4790 DramcModeRegWriteByRank(p, p->rank, 13, u1MR13Value);
4791}
4792
4793void CBTEntry(DRAMC_CTX_T *p, U8 operating_fsp, U16 operation_frequency)
4794{
4795 //Write (DRAMC_AO_BASE+ 0xE<<2) [25] = 1b0 // disable dramc DCMEN
4796 //Write (DRAMC_AO_BASE+ 0xE<<2) [30] = 1b0 // set R_DMPHYCLKDYNGEN=0
4797 //Write (DRAMC_AO_BASE+ 0x80<<2) [29] = 1b0 // set R_DMDQSIENCG_NORMAL_EN=0
4798 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), P_Fld(0, DRAMC_PD_CTRL_PHYCLKDYNGEN)| P_Fld(0, DRAMC_PD_CTRL_DCMEN));
4799
4800
4801 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL), 0, STBCAL_DQSIENCG_NORMAL_EN);
4802
4803 //Step 0.0 CKE go high (Release R_DMCKEFIXOFF, R_DMCKEFIXON=1)
4804 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF); //MIOCKCTRLOFF=1
4805
4806 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
4807
4808 //Step 0: MRW MR13 OP[0]=1 to enable CBT
4809 vSetDramMRCBTOnOff(p, ENABLE, operating_fsp);
4810
4811 //Step 0.1: before CKE low, Let DQS=0 by R_DMwrite_level_en=1, spec: DQS_t has to retain a low level during tDQSCKE period
4812 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
4813 {
4814 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_WRITE_LEVEL_EN);
4815 }
4816
4817 mcDELAY_US(1);
4818
4819 //Step 1.0: let CKE go low
4820 CKEFixOnOff(p, p->rank, CKE_FIXOFF, CKE_WRITE_TO_ONE_CHANNEL);
4821
4822
4823 // Step 1.1 : let IO to O1 path valid
4824 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
4825 {
4826 // Let R_DMFIXDQIEN1=1 (byte1), 0xd8[13] ==> Note: Do not enable again.
4827 //Currently set in O1PathOnOff
4828 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0x3, PADCTRL_FIXDQIEN);
4829
4830 // Let DDRPHY RG_RX_ARDQ_SMT_EN_B1=1 (byte1)
4831 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 1, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1);
4832 O1PathOnOff(p, 1);
4833 }
4834
4835 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
4836 {
4837 // let IO to O1 path valid by DDRPHY RG_RX_ARDQ_SMT_EN_B0=1
4838 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 1, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0);
4839 O1PathOnOff(p, 1);
4840 }
4841}
4842
4843void CBTExit(DRAMC_CTX_T *p, U8 operating_fsp, U8 operation_frequency)
4844{
4845 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE || p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
4846 {
4847 //Step 1: CKE go high (Release R_DMCKEFIXOFF, R_DMCKEFIXON=1)
4848 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
4849
4850 //Step 2:wait tCATX, wait tFC
4851 mcDELAY_US(1);
4852
4853 //Step 3: MRW to command bus training exit (MR13 OP[0]=0 to disable CBT)
4854 vSetDramMRCBTOnOff(p, DISABLE, operating_fsp);
4855 }
4856
4857 //Step 4:
4858 //Disable O1 path output
4859 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
4860 {
4861 //Let DDRPHY RG_RX_ARDQ_SMT_EN_B1=0
4862 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 0, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1);
4863 O1PathOnOff(p, 0);
4864
4865 //Let FIXDQIEN1=0 ==> Note: Do not enable again.
4866 //Moved into O1PathOnOff
4867 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), 0, PADCTRL_FIXDQIEN);
4868 }
4869
4870 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
4871 {
4872 //Let DDRPHY RG_RX_ARDQ_SMT_EN_B0=0
4873 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 0, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0);
4874 O1PathOnOff(p, 0);
4875
4876 //Disable Byte mode CBT enable bit
4877 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0, WRITE_LEV_BYTEMODECBTEN); //BYTEMODECBTEN=0
4878 }
4879}
4880
4881static void CBTSetFSP(DRAMC_CTX_T *p, U8 operating_fsp, U8 final_set_flag)
4882{
4883 if(operating_fsp==FSP_0)
4884 {
4885 u1MR13Value &= ~(1<<6); //OP[6], fsp_wr=0
4886 u1MR13Value &= 0x7f; // OP[7] =0;
4887 }
4888 else
4889 {
4890#if (DUAL_FREQ_K)
4891 if (final_set_flag==0)
4892 {
4893 u1MR13Value |= (1<<6); //OP[6], fsp_wr=1
4894 u1MR13Value &= 0x7f; // OP[7] =0;
4895 }
4896 else
4897 {
4898 u1MR13Value |= (1<<6); //OP[6], fsp_wr=1
4899 u1MR13Value |= 0x80; // OP[7] =1;
4900 }
4901#else
4902 u1MR13Value |= (1<<6); //OP[6], fsp_wr=1
4903 u1MR13Value |= 0x80; // OP[7] =1;
4904#endif
4905 }
4906
4907 DramcModeRegWriteByRank(p, p->rank, 13, u1MR13Value);
4908}
4909
4910static void CBTSetVref(DRAMC_CTX_T *p, U32 u2VrefLevel, U8 operating_fsp, U8 final_set_flag)
4911{
4912 U32 u4DbgValue;
4913 U8 u1VrefValue_pinmux;
4914
4915 u1VrefValue_pinmux = (GetCmdBusTrainingVrefPinMuxRevertValue(p, u2VrefLevel) & 0x3f);
4916
4917#if !REDUCE_LOG_FOR_PRELOADER
4918 mcSHOW_DBG_MSG(("\nCH_%d, RK_%d, Range=%d, VrefValue_pinmux = 0x%x\n",p->channel, p->rank, gCBT_VREF_RANGE_SEL, u1VrefValue_pinmux));
4919#endif
4920 mcFPRINTF((fp_A60501, "\nCBTSetVref = 0x%x\n", u2VrefLevel));
4921
4922
4923 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE && final_set_flag==0)
4924 {
4925 u1MR12Value[p->channel][p->rank][operating_fsp] = ((gCBT_VREF_RANGE_SEL&0x1) <<6) | u1VrefValue_pinmux;
4926
4927 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), ((gCBT_VREF_RANGE_SEL&0x1) <<6) | (u2VrefLevel & 0x3f), WRITE_LEV_DMVREFCA); //MR12, bit[25:20]=OP[5:0] bit 26=OP[6]
4928 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), u2VrefLevel, WRITE_LEV_DMVREFCA); //MR12, bit[25:20]=OP[5:0] bit 26=OP[6]
4929
4930 //DQS_SEL=1, DQS_B1_G=1, Toggle R_DMDQS_WLEV (1 to 0)
4931 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1 , WRITE_LEV_DQS_SEL);
4932 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0xa , WRITE_LEV_DQSBX_G);
4933 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1 , WRITE_LEV_DQS_WLEV);
4934 mcDELAY_US(1);
4935 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0, WRITE_LEV_DQS_WLEV);
4936
4937 }
4938 else
4939 {
4940 u4DbgValue = (((gCBT_VREF_RANGE_SEL&0x1) <<6) | (u2VrefLevel & 0x3f));
4941 u1MR12Value[p->channel][p->rank][operating_fsp] = u4DbgValue;
4942 mcSHOW_DBG_MSG3(("u4DbgValue = 0x%x\n", u4DbgValue));
4943
4944 DramcModeRegWriteByRank(p, p->rank, 12, u4DbgValue);
4945 }
4946
4947 //wait tVREF_LONG
4948 mcDELAY_US(1);
4949}
4950
4951static U32 CBTDelayCACLKCompare(DRAMC_CTX_T *p, S32 iDelay)
4952{
4953 U32 u4Result=0, u4Result0=0, u4Ready;
4954 U32 u4TimeCnt;
4955
4956 u4TimeCnt = TIME_OUT_CNT;
4957 if(iDelay < 0)
4958 { //Set CLK delay
4959 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) |
4960 P_Fld(-iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) |
4961 P_Fld(-iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
4962 }
4963 else if(iDelay>=64)
4964 { //Set CA output delay + 2UI
4965 DramcCmdUIDelaySetting(p, 2);
4966
4967 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(iDelay-64, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) |
4968 P_Fld(CLK_SHIFT_PI_DELAY, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) |
4969 P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
4970 }
4971 else
4972 { //Set CA output delay
4973 DramcCmdUIDelaySetting(p, 0);
4974
4975 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(iDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) |
4976 P_Fld(CLK_SHIFT_PI_DELAY, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) |
4977 P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
4978 }
4979
4980 //Let R_DMTESTCATRAIN=1 to enable HW CAPAT Generator
4981 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 1, CATRAINING1_TESTCATRAIN);
4982
4983 //Check CA training compare ready (dramc_conf_nao 0x3fc , CATRAIN_CMP_CPT)
4984 do
4985 {
4986 u4Ready = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TCMDO1LAT), TCMDO1LAT_CATRAIN_CMP_CPT);
4987 u4TimeCnt --;
4988 mcDELAY_US(1);
4989 }while((u4Ready==0) &&(u4TimeCnt>0));
4990
4991 if(u4TimeCnt==0)//time out
4992 {
4993 mcSHOW_DBG_MSG(("[CBTDelayCACLKCompare] Resp fail (time out)\n"));
4994 mcFPRINTF((fp_A60501, "[CBTDelayCACLKCompare] Resp fail (time out)\n"));
4995 //return DRAM_FAIL;
4996 }
4997
4998 //Get CA training compare result (dramc_conf_nao 0x3fc , CATRAIN_CMP_ERR)
4999 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
5000 {
5001 u4Result = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TCMDO1LAT), TCMDO1LAT_CATRAIN_CMP_ERR);
5002 }
5003 else
5004 {
5005 u4Result0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TCMDO1LAT), TCMDO1LAT_CATRAIN_CMP_ERR0);
5006// mcSHOW_DBG_MSG(("[Francis] TCMDO1LAT_CATRAIN_CMP_ERR0=0x%x\n", u4Result0));
5007 u4Result = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TCMDO1LAT), TCMDO1LAT_CATRAIN_CMP_ERR);
5008// mcSHOW_DBG_MSG(("[Francis] TCMDO1LAT_CATRAIN_CMP_ERR=0x%x\n", u4Result));
5009 }
5010
5011 //Let R_DMTESTCATRAIN=0 to disable HW CAPAT Generator
5012 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_CATRAINING1), 0, CATRAINING1_TESTCATRAIN);
5013
5014 return (u4Result|u4Result0); // return pattern compre result
5015}
5016
5017
5018static U32 CBTDelayCSCompare(DRAMC_CTX_T *p, U32 uiDelay)
5019{
5020 U8 *uiLPDDR_O1_Mapping = NULL;
5021 U32 u4Result, u4Ready;
5022 U32 u4TimeCnt;
5023 U32 u4dq_o1;
5024 U32 u4byte_index;
5025
5026 u4TimeCnt = TIME_OUT_CNT;
5027
5028 if (u1IsLP4Family(p->dram_type))
5029 {
5030 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR4_O1_Mapping_POP[p->channel];
5031 }
5032#if ENABLE_LP3_SW
5033 else
5034 {
5035 #if (fcFOR_CHIP_ID == fcLaurel)
5036 if(p->bDLP3)
5037 {
5038 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR3_O1_Mapping_POP_DLP3;
5039 }
5040 else
5041 #endif
5042 {
5043 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR3_O1_Mapping_POP;
5044 }
5045 }
5046#endif /* ENABLE_LP3_SW */
5047
5048 //Set CS output delay
5049 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), uiDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
5050 //Step 5: toggle CS/CA for CS training by R_DMTCMDEN (wait dramc_nao tcmd_response=1, disable R_DMTCMDEN), 0x1e4[5]
5051 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_TCMDEN);
5052 do
5053 {
5054 u4Ready = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_TCMD_RESPONSE);
5055 u4TimeCnt --;
5056 mcDELAY_US(1);
5057 }while((u4Ready==0) &&(u4TimeCnt>0));
5058
5059
5060 if(u4TimeCnt==0)//time out
5061 {
5062 mcSHOW_DBG_MSG(("[CBTDelayCSCompare] Resp fail (time out)\n"));
5063 mcFPRINTF((fp_A60501, "[CBTDelayCSCompare] Resp fail (time out)\n"));
5064 //return DRAM_FAIL;
5065 }
5066
5067 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_TCMDEN);
5068
5069 //Step 6: check CS training result on DQ[13:8] by O1, DDRPHYCFG 0xF80
5070 //Expected CA value is h2a (CA pulse width is 6UI, CS pulse is 1UI)
5071 u4dq_o1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_DQO1), MISC_DQO1_DQO1_RO);
5072 u4Result = 0;
5073 for(u4byte_index=8; u4byte_index<=13; u4byte_index++)
5074 {
5075 u4Result |= (((u4dq_o1 & (1<<uiLPDDR_O1_Mapping[u4byte_index])) >> (uiLPDDR_O1_Mapping[u4byte_index])) << (u4byte_index-8));
5076 }
5077 mcSHOW_DBG_MSG3(("CS Dly = %d, Result=0x%x\n", uiDelay, u4Result));
5078 return u4Result; // return pattern compre result
5079}
5080
5081#if 0 //for CBT CS test
5082static U32 CBTDelayCSCompare2(DRAMC_CTX_T *p)
5083{
5084 U32 u4err_value, uiDelay;
5085
5086 for (uiDelay=0; uiDelay<=MAX_CS_PI_DELAY; uiDelay++)
5087 {
5088 // Set CS output delay
5089 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_ARPI_CMD), uiDelay, ARPI_CMD_DA_ARPI_CS);
5090 u4err_value= TestEngineCompare(p);
5091 mcSHOW_DBG_MSG(("CBTDelayCSCompare2= %3d, u4err_value=0x%2x\n", uiDelay, u4err_value));
5092 }
5093
5094 return DRAM_OK; // return pattern compre result
5095}
5096#endif
5097
5098#if 0
5099void DramcCmdBusTrainingPostProcess(DRAMC_CTX_T *p)
5100{
5101 S32 iCSFinalClkDelay, iCSFinalCmdDelay, iCSFinalCSDelay;
5102 U8 backup_rank, irank;
5103
5104 // CBT Rank0/1 must set Clk/CA/CS the same from Wei-Jen
5105
5106 mcSHOW_DBG_MSG(("[DramcCmdBusTrainingPostProcess] p->frequency=%d\n", p->frequency));
5107
5108 backup_rank = u1GetRank(p);
5109
5110 iCSFinalClkDelay= (CATrain_ClkDelay[p->channel][RANK_0] + CATrain_ClkDelay[p->channel][RANK_1])/2;
5111 CATrain_ClkDelay[p->channel][RANK_0] = iCSFinalClkDelay;
5112 CATrain_ClkDelay[p->channel][RANK_1] = iCSFinalClkDelay;
5113
5114 iCSFinalCmdDelay= (CATrain_CmdDelay[p->channel][RANK_0] + CATrain_CmdDelay[p->channel][RANK_1])/2;
5115 CATrain_CmdDelay[p->channel][RANK_0] = iCSFinalCmdDelay;
5116 CATrain_CmdDelay[p->channel][RANK_1] = iCSFinalCmdDelay;
5117
5118 iCSFinalCSDelay= (CATrain_CsDelay[p->channel][RANK_0] + CATrain_CsDelay[p->channel][RANK_1])/2;
5119 CATrain_CsDelay[p->channel][RANK_0] = iCSFinalCSDelay;
5120 CATrain_CsDelay[p->channel][RANK_1] = iCSFinalCSDelay;
5121
5122 for(irank=RANK_0; irank<=RANK_1; irank++)
5123 {
5124 vSetRank(p, irank);
5125 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(iCSFinalClkDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) |
5126 P_Fld(iCSFinalCmdDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) |
5127 P_Fld(iCSFinalCSDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
5128 }
5129
5130 mcSHOW_DBG_MSG(("Clk Dly = %d\nCmd Dly = %d\nCS Dly = %d\n", iCSFinalClkDelay, iCSFinalCmdDelay, iCSFinalCSDelay));
5131
5132
5133#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
5134 if(p->femmc_Ready==0)
5135 {
5136 p->pSavetimeData->u1CBTClkDelay_Save[p->channel][RANK_0]= iCSFinalClkDelay;
5137 p->pSavetimeData->u1CBTClkDelay_Save[p->channel][RANK_1]= iCSFinalClkDelay;
5138
5139 p->pSavetimeData->u1CBTCmdDelay_Save[p->channel][RANK_0]= iCSFinalCmdDelay;
5140 p->pSavetimeData->u1CBTCmdDelay_Save[p->channel][RANK_1]= iCSFinalCmdDelay;
5141
5142 p->pSavetimeData->u1CBTCsDelay_Save[p->channel][RANK_0]= iCSFinalCSDelay;
5143 p->pSavetimeData->u1CBTCsDelay_Save[p->channel][RANK_1]= iCSFinalCSDelay;
5144 }
5145#endif
5146
5147 vSetRank(p, backup_rank);
5148}
5149#endif
5150
5151static void CBTAdjustCS(DRAMC_CTX_T *p)
5152{
5153 S32 iFirstCSPass, iLastCSPass, iCSFinalDelay;//iCSCenter
5154 U32 uiDelay, u4ValueReadBack, u4CSWinSize;
5155 U8 backup_rank, rank_i;
5156
5157 backup_rank = u1GetRank(p);
5158
5159#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT)
5160 if(p->femmc_Ready==1)
5161 {
5162 iCSFinalDelay=p->pSavetimeData->u1CBTCsDelay_Save[p->channel][p->rank];
5163 }
5164 else
5165#endif
5166 {
5167 iFirstCSPass = -1;
5168 iLastCSPass = -1;
5169
5170 for (uiDelay=0; uiDelay<=MAX_CS_PI_DELAY; uiDelay++)
5171 {
5172 u4ValueReadBack = CBTDelayCSCompare(p, uiDelay);
5173
5174 if(iFirstCSPass == -1)
5175 {
5176 if(u4ValueReadBack== 0x2a) // compare pass
5177 {
5178 iFirstCSPass = uiDelay;
5179 }
5180 }
5181 else if(iLastCSPass == -1)
5182 {
5183 if(u4ValueReadBack != 0x2a) // compare fail
5184 {
5185 iLastCSPass = uiDelay-1;
5186 }
5187 else if (uiDelay ==MAX_CS_PI_DELAY)
5188 {
5189 iLastCSPass = uiDelay;
5190 }
5191 }
5192
5193 // Wait time before output CS pattern to DDR again.. (Review this if need to save time)
5194 mcDELAY_US(1);
5195 }
5196
5197 u4CSWinSize = iLastCSPass - iFirstCSPass + (iLastCSPass==iFirstCSPass?0:1);
5198
5199 if(u4CSWinSize > ((MAX_CS_PI_DELAY+1)>>1)) // if winSize >32, CS delay= winSize -32.
5200 {
5201 iCSFinalDelay = u4CSWinSize -((MAX_CS_PI_DELAY+1)>>1);
5202 }
5203 else ///TODO: need to delay CLK? A60817 and A60501 cannot move CLK PI due to multi_phase problem.
5204 {
5205 iCSFinalDelay =0;
5206 }
5207
5208 CATrain_CsDelay[p->channel][p->rank] = iCSFinalDelay;
5209 mcSHOW_DBG_MSG(("\nCS Dly= %d (%d-%d-32)\n", iCSFinalDelay, iLastCSPass, iFirstCSPass));
5210 mcFPRINTF((fp_A60501, "\nCS Dly= %d (%d-%d-32)\n", iCSFinalDelay, iLastCSPass, iFirstCSPass));
5211
5212 // if dual rank, use average position of both rank
5213 if(backup_rank == RANK_1)
5214 {
5215 iCSFinalDelay = (CATrain_CsDelay[p->channel][RANK_0] + CATrain_CsDelay[p->channel][RANK_1])/2;
5216 }
5217 }
5218 //Set CS output delay after training
5219 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
5220 for(rank_i=RANK_0; rank_i<backup_rank+1; rank_i++)
5221 {
5222 vSetRank(p, rank_i);
5223
5224 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
5225 if(p->femmc_Ready==0)
5226 {
5227 p->pSavetimeData->u1CBTCsDelay_Save[p->channel][p->rank]= iCSFinalDelay;
5228 }
5229 #endif
5230
5231 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), iCSFinalDelay, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
5232 CATrain_CsDelay[p->channel][rank_i]= iCSFinalDelay;
5233 //mcSHOW_DBG_MSG(("\n[CBTAdjustCS] RK%d ,CS Dly: %d\n",rank_i, iCSFinalDelay));
5234 }
5235 vSetRank(p, backup_rank);
5236}
5237
5238static void CBTSetCACLKResult(DRAMC_CTX_T *p, S8 s1FinalCACLK, S8 *ps1CACenterDiff)
5239{
5240 U8 backup_rank, rank_i;
5241
5242#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
5243 U8 uiCA;
5244#endif
5245
5246 backup_rank = u1GetRank(p);
5247
5248 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
5249 for(rank_i=RANK_0; rank_i<backup_rank+1; rank_i++)
5250 {
5251 vSetRank(p, rank_i);
5252
5253 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT)
5254 if(p->femmc_Ready==1)
5255 {
5256 CATrain_ClkDelay[p->channel][p->rank]=p->pSavetimeData->u1CBTClkDelay_Save[p->channel][p->rank];
5257 CATrain_CmdDelay[p->channel][p->rank]=p->pSavetimeData->u1CBTCmdDelay_Save[p->channel][p->rank];
5258
5259 #if CA_PER_BIT_DELAY_CELL
5260 for (uiCA = 0; uiCA < CATRAINING_NUM_LP4; uiCA++)
5261 {
5262 ps1CACenterDiff[uiCA] = p->pSavetimeData->u1CBTCA_PerBit_DelayLine_Save[p->channel][p->rank][uiCA];
5263 }
5264 #endif
5265
5266 vSetCalibrationResult(p, DRAM_CALIBRATION_CA_TRAIN, DRAM_OK); // set default result OK, udpate status when per bit fail
5267 }
5268 else
5269 #endif
5270 {
5271 CATrain_ClkDelay[p->channel][p->rank] = CLK_SHIFT_PI_DELAY;
5272
5273 if(s1FinalCACLK<0)
5274 {
5275 CATrain_CmdDelay[p->channel][p->rank] = 0;
5276 }
5277 else
5278 {
5279 if(s1FinalCACLK>=64)
5280 CATrain_CmdDelay[p->channel][p->rank] = s1FinalCACLK-64;
5281 else
5282 CATrain_CmdDelay[p->channel][p->rank] = s1FinalCACLK;
5283 }
5284 }
5285
5286 //mcSHOW_DBG_MSG(("[CBTSetCACLKResult]Rank%d, Clk dly= %d, CA dly= %d\n", rank_i, CATrain_ClkDelay[p->channel][p->rank], CATrain_CmdDelay[p->channel][p->rank]));
5287 //mcFPRINTF((fp_A60501, "[CBTSetCACLKResult]Rank%d, Clk dly= %d, CA dly= %d\n", rank_i, CATrain_ClkDelay[p->channel][p->rank], CATrain_CmdDelay[p->channel][p->rank]));
5288 if(s1FinalCACLK<64)
5289 {
5290 DramcCmdUIDelaySetting(p, 0);
5291 }
5292 else
5293 {
5294 DramcCmdUIDelaySetting(p, 2);
5295 }
5296
5297 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(CATrain_CmdDelay[p->channel][p->rank], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) |
5298 P_Fld(CATrain_ClkDelay[p->channel][p->rank], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK));
5299
5300 #if CA_PER_BIT_DELAY_CELL
5301 CATrainingSetPerBitDelayCell(p, ps1CACenterDiff);
5302 #endif
5303
5304
5305 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
5306 if(p->femmc_Ready==0)
5307 {
5308 p->pSavetimeData->u1CBTClkDelay_Save[p->channel][p->rank]= CATrain_ClkDelay[p->channel][p->rank];
5309 p->pSavetimeData->u1CBTCmdDelay_Save[p->channel][p->rank]= CATrain_CmdDelay[p->channel][p->rank];
5310
5311 #if CA_PER_BIT_DELAY_CELL
5312 for (uiCA = 0; uiCA < CATRAINING_NUM_LP4; uiCA++)
5313 {
5314 p->pSavetimeData->u1CBTCA_PerBit_DelayLine_Save[p->channel][p->rank][uiCA] = ps1CACenterDiff[uiCA];
5315 }
5316
5317#endif
5318 }
5319 #endif
5320 }
5321
5322 vSetRank(p, backup_rank);
5323
5324#if EYESCAN_LOG
5325 gEyeScan_CaliDelay[0] = CATrain_CmdDelay[p->channel][p->rank] + (CBT_MOVE_CA_INSTEAD_OF_CLK==0?MAX_CLK_PI_DELAY:0);
5326#endif
5327}
5328
5329
5330U8 GetCmdBusTrainingVrefPinMuxValue(DRAMC_CTX_T *p, U8 u1VrefLevel)
5331{
5332 U8 u2VrefBit, u2Vref_new, u2Vref_org;
5333
5334 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) return ((gCBT_VREF_RANGE_SEL&0x1) <<6) | (u1VrefLevel & 0x3f);
5335
5336
5337 u2Vref_new = 0;
5338 u2Vref_org = ((gCBT_VREF_RANGE_SEL&0x1) <<6) | (u1VrefLevel & 0x3f);
5339 for (u2VrefBit = 0; u2VrefBit < 8; u2VrefBit++)
5340 {
5341// mcSHOW_DBG_MSG(("=== u2VrefBit: %d, %d\n",u2VrefBit,uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit]));
5342 if (u2Vref_org & (1 << u2VrefBit))
5343 {
5344 u2Vref_new |= (1 << uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit]);
5345// mcSHOW_DBG_MSG(("=== u2VrefBit: %d, %d, u2Vref_org: %x, u2Vref_new: 0x%x\n",u2VrefBit,uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit],u2Vref_org,u2Vref_new));
5346 }
5347 }
5348
5349 mcSHOW_DBG_MSG3(("=== u2Vref_new: 0x%x --> 0x%x\n",u2Vref_org,u2Vref_new));
5350
5351 return u2Vref_new;
5352}
5353
5354U8 GetCmdBusTrainingVrefPinMuxRevertValue(DRAMC_CTX_T *p, U8 u1VrefLevel)
5355{
5356 U8 u2VrefBit, u2Vref_new, u2Vref_org;
5357
5358 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1) return u1VrefLevel;
5359
5360 u2Vref_new = 0;
5361 u2Vref_org = u1VrefLevel;
5362 for (u2VrefBit = 0; u2VrefBit < 8; u2VrefBit++)
5363 {
5364 u2Vref_new |= ((u2Vref_org>>uiLPDDR4_O1_Mapping_POP[p->channel][u2VrefBit])&1) << u2VrefBit;
5365 }
5366
5367 mcSHOW_DBG_MSG3(("=== Revert u2Vref_new: 0x%x --> 0x%x\n",u2Vref_org,u2Vref_new));
5368
5369 return u2Vref_new;
5370}
5371
5372
5373DRAM_STATUS_T CmdBusTrainingLP4(DRAMC_CTX_T *p)
5374{
5375 U16 u1VrefLevel, uiFinalVref;
5376 U32 u4CompareResult;
5377 PASS_WIN_DATA_T FinalWinPerCA[CATRAINING_NUM_LP4];
5378 U32 uiCA, uiFinishCount, uiTemp;
5379 S16 iDelay;
5380#if CBT_SPEED_UP_CALIBRATION
5381 U8 all_first_pass_flag=0, already_speed_up_flag=0;
5382#endif
5383
5384 S32 iFirstPass_temp[CATRAINING_NUM_LP4], iLastPass_temp[CATRAINING_NUM_LP4];
5385 U32 uiCAWinSum, uiCAWinSumMax;
5386 //S32 iCACenter[CATRAINING_NUM_LP4] = {0}, iCACenterSum = 0, iCAFinalCenter[CATRAINING_NUM_LP4] = {0};
5387 U8 operating_fsp;
5388 U16 operation_frequency;
5389 U8 irange, irange_start, irange_end;
5390 U16 uiFinalRange=0;
5391 U8 u1CBTEyeScanEnable;
5392
5393 S8 iFinalCACLK;
5394 S8 s1CACenterDiff[CATRAINING_NUM]={0}; //for CA_PER_BIT
5395
5396#if EYESCAN_LOG
5397 U8 EyeScan_index[CATRAINING_NUM_LP4];
5398#endif
5399 U32 u4RegBackupAddress[] =
5400 {
5401 (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)),
5402 (DRAMC_REG_ADDR(DRAMC_REG_STBCAL)),
5403 (DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)),
5404 (DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV)),
5405 (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)),
5406 (DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL)),
5407 };
5408
5409#if MRW_CHECK_ONLY
5410 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
5411#endif
5412
5413 u1CBTEyeScanEnable = (gCBT_EYE_Scan_flag==1 && ((gCBT_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gCBT_EYE_Scan_only_higheset_freq_flag==0));
5414
5415#if EYESCAN_LOG
5416 U32 u1vrefidx, ii;
5417
5418 if (u1IsLP4Family(p->dram_type))
5419 {
5420 for(u1vrefidx=0; u1vrefidx<VREF_TOTAL_NUM_WITH_RANGE;u1vrefidx++)
5421 {
5422 for (uiCA = 0; uiCA < CATRAINING_NUM_LP4; uiCA++)
5423 {
5424 for(ii=0; ii<EYESCAN_BROKEN_NUM; ii++)
5425 {
5426 gEyeScan_Min[u1vrefidx][uiCA][ii] = EYESCAN_DATA_INVALID;
5427 gEyeScan_Max[u1vrefidx][uiCA][ii] = EYESCAN_DATA_INVALID;
5428 }
5429
5430 FinalWinPerCA[uiCA].first_pass = EYESCAN_DATA_INVALID;
5431 FinalWinPerCA[uiCA].last_pass = EYESCAN_DATA_INVALID;
5432 FinalWinPerCA[uiCA].win_center = 0;
5433 FinalWinPerCA[uiCA].win_size = 0;
5434 }
5435 }
5436 }
5437#endif
5438
5439 //Back up dramC register
5440 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
5441
5442 vAutoRefreshSwitch(p, DISABLE); //When doing CA training, should make sure that auto refresh is disable
5443
5444 //tx_rank_sel is selected by SW //Lewis@20180509: tx_rank_sel is selected by SW in CBT if TMRRI design has changed.
5445 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), p->rank, RKCFG_TXRANK);
5446 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX); //TXRANKFIX should be write after TXRANK
5447
5448 //SW variable initialization
5449 uiCAWinSumMax=0;
5450 uiFinalVref=u1MR12Value[p->channel][p->rank][p->dram_fsp] & 0x3f;
5451 iFinalCACLK=0;
5452 operating_fsp = p->dram_fsp;
5453 operation_frequency = p->frequency;
5454 #if CA_PER_BIT_DELAY_CELL
5455 CATrainingSetPerBitDelayCell(p, s1CACenterDiff);
5456 #endif
5457
5458
5459 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
5460 {
5461 //switch to low freq
5462 if (operating_fsp == FSP_1)
5463 {
5464 CBT_Switch_Freq(p, CBT_LOW_FREQ);
5465 }
5466 //Step 1: Enter Command Bus Training Mode
5467 CBTEntry(p, operating_fsp, operation_frequency);
5468 //Step 2: wait tCAENT
5469 mcDELAY_US(1);
5470 //switch to high freq
5471 if (operating_fsp == FSP_1)
5472 {
5473 CBT_Switch_Freq(p, CBT_HIGH_FREQ);
5474 }
5475 }
5476
5477#if PINMUX_AUTO_TEST_PER_BIT_CA
5478#if ENABLE_LPDDR4
5479 CheckCADelayCell(p);
5480#endif
5481#endif
5482
5483#if VENDER_JV_LOG
5484 vPrintCalibrationBasicInfo_ForJV(p);
5485#else
5486 vPrintCalibrationBasicInfo(p);
5487#endif
5488
5489 //Step 3: set CBT range, verify range and setp
5490#if (SW_CHANGE_FOR_SIMULATION ||FOR_DV_SIMULATION_USED)
5491 gCBT_VREF_RANGE_SEL = 0; //MR12,OP[6]
5492 irange_start=irange_end=0;
5493 gCBT_VREF_RANGE_BEGIN = 0;
5494 gCBT_VREF_RANGE_END = 2; // binary 110010
5495 gCBT_VREF_RANGE_STEP = 2;
5496#else
5497 gCBT_VREF_RANGE_SEL = 1; //MR12,OP[6]
5498 irange_start=irange_end=1;
5499 gCBT_VREF_RANGE_STEP = 2;
5500
5501 if (p->enable_cbt_scan_vref == DISABLE_VREF_SCAN)
5502 {
5503 gCBT_VREF_RANGE_BEGIN = (u1MR12Value[p->channel][p->rank][p->dram_fsp] & 0x3f);
5504 gCBT_VREF_RANGE_END = gCBT_VREF_RANGE_BEGIN;
5505 }
5506 else
5507 {
5508 if (p->dram_type == TYPE_LPDDR4)
5509 {
5510 //range 1
5511 gCBT_VREF_RANGE_BEGIN = 13 - 5; // 300/1100(VDDQ) = 27.2%
5512 gCBT_VREF_RANGE_END = 13 + 5;
5513 }
5514 else
5515 {
5516 //range 1
5517 gCBT_VREF_RANGE_BEGIN = 27 - 5; // 290/600(VDDQ)=48.3%
5518 gCBT_VREF_RANGE_END = 27 + 5;
5519 }
5520 }
5521#endif
5522
5523 if (u1CBTEyeScanEnable)
5524 {
5525 irange_start = 0;
5526 irange_end = 1;
5527 }
5528
5529 for(irange=irange_start; irange<=irange_end; irange++)
5530 {
5531 if (u1CBTEyeScanEnable)
5532 {
5533 gCBT_VREF_RANGE_SEL = irange;
5534 gCBT_VREF_RANGE_BEGIN = 0;
5535 gCBT_VREF_RANGE_END = 50;
5536 gCBT_VREF_RANGE_STEP = 1;
5537
5538 if (gCBT_VREF_RANGE_SEL == 1)
5539 {
5540 gCBT_VREF_RANGE_BEGIN = 21;
5541 }
5542 }
5543
5544#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL)
5545 if(p->femmc_Ready==1)
5546 {
5547 mcSHOW_DBG_MSG(("\n[FAST_K] BYPASS_VREF_CAL CBT\n"));
5548 }
5549 else
5550#endif
5551 {
5552 for(u1VrefLevel = gCBT_VREF_RANGE_BEGIN; u1VrefLevel<=gCBT_VREF_RANGE_END; u1VrefLevel+=gCBT_VREF_RANGE_STEP)
5553 {
5554#if EYESCAN_LOG
5555 for (uiCA = 0; uiCA < CATRAINING_NUM_LP4; uiCA++)
5556 {
5557 gEyeScan_DelayCellPI[uiCA] = 0;
5558 EyeScan_index[uiCA] = 0;
5559 }
5560#endif
5561
5562 //VREFCA = you want
5563 {
5564 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
5565 {
5566#if (FOR_DV_SIMULATION_USED==0)
5567 //switch to low freq
5568 if (operating_fsp == FSP_1)
5569 {
5570 CBT_Switch_Freq(p, CBT_LOW_FREQ);
5571 }
5572#endif
5573 CBTSetFSP(p, operating_fsp, 0);
5574 }
5575 CBTSetVref(p, GetCmdBusTrainingVrefPinMuxValue(p, u1VrefLevel), operating_fsp, 0);
5576 }
5577
5578#if VENDER_JV_LOG
5579 mcSHOW_DBG_MSG5(("\n\tLP4 CBT VrefRange %d, VrefLevel=%d\n", gCBT_VREF_RANGE_SEL, u1VrefLevel));
5580#endif
5581 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
5582 {
5583 //Step 1: Enter Command Bus Training Mode
5584 CBTEntry(p, operating_fsp, operation_frequency);
5585 //Step 2: wait tCAENT
5586 mcDELAY_US(1);
5587
5588#if (FOR_DV_SIMULATION_USED==0)
5589 //switch to high freq
5590 if (operating_fsp == FSP_1)
5591 {
5592 CBT_Switch_Freq(p, CBT_HIGH_FREQ);
5593 }
5594#endif
5595 }
5596 // Delay CA output delay to do CA training in order to get the pass window.
5597 // moving CA relative to CK and repeating until CA is centered on the latching edge of CK
5598 // Note !!!!!!!!!!!!!!!!!!!!!!!
5599 // Assume : Leave clk as the init value and adjust CA delay only can find out each CA window including of the left boundary.
5600 // If NOT, we may need to off-line adjust 0x404 SELPH2_TXDLY_CMD
5601 // SW variable initialization
5602 uiFinishCount = 0;
5603 uiCAWinSum = 0;
5604#if CBT_SPEED_UP_CALIBRATION
5605 already_speed_up_flag = 0;
5606#endif
5607 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5608 {
5609 iLastPass_temp[uiCA] = PASS_RANGE_NA;
5610 iFirstPass_temp[uiCA] = PASS_RANGE_NA;
5611 }
5612
5613#if CBT_MOVE_CA_INSTEAD_OF_CLK
5614 for (iDelay=0; iDelay<=MAX_CA_PI_DELAY; iDelay++)
5615#else
5616 for (iDelay= (-MAX_CLK_PI_DELAY); iDelay<=MAX_CA_PI_DELAY; iDelay++)
5617#endif
5618 {
5619 u4CompareResult= CBTDelayCACLKCompare(p, iDelay);
5620
5621 //Wait tCACD(22clk) before output CA pattern to DDR again..
5622 mcDELAY_US(1);
5623
5624 mcSHOW_DBG_MSG3(("CBTDelayCACLK Delay= %d, CompareResult 0x%x\n", iDelay, u4CompareResult));
5625 mcFPRINTF((fp_A60501, "CBTDelayCACLK Delay = %d, CompareResult 0x%x\n", iDelay, u4CompareResult));
5626
5627 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5628 {
5629 if((iFirstPass_temp[uiCA] != PASS_RANGE_NA) && (iLastPass_temp[uiCA] != PASS_RANGE_NA))
5630 {
5631 continue;
5632 }
5633
5634 uiTemp = (u4CompareResult >>uiCA) & 0x1; //Get Each bit of CA result
5635
5636 if(iFirstPass_temp[uiCA] == PASS_RANGE_NA)
5637 {
5638 if(uiTemp==0) //compare correct: pass
5639 {
5640 iFirstPass_temp[uiCA] = iDelay;
5641 }
5642 }
5643 else if(iLastPass_temp[uiCA] == PASS_RANGE_NA)
5644 {
5645 if(uiTemp==1) //compare error : fail
5646 {
5647 #if CBT_SPEED_UP_CALIBRATION
5648 if (already_speed_up_flag==1)
5649 {
5650 // fra : if test fail after first step of speed up, then show warning message
5651 mcSHOW_ERR_MSG(("[CBT] CA=%d, fail after speed up! iDelay=%d !!\n", uiCA, iDelay));
5652 #if __ETT__
5653 while(1);
5654 #endif
5655 }
5656 #endif
5657
5658 if ((iDelay-iFirstPass_temp[uiCA]) < 5) //prevent glitch
5659 {
5660 iFirstPass_temp[uiCA] = PASS_RANGE_NA;
5661 continue;
5662 }
5663
5664 iLastPass_temp[uiCA] = (iDelay-1);
5665 }
5666 else if (iDelay==MAX_CA_PI_DELAY)
5667 {
5668 iLastPass_temp[uiCA] = iDelay;
5669 }
5670
5671 if(iLastPass_temp[uiCA] !=PASS_RANGE_NA)
5672 {
5673 uiFinishCount++;
5674 uiCAWinSum += (iLastPass_temp[uiCA] -iFirstPass_temp[uiCA]); //Sum of CA Windows for vref selection
5675 //iCACenter[uiCA] = (iLastPass_temp[uiCA] +iFirstPass_temp[uiCA])>>1; //window center of each CA bit
5676 //iCACenterSum += iCACenter[uiCA];
5677#if !REDUCE_LOG_FOR_PRELOADER
5678 mcSHOW_DBG_MSG(("\n[CA %d] Center %d (%d~%d)\n", uiCA, iCACenter[uiCA] , iFirstPass_temp[uiCA], iLastPass_temp[uiCA]));
5679#endif
5680#if EYESCAN_LOG
5681 if (EyeScan_index[uiCA] < EYESCAN_BROKEN_NUM)
5682 {
5683 gEyeScan_Min[u1VrefLevel+irange*30][uiCA][EyeScan_index[uiCA]] = iFirstPass_temp[uiCA]+(CBT_MOVE_CA_INSTEAD_OF_CLK==0?MAX_CLK_PI_DELAY:0);
5684 gEyeScan_Max[u1VrefLevel+irange*30][uiCA][EyeScan_index[uiCA]] = iLastPass_temp[uiCA]+(CBT_MOVE_CA_INSTEAD_OF_CLK==0?MAX_CLK_PI_DELAY:0);
5685 mcSHOW_DBG_MSG3(("u2VrefLevel=%d, u2VrefRange=%d, %d, uiCA=%d, index=%d (%d, %d)==\n",u1VrefLevel, irange, u1VrefLevel+irange*30, uiCA, EyeScan_index[uiCA], gEyeScan_Min[u1VrefLevel+irange*30][uiCA][EyeScan_index[uiCA]], gEyeScan_Max[u1VrefLevel+irange*30][uiCA][EyeScan_index[uiCA]]));
5686 EyeScan_index[uiCA]=EyeScan_index[uiCA]+1;
5687 }
5688#endif
5689 }
5690 }
5691 }
5692
5693
5694#if CBT_SPEED_UP_CALIBRATION
5695 if (!u1CBTEyeScanEnable)
5696 {
5697 if (already_speed_up_flag==0)
5698 {
5699 all_first_pass_flag=0;
5700 for (uiCA = 0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5701 {
5702 if (iFirstPass_temp[uiCA] != PASS_RANGE_NA && (iDelay-iFirstPass_temp[uiCA]) >= 5) //prevent glitch
5703 {
5704 all_first_pass_flag|=1<<uiCA;
5705 }
5706 }
5707
5708 if (all_first_pass_flag==0x3f)
5709 {
5710 // fra : speed up 30 steps to save K time
5711 iDelay+=30;
5712 already_speed_up_flag = 1;
5713 }
5714 }
5715 else
5716 {
5717 already_speed_up_flag=2; //the check fail of first step after already speed up done.
5718 }
5719 }
5720#endif
5721
5722 if(uiFinishCount == CATRAINING_NUM_LP4)
5723 break;
5724 }
5725#if VENDER_JV_LOG
5726 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5727 {
5728 mcSHOW_DBG_MSG5(("CBT Bit%d, CA window %d ps\n", uiCA, (iLastPass_temp[uiCA]-iFirstPass_temp[uiCA]+1)*1000000/p->frequency/64));
5729 }
5730#endif
5731
5732 //set CK/CS pi delay to 0 and set CA pi delay to center
5733 #if CBT_MOVE_CA_INSTEAD_OF_CLK
5734 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(0x20, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) | P_Fld(CLK_SHIFT_PI_DELAY, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) | P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
5735 #else
5736 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD) | P_Fld(CLK_SHIFT_PI_DELAY, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK) | P_Fld(0, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS));
5737 #endif
5738
5739#if !REDUCE_LOG_FOR_PRELOADER
5740 mcSHOW_DBG_MSG(("\n[CmdBusTrainingLP4] CAWinSum: %d\n", uiCAWinSum));
5741#endif
5742 if(uiCAWinSum > uiCAWinSumMax)
5743 {
5744 uiCAWinSumMax =uiCAWinSum;
5745 uiFinalVref = u1VrefLevel;
5746 if (u1CBTEyeScanEnable) uiFinalRange = gCBT_VREF_RANGE_SEL;
5747
5748 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5749 {
5750 FinalWinPerCA[uiCA].first_pass = iFirstPass_temp[uiCA];
5751 FinalWinPerCA[uiCA].last_pass = iLastPass_temp[uiCA];
5752 }
5753 }
5754
5755#if EYESCAN_LOG
5756 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5757 {
5758 gEyeScan_WinSize[u1VrefLevel+irange*30][uiCA] = (iLastPass_temp[uiCA] - iFirstPass_temp[uiCA])+(iLastPass_temp[uiCA]==iFirstPass_temp[uiCA]?0:1);
5759 }
5760#endif
5761 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
5762 {
5763#if (FOR_DV_SIMULATION_USED==0)
5764 //switch to low freq
5765 if (operating_fsp == FSP_1)
5766 {
5767 CBT_Switch_Freq(p, CBT_LOW_FREQ);
5768 }
5769#endif
5770 //Step 1: Enter Command Bus Training Mode
5771 CBTExit(p, operating_fsp, operation_frequency);
5772 //Step 2: wait tCAENT
5773 mcDELAY_US(1);
5774 }
5775
5776 if (gCBT_EYE_Scan_flag == 0)
5777 {
5778 if(uiCAWinSum < (uiCAWinSumMax*95/100))
5779 {
5780 mcSHOW_DBG_MSG(("\nCBT Vref found, early break!\n"));
5781 break;//max vref found, early break;
5782 }
5783 }
5784 }
5785 }
5786 }
5787
5788 if (u1CBTEyeScanEnable)
5789 gCBT_VREF_RANGE_SEL = uiFinalRange;
5790
5791#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL)
5792 if(p->femmc_Ready==0)
5793#endif
5794 {
5795 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5796 {
5797 FinalWinPerCA[uiCA].win_center = (FinalWinPerCA[uiCA].first_pass + FinalWinPerCA[uiCA].last_pass)/2;
5798 FinalWinPerCA[uiCA].win_size = (FinalWinPerCA[uiCA].last_pass - FinalWinPerCA[uiCA].first_pass)+(FinalWinPerCA[uiCA].last_pass==FinalWinPerCA[uiCA].first_pass?0:1);
5799
5800 #if 1//CA_PER_BIT_DELAY_CELL
5801 iFirstCAPass[p->rank][0][uiCA] = FinalWinPerCA[uiCA].first_pass;
5802 iLastCAPass[p->rank][0][uiCA] = FinalWinPerCA[uiCA].last_pass;
5803 #endif
5804
5805 #ifdef FOR_HQA_TEST_USED
5806 gFinalCBTCA[p->channel][p->rank][uiCA] = FinalWinPerCA[uiCA].win_size;
5807 #endif
5808
5809 #if PINMUX_AUTO_TEST_PER_BIT_CA
5810 gFinalCAPerbitFirstPass[p->channel][p->rank][uiCA] = FinalWinPerCA[uiCA].first_pass;
5811 #endif
5812
5813 mcSHOW_DBG_MSG(("[CA %d] Center %d (%d~%d) winsize %d\n", uiCA, FinalWinPerCA[uiCA].win_center , FinalWinPerCA[uiCA].first_pass, FinalWinPerCA[uiCA].last_pass, FinalWinPerCA[uiCA].win_size));
5814 }
5815
5816#ifdef FOR_HQA_REPORT_USED
5817 if (gHQALog_flag==1)
5818 {
5819 mcSHOW_DBG_MSG(("\n"));
5820 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
5821 {
5822 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Center", uiCA, FinalWinPerCA[uiCA].win_center, NULL);
5823 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Window", uiCA, FinalWinPerCA[uiCA].win_size, NULL);
5824 }
5825 }
5826#endif
5827
5828 #if 1//CA_PER_BIT_DELAY_CELL
5829 // LP4 has already consider two dies. No more position calculation of 2 dies.
5830 gu1LP3DieNum[p->rank] =1;
5831 CATrainingPosCal(p, gu1LP3DieNum, &iFinalCACLK, s1CACenterDiff);
5832 #else
5833 #if SW_CHANGE_FOR_SIMULATION
5834 iFinalCACLK =(int)((float) iCACenterSum/(float)CATRAINING_NUM_LP4);
5835 #else
5836 iFinalCACLK = iCACenterSum/CATRAINING_NUM_LP4;
5837 #endif
5838 #endif
5839 }
5840
5841#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL)
5842 if(p->femmc_Ready==1 )
5843 {
5844 uiFinalVref = p->pSavetimeData->u1CBTVref_Save[p->channel][p->rank];
5845 }
5846#endif
5847
5848#ifdef DEVIATION
5849 if (p->frequency == u2DFSGetHighestFreq(p) && gSetSpecificedVref_Enable[0]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[0] && p->rank==gSetSpecificedVref_Rank[0]) || gSetSpecificedVref_All_ChRk[0]==ENABLE))
5850 {
5851 uiFinalRange = gCBT_VREF_RANGE_SEL;
5852 DeviationAddVrefOffset(0, &uiFinalRange, &uiFinalVref, gSetSpecificedVref_Vref_Offset[0]);
5853 gCBT_VREF_RANGE_SEL = (U8) uiFinalRange;
5854 }
5855#endif
5856
5857 //Set Vref after trainging
5858 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
5859 {
5860#if (FOR_DV_SIMULATION_USED==0)
5861 //switch to low freq
5862 if (operating_fsp == FSP_1)
5863 {
5864 CBT_Switch_Freq(p, CBT_LOW_FREQ);
5865 }
5866#endif
5867 CBTSetFSP(p, operating_fsp, 1);
5868 CBTSetVref(p, GetCmdBusTrainingVrefPinMuxValue(p,uiFinalVref), operating_fsp, 1);
5869 }
5870 else
5871 {
5872 CBTSetVref(p, GetCmdBusTrainingVrefPinMuxValue(p,uiFinalVref), operating_fsp, 0); //Francis, normol mode go DQ pin set vref, don't set final_set_flag here
5873 }
5874
5875 mcSHOW_DBG_MSG(("\nVref(ca) range %d: %d\n", gCBT_VREF_RANGE_SEL, uiFinalVref));
5876 mcFPRINTF((fp_A60501, "\nVref(ca) is Range %d: %d\n", gCBT_VREF_RANGE_SEL, uiFinalVref));
5877#if VENDER_JV_LOG
5878 mcSHOW_DBG_MSG5(("\nVref(ca) range %d: %d\n", gCBT_VREF_RANGE_SEL, uiFinalVref));
5879#endif
5880
5881#ifdef FOR_HQA_TEST_USED
5882 gFinalCBTVrefCA[p->channel][p->rank] = uiFinalVref & 0x3f;
5883#endif
5884#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
5885 if(p->femmc_Ready==0)
5886 {
5887 p->pSavetimeData->u1CBTVref_Save[p->channel][p->rank]= uiFinalVref;
5888 }
5889#endif
5890
5891 if (p->dram_cbt_mode[p->rank] == CBT_BYTE_MODE1)
5892 {
5893 //Step 1: Enter Command Bus Training Mode
5894 CBTEntry(p, operating_fsp, operation_frequency);
5895 //Step 2: wait tCAENT
5896 mcDELAY_US(1);
5897
5898#if (FOR_DV_SIMULATION_USED==0)
5899 //switch to high freq
5900 if (operating_fsp == FSP_1)
5901 {
5902 CBT_Switch_Freq(p, CBT_HIGH_FREQ);
5903 }
5904#endif
5905 }
5906
5907 //Set CLK and CA delay in CBT mode to prevent dram abnormal.
5908 CBTSetCACLKResult(p, iFinalCACLK, s1CACenterDiff);
5909
5910 //wait tVREF_LONG
5911 mcDELAY_US(1);
5912
5913 //------------- CS and CLK ----------
5914 CBTAdjustCS(p);
5915
5916//------- Going to exit Command bus training(CBT) mode.-------------
5917#if (FOR_DV_SIMULATION_USED==0)
5918 //switch to low freq
5919 if (operating_fsp == FSP_1)
5920 {
5921 CBT_Switch_Freq(p, CBT_LOW_FREQ);
5922 }
5923#endif
5924
5925#if EYESCAN_LOG || defined(FOR_HQA_TEST_USED)
5926 gFinalCBTVrefDQ[p->channel][p->rank] = uiFinalVref;
5927#endif
5928
5929 CBTExit(p, operating_fsp, operation_frequency);
5930
5931 if (p->dram_cbt_mode[p->rank] == CBT_NORMAL_MODE)
5932 {
5933 CBTSetFSP(p, operating_fsp, 1);
5934 CBTSetVref(p, uiFinalVref, operating_fsp, 1); //francis, normal mode go MR12 set vref again, set final_set_flag to force to MR12 flow
5935 }
5936
5937#if (FOR_DV_SIMULATION_USED==0)
5938 //switch to high freq
5939 if (operating_fsp == FSP_1)
5940 {
5941 CBT_Switch_Freq(p, CBT_HIGH_FREQ);
5942 }
5943#endif
5944
5945 if((p->rank+1) == p->support_rank_num) // both rank calibration done.
5946 {
5947 mcSHOW_DBG_MSG(("\n[CmdBusTrainingLP4] Final result for both ranks\nClk dly= %d PI\nCA dly= %d PI\nCS dly= %d PI\n\n", CATrain_ClkDelay[p->channel][p->rank], CATrain_CmdDelay[p->channel][p->rank], CATrain_CsDelay[p->channel][p->rank]));
5948 mcFPRINTF((fp_A60501, "\n[CmdBusTrainingLP4] Final result for both ranks\nClk dly= %d PI\nCA dly= %d PI\nCS dly=%d PI\n\n", CATrain_ClkDelay[p->channel][p->rank], CATrain_CmdDelay[p->channel][p->rank], CATrain_CsDelay[p->channel][p->rank]));
5949 }
5950 mcSHOW_DBG_MSG3(("\n[CmdBusTrainingLP4] Done\n"));
5951 mcFPRINTF((fp_A60501, "\n[CmdBusTrainingLP4] Done\n"));
5952
5953 //tx_rank_sel is selected by HW //Lewis@20180509: tx_rank_sel is selected by SW in CBT if TMRRI design has changed.
5954 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANK);
5955 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANKFIX); //TXRANKFIX should be write after TXRANK
5956
5957 //Restore setting registers
5958 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
5959
5960 return DRAM_OK;
5961}
5962#endif //SIMUILATION_LP4_CBT
5963
5964//-------------------------------------------------------------------------
5965/** DramcWriteLeveling
5966 * start Write Leveling Calibration.
5967 * @param p Pointer of context created by DramcCtxCreate.
5968 * @param apply (U8): 0 don't apply the register we set 1 apply the register we set ,default don't apply.
5969 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
5970 */
5971//-------------------------------------------------------------------------
5972#define WRITE_LEVELING_MOVD_DQS 1//UI
5973
5974
5975// NOT suitable for Gating delay
5976static DRAM_STATUS_T ExecuteMoveDramCDelay(DRAMC_CTX_T *p, REG_TRANSFER_T regs[], S8 iShiftUI)
5977{
5978 S32 s4HighLevelDelay, s4DelaySum;
5979 U32 u4Tmp0p5T, u4Tmp2T;
5980 U8 ucDataRateDivShift = 0;
5981 DRAM_STATUS_T MoveResult;
5982
5983 if (u1IsLP4Family(p->dram_type))
5984 {
5985 ucDataRateDivShift = 3;
5986 }
5987#if ENABLE_LP3_SW
5988 else
5989 {
5990 ucDataRateDivShift = 2;
5991 }
5992#endif /* ENABLE_LP3_SW */
5993
5994 u4Tmp0p5T = u4IO32ReadFldAlign(DRAMC_REG_ADDR(regs[0].u4Addr), regs[0].u4Fld) & (~(1<<ucDataRateDivShift));
5995 u4Tmp2T = u4IO32ReadFldAlign(DRAMC_REG_ADDR(regs[1].u4Addr), regs[1].u4Fld);
5996 //mcSHOW_DBG_MSG(("\n[MoveDramC_Orz] u4Tmp2T:%d, u4Tmp0p5T: %d,\n", u4Tmp2T, u4Tmp0p5T));
5997 //mcFPRINTF((fp_A60501, "\n[MoveDramC_Orz] u4Tmp2T:%d, u4Tmp0p5T: %d,\n", u4Tmp2T, u4Tmp0p5T));
5998
5999 s4HighLevelDelay = (u4Tmp2T <<ucDataRateDivShift) + u4Tmp0p5T;
6000 s4DelaySum = (s4HighLevelDelay + iShiftUI);
6001 //mcSHOW_DBG_MSG(("\n[MoveDramC_Orz] s4HighLevelDealy(%d) + iShiftUI(%d) = %d\n", s4HighLevelDelay, iShiftUI, s4DelaySum));
6002
6003 if(s4DelaySum < 0)
6004 {
6005 u4Tmp0p5T =0;
6006 u4Tmp2T=0;
6007 MoveResult = DRAM_FAIL;
6008 //mcSHOW_ERR_MSG(("\n[MoveDramC_Orz] s4HighLevelDealy(%d) + iShiftUI(%d) is small than 0!!\n", s4HighLevelDelay, iShiftUI));
6009 }
6010 else
6011 {
6012 u4Tmp2T = s4DelaySum >> ucDataRateDivShift;
6013 u4Tmp0p5T = s4DelaySum - (u4Tmp2T <<ucDataRateDivShift);
6014 MoveResult = DRAM_OK;
6015 }
6016
6017 vIO32WriteFldAlign(DRAMC_REG_ADDR(regs[0].u4Addr), u4Tmp0p5T, regs[0].u4Fld);
6018 vIO32WriteFldAlign(DRAMC_REG_ADDR(regs[1].u4Addr), u4Tmp2T, regs[1].u4Fld);
6019 //mcSHOW_DBG_MSG(("\n[MoveDramC_Orz] Final ==> u4Tmp2T:%d, u4Tmp0p5T: %d,\n", u4Tmp2T, u4Tmp0p5T));
6020 //mcFPRINTF((fp_A60501, "\n[MoveDramC_Orz] Final ==> u4Tmp2T:%d, u4Tmp0p5T: %d,\n", u4Tmp2T, u4Tmp0p5T));
6021
6022 return MoveResult;
6023}
6024
6025void MoveDramC_TX_DQS(DRAMC_CTX_T *p, U8 u1ByteIdx, S8 iShiftUI)
6026{
6027 REG_TRANSFER_T TransferReg[2];
6028
6029 //mcSHOW_DBG_MSG(("\n[MoveDramC_TX_DQS] Byte %d, iShiftUI %d\n", u1ByteIdx, iShiftUI));
6030
6031 switch(u1ByteIdx)
6032 {
6033 case 0:
6034 // DQS0
6035 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6036 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_DQS0;
6037 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6038 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_DQS0;
6039 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6040 break;
6041
6042 case 1:
6043 // DQS1
6044 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6045 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_DQS1;
6046 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6047 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_DQS1;
6048 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6049 break;
6050
6051 case 2:
6052 // DQS2
6053 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6054 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_DQS2;
6055 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6056 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_DQS2;
6057 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6058 break;
6059
6060 case 3:
6061 // DQS3
6062 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6063 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_DQS3;
6064 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6065 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_DQS3;
6066 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6067 break;
6068
6069 default:
6070 break;
6071 }
6072}
6073
6074void MoveDramC_TX_DQS_OEN(DRAMC_CTX_T *p, U8 u1ByteIdx, S8 iShiftUI)
6075{
6076 REG_TRANSFER_T TransferReg[2];
6077
6078 //mcSHOW_DBG_MSG(("\n[MoveDramC_TX_DQS_OEN] Byte %d, iShiftUI %d\n", u1ByteIdx, iShiftUI));
6079
6080 switch(u1ByteIdx)
6081 {
6082 case 0:
6083 // DQS_OEN_0
6084 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6085 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_OEN_DQS0;
6086 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6087 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_OEN_DQS0;
6088 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6089 break;
6090
6091 case 1:
6092 // DQS_OEN_1
6093 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6094 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_OEN_DQS1;
6095 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6096 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_OEN_DQS1;
6097 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6098 break;
6099
6100 case 2:
6101 // DQS_OEN_2
6102 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6103 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_OEN_DQS2;
6104 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6105 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_OEN_DQS2;
6106 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6107 break;
6108
6109 case 3:
6110 // DQS_OEN_3
6111 TransferReg[0].u4Addr = DRAMC_REG_SHU_SELPH_DQS1;
6112 TransferReg[0].u4Fld =SHU_SELPH_DQS1_DLY_OEN_DQS3;
6113 TransferReg[1].u4Addr = DRAMC_REG_SHU_SELPH_DQS0;
6114 TransferReg[1].u4Fld =SHU_SELPH_DQS0_TXDLY_OEN_DQS3;
6115 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6116 break;
6117
6118 default:
6119 break;
6120 }
6121}
6122
6123
6124void MoveDramC_TX_DQ(DRAMC_CTX_T *p, U8 u1ByteIdx, S8 iShiftUI)
6125{
6126 REG_TRANSFER_T TransferReg[2];
6127
6128 //mcSHOW_DBG_MSG(("\n[MoveDramC_TX_DQ] Byte %d, iShiftUI %d\n", u1ByteIdx, iShiftUI));
6129
6130 switch(u1ByteIdx)
6131 {
6132 case 0:
6133 // DQM0
6134 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6135 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM0;
6136 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6137 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM0;
6138 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6139
6140 // DQ0
6141 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6142 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ0;
6143 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6144 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ0;
6145 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6146 break;
6147
6148 case 1:
6149 // DQM1
6150 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6151 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM1;
6152 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6153 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM1;
6154 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6155 // DQ1
6156 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6157 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ1;
6158 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6159 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ1;
6160 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6161 break;
6162
6163 case 2:
6164 // DQM2
6165 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6166 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM2;
6167 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6168 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM2;
6169 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6170 // DQ2
6171 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6172 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ2;
6173 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6174 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ2;
6175 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6176 break;
6177
6178 case 3:
6179 // DQM3
6180 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6181 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM3;
6182 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6183 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM3;
6184 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6185 // DQ3
6186 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6187 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ3;
6188 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6189 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ3;
6190 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6191 break;
6192 }
6193}
6194
6195void MoveDramC_TX_DQ_OEN(DRAMC_CTX_T *p, U8 u1ByteIdx, S8 iShiftUI)
6196{
6197 REG_TRANSFER_T TransferReg[2];
6198
6199 //mcSHOW_DBG_MSG(("\n[MoveDramC_TX_DQ_OEN] Byte %d, iShiftUI %d\n", u1ByteIdx, iShiftUI));
6200
6201 switch(u1ByteIdx)
6202 {
6203 case 0:
6204 // DQM_OEN_0
6205 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6206 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_OEN_DQM0;
6207 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6208 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_OEN_DQM0;
6209 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6210 // DQ_OEN_0
6211 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6212 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_OEN_DQ0;
6213 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6214 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_OEN_DQ0;
6215 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6216 break;
6217
6218 case 1:
6219 // DQM_OEN_1
6220 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6221 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_OEN_DQM1;
6222 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6223 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_OEN_DQM1;
6224 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6225 // DQ_OEN_1
6226 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6227 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_OEN_DQ1;
6228 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6229 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_OEN_DQ1;
6230 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6231 break;
6232
6233 case 2:
6234 // DQM_OEN_2
6235 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6236 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_OEN_DQM2;
6237 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6238 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_OEN_DQM2;
6239 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6240 // DQ_OEN_2
6241 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6242 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_OEN_DQ2;
6243 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6244 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_OEN_DQ2;
6245 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6246 break;
6247
6248 case 3:
6249 // DQM_OEN_3
6250 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
6251 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_OEN_DQM3;
6252 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
6253 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_OEN_DQM3;
6254 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6255 // DQ_OEN_3
6256 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
6257 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_OEN_DQ3;
6258 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
6259 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_OEN_DQ3;
6260 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
6261 break;
6262 }
6263}
6264
6265#if ENABLE_LP3_SW
6266//for LPDDR3 DQ delay line used
6267void Set_RX_DQ_DelayLine_Phy_Byte(DRAMC_CTX_T *p, U8 u1ByteIdx, U8 value[8])
6268{
6269 DRAM_CHANNEL_T backup_channel;
6270 backup_channel = p->channel;
6271
6272#if (fcFOR_PINMUX == fcLaurel)
6273
6274 switch(u1ByteIdx)
6275 {
6276 case 0:
6277 p->channel = CHANNEL_B;
6278 //DQ0 -> BRDQ0_B1 //DQ3 -> BRDQ1_B1
6279 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2),
6280 P_Fld(value[0], SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_F_DLY_B1) |
6281 P_Fld(value[0], SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_R_DLY_B1) |
6282 P_Fld(value[3], SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_F_DLY_B1) |
6283 P_Fld(value[3], SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_R_DLY_B1) );
6284 //DQ7 -> BRDQ2_B1 //DQ1 -> BRDQ3_B1
6285 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ3),
6286 P_Fld(value[7], SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_F_DLY_B1) |
6287 P_Fld(value[7], SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_R_DLY_B1) |
6288 P_Fld(value[1], SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_F_DLY_B1) |
6289 P_Fld(value[1], SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_R_DLY_B1) );
6290 //DQ2 -> BRDQ4_B1 //DQ6 -> BRDQ5_B1
6291 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ4),
6292 P_Fld(value[2], SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_F_DLY_B1) |
6293 P_Fld(value[2], SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_R_DLY_B1) |
6294 P_Fld(value[6], SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_F_DLY_B1) |
6295 P_Fld(value[6], SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_R_DLY_B1));
6296 //DQ5 -> BRDQ6_B1 //DQ4 -> BRDQ7_B1
6297 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ5),
6298 P_Fld(value[5], SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_F_DLY_B1) |
6299 P_Fld(value[5], SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_R_DLY_B1) |
6300 P_Fld(value[4], SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_F_DLY_B1) |
6301 P_Fld(value[4], SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_R_DLY_B1));
6302 break;
6303 case 1:
6304 p->channel = CHANNEL_B;
6305 //DQ5 -> BRCA0 //DQ1 -> BRCA1
6306 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD2),
6307 P_Fld(value[5], SHU1_R0_CA_CMD2_RG_RK0_RX_ARCA0_F_DLY) |
6308 P_Fld(value[5], SHU1_R0_CA_CMD2_RG_RK0_RX_ARCA0_R_DLY) |
6309 P_Fld(value[1], SHU1_R0_CA_CMD2_RG_RK0_RX_ARCA1_F_DLY) |
6310 P_Fld(value[1], SHU1_R0_CA_CMD2_RG_RK0_RX_ARCA1_R_DLY));
6311 //DQ4 -> BRCA2 //DQ6 -> BRCA3
6312 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD3),
6313 P_Fld(value[4], SHU1_R0_CA_CMD3_RG_RK0_RX_ARCA2_F_DLY) |
6314 P_Fld(value[4], SHU1_R0_CA_CMD3_RG_RK0_RX_ARCA2_R_DLY) |
6315 P_Fld(value[6], SHU1_R0_CA_CMD3_RG_RK0_RX_ARCA3_F_DLY) |
6316 P_Fld(value[6], SHU1_R0_CA_CMD3_RG_RK0_RX_ARCA3_R_DLY));
6317 //DQ2 -> BRCA4 //DQ7 -> BRCS5
6318 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD4),
6319 P_Fld(value[2], SHU1_R0_CA_CMD4_RG_RK0_RX_ARCA4_F_DLY) |
6320 P_Fld(value[2], SHU1_R0_CA_CMD4_RG_RK0_RX_ARCA4_R_DLY) |
6321 P_Fld(value[7], SHU1_R0_CA_CMD4_RG_RK0_RX_ARCA5_F_DLY) |
6322 P_Fld(value[7], SHU1_R0_CA_CMD4_RG_RK0_RX_ARCA5_R_DLY));
6323 //DQ3 -> BRCKE0 //DQ0 -> BRCKE1
6324 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD5),
6325 P_Fld(value[3], SHU1_R0_CA_CMD5_RG_RK0_RX_ARCKE0_F_DLY) |
6326 P_Fld(value[3], SHU1_R0_CA_CMD5_RG_RK0_RX_ARCKE0_R_DLY) |
6327 P_Fld(value[0], SHU1_R0_CA_CMD5_RG_RK0_RX_ARCKE1_F_DLY) |
6328 P_Fld(value[0], SHU1_R0_CA_CMD5_RG_RK0_RX_ARCKE1_R_DLY));
6329
6330 break;
6331 case 2:
6332 p->channel = CHANNEL_A;
6333 //DQ1 -> ARDQ0_B1 //DQ0 -> ARDQ1_B1
6334 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2),
6335 P_Fld(value[1], SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_F_DLY_B1) |
6336 P_Fld(value[1], SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_R_DLY_B1) |
6337 P_Fld(value[0], SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_F_DLY_B1) |
6338 P_Fld(value[0], SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_R_DLY_B1));
6339 //DQ4 -> ARDQ2_B1 //DQ5 -> ARDQ3_B1
6340 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ3),
6341 P_Fld(value[4], SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_F_DLY_B1) |
6342 P_Fld(value[4], SHU1_R0_B1_DQ3_RK0_RX_ARDQ2_R_DLY_B1) |
6343 P_Fld(value[5], SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_F_DLY_B1) |
6344 P_Fld(value[5], SHU1_R0_B1_DQ3_RK0_RX_ARDQ3_R_DLY_B1));
6345 //DQ2 -> ARDQ4_B1 //DQ6 -> ARDQ5_B1
6346 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ4),
6347 P_Fld(value[2], SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_F_DLY_B1) |
6348 P_Fld(value[2], SHU1_R0_B1_DQ4_RK0_RX_ARDQ4_R_DLY_B1) |
6349 P_Fld(value[6], SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_F_DLY_B1) |
6350 P_Fld(value[6], SHU1_R0_B1_DQ4_RK0_RX_ARDQ5_R_DLY_B1));
6351 //DQ3 -> ARDQ6_B1 //DQ7 -> ARDQ7_B1
6352 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ5),
6353 P_Fld(value[3], SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_F_DLY_B1) |
6354 P_Fld(value[3], SHU1_R0_B1_DQ5_RK0_RX_ARDQ6_R_DLY_B1) |
6355 P_Fld(value[7], SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_F_DLY_B1) |
6356 P_Fld(value[7], SHU1_R0_B1_DQ5_RK0_RX_ARDQ7_R_DLY_B1));
6357 break;
6358 case 3:
6359 p->channel = CHANNEL_B;
6360 //DQ5 -> BRDQ0_B0 //DQ0 -> BRDQ1_B0
6361 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2),
6362 P_Fld(value[5], SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_F_DLY_B0) |
6363 P_Fld(value[5], SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_R_DLY_B0) |
6364 P_Fld(value[0], SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_F_DLY_B0) |
6365 P_Fld(value[0], SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_R_DLY_B0));
6366 //DQ6 -> BRDQ2_B0 //DQ4 -> BRDQ3_B0
6367 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ3),
6368 P_Fld(value[6], SHU1_R0_B0_DQ3_RK0_RX_ARDQ2_F_DLY_B0) |
6369 P_Fld(value[6], SHU1_R0_B0_DQ3_RK0_RX_ARDQ2_R_DLY_B0) |
6370 P_Fld(value[4], SHU1_R0_B0_DQ3_RK0_RX_ARDQ3_F_DLY_B0) |
6371 P_Fld(value[4], SHU1_R0_B0_DQ3_RK0_RX_ARDQ3_R_DLY_B0));
6372 //DQ3 -> BRDQ4_B0 //DQ7 -> BRDQ5_B0
6373 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ4),
6374 P_Fld(value[3], SHU1_R0_B0_DQ4_RK0_RX_ARDQ4_F_DLY_B0) |
6375 P_Fld(value[3], SHU1_R0_B0_DQ4_RK0_RX_ARDQ4_R_DLY_B0) |
6376 P_Fld(value[7], SHU1_R0_B0_DQ4_RK0_RX_ARDQ5_F_DLY_B0) |
6377 P_Fld(value[7], SHU1_R0_B0_DQ4_RK0_RX_ARDQ5_R_DLY_B0));
6378 //DQ2 -> BRDQ6_B0 //DQ1 -> BRDQ7_B0
6379 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ5),
6380 P_Fld(value[2], SHU1_R0_B0_DQ5_RK0_RX_ARDQ6_F_DLY_B0) |
6381 P_Fld(value[2], SHU1_R0_B0_DQ5_RK0_RX_ARDQ6_R_DLY_B0) |
6382 P_Fld(value[1], SHU1_R0_B0_DQ5_RK0_RX_ARDQ7_F_DLY_B0) |
6383 P_Fld(value[1], SHU1_R0_B0_DQ5_RK0_RX_ARDQ7_R_DLY_B0));
6384 break;
6385
6386 }
6387#endif
6388 p->channel = backup_channel;
6389}
6390
6391//for LPDDR3 DQM delay line used
6392void Set_RX_DQM_DelayLine_Phy_Byte(DRAMC_CTX_T *p, U8 u1ByteIdx, S8 value)
6393{
6394 DRAM_CHANNEL_T backup_channel;
6395 backup_channel = p->channel;
6396
6397#if (fcFOR_PINMUX == fcLaurel)
6398 switch(u1ByteIdx)
6399 {
6400 case 0:
6401 p->channel = CHANNEL_B;
6402 //DQM0 -> BRDQM0_B1
6403 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), P_Fld(value, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_F_DLY_B1) | P_Fld(value, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_R_DLY_B1));
6404 break;
6405 case 1:
6406 p->channel = CHANNEL_B;
6407 //DQM1 -> BRCS0
6408 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD6), P_Fld(value, SHU1_R0_CA_CMD6_RG_RK0_RX_ARCS0_F_DLY) | P_Fld(value, SHU1_R0_CA_CMD6_RG_RK0_RX_ARCS0_R_DLY));
6409 break;
6410 case 2:
6411 p->channel = CHANNEL_A;
6412 //DQM2 -> ARDQM0_B1
6413 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), P_Fld(value, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_F_DLY_B1) | P_Fld(value, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_R_DLY_B1));
6414 break;
6415 case 3:
6416 p->channel = CHANNEL_B;
6417 //DQM3 -> BRDQM0_B0
6418 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), P_Fld(value, SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_F_DLY_B0) | P_Fld(value, SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_R_DLY_B0));
6419 break;
6420
6421 }
6422#endif
6423
6424 p->channel = backup_channel;
6425}
6426#endif
6427
6428#if SIMULATION_WRITE_LEVELING
6429#if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6430void WriteLevelingMoveDQSInsteadOfCLK(DRAMC_CTX_T *p)
6431{
6432 U8 u1ByteIdx;
6433 U8 backup_rank, ii;
6434
6435 backup_rank = u1GetRank(p);
6436
6437 for(u1ByteIdx =0 ; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
6438 {
6439 MoveDramC_TX_DQS(p, u1ByteIdx, -WRITE_LEVELING_MOVD_DQS);
6440 MoveDramC_TX_DQS_OEN(p, u1ByteIdx, -WRITE_LEVELING_MOVD_DQS);
6441
6442 for(ii=RANK_0; ii<RANK_MAX; ii++)
6443 {
6444 vSetRank(p, ii);
6445 MoveDramC_TX_DQ(p, u1ByteIdx, -WRITE_LEVELING_MOVD_DQS);
6446 MoveDramC_TX_DQ_OEN(p, u1ByteIdx, -WRITE_LEVELING_MOVD_DQS);
6447 }
6448 vSetRank(p, backup_rank);
6449 }
6450}
6451#endif
6452
6453
6454//static void vSetDramMRWriteLevelingOnOff(DRAMC_CTX_T *p, U8 u1OnOff)
6455void vSetDramMRWriteLevelingOnOff(DRAMC_CTX_T *p, U8 u1OnOff)
6456{
6457 // MR2 OP[7] to enable/disable write leveling
6458 if(u1OnOff)
6459 u1MR02Value[p->dram_fsp] |= 0x80; // OP[7] WR LEV =1
6460 else
6461 u1MR02Value[p->dram_fsp] &= 0x7f; // OP[7] WR LEV =0
6462
6463 DramcModeRegWriteByRank(p, p->rank, 2, u1MR02Value[p->dram_fsp]);
6464}
6465
6466#define DQS_DUTY_MEASURE_WITH_WRITE_LEVELING 0
6467DRAM_STATUS_T DramcWriteLeveling(DRAMC_CTX_T *p)
6468{
6469// Note that below procedure is based on "ODT off"
6470 DRAM_STATUS_T KResult= DRAM_FAIL;
6471
6472 U32 u4value=0, u4dq_o1=0;
6473 U8 byte_i, ucsample_count;
6474 S32 ii;
6475 U8 ucsample_status[DQS_NUMBER], ucdq_o1_perbyte[DQS_NUMBER], ucdq_o1_index[DQS_NUMBER];
6476 DRAM_RANK_T backup_rank;
6477
6478 S32 wrlevel_dq_delay[DQS_NUMBER]; // 3 is channel number
6479#if ENABLE_LP3_SW
6480 S32 wrlevel_dqs_delay[DQS_NUMBER]; // 3 is channel number
6481#endif
6482
6483 #if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6484 S32 i4PIBegin, i4PIEnd;
6485 U8 u1PIStep;
6486 #endif
6487
6488 #if DQS_DUTY_MEASURE_WITH_WRITE_LEVELING
6489 U16 u2TriggerCnt;
6490 #endif
6491
6492 // error handling
6493 if (!p)
6494 {
6495 mcSHOW_ERR_MSG(("context NULL\n"));
6496 return DRAM_FAIL;
6497 }
6498
6499 U32 u4RegBackupAddress[] =
6500 {
6501 (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)),
6502 (DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL)),
6503 (DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL)),
6504 (DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV)),
6505 (DRAMC_REG_ADDR(DRAMC_REG_CKECTRL)),
6506 };
6507
6508#if MRW_CHECK_ONLY
6509 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
6510#endif
6511
6512 vPrintCalibrationBasicInfo(p);
6513
6514 fgwrlevel_done = 0;
6515 backup_rank = u1GetRank(p);
6516
6517 #if CBT_WORKAROUND_O1_SWAP
6518 if(u1IsLP4Family(p->dram_type))
6519 {
6520 CATrain_CmdDelay[p->channel][p->rank] = 0;//u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_ARPI_CMD), ARPI_CMD_DA_ARPI_CMD);
6521 CATrain_CsDelay[p->channel][p->rank] = 0;//u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_ARPI_CMD), ARPI_CMD_DA_ARPI_CS);
6522 CATrain_ClkDelay[p->channel][p->rank] = 0;//u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_ARPI_CMD), ARPI_CMD_DA_ARPI_CK);
6523 }
6524 #endif
6525
6526 //DramcRankSwap(p, p->rank);
6527 //tx_rank_sel is selected by SW //Lewis@20180604: tx_rank_sel is selected by SW in WL if TMRRI design has changed.
6528 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), p->rank, RKCFG_TXRANK);
6529 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX); //TXRANKFIX should be write after TXRANK
6530
6531 // DQ mapping
6532 ///!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6533 /// Note : uiLPDDR_O1_Mapping_POP, need to take care mapping in real chip, but not in test chip.
6534 /// Everest : there is bit swap inside single byte. PHY & DRAM is 1-1 byte mapping, no swap.
6535 for (byte_i=0; byte_i<(p->data_width/DQS_BIT_NUMBER); byte_i++)
6536 {
6537 ucdq_o1_index[byte_i] = byte_i*8;
6538 }
6539
6540#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
6541 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
6542 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
6543#endif
6544
6545#if REG_ACCESS_PORTING_DGB
6546 RegLogEnable =1;
6547 mcSHOW_DBG_MSG(("\n[REG_ACCESS_PORTING_FUNC] DramcWriteLeveling\n"));
6548 mcFPRINTF((fp_A60501, "\n[REG_ACCESS_PORTING_FUNC] DramcWriteLeveling\n"));
6549#endif
6550
6551 // backup mode settings
6552 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
6553
6554 vAutoRefreshSwitch(p, DISABLE); //When doing CA training, should make sure that auto refresh is disable
6555
6556 #if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6557 if(p->arfgWriteLevelingInitShif[p->channel][p->rank] ==FALSE)
6558 {
6559 WriteLevelingMoveDQSInsteadOfCLK(p);
6560 //p->arfgWriteLevelingInitShif[p->channel][p->rank] =TRUE;
6561 p->arfgWriteLevelingInitShif[p->channel][RANK_0] =TRUE;
6562 p->arfgWriteLevelingInitShif[p->channel][RANK_1] =TRUE;
6563 #if TX_PERBIT_INIT_FLOW_CONTROL
6564 // both 2 rank use one write leveling result, TX need to udpate.
6565 p->fgTXPerbifInit[p->channel][RANK_0]= FALSE;
6566 p->fgTXPerbifInit[p->channel][RANK_1]= FALSE;
6567 #endif
6568
6569 mcSHOW_DBG_MSG3(("WriteLevelingMoveDQSInsteadOfCLK\n"));
6570 mcFPRINTF((fp_A60501, "WriteLevelingMoveDQSInsteadOfCLK\n"));
6571 }
6572 #endif
6573
6574#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_WRITELEVELING)
6575 if(p->femmc_Ready==1)
6576 {
6577 wrlevel_dqs_final_delay[0] =p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][0];
6578 wrlevel_dqs_final_delay[1] =p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][1];
6579
6580 ucsample_count = 0xff;
6581 KResult = DRAM_OK;
6582 vSetCalibrationResult(p, DRAM_CALIBRATION_WRITE_LEVEL, DRAM_OK);
6583 }
6584 else
6585#endif
6586 {
6587 //write leveling mode initialization
6588 //REFCNT_FR_CLK = 0 (0x1dc[23:16]), ADVREFEN = 0 (0x44[30]), (CONF2_REFCNT =0)
6589 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF); //MIOCKCTRLOFF=1
6590 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_PHYCLKDYNGEN); //PHYCLKDYNGEN=0
6591
6592 //Make CKE fixed at 1 (Don't enter power down, Put this before issuing MRS): CKEFIXON = 1
6593 CKEFixOnOff(p, p->rank, CKE_FIXON, CKE_WRITE_TO_ONE_CHANNEL);
6594
6595 //PHY RX Setting for Write Leveling
6596 //Let IO toO1 path valid, Enable SMT_EN
6597 O1PathOnOff(p, 1);
6598
6599 // enable DDR write leveling mode: issue MR2[7] to enable write leveling (refer to DEFAULT MR2 value)
6600 vSetDramMRWriteLevelingOnOff(p, ENABLE);
6601
6602 //wait tWLDQSEN (25 nCK / 25ns) after enabling write leveling mode (DDR3 / LPDDDR3)
6603 mcDELAY_US(1);
6604
6605 //Set {R_DQS_B3_G R_DQS_B2_G R_DQS_B1_G R_DQS_B0_G}=1010: 0x13c[4:1] (this depends on sel_ph setting)
6606 //Enable Write leveling: 0x13c[0]
6607 //vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEVELING), P_Fld(0xa, WRITE_LEVELING_DQSBX_G)|P_Fld(1, WRITE_LEVELING_WRITE_LEVEL_EN));
6608 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0xa, WRITE_LEV_DQSBX_G);
6609 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_WRITE_LEVEL_EN);
6610 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_CBTMASKDQSOE);
6611
6612 // select DQS
6613#if ENABLE_LP3_SW
6614 if(p->dram_type == TYPE_LPDDR3)
6615 {
6616 u4value = 0xf;//select byte 0.1.2.3
6617 }
6618 else //LPDDR4
6619#endif /* ENABLE_LP3_SW */
6620 {
6621 u4value = 0x3;//select byte 0.1
6622 }
6623 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), u4value, WRITE_LEV_DQS_SEL);
6624
6625 // wait tWLMRD (40 nCL / 40 ns) before DQS pulse (DDR3 / LPDDR3)
6626 mcDELAY_US(1);
6627
6628 //Proceed write leveling...
6629 //Initilize sw parameters
6630 for (ii=0; ii < (S32)(p->data_width/DQS_BIT_NUMBER); ii++)
6631 {
6632 ucsample_status[ii] = 0;
6633 wrlevel_dqs_final_delay[ii] = 0;
6634 }
6635
6636 //used for WL done status
6637 // each bit of sample_cnt represents one-byte WL status
6638 // 1: done or N/A. 0: NOK
6639 if ((p->data_width == DATA_WIDTH_16BIT))
6640 {
6641 ucsample_count = 0xfc;
6642 }
6643 else
6644 {
6645 ucsample_count = 0xf0;
6646 }
6647
6648 mcSHOW_DBG_MSG(("[Write Leveling]\n"));
6649 mcSHOW_DBG_MSG(("delay byte0 byte1 byte2 byte3\n\n"));
6650
6651 mcFPRINTF((fp_A60501, "\n\tdramc_write_leveling_swcal\n"));
6652 mcFPRINTF((fp_A60501, "delay byte0 byte1 byte2 byte3\n\n"));
6653
6654 // Set DQS output delay to 0
6655 if(u1IsLP4Family(p->dram_type))
6656 {
6657 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0); //rank0, byte0, DQS delay
6658 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), 0, SHU1_R0_B1_DQ7_RK0_ARPI_PBYTE_B1); //rank0, byte1, DQS delay
6659 }
6660#if ENABLE_LP3_SW
6661 else
6662 {
6663 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6664 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6665 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6666 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), 0, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6667 }
6668#endif
6669 #if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6670 i4PIBegin = WRITE_LEVELING_MOVD_DQS*32 -MAX_CLK_PI_DELAY-1;
6671 #endif
6672
6673 #if (fcFOR_CHIP_ID == fcLaurel)
6674 i4PIBegin += 10; // for save time
6675 #endif
6676
6677 i4PIEnd = 63; // SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0: 6 bits
6678
6679 #if DQS_DUTY_MEASURE_WITH_WRITE_LEVELING
6680 if(p->channel==CHANNEL_A && p->frequency == u2DFSGetHighestFreq(p))
6681 u1PIStep =2;
6682 else
6683 #endif
6684 u1PIStep =1;
6685
6686 #if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6687 for (ii=i4PIBegin; ii<i4PIEnd; ii+=u1PIStep)
6688 #else
6689 for (ii=(-MAX_CLK_PI_DELAY); ii<=MAX_TX_DQSDLY_TAPS; ii++)
6690 #endif
6691 {
6692 #if DQS_DUTY_MEASURE_WITH_WRITE_LEVELING
6693 if(u1PIStep==2)
6694 mcDELAY_MS(10000);
6695 #endif
6696
6697 if (ii <= 0)
6698 {
6699 // Adjust Clk output delay.
6700 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), -ii, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK);
6701 }
6702 else
6703 {
6704 // Adjust DQS output delay.
6705 // PI (TX DQ/DQS adjust at the same time)
6706 if(u1IsLP4Family(p->dram_type))
6707 {
6708 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ii, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0); //rank0, byte0, DQS delay
6709 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), ii, SHU1_R0_B1_DQ7_RK0_ARPI_PBYTE_B1); //rank0, byte1, DQS delay
6710 }
6711#if ENABLE_LP3_SW
6712 else
6713 {
6714 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ii, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6715 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ii, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6716 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ii, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6717 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ii, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6718 }
6719#endif
6720 }
6721
6722 //Trigger DQS pulse, R_DQS_WLEV: 0x13c[8] from 1 to 0
6723 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_DQS_WLEV);
6724 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0, WRITE_LEV_DQS_WLEV);
6725
6726 #if DQS_DUTY_MEASURE_WITH_WRITE_LEVELING
6727 if(u1PIStep==2)
6728 {
6729 for(u2TriggerCnt=0; u2TriggerCnt<10000; u2TriggerCnt++)
6730 {
6731 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 1, WRITE_LEV_DQS_WLEV);
6732 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_WRITE_LEV), 0, WRITE_LEV_DQS_WLEV);
6733 }
6734 }
6735 #endif
6736
6737 //wait tWLO (7.5ns / 20ns) before output (DDR3 / LPDDR3)
6738 mcDELAY_US(1);
6739
6740 //Read DQ_O1 from register
6741 if(u1IsLP4Family(p->dram_type))
6742 {
6743 u4dq_o1 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_DQO1));
6744 }
6745#if ENABLE_LP3_SW
6746 else //LPRRR3
6747 {
6748 // Get DQ value.
6749 u4dq_o1 = u4IO32Read4B(DRAMC_REG_ADDR(DDRPHY_MISC_DQO1));
6750 //mcSHOW_DBG_MSG2(("DQ_O1: 0x%x\n", u4dq_o1));
6751 }
6752#endif
6753 #ifdef ETT_PRINT_FORMAT
6754 mcSHOW_DBG_MSG2(("%d ", ii));
6755 #else
6756 mcSHOW_DBG_MSG2(("%2d ", ii));
6757 #endif
6758 mcFPRINTF((fp_A60501, "%2d ", ii));
6759
6760 //mcSHOW_DBG_MSG(("0x%x ", u4dq_o1));
6761 //mcFPRINTF((fp_A60501, "0x%x ", u4dq_o1));
6762
6763 for (byte_i = 0; byte_i < (p->data_width/DQS_BIT_NUMBER); byte_i++)
6764 {
6765 ucdq_o1_perbyte[byte_i] = (U8)((u4dq_o1>>ucdq_o1_index[byte_i]) & 0xff); // ==> TOBEREVIEW
6766
6767 mcSHOW_DBG_MSG2(("%x ", ucdq_o1_perbyte[byte_i]));
6768 mcFPRINTF((fp_A60501, "%x ", ucdq_o1_perbyte[byte_i]));
6769
6770 if ((ucsample_status[byte_i]==0) && (ucdq_o1_perbyte[byte_i]==0))
6771 {
6772 ucsample_status[byte_i] = 1;
6773 }
6774 else if ((ucsample_status[byte_i]>=1) && (ucdq_o1_perbyte[byte_i] ==0))
6775 {
6776 ucsample_status[byte_i] = 1;
6777 }
6778 else if ((ucsample_status[byte_i]>=1) && (ucdq_o1_perbyte[byte_i] !=0))
6779 {
6780 ucsample_status[byte_i]++;
6781 }
6782 //mcSHOW_DBG_MSG(("(%x) ", ucsample_status[byte_i]));
6783
6784 if((ucsample_count &(0x01 << byte_i))==0)// result not found of byte yet
6785 {
6786 #if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
6787 if((ucsample_status[byte_i] ==8) || ((ii==i4PIEnd-1) && (ucsample_status[byte_i] >1)))
6788 #else
6789 if((ucsample_status[byte_i] ==8) || ((ii==MAX_TX_DQSDLY_TAPS)&& (ucsample_status[byte_i] >1)))
6790 #endif
6791 {
6792 wrlevel_dqs_final_delay[byte_i] = ii -ucsample_status[byte_i] +2;
6793 ucsample_count |= (0x01 << byte_i);
6794 //mcSHOW_DBG_MSG(("(record %d) ", wrlevel_dqs_final_delay[byte_i]));
6795 }
6796 }
6797 }
6798 mcSHOW_DBG_MSG2(("\n"));
6799 mcFPRINTF((fp_A60501, "\n"));
6800
6801 #if !DQS_DUTY_MEASURE_WITH_WRITE_LEVELING
6802 if (ucsample_count == 0xff)
6803 break; // all byte found, early break.
6804 #endif
6805 }
6806 }
6807
6808 if (ucsample_count == 0xff)
6809 {
6810 // all bytes are done
6811 fgwrlevel_done= 1;
6812 KResult = DRAM_OK;
6813 }
6814 else
6815 {
6816 KResult = DRAM_FAIL;
6817 }
6818
6819 vSetCalibrationResult(p, DRAM_CALIBRATION_WRITE_LEVEL, KResult);
6820
6821 mcSHOW_DBG_MSG2(("pass bytecount = 0x%x (0xff: all bytes pass) \n\n", ucsample_count));
6822 mcFPRINTF((fp_A60501, "pass bytecount = 0x%x (0xff: all bytes pass)\n\n", ucsample_count));
6823#if 0
6824 U32 u4value1=0
6825 S32 ClockDelayMax = MAX_TX_DQSDLY_TAPS;
6826
6827 for (byte_i = 0; byte_i < (p->data_width/DQS_BIT_NUMBER); byte_i++)
6828 {
6829 if (ClockDelayMax > wrlevel_dqs_final_delay[byte_i])
6830 {
6831 ClockDelayMax = wrlevel_dqs_final_delay[byte_i];
6832 }
6833 }
6834
6835 if (ClockDelayMax > 0)
6836 {
6837 ClockDelayMax = 0;
6838 }
6839 else
6840 {
6841 ClockDelayMax = -ClockDelayMax;
6842 }
6843
6844 vPrintCalibrationBasicInfo(p);
6845
6846 mcSHOW_DBG_MSG(("WL Clk dly = %d, CA clk dly = %d\n", ClockDelayMax, CATrain_ClkDelay[p->channel][p->rank]));
6847 mcFPRINTF((fp_A60501, "WL Clk dly = %d, CA clk dly = %d\n", ClockDelayMax, CATrain_ClkDelay[p->channel][p->rank]));
6848
6849 // Adjust Clk & CA if needed
6850 if (CATrain_ClkDelay[p->channel][p->rank] < ClockDelayMax)
6851 {
6852 S32 Diff = ClockDelayMax - CATrain_ClkDelay[p->channel][p->rank];
6853 mcSHOW_DBG_MSG(("CA adjust %d taps\n", Diff));
6854 // Write shift value into CA output delay.
6855 if(u1IsLP4Family(p->dram_type))
6856 {
6857 u4value = CATrain_CmdDelay[p->channel][p->rank];
6858 u4value += Diff;
6859 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), u4value, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD);
6860 }
6861#if ENABLE_LP3_SW
6862 else
6863 {
6864#if (fcFOR_PINMUX == fcLaurel)
6865 for(ii=p->rank; ii<RANK_MAX; ii++)
6866 {
6867 vSetRank(p,ii);
6868 u4value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD);
6869 u4value += Diff;
6870 //default value in init() is 0x10 , vIO32Write4B(mcSET_DDRPHY_REG_ADDR_CHC(0x0458), 0x00100000); // Partickl
6871 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), u4value, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CMD);
6872
6873 u4value1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
6874 u4value1 += Diff;
6875 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), u4value1, SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
6876 }
6877 vSetRank(p, backup_rank);
6878#endif
6879 }
6880#endif
6881 mcSHOW_DBG_MSG(("Update CA PI Dly Macro0 = %d, Macro1 = %d\n", u4value, u4value1));
6882 mcFPRINTF((fp_A60501, "Update CA PI Dly Macro0 = %d, Macro1 = %d\n", u4value, u4value1));
6883
6884 // Write shift value into CS output delay.
6885 if(u1IsLP4Family(p->dram_type))
6886 {
6887 //u4value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_ARPI_CMD), ARPI_CMD_DA_ARPI_CS);
6888 u4value = CATrain_CsDelay[p->channel][p->rank];
6889 u4value += Diff;
6890 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), u4value, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
6891 mcSHOW_DBG_MSG(("Update CS Dly = %d\n", u4value));
6892 mcFPRINTF((fp_A60501, "Update CS Dly = %d\n", u4value));
6893 }
6894#if ENABLE_LP3_SW
6895 else
6896 {
6897#if (fcFOR_PINMUX == fcLaurel)
6898 for(ii=p->rank; ii<RANK_MAX; ii++)
6899 {
6900 vSetRank(p,ii);
6901 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), ClockDelayMax, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
6902 mcSHOW_DBG_MSG(("Update CS Dly = %d\n", ClockDelayMax));
6903 mcFPRINTF((fp_A60501, "Update CS Dly = %d\n", ClockDelayMax));
6904 }
6905 vSetRank(p, backup_rank);
6906#endif
6907 }
6908#endif
6909 }
6910 else
6911 {
6912 mcSHOW_DBG_MSG(("No need to update CA/CS dly (CLK dly smaller than CA training)\n"));
6913 ClockDelayMax = CATrain_ClkDelay[p->channel][p->rank];
6914 }
6915
6916 //DramcEnterSelfRefresh(p, 1); //enter self refresh mode when changing CLK
6917 // Write max center value into Clk output delay.
6918 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), ClockDelayMax, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK);
6919 //DramcEnterSelfRefresh(p, 0);
6920
6921 mcFPRINTF((fp_A60501, "Final Clk output dly = %d\n", ClockDelayMax));
6922 mcSHOW_DBG_MSG(("Final Clk output dly = %d\n", ClockDelayMax));
6923 //mcSHOW_DBG_MSG(("After adjustment...\n"));
6924#endif
6925 for (byte_i = 0; byte_i < (p->data_width/DQS_BIT_NUMBER); byte_i++)
6926 {
6927 #if 0
6928 wrlevel_dqs_final_delay[byte_i] += (ClockDelayMax);
6929 #endif
6930 mcSHOW_DBG_MSG(("DQS%d dly: %d\n", byte_i, wrlevel_dqs_final_delay[byte_i]));
6931 mcFPRINTF((fp_A60501, "DQS%d dly: %d\n", byte_i, wrlevel_dqs_final_delay[byte_i]));
6932
6933#ifdef FOR_HQA_TEST_USED
6934 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "WriteLeveling_DQS", byte_i, wrlevel_dqs_final_delay[byte_i], NULL);
6935#endif
6936 }
6937
6938 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
6939 if(p->femmc_Ready==0)
6940 {
6941 p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][0]=wrlevel_dqs_final_delay[0];
6942 p->pSavetimeData->u1WriteLeveling_bypass_Save[p->channel][p->rank][1]=wrlevel_dqs_final_delay[1];
6943 }
6944 #endif
6945 // write leveling done, mode settings recovery if necessary
6946 // recover mode registers : issue MR2[7] to disable write leveling (refer to DEFAULT MR2 value)
6947 vSetDramMRWriteLevelingOnOff(p, DISABLE);
6948
6949 // restore registers.
6950 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
6951
6952 //Disable DQ_O1, SELO1ASO=0 for power saving
6953 O1PathOnOff(p, 0);
6954 if(u1IsLP4Family(p->dram_type))
6955 {
6956 #if REG_SHUFFLE_REG_CHECK
6957 ShuffleRegCheck =1;
6958 #endif
6959
6960 // set to best values for DQS
6961 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_final_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
6962 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), wrlevel_dqs_final_delay[1], SHU1_R0_B1_DQ7_RK0_ARPI_PBYTE_B1);
6963
6964 for(byte_i = 0; byte_i < (p->data_width/DQS_BIT_NUMBER); byte_i++)
6965 {
6966 wrlevel_dq_delay[byte_i] = wrlevel_dqs_final_delay[byte_i] + 0x10;
6967 if(wrlevel_dq_delay[byte_i] >= 0x40) //ARPI_DQ_B* is 6 bits, max 0x40
6968 {
6969 wrlevel_dq_delay[byte_i] -= 0x40;
6970 MoveDramC_TX_DQ(p, byte_i, 2);
6971 MoveDramC_TX_DQ_OEN(p, byte_i, 2);
6972 }
6973 }
6974
6975 #ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
6976 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
6977 #endif
6978
6979 // set to best values for DQM, DQ
6980 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7),
6981 P_Fld(wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0) |
6982 P_Fld(wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0));
6983
6984 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7),
6985 P_Fld(wrlevel_dq_delay[1], SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1) |
6986 P_Fld(wrlevel_dq_delay[1], SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1));
6987
6988 #if REG_SHUFFLE_REG_CHECK
6989 ShuffleRegCheck =0;
6990 #endif
6991 }
6992#if ENABLE_LP3_SW
6993 else //LPDDR3
6994 {
6995 #if REG_SHUFFLE_REG_CHECK
6996 ShuffleRegCheck =1;
6997 #endif
6998
6999 for(byte_i=0; byte_i<(p->data_width/DQS_BIT_NUMBER); byte_i++)
7000 {
7001 if(wrlevel_dqs_final_delay[byte_i] >= 0x40) //ARPI_PBYTE_B* is 6 bits, max 0x40
7002 {
7003 wrlevel_dqs_final_delay[byte_i] -= 0x40;
7004 MoveDramC_TX_DQS(p, byte_i, 2);
7005 MoveDramC_TX_DQS_OEN(p, byte_i, 2);
7006 }
7007 wrlevel_dqs_delay[byte_i] = wrlevel_dqs_final_delay[byte_i];
7008 }
7009
7010#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
7011 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
7012#endif
7013
7014#if 1
7015 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
7016 for(ii=p->rank; ii<RANK_MAX; ii++)
7017 {
7018 vSetRank(p,ii);
7019
7020 // set to best values for DQS
7021 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7022 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7023 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7024 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7025 }
7026 vSetRank(p,backup_rank);
7027#else
7028 // set to best values for DQS
7029 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7030 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7031 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7032 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dqs_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
7033#endif
7034
7035
7036 #if 1//EVEREST_CHANGE_OF_PHY_PBYTE
7037 //Evereest new change, ARPI_DQ_RK0_ARPI_PBYTE_B* only move DQS, not including of DQM&DQ anymore.
7038 //Add move DQ, DQ= DQS+0x10, after cali. take care diff. UI. with DQS
7039 for(byte_i=0; byte_i<(p->data_width/DQS_BIT_NUMBER); byte_i++)
7040 {
7041 wrlevel_dq_delay[byte_i] = wrlevel_dqs_final_delay[byte_i] + 0x10;
7042 if(wrlevel_dq_delay[byte_i] >= 0x40) //ARPI_DQ_B* is 6 bits, max 0x40
7043 {
7044 wrlevel_dq_delay[byte_i] -= 0x40;
7045 MoveDramC_TX_DQ(p, byte_i, 2);
7046 MoveDramC_TX_DQ_OEN(p, byte_i, 2);
7047 }
7048 }
7049
7050#if 1
7051 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
7052 for(ii=p->rank; ii<RANK_MAX; ii++)
7053 {
7054 vSetRank(p,ii);
7055
7056 // set to best values for DQ/DQM/DQ_OEN/DQM_OEN
7057 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7058 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7059 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7060 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7061
7062 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7063 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7064 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7065 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7066 }
7067 vSetRank(p,backup_rank);
7068#else
7069 // set to best values for DQ/DQM/DQ_OEN/DQM_OEN
7070 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7071 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7072 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7073 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
7074
7075
7076 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7077#if (FOR_DV_SIMULATION_USED!=0)
7078 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[1], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
7079 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7080
7081#else
7082 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7083 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[2], SHU1_R0_CA_CMD9_RG_RK0_ARPI_CS);
7084#endif
7085 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), wrlevel_dq_delay[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
7086#endif
7087
7088 #endif
7089
7090 #if REG_SHUFFLE_REG_CHECK
7091 ShuffleRegCheck =0;
7092 #endif
7093 }
7094#endif
7095 //DramcRankSwap(p, RANK_0);
7096 //tx_rank_sel is selected by HW
7097 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANK);
7098 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANKFIX); //TXRANKFIX should be write after TXRANK
7099
7100#if REG_ACCESS_PORTING_DGB
7101 RegLogEnable =0;
7102#endif
7103 mcSHOW_DBG_MSG3(("[DramcWriteLeveling] Done\n\n"));
7104 mcFPRINTF((fp_A60501, "[DramcWriteLeveling] Done\n\n"));
7105
7106 return KResult;
7107}
7108#endif //SIMULATION_WRITE_LEVELING
7109
7110
7111#if SIMULATION_GATING
7112//LP3 RODT is not enable, don't need to set the RODT settings.
7113//LP4 RODT range is very large(5ns), no need to adjust with gating position
7114//0x860 SHU_ODTCTRL 32 ODT CONTROL REGISTER
7115// 31 31 RODTE RW PUBLIC 1'b1
7116// 30 30 RODTE2 RW PUBLIC 1'b1
7117// 7 4 RODT RW PUBLIC 4'bx= DQSINCTL or -1
7118#if ENABLE_RODT_TRACKING
7119#define GATING_RODT_LATANCY_EN 0 //disable when RODT tracking enable
7120#else
7121#define GATING_RODT_LATANCY_EN 1 //Need to enable when RODT enable
7122#endif
7123
7124#define GATING_PATTERN_NUM_LP4 0x23
7125#define GATING_GOLDEND_DQSCNT_LP4 0x4646
7126
7127#define GATING_PATTERN_NUM_LP3 0x46
7128#define GATING_GOLDEND_DQSCNT_LP3 0x2323
7129
7130#define GATING_TXDLY_CHNAGE 1 //Gating txdly chcange & RANKINCTL setting
7131
7132#if SW_CHANGE_FOR_SIMULATION
7133#define ucRX_DLY_DQSIENSTB_LOOP 32
7134#define ucRX_DQS_CTL_LOOP 8
7135#endif
7136
7137#if GATING_ADJUST_TXDLY_FOR_TRACKING
7138U8 u1TXDLY_Cal_min =0xff, u1TXDLY_Cal_max=0;
7139U8 ucbest_coarse_tune2T_backup[RANK_MAX][DQS_NUMBER];
7140U8 ucbest_coarse_tune0p5T_backup[RANK_MAX][DQS_NUMBER];
7141U8 ucbest_coarse_tune2T_P1_backup[RANK_MAX][DQS_NUMBER];
7142U8 ucbest_coarse_tune0p5T_P1_backup[RANK_MAX][DQS_NUMBER];
7143#endif
7144
7145// Use gating old burst mode to find gating window boundary
7146// Set the begining of window as new burst mode gating window center.
7147#define LP4_GATING_OLD_BURST_MODE 1
7148#define LP4_GATING_LEAD_LAG_FLAG_JUDGE LP4_GATING_OLD_BURST_MODE
7149
7150/* Current function is for LP4 only
7151 * u1Mode decides old or new length modes (7UI, 8UI) should be used
7152 * 0: OLD 8UI mode (not extend 2T RD preamble)
7153 * 1: NEW 7UI mode (extend 2T RD preamble) (DQS_GW_7UI defined)
7154 * NEW 8UI mode (extend 2T RD preamble) (DQS_GW_7UI not defined)
7155 */
7156void DramcGatingMode(DRAMC_CTX_T *p, U8 u1Mode)
7157{
7158 // mode 0: old burst mode
7159 // mode 1: 7UI or 8UI gating window length mode (depends on if DQS_GW_7UI is defined)
7160#if (fcFOR_CHIP_ID == fcLaurel)
7161 /* There are currently 2 ways to set GatingMode (sets different registers)
7162 * 1. Alaska
7163 * 2. Bianco, Whitney, Kibo+(Olympus)
7164 */
7165 U8 u1VrefSel = 0, u1BurstE2 = 0;
7166
7167 //mcSHOW_DBG_MSG3(("[GatingMode] "));
7168 if (u1Mode == 0) /* old mode */
7169 {
7170 u1VrefSel = 0;
7171 u1BurstE2 = 0;
7172 //mcSHOW_DBG_MSG3(("old 8UI\n"));
7173 }
7174 else /* 7UI or 8UI gating window length mode */
7175 {
7176#ifdef DQS_GW_7UI
7177 u1VrefSel = 2;
7178 u1BurstE2 = 1;
7179 //mcSHOW_DBG_MSG3(("new 7UI\n"));
7180#else
7181 u1VrefSel = 1;
7182 u1BurstE2 = 0;
7183 //mcSHOW_DBG_MSG3(("new 8UI\n"));
7184#endif
7185 }
7186
7187 /* BIAS_VREF_SEL is used as switch for old, new burst modes */
7188 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), u1VrefSel, B0_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B0);
7189 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), u1VrefSel, B1_DQ6_RG_RX_ARDQ_BIAS_VREF_SEL_B1);
7190#endif /* fcFOR_CHIP_ID */
7191
7192 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), 1, B0_DQ9_RG_RX_ARDQS0_DQSIENMODE_B0);
7193 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), 1, B1_DQ9_RG_RX_ARDQS0_DQSIENMODE_B1);
7194
7195 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL1), u1BurstE2, STBCAL1_DQSIEN_7UI_EN);
7196
7197 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL), 1, STBCAL_DQSIENMODE_SELPH);
7198
7199 /* Perform reset (makes sure PHY's behavior works as the above setting) */
7200 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(0, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(0, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
7201 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(0, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) |P_Fld(0, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
7202 mcDELAY_US(1);//delay 10ns
7203 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ9), P_Fld(1, B1_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B1) |P_Fld(1, B1_DQ9_RG_RX_ARDQ_STBEN_RESETB_B1));
7204 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ9), P_Fld(1, B0_DQ9_RG_RX_ARDQS0_STBEN_RESETB_B0) |P_Fld(1, B0_DQ9_RG_RX_ARDQ_STBEN_RESETB_B0));
7205 //DramPhyReset(p);
7206#if __ETT__
7207 if (u1IsLP4Family(p->dram_type) == FALSE)
7208 { // GatingMode() is designed for LP4 only (only resets current channel PHY)
7209 mcSHOW_ERR_MSG(("GatingMode err!(LP4 only)\n"));
7210 }
7211#endif
7212}
7213
7214U8 u1GetGatingStartPos(DRAMC_CTX_T *p)
7215{
7216 const U8 au1MR2MappingToRL[2][8] = {{6, 10, 14, 20, 24, 28, 32, 36}, /*normal mode*/
7217 {6, 10, 16, 22, 26, 32, 36, 40}}; /*byte mode*/
7218
7219 U8 u1MR0_LatencyMode;
7220 U8 u1MR2RLValue = u1MR02Value[p->dram_fsp] & 0x7; /*MR2 Op[2:0]*/
7221 U8 u1RX_Path_delay_UI, u1RealRL,u1StartUI, u1ExtraMCKfor1_4mode;
7222 U8 u1MCK2CK_UI, u1ReadDQSINCTL, u1DQSINCTL_UI;
7223 U8 u4TDQSCK_UI_min = 1500 * p->frequency *2/ 1000000;
7224 /* 1500ps = ? UI */
7225
7226 if(gu2MR0_Value[p->rank] == 0xffff) /*MR0 is not ready*/
7227 {
7228 u1MR0_LatencyMode = CBT_NORMAL_MODE;
7229 }
7230 else
7231 {
7232 u1MR0_LatencyMode = (gu2MR0_Value[p->rank]>>1) & 0x1; /*MR0 OP[1], 0:normal mode, 1:byte mode*/
7233 }
7234
7235 u1RealRL = au1MR2MappingToRL[u1MR0_LatencyMode][u1MR2RLValue];
7236
7237 if(0) /*(vGet_Div_Mode(p) == DIV4_MODE)*/
7238 {
7239 u1MCK2CK_UI = 4;
7240 u1ExtraMCKfor1_4mode = 1;
7241 }
7242 else
7243 {
7244 u1MCK2CK_UI = 8;
7245 u1ExtraMCKfor1_4mode = 0;
7246 }
7247
7248 /* RX_Path_delay_UI = RL*2 + tDQSCK_UI<1500~3500ps> - PHY_interanl<skip 30ps> - GatingAheadDQS<2UI> + if(1:4 mod)+1MCK */
7249 u1RX_Path_delay_UI = (u1RealRL<<1) + u4TDQSCK_UI_min - 2 + (u1MCK2CK_UI*u1ExtraMCKfor1_4mode);
7250
7251 u1ReadDQSINCTL = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSCTL), SHURK0_DQSCTL_DQSINCTL);
7252 u1DQSINCTL_UI = u1ReadDQSINCTL * u1MCK2CK_UI;
7253
7254 if((u1RX_Path_delay_UI-3) >= u1DQSINCTL_UI)
7255 u1StartUI = (u1RX_Path_delay_UI -3) - u1DQSINCTL_UI; /* gating start calibration position = gating min position(1500ns) -3UI */
7256 else
7257 {
7258 u1StartUI =0;
7259 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));
7260 #if __ETT__
7261 while(1);
7262 #endif
7263 }
7264
7265 mcSHOW_DBG_MSG(("[GatingStartPos] MR0_LatencyMode %d, u1RealRL %d , u4TDQSCK_UI_min %d, 1:4ExtraMCK %d\n", u1MR0_LatencyMode, u1RealRL, u4TDQSCK_UI_min, u1ExtraMCKfor1_4mode));
7266 mcSHOW_DBG_MSG(("RX_Path_delay_UI(%d) -3 - DQSINCTL_UI(%d) = u1StartUI(%d)\n", u1RX_Path_delay_UI, u1DQSINCTL_UI, u1StartUI));
7267
7268 return u1StartUI;
7269}
7270
7271
7272DRAM_STATUS_T DramcRxdqsGatingCal(DRAMC_CTX_T *p)
7273{
7274 #if !SW_CHANGE_FOR_SIMULATION
7275 U8 ucRX_DLY_DQSIENSTB_LOOP,ucRX_DQS_CTL_LOOP;
7276 #endif
7277 U32 u4value, u4all_result_R=0, u4all_result_F=0, u4err_value;
7278 U8 ucpass_begin[DQS_NUMBER] = {0}, ucpass_count[DQS_NUMBER] = {0}, ucCurrentPass;
7279 U8 ucmin_coarse_tune2T[DQS_NUMBER] = {0}, ucmin_coarse_tune0p5T[DQS_NUMBER] = {0}, ucmin_fine_tune[DQS_NUMBER] = {0};
7280 U8 ucpass_count_1[DQS_NUMBER] = {0}, ucmin_coarse_tune2T_1[DQS_NUMBER] = {0}, ucmin_coarse_tune0p5T_1[DQS_NUMBER] = {0}, ucmin_fine_tune_1[DQS_NUMBER] = {0};
7281 U8 dqs_i=0, ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT, ucDQS_GW_FINE_STEP;
7282 U8 ucdqs_result_R, ucdqs_result_F, uctmp_offset, uctmp_value;
7283 U8 ucbest_fine_tune[DQS_NUMBER] = {0}, ucbest_coarse_tune0p5T[DQS_NUMBER] = {0}, ucbest_coarse_tune2T[DQS_NUMBER] = {0};
7284 U8 ucbest_fine_tune_P1[DQS_NUMBER] = {0}, ucbest_coarse_tune0p5T_P1[DQS_NUMBER] = {0}, ucbest_coarse_tune2T_P1[DQS_NUMBER] = {0};
7285
7286 U8 ucFreqDiv;
7287 U8 ucdly_coarse_large_P1, ucdly_coarse_0p5T_P1;
7288
7289 #if GATING_ADJUST_TXDLY_FOR_TRACKING
7290 U8 u1TX_dly_DQSgated = 0;
7291 #endif
7292
7293 #if GATING_RODT_LATANCY_EN
7294 U8 ucdly_coarse_large_RODT, ucdly_coarse_0p5T_RODT;
7295 U8 ucdly_coarse_large_RODT_P1 = 0, ucdly_coarse_0p5T_RODT_P1 = 0;
7296 U8 ucbest_coarse_large_RODT[DQS_NUMBER] = {0}, ucbest_coarse_0p5T_RODT[DQS_NUMBER] = {0};
7297 U8 ucbest_coarse_large_RODT_P1[DQS_NUMBER] = {0}, ucbest_coarse_0p5T_RODT_P1[DQS_NUMBER] = {0};
7298 #endif
7299 U8 ucCoarseTune=0, ucCoarseStart=8, ucCoarseEnd=8;
7300#if ENABLE_LP3_SW
7301 U32 LP3_DataPerByte[DQS_NUMBER] = {0};
7302#endif
7303 U32 u4DebugCnt[DQS_NUMBER] = {0};
7304 U16 u2DebugCntPerByte;
7305
7306 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7307 U8 u1DQS_lead[DQS_NUMBER] = {0}, u1DQS_lag[DQS_NUMBER] = {0}, u1DQS_high[DQS_NUMBER] = {0}, u1DQS_transition[DQS_NUMBER] = {0}, u1DQSGatingFound[DQS_NUMBER] = {0};
7308 U8 ucdly_coarse_large_leadLag[DQS_NUMBER] = {0}, ucdly_coarse_0p5T_leadLag[DQS_NUMBER] = {0}, ucdly_fine_tune_leadLag[DQS_NUMBER] = {0};
7309 #endif
7310
7311 U8 u1PassByteCount=0;
7312
7313 #if 0///SUPPORT_SAVE_TIME_FOR_CALIBRATION
7314 U8 ucpass_offset=0;
7315 U8 ucpass_count_0_temp=0;
7316 U8 ucpass_count_1_temp=0;
7317 U8 ucCoarseTune_offset=0;
7318 U8 minpasscount=0;
7319 #endif
7320
7321 // error handling
7322 if (!p)
7323 {
7324 mcSHOW_ERR_MSG(("context NULL\n"));
7325 return DRAM_FAIL;
7326 }
7327
7328 U32 u4RegBackupAddress[] =
7329 {
7330 (DRAMC_REG_ADDR(DRAMC_REG_STBCAL)),
7331 (DRAMC_REG_ADDR(DRAMC_REG_STBCAL1)),
7332 (DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0)),
7333 (DRAMC_REG_ADDR(DRAMC_REG_SPCMD)),
7334 (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)),
7335 #if LP4_GATING_OLD_BURST_MODE
7336 (DRAMC_REG_ADDR(DDRPHY_B0_DQ6)),
7337 (DRAMC_REG_ADDR(DDRPHY_B1_DQ6)),
7338 #else
7339 (DRAMC_REG_ADDR(DDRPHY_B0_DQ7)),
7340 (DRAMC_REG_ADDR(DDRPHY_B1_DQ7)),
7341 #endif
7342 };
7343
7344
7345 //Register backup
7346 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
7347
7348 //Justin: DQ_REV_B*[5] =1, select RX gating mode to prevent 0.5T fake gating window behind real window.
7349 if(u1IsLP4Family(p->dram_type))
7350 {
7351 #if MRW_CHECK_ONLY
7352 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
7353 #endif
7354 /* LP4: Disable(set to 0) "RX DQS ISI pulse CG function" during gating window calibration (must set to 1 when done) */
7355 RxDQSIsiPulseCG(p, DISABLE);
7356
7357 #if LP4_GATING_OLD_BURST_MODE
7358 #if !LP4_GATING_LEAD_LAG_FLAG_JUDGE
7359 DramcGatingMode(p, 0);
7360 #endif
7361 u1MR01Value[p->dram_fsp] |= 0x80;
7362 DramcModeRegWriteByRank(p, p->rank, 1, u1MR01Value[p->dram_fsp]);
7363 #else
7364 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ7), P_Fld( 1, B0_DQ7_RG_TX_ARDQS_PULL_UP_B0) | P_Fld( 1, B0_DQ7_RG_TX_ARDQSB_PULL_DN_B0));
7365 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ7), P_Fld( 1, B1_DQ7_RG_TX_ARDQS0_PULL_UP_B1) | P_Fld( 1, B1_DQ7_RG_TX_ARDQS0B_PULL_DN_B1));
7366 #endif
7367 }
7368 #if 0 // LP3: Since it is always set to 1 (should be set during initial register settings, comment out here to save code size
7369 else
7370 {
7371 /* LP3: Always enable(set to 1) "RX DQS ISI pulse CG function" */
7372 RxDQSIsiPulseCG(p, ENABLE);
7373 }
7374 #endif
7375
7376 //Disable perbank refresh, use all bank refresh, currently DUT problem
7377 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0), 0, REFCTRL0_PBREFEN);
7378
7379 // Disable HW gating first, 0x1c0[31], need to disable both UI and PI tracking or the gating delay reg won't be valid.
7380 DramcHWGatingOnOff(p, 0);
7381
7382 //If DQS ring counter is different as our expectation, error flag is asserted and the status is in ddrphycfg 0xFC0 ~ 0xFCC
7383 //Enable this function by R_DMSTBENCMPEN=1 (0x348[18])
7384 //Set R_DMSTBCNT_LATCH_EN=1, 0x348[11]
7385 //Set R_DM4TO1MODE=0, 0x54[11]
7386 //Clear error flag by ddrphycfg 0x5c0[1] R_DMPHYRST
7387 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL1), 1, STBCAL1_STBENCMPEN);
7388 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL1), 1, STBCAL1_STBCNT_LATCH_EN);
7389 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDRCONF0), 0, DDRCONF0_DM4TO1MODE);
7390
7391 //enable &reset DQS counter
7392 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_DQSGCNTEN);
7393 mcDELAY_US(4);//wait 1 auto refresh after DQS Counter enable
7394
7395 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_DQSGCNTRST);
7396 mcDELAY_US(1);//delay 2T
7397 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_DQSGCNTRST);
7398
7399 if(u1IsLP4Family(p->dram_type))
7400 {
7401 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), u1GetRank(p), MISC_CTRL1_R_DMSTBENCMP_RK_OPT);
7402 DramcEngine2Init(p, 0x55000000, 0xaa000000 |GATING_PATTERN_NUM_LP4, TEST_AUDIO_PATTERN, 0);
7403 }
7404#if ENABLE_LP3_SW
7405 else
7406 {
7407 vIO32WriteFldAlign_All(DDRPHY_MISC_CTRL1, u1GetRank(p), MISC_CTRL1_R_DMSTBENCMP_RK_OPT);
7408 DramcEngine2Init(p, 0x55000000, 0xaa000000 |GATING_PATTERN_NUM_LP3, TEST_AUDIO_PATTERN, 0);
7409 }
7410#endif
7411
7412 #if 0 // Array initialization are now performed during declaration
7413 //Initialize variables
7414 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7415 {
7416 ucpass_begin[dqs_i] = 0;
7417 ucpass_count[dqs_i] = 0;
7418 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7419 u1DQS_lead[dqs_i] = 0;
7420 u1DQS_lag[dqs_i] = 0;
7421 u1DQS_high[dqs_i] = 0;
7422 u1DQS_transition[dqs_i] =0;
7423
7424 ucdly_coarse_large_leadLag[dqs_i] = 0;
7425 ucdly_coarse_0p5T_leadLag[dqs_i] = 0;
7426 ucdly_fine_tune_leadLag[dqs_i] = 0;
7427 #endif
7428 }
7429 #endif
7430 #if !SW_CHANGE_FOR_SIMULATION
7431 ucRX_DLY_DQSIENSTB_LOOP= 32;// PI fine tune 0->31
7432 ucRX_DQS_CTL_LOOP = 8; // Since Everest, no matter LP3 or LP4. ucRX_DQS_CTL_LOOP is 8.
7433 #endif
7434
7435 #ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
7436 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
7437 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
7438 #endif
7439
7440 mcSHOW_DBG_MSG2(("[Gating]\n"));
7441 vPrintCalibrationBasicInfo(p);
7442
7443 if(u1IsLP4Family(p->dram_type))
7444 {
7445 ucFreqDiv= 4;
7446 ucDQS_GW_FINE_STEP = DQS_GW_FINE_STEP;
7447
7448 /* ucCoarseStart
7449 * 1. Depends on current freq's DQSINCTL setting
7450 * 2. Preserves ~4UI before actual DQS delay value
7451 */
7452
7453 ucCoarseStart = u1GetGatingStartPos(p);
7454
7455#if SPECIAL_WORKAROUND_FOR_LP4
7456 //for Biwin/LongSys DRAM special workaround
7457 if (p->dram_type == TYPE_LPDDR4)
7458 {
7459 ucCoarseStart -= 8;
7460 ucCoarseEnd = ucCoarseStart + 28; // for Hynix LP4
7461 }
7462 else
7463#endif
7464 ucCoarseEnd = ucCoarseStart + 12;
7465
7466 if (Get_MDL_Used_Flag()==GET_MDL_USED)
7467 ucCoarseEnd+=8; // extend gating calibration range if wrong byte/normal setting
7468 }
7469#if ENABLE_LP3_SW
7470 else //LPDDR3
7471 {
7472 ucFreqDiv= 2;
7473 ucDQS_GW_FINE_STEP = DQS_GW_FINE_STEP;
7474
7475 if(p->frequency >= 933) //1600
7476 ucCoarseStart = 8;
7477 else if(p->frequency >= 800) //1600
7478 ucCoarseStart = 8;
7479 else if(p->frequency >= 600) //1333, 1200
7480 ucCoarseStart = 8;
7481 else //if(p->frequency >= 533) //933
7482 ucCoarseStart = 6;
7483
7484 #if 0//FOR_DV_SIMULATION_USED
7485 if(ucCoarseStart >=5)
7486 ucCoarseStart -=5;
7487 else
7488 ucCoarseStart=0;
7489 #endif
7490
7491 ucCoarseEnd = ucCoarseStart+12;
7492 }
7493#endif
7494
7495 #if GATING_RODT_LATANCY_EN //LP3 RODT is not enable, don't need to set the RODT settings.
7496 // Fix build warning, initialize variables.
7497 ucdly_coarse_large_RODT = 0;
7498 ucdly_coarse_0p5T_RODT = 0;
7499
7500 if (u1IsLP4Family(p->dram_type))
7501 {
7502 ucdly_coarse_large_RODT_P1 = 4;
7503 ucdly_coarse_0p5T_RODT_P1 = 4;
7504 }
7505#if ENABLE_LP3_SW
7506 else
7507 {
7508 ucdly_coarse_large_RODT_P1 = 2;
7509 ucdly_coarse_0p5T_RODT_P1 = 2;
7510 }
7511#endif /* ENABLE_LP3_SW */
7512
7513 // 1. DQSG latency =
7514 // (1) R_DMR*DQSINCTL[3:0] (MCK) +
7515 // (2) selph_TX_DLY[2:0] (MCK) +
7516 // (3) selph_dly[2:0] (UI)
7517
7518 // 2. RODT latency =
7519 // (1) R_DMTRODT[3:0] (MCK) +
7520 // (2) selph_TX_DLY[2:0] (MCK) +
7521 // (3) selph_dly[2:0] (UI)
7522
7523 #if 0
7524 if(u1IsLP4Family(p->dram_type))
7525 {
7526 //R_DMTRODT[3:0] (MCK) = R_DMR*DQSINCTL[3:0] (MCK)
7527 //if(p->rank == RANK_0)
7528 {
7529 u4value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSCTL), SHURK0_DQSCTL_DQSINCTL);
7530 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), u4value, SHU_ODTCTRL_RODT);
7531 }
7532 #if 0 //R1DQSINCTL and R2DQSINCTL is useless on A-PHY. Only need to set RODT once.
7533 else //rank1
7534 {
7535 u4value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSCTL2), DQSCTL2_R1DQSINCTL);
7536 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDR2CTL), u4value & 0x7, DDR2CTL_RODT);//R_DMTRODT[2:0]
7537 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DDR2CTL), (u4value >>3), DDR2CTL_RODT3);//R_DMTRODT[3]
7538 }
7539 #endif
7540 }
7541 #endif
7542 #endif
7543
7544#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_GatingCal)
7545 if(p->femmc_Ready==1)
7546 {
7547 mcSHOW_DBG_MSG2(("[bypass Gating]\n"));
7548 }
7549 else
7550#endif
7551 {
7552 for (ucCoarseTune = ucCoarseStart; ucCoarseTune < ucCoarseEnd; ucCoarseTune += DQS_GW_COARSE_STEP)
7553 {
7554 ucdly_coarse_large = ucCoarseTune / ucRX_DQS_CTL_LOOP;
7555 ucdly_coarse_0p5T = ucCoarseTune % ucRX_DQS_CTL_LOOP;
7556
7557 ucdly_coarse_large_P1 = (ucCoarseTune + ucFreqDiv) / ucRX_DQS_CTL_LOOP;
7558 ucdly_coarse_0p5T_P1 =(ucCoarseTune + ucFreqDiv) % ucRX_DQS_CTL_LOOP;
7559
7560 #if GATING_RODT_LATANCY_EN //LP3 RODT is not enable, don't need to set the RODT settings.
7561 if(u1IsLP4Family(p->dram_type))
7562 {
7563 u4value = (ucdly_coarse_large <<3)+ucdly_coarse_0p5T;
7564
7565 if(u4value>=11)
7566 {
7567 u4value -=11;
7568 ucdly_coarse_large_RODT = u4value>>3;
7569 ucdly_coarse_0p5T_RODT = u4value -(ucdly_coarse_large_RODT<<3);
7570
7571 u4value = (ucdly_coarse_large <<3)+ucdly_coarse_0p5T -11;
7572 ucdly_coarse_large_RODT_P1 = u4value>>3;
7573 ucdly_coarse_0p5T_RODT_P1 = u4value -(ucdly_coarse_large_RODT_P1<<3);
7574 }
7575 else
7576 {
7577 ucdly_coarse_large_RODT = 0;
7578 ucdly_coarse_0p5T_RODT = 0;
7579
7580 ucdly_coarse_large_RODT_P1 = 4;
7581 ucdly_coarse_0p5T_RODT_P1 = 4;
7582
7583 mcSHOW_ERR_MSG(("[RxdqsGatingCal] Error: ucdly_coarse_large_RODT[%d] is already 0. RODT cannot be -11 UI\n", dqs_i));
7584 mcFPRINTF((fp_A60501, "[RxdqsGatingCal] Error: ucdly_coarse_large_RODT[%d] is already 0. RODT cannot be -11 UI\n", dqs_i));
7585 }
7586 }
7587 #endif
7588
7589 //DramPhyCGReset(p, 1);// need to reset when UI update or PI change >=2
7590
7591 // 4T or 2T coarse tune
7592 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG0), \
7593 P_Fld((U32) ucdly_coarse_large, SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED)| \
7594 P_Fld((U32) ucdly_coarse_large, SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED)| \
7595 P_Fld((U32) ucdly_coarse_large, SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED)| \
7596 P_Fld((U32) ucdly_coarse_large, SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED)| \
7597 P_Fld((U32) ucdly_coarse_large_P1, SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED_P1)| \
7598 P_Fld((U32) ucdly_coarse_large_P1, SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED_P1)| \
7599 P_Fld((U32) ucdly_coarse_large_P1, SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED_P1)| \
7600 P_Fld((U32) ucdly_coarse_large_P1, SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED_P1));
7601
7602 // 0.5T coarse tune
7603 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG1), \
7604 P_Fld((U32) ucdly_coarse_0p5T, SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED)| \
7605 P_Fld((U32) ucdly_coarse_0p5T, SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED)| \
7606 P_Fld((U32) ucdly_coarse_0p5T, SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED)| \
7607 P_Fld((U32) ucdly_coarse_0p5T, SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED)| \
7608 P_Fld((U32) ucdly_coarse_0p5T_P1, SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED_P1)| \
7609 P_Fld((U32) ucdly_coarse_0p5T_P1, SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED_P1)| \
7610 P_Fld((U32) ucdly_coarse_0p5T_P1, SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED_P1)| \
7611 P_Fld((U32) ucdly_coarse_0p5T_P1, SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED_P1));
7612
7613 #if GATING_RODT_LATANCY_EN //LP3 RODT is not enable, don't need to set the RODT settings.
7614 if(u1IsLP4Family(p->dram_type))
7615 {
7616 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_ODTEN0), \
7617 P_Fld((U32) ucdly_coarse_large_RODT, SHURK0_SELPH_ODTEN0_TXDLY_B0_RODTEN)| \
7618 P_Fld((U32) ucdly_coarse_large_RODT, SHURK0_SELPH_ODTEN0_TXDLY_B1_RODTEN)| \
7619 P_Fld((U32) ucdly_coarse_large_RODT, SHURK0_SELPH_ODTEN0_TXDLY_B2_RODTEN)| \
7620 P_Fld((U32) ucdly_coarse_large_RODT, SHURK0_SELPH_ODTEN0_TXDLY_B3_RODTEN)| \
7621 P_Fld((U32) ucdly_coarse_large_RODT_P1, SHURK0_SELPH_ODTEN0_TXDLY_B0_RODTEN_P1)| \
7622 P_Fld((U32) ucdly_coarse_large_RODT_P1, SHURK0_SELPH_ODTEN0_TXDLY_B1_RODTEN_P1)| \
7623 P_Fld((U32) ucdly_coarse_large_RODT_P1, SHURK0_SELPH_ODTEN0_TXDLY_B2_RODTEN_P1)| \
7624 P_Fld((U32) ucdly_coarse_large_RODT_P1, SHURK0_SELPH_ODTEN0_TXDLY_B3_RODTEN_P1));
7625
7626 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_ODTEN1), \
7627 P_Fld((U32) ucdly_coarse_0p5T_RODT, SHURK0_SELPH_ODTEN1_DLY_B0_RODTEN)| \
7628 P_Fld((U32) ucdly_coarse_0p5T_RODT, SHURK0_SELPH_ODTEN1_DLY_B1_RODTEN)| \
7629 P_Fld((U32) ucdly_coarse_0p5T_RODT, SHURK0_SELPH_ODTEN1_DLY_B2_RODTEN)| \
7630 P_Fld((U32) ucdly_coarse_0p5T_RODT, SHURK0_SELPH_ODTEN1_DLY_B3_RODTEN)| \
7631 P_Fld((U32) ucdly_coarse_0p5T_RODT_P1, SHURK0_SELPH_ODTEN1_DLY_B0_RODTEN_P1)| \
7632 P_Fld((U32) ucdly_coarse_0p5T_RODT_P1, SHURK0_SELPH_ODTEN1_DLY_B1_RODTEN_P1)| \
7633 P_Fld((U32) ucdly_coarse_0p5T_RODT_P1, SHURK0_SELPH_ODTEN1_DLY_B2_RODTEN_P1)| \
7634 P_Fld((U32) ucdly_coarse_0p5T_RODT_P1, SHURK0_SELPH_ODTEN1_DLY_B3_RODTEN_P1));
7635
7636 //mcSHOW_DBG_MSG2(("RODT delay(2T, 0.5T) = (%d, %d)\n", ucdly_coarse_large_RODT, ucdly_coarse_0p5T_RODT));
7637 //mcFPRINTF((fp_A60501,"RODT delay(2T, 0.5T) = (%d, %d)\n", ucdly_coarse_large_RODT, ucdly_coarse_0p5T_RODT));
7638 }
7639 #endif
7640
7641 for (ucdly_fine_xT=DQS_GW_FINE_START; ucdly_fine_xT<DQS_GW_FINE_END; ucdly_fine_xT+=ucDQS_GW_FINE_STEP)
7642 {
7643 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7644 if(u1IsLP4Family(p->dram_type))
7645 {
7646 DramcGatingMode(p, 0);
7647 }
7648 #endif
7649
7650 //ok we set a coarse/fine tune value already
7651 u4value = ucdly_fine_xT | (ucdly_fine_xT<<8) | (ucdly_fine_xT<<16) | (ucdly_fine_xT<<24);
7652 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSIEN), u4value);
7653
7654 //reset phy, reset read data counter
7655 DramPhyReset(p);
7656
7657 //reset DQS counter
7658 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_DQSGCNTRST);
7659 mcDELAY_US(1);//delay 2T
7660 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_DQSGCNTRST);
7661
7662 // enable TE2, audio pattern
7663 DramcEngine2Run(p, TE_OP_READ_CHECK, TEST_AUDIO_PATTERN);
7664
7665 if(u1IsLP4Family(p->dram_type))
7666 {
7667 u4all_result_R = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_STBERR_RK0_R), MISC_STBERR_RK0_R_STBERR_RK0_R);
7668 u4all_result_F = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_STBERR_RK0_F), MISC_STBERR_RK0_F_STBERR_RK0_F);
7669 }
7670 #if ENABLE_LP3_SW
7671 else //LPDDR3
7672 {
7673 LP3_DataPerByte[0] = u4IO32ReadFldAlign(DDRPHY_MISC_STBERR_RK0_R, MISC_STBERR_RK0_R_STBERR_RK0_R); // CHA for B0 and B1
7674 LP3_DataPerByte[1] = u4IO32ReadFldAlign(DDRPHY_MISC_STBERR_RK0_R+SHIFT_TO_CHB_ADDR, MISC_STBERR_RK0_R_STBERR_RK0_R);// CHB for B2 and B3
7675 u4all_result_R = LP3_DataPerByte[0] | (LP3_DataPerByte[1] <<16);
7676
7677 LP3_DataPerByte[0] = u4IO32ReadFldAlign(DDRPHY_MISC_STBERR_RK0_F, MISC_STBERR_RK0_F_STBERR_RK0_F); // CHA for B0 and B1
7678 LP3_DataPerByte[1] = u4IO32ReadFldAlign(DDRPHY_MISC_STBERR_RK0_F+SHIFT_TO_CHB_ADDR, MISC_STBERR_RK0_F_STBERR_RK0_F);// CHB for B2 and B3
7679 u4all_result_F = LP3_DataPerByte[0] | (LP3_DataPerByte[1] <<16);
7680 }
7681 #endif
7682
7683 //read DQS counter
7684 u4DebugCnt[0] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_DQSGNWCNT0));
7685 u4DebugCnt[1] = (u4DebugCnt[0] >> 16) & 0xffff;
7686 u4DebugCnt[0] &= 0xffff;
7687#if ENABLE_LP3_SW
7688 if(p->dram_type == TYPE_LPDDR3)
7689 {
7690 u4DebugCnt[2] = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_DQSGNWCNT1));
7691 u4DebugCnt[3] = (u4DebugCnt[2] >> 16) & 0xffff;
7692 u4DebugCnt[2] &= 0xffff;
7693 }
7694#endif /* ENABLE_LP3_SW */
7695 u4err_value =0;
7696
7697 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7698 if(u1IsLP4Family(p->dram_type))
7699 {
7700 DramcGatingMode(p, 1);
7701 DramcEngine2Run(p, TE_OP_READ_CHECK, TEST_AUDIO_PATTERN);// trigger read to make lead/lag flag update.
7702
7703 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7704 {
7705 if(u1DQSGatingFound[dqs_i]==1)
7706 {
7707 continue;
7708 }
7709
7710 if(dqs_i==0)
7711 {
7712 u1DQS_lead[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_STBEN_B0), MISC_PHY_RGS_STBEN_B0_AD_RX_ARDQS0_STBEN_LEAD_B0);
7713 u1DQS_lag[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_STBEN_B0), MISC_PHY_RGS_STBEN_B0_AD_RX_ARDQS0_STBEN_LAG_B0);
7714 }
7715 else //dqs1
7716 {
7717 u1DQS_lead[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_STBEN_B1), MISC_PHY_RGS_STBEN_B1_AD_RX_ARDQS0_STBEN_LEAD_B1);
7718 u1DQS_lag[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_PHY_RGS_STBEN_B1), MISC_PHY_RGS_STBEN_B1_AD_RX_ARDQS0_STBEN_LAG_B1);
7719 }
7720
7721 if((u1DQS_lead[dqs_i]==1) && (u1DQS_lag[dqs_i]==1))
7722 {
7723 u1DQS_high[dqs_i] ++;
7724 //mcSHOW_DBG_MSG2(("[Byte %d] Lead/lag falling high (%d)\n", dqs_i,u1DQS_high[dqs_i]));
7725 }
7726
7727 if(u1DQS_high[dqs_i] *ucDQS_GW_FINE_STEP >16)//>16 PI prevent glitch
7728 {
7729 if((u1DQS_lead[dqs_i]==1) && (u1DQS_lag[dqs_i]==1))
7730 {
7731 ucdly_coarse_large_leadLag[dqs_i] = ucdly_coarse_large;
7732 ucdly_coarse_0p5T_leadLag[dqs_i] = ucdly_coarse_0p5T;
7733 ucdly_fine_tune_leadLag[dqs_i] = ucdly_fine_xT;
7734 u1DQS_transition[dqs_i] =1;
7735 }
7736 else if(((u1DQS_lead[dqs_i]==1) && (u1DQS_lag[dqs_i]==0)) ||((u1DQS_lead[dqs_i]==0) && (u1DQS_lag[dqs_i]==1)))
7737 {
7738 if(u1DQS_transition[dqs_i] ==1)
7739 {
7740 mcSHOW_DBG_MSG(("[Byte %d] Lead/lag falling Transition (%d, %d, %d)\n", dqs_i,ucdly_coarse_large_leadLag[dqs_i], ucdly_coarse_0p5T_leadLag[dqs_i], ucdly_fine_tune_leadLag[dqs_i]));
7741 }
7742 u1DQS_transition[dqs_i] ++;
7743 }
7744 else if((u1DQS_lead[dqs_i]==0) && (u1DQS_lag[dqs_i]==0))
7745 {
7746 mcSHOW_DBG_MSG(("[Byte %d] Lead/lag Transition tap number (%d)\n", dqs_i, u1DQS_transition[dqs_i]));
7747 u1DQS_high[dqs_i] =0;
7748 }
7749 }
7750 }
7751 }
7752 #endif
7753
7754 /*TINFO="%2d %2d %2d |(B3->B0) 0x%4x, 0x%4x, 0x%4x, 0x%4x | %2x %2x %2x %2x %2x %2x %2x %2x | 0x%8x\n", ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT, \
7755 u4DebugCnt[3], u4DebugCnt[2], u4DebugCnt[1], u4DebugCnt[0], \
7756 (u4all_result_F>>24)&0xff, (u4all_result_R>>24)&0xff, \
7757 (u4all_result_F>>16)&0xff, (u4all_result_R>>16)&0xff, \
7758 (u4all_result_F>>8)&0xff, (u4all_result_R>>8)&0xff, \
7759 (u4all_result_F)&0xff, (u4all_result_R)&0xff, u4err_value*/
7760
7761 #ifdef ETT_PRINT_FORMAT
7762 #if 0
7763 mcSHOW_DBG_MSG(("%d %d %d |(B3->B0) 0x%H, 0x%H, 0x%H, 0x%H | %B %B %B %B %B %B %B %B | B0(%d, %d) B1(%d, %d) |0x%X\n",
7764 ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT, \
7765 u4DebugCnt[3], u4DebugCnt[2], u4DebugCnt[1], u4DebugCnt[0], \
7766 (u4all_result_F>>24)&0xff, (u4all_result_R>>24)&0xff, \
7767 (u4all_result_F>>16)&0xff, (u4all_result_R>>16)&0xff, \
7768 (u4all_result_F>>8)&0xff, (u4all_result_R>>8)&0xff, \
7769 (u4all_result_F)&0xff, (u4all_result_R)&0xff,
7770 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7771 u1DQS_lead[0], u1DQS_lag[0], u1DQS_lead[1], u1DQS_lag[1],
7772 #else
7773 0,0,0,0,
7774 #endif
7775 u4err_value));
7776 #else
7777 mcSHOW_DBG_MSG(("%d %d %d |", ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT ));
7778
7779 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7780 {
7781 mcSHOW_DBG_MSG(("%X ", u4DebugCnt[dqs_i]));
7782 }
7783 mcSHOW_DBG_MSG((" |"));
7784 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7785 {
7786 mcSHOW_DBG_MSG(("(%X %X)", (u4all_result_F>>(DQS_BIT_NUMBER*dqs_i)) & 0xff, (u4all_result_R>>(DQS_BIT_NUMBER*dqs_i)) & 0xff));
7787 }
7788
7789 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7790 mcSHOW_DBG_MSG((" |"));
7791 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7792 {
7793 mcSHOW_DBG_MSG(("(%d %d)", u1DQS_lead[dqs_i], u1DQS_lag[dqs_i]));
7794 }
7795 #endif
7796
7797 mcSHOW_DBG_MSG2(("| %X", u4err_value));
7798 mcSHOW_DBG_MSG(("\n"));
7799 #endif
7800
7801 #else
7802 mcSHOW_DBG_MSG(("%2d %2d %2d |(B3->B0) 0x%4x, 0x%4x, 0x%4x, 0x%4x | %2x %2x %2x %2x %2x %2x %2x %2x | 0x%8x\n", ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT, \
7803 u4DebugCnt[3], u4DebugCnt[2], u4DebugCnt[1], u4DebugCnt[0], \
7804 (u4all_result_F>>24)&0xff, (u4all_result_R>>24)&0xff, \
7805 (u4all_result_F>>16)&0xff, (u4all_result_R>>16)&0xff, \
7806 (u4all_result_F>>8)&0xff, (u4all_result_R>>8)&0xff, \
7807 (u4all_result_F)&0xff, (u4all_result_R)&0xff, u4err_value));
7808
7809 #endif
7810
7811 mcFPRINTF((fp_A60501,"%2d %2d %2d |(B3->B0) 0x%4x, 0x%4x, 0x%4x, 0x%4x | (B3->B0) %2x %2x %2x %2x %2x %2x %2x %2x | 0x%8x\n", ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT, \
7812 u4DebugCnt[3], u4DebugCnt[2], u4DebugCnt[1], u4DebugCnt[0], \
7813 (u4all_result_F>>24)&0xff, (u4all_result_R>>24)&0xff, \
7814 (u4all_result_F>>16)&0xff, (u4all_result_R>>16)&0xff, \
7815 (u4all_result_F>>8)&0xff, (u4all_result_R>>8)&0xff, \
7816 (u4all_result_F)&0xff, (u4all_result_R)&0xff, u4err_value));
7817
7818 //find gating window pass range per DQS separately
7819 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7820 {
7821 if(u1PassByteCount & (1<<dqs_i))
7822 {
7823 // real window found, break to prevent finding fake window.
7824 continue;
7825 }
7826 //get dqs error result
7827 ucdqs_result_R = (U8)((u4all_result_R>>(8*dqs_i))&0xff);
7828 ucdqs_result_F = (U8)((u4all_result_F>>(8*dqs_i))&0xff);
7829 u2DebugCntPerByte =(U16) u4DebugCnt[dqs_i];
7830
7831 // check if current tap is pass
7832 ucCurrentPass =0;
7833 if(u1IsLP4Family(p->dram_type))
7834 {
7835 if((ucdqs_result_R==0) && (ucdqs_result_F==0) && (u2DebugCntPerByte==GATING_GOLDEND_DQSCNT_LP4))
7836 ucCurrentPass =1;
7837 }
7838 #if ENABLE_LP3_SW
7839 else //LPDDR3
7840 {
7841 if((ucdqs_result_R==0) && (ucdqs_result_F==0) && (u2DebugCntPerByte==GATING_GOLDEND_DQSCNT_LP3))
7842 {
7843 ucCurrentPass =1;
7844 ucDQS_GW_FINE_STEP = 1;
7845 }
7846 }
7847 #endif
7848
7849 //if current tap is pass
7850 if (ucCurrentPass)
7851 {
7852 if (ucpass_begin[dqs_i]==0)
7853 {
7854 //no pass tap before , so it is the begining of pass range
7855 ucpass_begin[dqs_i] = 1;
7856 ucpass_count_1[dqs_i] = 0;
7857 ucmin_coarse_tune2T_1[dqs_i] = ucdly_coarse_large;
7858 ucmin_coarse_tune0p5T_1[dqs_i] = ucdly_coarse_0p5T;
7859 ucmin_fine_tune_1[dqs_i] = ucdly_fine_xT;
7860
7861 /*TINFO="[Byte %d]First pass (%d, %d, %d)\n", dqs_i,ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT*/
7862 mcSHOW_DBG_MSG2(("[Byte %d]First pass (%d, %d, %d)\n", dqs_i, ucdly_coarse_large, ucdly_coarse_0p5T, ucdly_fine_xT));
7863 }
7864
7865 if (ucpass_begin[dqs_i]==1)
7866 {
7867 //incr pass tap number
7868 ucpass_count_1[dqs_i]++;
7869 }
7870
7871#if LP4_GATING_LEAD_LAG_FLAG_JUDGE
7872 // Francis add to prevent lead/lag transition miss judgement
7873 if (u1IsLP4Family(p->dram_type) && (ucpass_begin[dqs_i] == 1) && (ucpass_count_1[dqs_i]*ucDQS_GW_FINE_STEP > 32))
7874 {
7875 u1DQSGatingFound[dqs_i] =1;
7876 }
7877
7878 if (u1IsLP4Family(p->dram_type) && (ucpass_count_1[0]*ucDQS_GW_FINE_STEP > 32) && (ucpass_count_1[1]*ucDQS_GW_FINE_STEP > 32))
7879 {
7880 // if all bytes gating windows > 1UI, then early break;
7881 mcSHOW_DBG_MSG2(("All bytes gating window > 1UI, Early break!\n"));
7882 mcFPRINTF((fp_A60501, "All bytes gating window > 1UI, Early break!\n"));
7883 ucdly_fine_xT = DQS_GW_FINE_END;//break loop
7884 ucCoarseTune = ucCoarseEnd; //break loop
7885
7886 }
7887#endif
7888 }
7889 else // current tap is fail
7890 {
7891 if (ucpass_begin[dqs_i]==1)
7892 {
7893 //at the end of pass range
7894 ucpass_begin[dqs_i] = 0;
7895
7896 //save the max range settings, to avoid glitch
7897 if (ucpass_count_1[dqs_i] > ucpass_count[dqs_i])
7898 {
7899 ucmin_coarse_tune2T[dqs_i] = ucmin_coarse_tune2T_1[dqs_i];
7900 ucmin_coarse_tune0p5T[dqs_i] = ucmin_coarse_tune0p5T_1[dqs_i];
7901 ucmin_fine_tune[dqs_i] = ucmin_fine_tune_1[dqs_i];
7902 ucpass_count[dqs_i] = ucpass_count_1[dqs_i];
7903
7904#if ENABLE_LP3_SW
7905 //LP3 CHB_CA didn't has lead/lag RG, use SW workaround
7906 if (!u1IsLP4Family(p->dram_type))
7907 {
7908 if (ucpass_count_1[dqs_i] >= 70) // if didn't check fail region and pass UI more than 2UI, then workaround back to 2UI
7909 {
7910 ucpass_count_1[dqs_i] = 64; // 2UI
7911 ucpass_count[dqs_i] = ucpass_count_1[dqs_i];
7912 }
7913 }
7914#endif
7915
7916 /*TINFO="[Byte %d]Bigger pass win(%d, %d, %d) Pass tap=%d\n", \
7917 dqs_i, ucmin_coarse_tune2T_1[dqs_i], ucmin_coarse_tune0p5T_1[dqs_i], ucmin_fine_tune_1[dqs_i], ucpass_count_1[dqs_i]*/
7918 mcSHOW_DBG_MSG(("[Byte %d]Bigger pass win(%d, %d, %d) Pass tap=%d\n", \
7919 dqs_i, ucmin_coarse_tune2T_1[dqs_i], ucmin_coarse_tune0p5T_1[dqs_i], ucmin_fine_tune_1[dqs_i], ucpass_count_1[dqs_i]));
7920
7921 // LP4 pass window around 6 UI(burst mode), set 1~3 UI is pass
7922 // LP3 pass window around 2 UI(pause mode), set 1~3 UI is pass
7923 if((ucpass_count_1[dqs_i]*ucDQS_GW_FINE_STEP > 32) && (ucpass_count_1[dqs_i]*ucDQS_GW_FINE_STEP < 96))
7924 {
7925 u1PassByteCount |= (1<<dqs_i);
7926 }
7927
7928 if(((u1IsLP4Family(p->dram_type)) && (u1PassByteCount==0x3)) || ((p->dram_type==TYPE_LPDDR3) && (u1PassByteCount==0xf)))
7929 {
7930 mcSHOW_DBG_MSG2(("All bytes gating window pass Done, Early break!\n"));
7931 mcFPRINTF((fp_A60501, "All bytes gating window pass Done, Early break!\n"));
7932 ucdly_fine_xT = DQS_GW_FINE_END;//break loop
7933 ucCoarseTune = ucCoarseEnd; //break loop
7934 }
7935 }
7936 }
7937 }
7938 }
7939 }
7940 }
7941
7942 DramcEngine2End(p);
7943
7944#if !SW_CHANGE_FOR_SIMULATION
7945 vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_OK);
7946#endif
7947
7948 //check if there is no pass taps for each DQS
7949 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
7950 {
7951 if (ucpass_count[dqs_i]==0)
7952 {
7953#if LP4_GATING_LEAD_LAG_FLAG_JUDGE==0
7954 /*TINFO="error, no pass taps in DQS_%d !!!\n", dqs_i*/
7955 mcSHOW_ERR_MSG(("error, no pass taps in DQS_%d!\n", dqs_i));
7956 mcFPRINTF((fp_A60501, "error, no pass taps in DQS_%d!\n", dqs_i));
7957 #if !SW_CHANGE_FOR_SIMULATION
7958 vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_FAIL);
7959 #endif
7960#endif
7961 }
7962 }
7963
7964 #if LP4_GATING_OLD_BURST_MODE
7965 if(u1IsLP4Family(p->dram_type))
7966 {
7967 //Set the gating window begin as gating position
7968 //ucpass_count[0]=0;
7969 //ucpass_count[1]=0;
7970
7971 //Set the gating window end-2UI as gating position
7972 ucpass_count[0] <<=1;
7973 ucpass_count[1] <<=1;
7974 }
7975 #else
7976 if(u1IsLP4Family(p->dram_type))
7977 {
7978 // LP4 burst mode, may find 6 UI. The 2 UI of the begining may not work.
7979 //if gating window > 5UI, skip the first 2 UI.
7980 if((ucpass_count_1[0]*ucDQS_GW_FINE_STEP > 160) &&(ucpass_count_1[1]*ucDQS_GW_FINE_STEP > 160))
7981 {
7982 mcSHOW_DBG_MSG2(("If gating window > 4.5UI, skip the first 2 UI! \n"));
7983 mcFPRINTF((fp_A60501, "If gating window > 4.5UI, skip the first 2 UI!\n"));
7984
7985 for (dqs_i=0; dqs_i<2; dqs_i++)
7986 {
7987 ucmin_coarse_tune0p5T[dqs_i] +=2;
7988
7989 if(ucmin_coarse_tune0p5T[dqs_i] > ucRX_DQS_CTL_LOOP)
7990 {
7991 ucmin_coarse_tune0p5T[dqs_i] -= ucRX_DQS_CTL_LOOP;
7992 ucmin_coarse_tune2T[dqs_i] +=1;
7993 }
7994 mcSHOW_DBG_MSG2(("Change Byte%d Window begin to (%d, %d)\n", dqs_i, ucmin_coarse_tune2T[dqs_i], ucmin_coarse_tune0p5T[dqs_i]));
7995 mcFPRINTF((fp_A60501, "Change Byte%d Window begin to (%d, %d)\n", dqs_i ucmin_coarse_tune2T[dqs_i], ucmin_coarse_tune0p5T[dqs_i]));
7996 }
7997 }
7998 }
7999 #endif
8000}
8001 //find center of each byte
8002 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8003 {
8004#if SW_CHANGE_FOR_SIMULATION // simulation cannot support %
8005 // -- PI for Phase0 & Phase1 --
8006 uctmp_offset = ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP/2;
8007 uctmp_value = ucmin_fine_tune[dqs_i]+uctmp_offset;
8008 ucbest_fine_tune[dqs_i] = uctmp_value - (uctmp_value/ucRX_DLY_DQSIENSTB_LOOP) * ucRX_DLY_DQSIENSTB_LOOP;
8009 ucbest_fine_tune_P1[dqs_i] = ucbest_fine_tune[dqs_i];
8010
8011 // coarse tune 0.5T for Phase 0
8012 uctmp_offset = uctmp_value / ucRX_DLY_DQSIENSTB_LOOP;
8013 uctmp_value = ucmin_coarse_tune0p5T[dqs_i]+uctmp_offset;
8014 ucbest_coarse_tune0p5T[dqs_i] = uctmp_value - (uctmp_value/ucRX_DQS_CTL_LOOP) * ucRX_DQS_CTL_LOOP;
8015
8016 // coarse tune 2T for Phase 0
8017 uctmp_offset = uctmp_value/ucRX_DQS_CTL_LOOP;
8018 ucbest_coarse_tune2T[dqs_i] = ucmin_coarse_tune2T[dqs_i]+uctmp_offset;
8019
8020 // coarse tune 0.5T for Phase 1
8021 uctmp_value = ucbest_coarse_tune0p5T[dqs_i]+ ucFreqDiv;
8022 ucbest_coarse_tune0p5T_P1[dqs_i] = uctmp_value - (uctmp_value/ ucRX_DQS_CTL_LOOP) *ucRX_DQS_CTL_LOOP;
8023
8024 // coarse tune 2T for Phase 1
8025 uctmp_offset = uctmp_value/ucRX_DQS_CTL_LOOP;
8026 ucbest_coarse_tune2T_P1[dqs_i] = ucbest_coarse_tune2T[dqs_i]+uctmp_offset;
8027#else
8028
8029 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_GatingCal)
8030 if(p->femmc_Ready==1)
8031 {
8032 ucmin_coarse_tune2T[dqs_i]=p->pSavetimeData->u1Gating2T_Save[p->channel][p->rank][dqs_i];
8033 ucmin_coarse_tune0p5T[dqs_i]=p->pSavetimeData->u1Gating05T_Save[p->channel][p->rank][dqs_i];
8034 ucmin_fine_tune[dqs_i]=p->pSavetimeData->u1Gatingfine_tune_Save[p->channel][p->rank][dqs_i];
8035 ucpass_count[dqs_i]=p->pSavetimeData->u1Gatingucpass_count_Save[p->channel][p->rank][dqs_i];
8036 vSetCalibrationResult(p, DRAM_CALIBRATION_GATING, DRAM_OK);
8037 }
8038 else
8039#endif
8040 {
8041
8042 #if LP4_GATING_LEAD_LAG_FLAG_JUDGE
8043 if(u1IsLP4Family(p->dram_type))
8044 {
8045 ucpass_count[dqs_i] = u1DQS_transition[dqs_i];
8046 ucmin_fine_tune[dqs_i] = ucdly_fine_tune_leadLag[dqs_i];
8047 ucmin_coarse_tune0p5T[dqs_i] = ucdly_coarse_0p5T_leadLag[dqs_i];
8048 ucmin_coarse_tune2T[dqs_i] = ucdly_coarse_large_leadLag[dqs_i];
8049 }
8050 #endif
8051 }
8052
8053 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
8054 if(p->femmc_Ready==0)
8055 {
8056 p->pSavetimeData->u1Gating2T_Save[p->channel][p->rank][dqs_i]=ucmin_coarse_tune2T[dqs_i];
8057 p->pSavetimeData->u1Gating05T_Save[p->channel][p->rank][dqs_i]=ucmin_coarse_tune0p5T[dqs_i];
8058 p->pSavetimeData->u1Gatingfine_tune_Save[p->channel][p->rank][dqs_i]=ucmin_fine_tune[dqs_i];
8059 p->pSavetimeData->u1Gatingucpass_count_Save[p->channel][p->rank][dqs_i]=ucpass_count[dqs_i];
8060 // mcSHOW_DBG_MSG(("save Gating\n"));
8061 }
8062 #endif
8063 // -- PI for Phase0 & Phase1 --
8064 #if (LP4_GATING_END_MINUS2UI==1 && LP4_GATING_OLD_BURST_MODE==0)
8065 mcSHOW_DBG_MSG(("ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP=%d\n", (ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP)));
8066 if((ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP)<128)//window size < 4UI : select center
8067 {
8068 uctmp_offset = ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP/2;
8069 }
8070 else // select window_end-2UI
8071 {
8072 uctmp_offset = (ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP) - 64;
8073 }
8074 #else
8075 uctmp_offset = ucpass_count[dqs_i]*ucDQS_GW_FINE_STEP/2;
8076 #endif
8077
8078 uctmp_value = ucmin_fine_tune[dqs_i]+uctmp_offset;
8079 ucbest_fine_tune[dqs_i] = uctmp_value% ucRX_DLY_DQSIENSTB_LOOP;
8080 ucbest_fine_tune_P1[dqs_i] = ucbest_fine_tune[dqs_i];
8081
8082 // coarse tune 0.5T for Phase 0
8083 uctmp_offset = uctmp_value / ucRX_DLY_DQSIENSTB_LOOP;
8084 uctmp_value = ucmin_coarse_tune0p5T[dqs_i]+uctmp_offset;
8085 ucbest_coarse_tune0p5T[dqs_i] = uctmp_value% ucRX_DQS_CTL_LOOP;
8086
8087 // coarse tune 2T for Phase 0
8088 uctmp_offset = uctmp_value/ucRX_DQS_CTL_LOOP;
8089 ucbest_coarse_tune2T[dqs_i] = ucmin_coarse_tune2T[dqs_i]+uctmp_offset;
8090
8091 // coarse tune 0.5T for Phase 1
8092 uctmp_value = ucbest_coarse_tune0p5T[dqs_i]+ ucFreqDiv;
8093 ucbest_coarse_tune0p5T_P1[dqs_i] = uctmp_value% ucRX_DQS_CTL_LOOP;
8094
8095 // coarse tune 2T for Phase 1
8096 uctmp_offset = uctmp_value/ucRX_DQS_CTL_LOOP;
8097 ucbest_coarse_tune2T_P1[dqs_i] = ucbest_coarse_tune2T[dqs_i]+uctmp_offset;
8098#endif
8099 }
8100
8101 mcSHOW_DBG_MSG3(("\n\tdqs input gating window, final dly value\n\n"));
8102
8103 //mcSHOW_DBG_MSG(("test2_1: 0x%x, test2_2: 0x%x, test pattern: %d\n", p->test2_1,p->test2_2, p->test_pattern));
8104 //mcSHOW_DBG_MSG3(("\tdqs input gating window, best dly value\n\n"));
8105
8106
8107 mcFPRINTF((fp_A60501, "\n\tdqs input gating window, final dly value\n\n"));
8108 //mcFPRINTF((fp_A60501, "test2_1: 0x%x, test2_2: 0x%x, test pattern: %d\n", p->test2_1,p->test2_2, p->test_pattern));
8109 mcFPRINTF((fp_A60501, "\tdqs input gating window, best dly value\n\n"));
8110
8111 if(u1IsLP4Family(p->dram_type))
8112 {
8113 for (dqs_i=2; dqs_i<4; dqs_i++) // LP4, DQ byte 2 and byte 3 are useless, set gating result as 0.
8114 {
8115 ucbest_coarse_tune2T[dqs_i] = ucbest_coarse_tune0p5T[dqs_i] = ucbest_fine_tune[dqs_i]= 0;
8116 ucbest_coarse_tune2T_P1[dqs_i] = ucbest_coarse_tune0p5T_P1[dqs_i] = ucbest_fine_tune_P1[dqs_i]= 0;
8117
8118 #if GATING_ADJUST_TXDLY_FOR_TRACKING
8119 ucbest_coarse_tune2T_backup[p->rank][dqs_i] = ucbest_coarse_tune0p5T_backup[p->rank][dqs_i] = 0;
8120 ucbest_coarse_tune2T_P1_backup[p->rank][dqs_i] = ucbest_coarse_tune0p5T_P1_backup[p->rank][dqs_i] = 0;
8121 #endif
8122 }
8123 }
8124
8125 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8126 {
8127 #ifdef FOR_HQA_REPORT_USED
8128 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_2T", dqs_i, ucbest_coarse_tune2T[dqs_i], NULL);
8129 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_05T", dqs_i, ucbest_coarse_tune0p5T[dqs_i], NULL);
8130 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "Gating_Center_PI", dqs_i, ucbest_fine_tune[dqs_i], NULL);
8131 #endif
8132
8133 /*TINFO="best DQS%d delay(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T[dqs_i], ucbest_coarse_tune0p5T[dqs_i], ucbest_fine_tune[dqs_i]*/
8134 mcSHOW_DBG_MSG(("\nbest DQS%d dly(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T[dqs_i], ucbest_coarse_tune0p5T[dqs_i], ucbest_fine_tune[dqs_i]));
8135 mcFPRINTF((fp_A60501,"best DQS%d dly(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T[dqs_i], ucbest_coarse_tune0p5T[dqs_i], ucbest_fine_tune[dqs_i]));
8136 #if GATING_ADJUST_TXDLY_FOR_TRACKING
8137 // find min gating TXDLY (should be in P0)
8138 if (u1IsLP4Family(p->dram_type))
8139 {
8140 u1TX_dly_DQSgated =ucbest_coarse_tune2T[dqs_i];
8141 }
8142#if ENABLE_LP3_SW
8143 else
8144 {
8145 u1TX_dly_DQSgated = ((ucbest_coarse_tune2T[dqs_i] <<1)|((ucbest_coarse_tune0p5T[dqs_i] >>2)&0x1));
8146 }
8147#endif /* ENABLE_LP3_SW */
8148
8149 if(u1TX_dly_DQSgated < u1TXDLY_Cal_min)
8150 u1TXDLY_Cal_min = u1TX_dly_DQSgated;
8151
8152 ucbest_coarse_tune0p5T_backup[p->rank][dqs_i] = ucbest_coarse_tune0p5T[dqs_i];
8153 ucbest_coarse_tune2T_backup[p->rank][dqs_i] = ucbest_coarse_tune2T[dqs_i];
8154 #endif
8155 }
8156
8157 mcSHOW_DBG_MSG(("\n\n"));
8158 mcFPRINTF((fp_A60501,"\n\n"));
8159
8160 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8161 {
8162 /*TINFO="best DQS%d P1 delay(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T_P1[dqs_i], ucbest_coarse_tune0p5T_P1[dqs_i], ucbest_fine_tune[dqs_i]*/
8163 mcSHOW_DBG_MSG(("\nbest DQS%d P1 dly(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T_P1[dqs_i], ucbest_coarse_tune0p5T_P1[dqs_i], ucbest_fine_tune[dqs_i]));
8164 mcFPRINTF((fp_A60501,"best DQS%d P1 dly(2T, 0.5T, PI) = (%d, %d, %d)\n", dqs_i, ucbest_coarse_tune2T_P1[dqs_i], ucbest_coarse_tune0p5T_P1[dqs_i], ucbest_fine_tune[dqs_i]));
8165
8166 #if GATING_ADJUST_TXDLY_FOR_TRACKING
8167 // find max gating TXDLY (should be in P1)
8168
8169 if (u1IsLP4Family(p->dram_type))
8170 {
8171 u1TX_dly_DQSgated = ucbest_coarse_tune2T_P1[dqs_i];
8172 }
8173#if ENABLE_LP3_SW
8174 else
8175 {
8176 u1TX_dly_DQSgated = ((ucbest_coarse_tune2T_P1[dqs_i] <<1)|((ucbest_coarse_tune0p5T_P1[dqs_i] >>2)&0x1));
8177 }
8178#endif /* ENABLE_LP3_SW */
8179
8180 if(u1TX_dly_DQSgated > u1TXDLY_Cal_max)
8181 u1TXDLY_Cal_max = u1TX_dly_DQSgated;
8182
8183 ucbest_coarse_tune0p5T_P1_backup[p->rank][dqs_i] = ucbest_coarse_tune0p5T_P1[dqs_i];
8184 ucbest_coarse_tune2T_P1_backup[p->rank][dqs_i] = ucbest_coarse_tune2T_P1[dqs_i];
8185 #endif
8186 }
8187
8188 mcSHOW_DBG_MSG(("\n\n"));
8189 mcFPRINTF((fp_A60501,"\n\n"));
8190
8191 //Restore registers
8192 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
8193
8194#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
8195 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
8196#endif
8197
8198 #if LP4_GATING_OLD_BURST_MODE
8199 if(u1IsLP4Family(p->dram_type))
8200 {
8201 #if !LP4_GATING_LEAD_LAG_FLAG_JUDGE
8202 DramcGatingMode(p, 1);
8203 #endif
8204 //MR1 OP[7]=0;
8205 u1MR01Value[p->dram_fsp] &= 0x7f;
8206 DramcModeRegWriteByRank(p, p->rank, 1, u1MR01Value[p->dram_fsp]);
8207 }
8208 #endif
8209
8210 /* LP3/4: Set ARDQ_RPRE_TOG_EN must be 1 after gating window calibration */
8211 RxDQSIsiPulseCG(p, ENABLE);
8212
8213 #if REG_SHUFFLE_REG_CHECK
8214 ShuffleRegCheck =1;
8215 #endif
8216
8217 // 4T or 2T coarse tune
8218 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG0), \
8219 P_Fld((U32) ucbest_coarse_tune2T[0], SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED)| \
8220 P_Fld((U32) ucbest_coarse_tune2T[1], SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED)| \
8221 P_Fld((U32) ucbest_coarse_tune2T[2], SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED)| \
8222 P_Fld((U32) ucbest_coarse_tune2T[3], SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED)| \
8223 P_Fld((U32) ucbest_coarse_tune2T_P1[0], SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED_P1)| \
8224 P_Fld((U32) ucbest_coarse_tune2T_P1[1], SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED_P1)| \
8225 P_Fld((U32) ucbest_coarse_tune2T_P1[2], SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED_P1)| \
8226 P_Fld((U32) ucbest_coarse_tune2T_P1[3], SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED_P1));
8227
8228 // 0.5T coarse tune
8229 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG1), \
8230 P_Fld((U32) ucbest_coarse_tune0p5T[0], SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED)| \
8231 P_Fld((U32) ucbest_coarse_tune0p5T[1], SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED)| \
8232 P_Fld((U32) ucbest_coarse_tune0p5T[2], SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED)| \
8233 P_Fld((U32) ucbest_coarse_tune0p5T[3], SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED)| \
8234 P_Fld((U32) ucbest_coarse_tune0p5T_P1[0], SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED_P1)| \
8235 P_Fld((U32) ucbest_coarse_tune0p5T_P1[1], SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED_P1)| \
8236 P_Fld((U32) ucbest_coarse_tune0p5T_P1[2], SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED_P1)| \
8237 P_Fld((U32) ucbest_coarse_tune0p5T_P1[3], SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED_P1));
8238
8239
8240 #if GATING_RODT_LATANCY_EN //LP3 RODT is not enable, don't need to set the RODT settings.
8241 // RODT = Gating - 11UI,
8242 if(u1IsLP4Family(p->dram_type))
8243 {
8244 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8245 {
8246 uctmp_value = (ucbest_coarse_tune2T[dqs_i] <<3)+ucbest_coarse_tune0p5T[dqs_i];
8247
8248 if(uctmp_value>=11)
8249 {
8250 //P0
8251 uctmp_value -=11;
8252 ucbest_coarse_large_RODT[dqs_i] = uctmp_value >>3;
8253 ucbest_coarse_0p5T_RODT[dqs_i] = uctmp_value - (ucbest_coarse_large_RODT[dqs_i] <<3);
8254
8255 //P1
8256 uctmp_value = (ucbest_coarse_tune2T_P1[dqs_i] <<3)+ucbest_coarse_tune0p5T_P1[dqs_i] -11;
8257 ucbest_coarse_large_RODT_P1[dqs_i] = uctmp_value >>3;
8258 ucbest_coarse_0p5T_RODT_P1[dqs_i] = uctmp_value - (ucbest_coarse_large_RODT_P1[dqs_i] <<3);
8259
8260 mcSHOW_DBG_MSG2(("\nbest RODT dly(2T, 0.5T) = (%d, %d)\n", ucbest_coarse_large_RODT[dqs_i], ucbest_coarse_0p5T_RODT[dqs_i]));
8261 mcFPRINTF((fp_A60501,"best RODT dly(2T, 0.5T) = (%d, %d)\n", ucbest_coarse_large_RODT[dqs_i], ucbest_coarse_0p5T_RODT[dqs_i]));
8262 }
8263 else //if(ucbest_coarse_tune2T[0] ==0) //shouble not happen, just only protect this happen
8264 {
8265 //P0
8266 ucbest_coarse_large_RODT[dqs_i] =0;
8267 ucbest_coarse_0p5T_RODT[dqs_i] = 0;
8268 //P1
8269 ucbest_coarse_large_RODT_P1[dqs_i] =4;
8270 ucbest_coarse_0p5T_RODT_P1[dqs_i] = 4;
8271
8272 mcSHOW_ERR_MSG(("[RxdqsGatingCal] Error: ucbest_coarse_tune2T[%d] is already 0. RODT cannot be -1 UI\n", dqs_i));
8273 mcFPRINTF((fp_A60501, "[RxdqsGatingCal] Error: ucbest_coarse_tune2T[%d] is already 0. RODT cannot be -1 UI\n", dqs_i));
8274 }
8275 }
8276
8277 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_ODTEN0), \
8278 P_Fld((U32) ucbest_coarse_large_RODT[0], SHURK0_SELPH_ODTEN0_TXDLY_B0_RODTEN)| \
8279 P_Fld((U32) ucbest_coarse_large_RODT[1], SHURK0_SELPH_ODTEN0_TXDLY_B1_RODTEN)| \
8280 P_Fld((U32) ucbest_coarse_large_RODT[2], SHURK0_SELPH_ODTEN0_TXDLY_B2_RODTEN)| \
8281 P_Fld((U32) ucbest_coarse_large_RODT[3], SHURK0_SELPH_ODTEN0_TXDLY_B3_RODTEN)| \
8282 P_Fld((U32) ucbest_coarse_large_RODT_P1[0], SHURK0_SELPH_ODTEN0_TXDLY_B0_RODTEN_P1)| \
8283 P_Fld((U32) ucbest_coarse_large_RODT_P1[1], SHURK0_SELPH_ODTEN0_TXDLY_B1_RODTEN_P1)| \
8284 P_Fld((U32) ucbest_coarse_large_RODT_P1[2], SHURK0_SELPH_ODTEN0_TXDLY_B2_RODTEN_P1)| \
8285 P_Fld((U32) ucbest_coarse_large_RODT_P1[3], SHURK0_SELPH_ODTEN0_TXDLY_B3_RODTEN_P1));
8286
8287 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_ODTEN1), \
8288 P_Fld((U32) ucbest_coarse_0p5T_RODT[0], SHURK0_SELPH_ODTEN1_DLY_B0_RODTEN)| \
8289 P_Fld((U32) ucbest_coarse_0p5T_RODT[1], SHURK0_SELPH_ODTEN1_DLY_B1_RODTEN)| \
8290 P_Fld((U32) ucbest_coarse_0p5T_RODT[2], SHURK0_SELPH_ODTEN1_DLY_B2_RODTEN)| \
8291 P_Fld((U32) ucbest_coarse_0p5T_RODT[3], SHURK0_SELPH_ODTEN1_DLY_B3_RODTEN)| \
8292 P_Fld((U32) ucbest_coarse_0p5T_RODT_P1[0], SHURK0_SELPH_ODTEN1_DLY_B0_RODTEN_P1)| \
8293 P_Fld((U32) ucbest_coarse_0p5T_RODT_P1[1], SHURK0_SELPH_ODTEN1_DLY_B1_RODTEN_P1)| \
8294 P_Fld((U32) ucbest_coarse_0p5T_RODT_P1[2], SHURK0_SELPH_ODTEN1_DLY_B2_RODTEN_P1)| \
8295 P_Fld((U32) ucbest_coarse_0p5T_RODT_P1[3], SHURK0_SELPH_ODTEN1_DLY_B3_RODTEN_P1));
8296 }
8297 #endif
8298
8299 // Set Fine Tune Value to registers
8300 u4value = ucbest_fine_tune[0] | (ucbest_fine_tune[1]<<8) | (ucbest_fine_tune[2]<<16) | (ucbest_fine_tune[3]<<24);
8301 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSIEN), u4value);
8302
8303 #if REG_SHUFFLE_REG_CHECK
8304 ShuffleRegCheck =0;
8305 #endif
8306
8307 //mcDELAY_US(1);//delay 2T
8308 //DramPhyCGReset(p, 0);
8309 DramPhyReset(p); //reset phy, reset read data counter
8310
8311 /*TINFO="[DramcRxdqsGatingCal] Done\n"*/
8312 mcSHOW_DBG_MSG3(("[DramcRxdqsGatingCal] Done\n\n"));
8313 mcFPRINTF((fp_A60501, "[DramcRxdqsGatingCal] Done\n\n"));
8314
8315 return DRAM_OK;
8316 // log example
8317 /*
8318 0 1 12 |(B3->B0) 0x 0, 0x1211, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8319 0 1 16 |(B3->B0) 0x 0, 0x1211, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8320 0 1 20 |(B3->B0) 0x 0, 0x1211, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8321 0 1 24 |(B3->B0) 0x 0, 0x1211, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8322 0 1 28 |(B3->B0) 0x 0, 0x1211, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8323 0 2 0 |(B3->B0) 0x 0, 0x1d1c, 0x1212, 0x1211 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8324 0 2 4 |(B3->B0) 0x 0, 0x2324, 0x1212, 0x1413 | (B3->B0) 11 11 0 0 11 11 11 11 | 0xffffffff
8325 0 2 8 |(B3->B0) 0x 0, 0x2323, 0x1212, 0x2222 | (B3->B0) 0 0 0 0 11 11 11 11 | 0xff00ffff
8326 0 2 12 |(B3->B0) 0x 0, 0x2323, 0x1211, 0x2323 | (B3->B0) 0 0 0 0 11 11 0 0 | 0x ffff
8327 0 2 16 |(B3->B0) 0x 0, 0x2323, 0x 504, 0x2324 | (B3->B0) 0 0 0 0 11 11 0 0 | 0x ff00
8328 0 2 20 |(B3->B0) 0x 0, 0x2323, 0x 303, 0x2323 | (B3->B0) 0 0 0 0 1 1 0 0 | 0x ff00
8329 0 2 24 |(B3->B0) 0x 0, 0x2323, 0x2324, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8330 0 2 28 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8331 0 3 0 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8332 0 3 4 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8333 0 3 8 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8334 0 3 12 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8335 0 3 16 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8336 0 3 20 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8337 0 3 24 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8338 0 3 28 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0x 0
8339 1 0 0 |(B3->B0) 0x 0, 0x2120, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 0 0 0 0 | 0xffff0000
8340 1 0 4 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x1212 | (B3->B0) 11 11 0 0 0 0 11 11 | 0xffff00ff
8341 1 0 8 |(B3->B0) 0x 0, 0x2324, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0xffff00ff
8342 1 0 12 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0xffff00ff
8343 1 0 16 |(B3->B0) 0x 0, 0x2323, 0x1f1f, 0x2323 | (B3->B0) 0 0 0 0 11 11 0 0 | 0xffffffff
8344 1 0 20 |(B3->B0) 0x 0, 0x2323, 0x2324, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0xffffffff
8345 1 0 24 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 0 0 0 0 0 0 0 0 | 0xffffffff
8346 1 0 28 |(B3->B0) 0x 0, 0x2322, 0x2324, 0x2323 | (B3->B0) 11 11 11 11 0 0 0 0 | 0x ffff
8347 1 1 0 |(B3->B0) 0x 0, 0x2322, 0x2324, 0x2323 | (B3->B0) 11 11 11 11 0 0 0 0 | 0xffffffff
8348 1 1 4 |(B3->B0) 0x 0, 0x2323, 0x2324, 0x2322 | (B3->B0) 11 11 11 11 0 0 11 11 | 0xffffff00
8349 1 1 8 |(B3->B0) 0x 0, 0x2323, 0x2324, 0x2322 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8350 1 1 12 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8351 1 1 16 |(B3->B0) 0x 0, 0x2323, 0x2322, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8352 1 1 20 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8353 1 1 24 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8354 1 1 28 |(B3->B0) 0x 0, 0x2323, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8355 1 2 0 |(B3->B0) 0x 0, 0x1a1b, 0x2323, 0x2323 | (B3->B0) 11 11 11 11 11 11 11 11 | 0xffffffff
8356 1 2 4 |(B3->B0) 0x 0, 0x1a1b, 0x2323, 0x1e1f | (B3->B0) 0 0 11 11 11 11 0 0 | 0xffffffff
8357
8358 ===============================================================================
8359 dqs input gating widnow, final delay value
8360 channel=2(2:cha, 3:chb)
8361 ===============================================================================
8362 test2_1: 0x55000000, test2_2: 0xaa000400, test pattern: 5
8363 dqs input gating widnow, best delay value
8364 ===============================================================================
8365 best DQS0 delay(2T, 0.5T, PI) = (0, 3, 12)
8366 best DQS1 delay(2T, 0.5T, PI) = (0, 3, 22)
8367 best DQS2 delay(2T, 0.5T, PI) = (0, 3, 4)
8368 best DQS3 delay(2T, 0.5T, PI) = (0, 3, 4)
8369 ===============================================================================
8370 best DQS0 P1 delay(2T, 0.5T, PI) = (1, 1, 12)
8371 best DQS1 P1 delay(2T, 0.5T, PI) = (1, 1, 22)
8372 best DQS2 P1 delay(2T, 0.5T, PI) = (1, 1, 4)
8373 best DQS3 P1 delay(2T, 0.5T, PI) = (1, 1, 4)
8374 ===============================================================================
8375 [DramcRxdqsGatingCal] ====Done====
8376
8377*/
8378}
8379
8380#if GATING_ADJUST_TXDLY_FOR_TRACKING
8381void DramcRxdqsGatingPostProcess(DRAMC_CTX_T *p)
8382{
8383 U8 dqs_i;
8384#if ENABLE_LP3_SW
8385 U8 u1RankRxDVS=0;
8386#endif
8387 U8 u1RankIdx, u1RankMax;
8388 S8 s1ChangeDQSINCTL;
8389 U32 backup_rank;
8390 U32 u4ReadDQSINCTL, u4ReadTXDLY[RANK_MAX][DQS_NUMBER], u4ReadTXDLY_P1[RANK_MAX][DQS_NUMBER], u4RankINCTL_ROOT, u4XRTR2R, reg_TX_dly_DQSgated_min = 0;
8391
8392 backup_rank = u1GetRank(p);
8393
8394#ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY
8395 if (u1IsLP4Family(p->dram_type))
8396 {
8397 // wei-jen: DQSgated_min should be 2 when freq >= 1333, 1 when freq < 1333
8398 if (p->frequency >= 1333)
8399 {
8400 reg_TX_dly_DQSgated_min = 2;
8401 }
8402 else
8403 {
8404 reg_TX_dly_DQSgated_min = 1;
8405 }
8406 }
8407#if ENABLE_LP3_SW
8408 else
8409 {
8410 // 1866,1600,1333,1200 : reg_TX_dly_DQSgated (min) =2
8411 reg_TX_dly_DQSgated_min = 2;
8412 }
8413#endif /* ENABLE_LP3_SW */
8414#else
8415 if (u1IsLP4Family(p->dram_type))
8416 {
8417 // wei-jen: DQSgated_min should be 3 when freq >= 1333, 2 when freq < 1333
8418 if (p->frequency >= 1333)
8419 {
8420 reg_TX_dly_DQSgated_min = 3;
8421 }
8422 else
8423 {
8424 reg_TX_dly_DQSgated_min = 2;
8425 }
8426 }
8427#if ENABLE_LP3_SW
8428 else
8429 {
8430 // 800 : reg_TX_dly_DQSgated (min) =2
8431 // 1066 : reg_TX_dly_DQSgated (min) =2
8432 // 1270 : reg_TX_dly_DQSgated (min) =2
8433 // 1600 : reg_TX_dly_DQSgated (min) =3
8434 // 1866 : reg_TX_dly_DQSgated (min) =3
8435 if(p->frequency < 700)
8436 {
8437 reg_TX_dly_DQSgated_min = 2;
8438 }
8439 else
8440 {
8441 reg_TX_dly_DQSgated_min = 3;
8442 }
8443 }
8444#endif /* ENABLE_LP3_SW */
8445#endif
8446#if ENABLE_LP3_SW
8447 // === Begin of DVS setting =====
8448 //RANKRXDVS = reg_TX_dly_DQSgated (min) -1 = Roundup(tDQSCKdiff/MCK)
8449 if (!u1IsLP4Family(p->dram_type))
8450 {
8451 if(reg_TX_dly_DQSgated_min>1)
8452 {
8453 u1RankRxDVS = reg_TX_dly_DQSgated_min -1;
8454 }
8455 else
8456 {
8457 u1RankRxDVS=0;
8458 mcSHOW_ERR_MSG(("[RxdqsGatingPostProcess] u1RankRxDVS <1, Please check!\n"));
8459 }
8460 }
8461#endif
8462//Sylvia MP setting is switched to new mode, so RANKRXDVS can be set as 0 (review by HJ Huang)
8463#if 0
8464 if(u1IsLP4Family(p->dram_type))
8465 {
8466 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), u1RankRxDVS, SHU1_B0_DQ7_R_DMRANKRXDVS_B0);
8467 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7), u1RankRxDVS, SHU1_B1_DQ7_R_DMRANKRXDVS_B1);
8468 }
8469#endif
8470#if ENABLE_LP3_SW
8471 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8472 {
8473 vIO32WriteFldAlign_Phy_Byte(dqs_i, DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), u1RankRxDVS, SHU1_B0_DQ7_R_DMRANKRXDVS_B0);
8474 }
8475#endif /* ENABLE_LP3_SW */
8476 // === End of DVS setting =====
8477
8478 s1ChangeDQSINCTL = reg_TX_dly_DQSgated_min- u1TXDLY_Cal_min;
8479
8480 mcSHOW_DBG_MSG(("[RxdqsGatingPostProcess] freq %d\n"
8481 "ChangeDQSINCTL %d, reg_TX_dly_DQSgated_min %d, u1TXDLY_Cal_min %d\n",
8482 p->frequency,
8483 s1ChangeDQSINCTL, reg_TX_dly_DQSgated_min, u1TXDLY_Cal_min));
8484
8485 if(s1ChangeDQSINCTL!=0) // need to change DQSINCTL and TXDLY of each byte
8486 {
8487 u1TXDLY_Cal_min += s1ChangeDQSINCTL;
8488 u1TXDLY_Cal_max += s1ChangeDQSINCTL;
8489
8490 if (p->support_rank_num==RANK_DUAL)
8491 u1RankMax = RANK_MAX;
8492 else
8493 u1RankMax =RANK_1;
8494
8495 for(u1RankIdx=0; u1RankIdx<u1RankMax; u1RankIdx++)
8496 {
8497 mcSHOW_DBG_MSG2(("Rank: %d\n", u1RankIdx));
8498
8499 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8500 {
8501 if(u1IsLP4Family(p->dram_type))
8502 {
8503 u4ReadTXDLY[u1RankIdx][dqs_i]= ucbest_coarse_tune2T_backup[u1RankIdx][dqs_i];
8504 u4ReadTXDLY_P1[u1RankIdx][dqs_i]= ucbest_coarse_tune2T_P1_backup[u1RankIdx][dqs_i];
8505
8506 u4ReadTXDLY[u1RankIdx][dqs_i] += s1ChangeDQSINCTL;
8507 u4ReadTXDLY_P1[u1RankIdx][dqs_i] += s1ChangeDQSINCTL;
8508
8509 ucbest_coarse_tune2T_backup[u1RankIdx][dqs_i] = u4ReadTXDLY[u1RankIdx][dqs_i];
8510 ucbest_coarse_tune2T_P1_backup[u1RankIdx][dqs_i] = u4ReadTXDLY_P1[u1RankIdx][dqs_i];
8511 }
8512 else
8513 {
8514 u4ReadTXDLY[u1RankIdx][dqs_i]= ((ucbest_coarse_tune2T_backup[u1RankIdx][dqs_i]<<1) + ((ucbest_coarse_tune0p5T_backup[u1RankIdx][dqs_i]>>2) & 0x1));
8515 u4ReadTXDLY_P1[u1RankIdx][dqs_i]= ((ucbest_coarse_tune2T_P1_backup[u1RankIdx][dqs_i]<<1) + ((ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][dqs_i]>>2) & 0x1));
8516
8517 u4ReadTXDLY[u1RankIdx][dqs_i] += s1ChangeDQSINCTL;
8518 u4ReadTXDLY_P1[u1RankIdx][dqs_i] += s1ChangeDQSINCTL;
8519
8520 ucbest_coarse_tune2T_backup[u1RankIdx][dqs_i] = (u4ReadTXDLY[u1RankIdx][dqs_i] >>1);
8521 ucbest_coarse_tune0p5T_backup[u1RankIdx][dqs_i] = ((u4ReadTXDLY[u1RankIdx][dqs_i] & 0x1) <<2)+(ucbest_coarse_tune0p5T_backup[u1RankIdx][dqs_i] & 0x3);
8522
8523 ucbest_coarse_tune2T_P1_backup[u1RankIdx][dqs_i] = (u4ReadTXDLY_P1[u1RankIdx][dqs_i] >>1);
8524 ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][dqs_i] = ((u4ReadTXDLY_P1[u1RankIdx][dqs_i] & 0x1)<<2) +(ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][dqs_i] & 0x3);
8525 }
8526 mcSHOW_DBG_MSG(("best DQS%d dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_tune2T_backup[u1RankIdx][dqs_i], ucbest_coarse_tune0p5T_backup[u1RankIdx][dqs_i]));
8527 }
8528
8529 for (dqs_i=0; dqs_i<(p->data_width/DQS_BIT_NUMBER); dqs_i++)
8530 {
8531 mcSHOW_DBG_MSG(("best DQS%d P1 dly(2T, 0.5T) = (%d, %d)\n", dqs_i, ucbest_coarse_tune2T_P1_backup[u1RankIdx][dqs_i], ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][dqs_i]));
8532 }
8533 }
8534
8535 for(u1RankIdx=0; u1RankIdx<u1RankMax; u1RankIdx++)
8536 {
8537 vSetRank(p, u1RankIdx);
8538 // 4T or 2T coarse tune
8539 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG0), \
8540 P_Fld((U32) ucbest_coarse_tune2T_backup[u1RankIdx][0], SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED)| \
8541 P_Fld((U32) ucbest_coarse_tune2T_backup[u1RankIdx][1], SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED)| \
8542 P_Fld((U32) ucbest_coarse_tune2T_backup[u1RankIdx][2], SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED)| \
8543 P_Fld((U32) ucbest_coarse_tune2T_backup[u1RankIdx][3], SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED)| \
8544 P_Fld((U32) ucbest_coarse_tune2T_P1_backup[u1RankIdx][0], SHURK0_SELPH_DQSG0_TX_DLY_DQS0_GATED_P1)| \
8545 P_Fld((U32) ucbest_coarse_tune2T_P1_backup[u1RankIdx][1], SHURK0_SELPH_DQSG0_TX_DLY_DQS1_GATED_P1)| \
8546 P_Fld((U32) ucbest_coarse_tune2T_P1_backup[u1RankIdx][2], SHURK0_SELPH_DQSG0_TX_DLY_DQS2_GATED_P1)| \
8547 P_Fld((U32) ucbest_coarse_tune2T_P1_backup[u1RankIdx][3], SHURK0_SELPH_DQSG0_TX_DLY_DQS3_GATED_P1));
8548
8549 // 0.5T coarse tune
8550 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQSG1), \
8551 P_Fld((U32) ucbest_coarse_tune0p5T_backup[u1RankIdx][0], SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED)| \
8552 P_Fld((U32) ucbest_coarse_tune0p5T_backup[u1RankIdx][1], SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED)| \
8553 P_Fld((U32) ucbest_coarse_tune0p5T_backup[u1RankIdx][2], SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED)| \
8554 P_Fld((U32) ucbest_coarse_tune0p5T_backup[u1RankIdx][3], SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED)| \
8555 P_Fld((U32) ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][0], SHURK0_SELPH_DQSG1_REG_DLY_DQS0_GATED_P1)| \
8556 P_Fld((U32) ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][1], SHURK0_SELPH_DQSG1_REG_DLY_DQS1_GATED_P1)| \
8557 P_Fld((U32) ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][2], SHURK0_SELPH_DQSG1_REG_DLY_DQS2_GATED_P1)| \
8558 P_Fld((U32) ucbest_coarse_tune0p5T_P1_backup[u1RankIdx][3], SHURK0_SELPH_DQSG1_REG_DLY_DQS3_GATED_P1));
8559 }
8560 }
8561 vSetRank(p, backup_rank);
8562
8563 u4ReadDQSINCTL = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSCTL), SHURK0_DQSCTL_DQSINCTL);
8564 u4ReadDQSINCTL -= s1ChangeDQSINCTL;
8565
8566 #if ENABLE_READ_DBI
8567 U32 u4ReadRODT;
8568 if(p->DBI_R_onoff[p->dram_fsp])
8569 {
8570 u4ReadDQSINCTL++;
8571 u4ReadRODT = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), SHU_ODTCTRL_RODT);
8572 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), u4ReadRODT+1, SHU_ODTCTRL_RODT); //update RODT value when READ_DBI is on
8573 }
8574 #endif
8575
8576#ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY
8577 // Wei-Jen: RANKINCTL_RXDLY = RANKINCTL = RankINCTL_ROOT = u4ReadDQSINCTL-2, if XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY enable
8578 // Wei-Jen: New algorithm : u4ReadDQSINCTL-2 >= 0
8579 if(u4ReadDQSINCTL>=2)
8580 {
8581 u4RankINCTL_ROOT = u4ReadDQSINCTL-2;
8582 }
8583 else
8584 {
8585 u4RankINCTL_ROOT=0;
8586 mcSHOW_ERR_MSG(("u4RankINCTL_ROOT <2, Please check\n"));
8587#if (__ETT__)
8588 while(1);
8589#endif
8590 }
8591#else
8592 //Modify for corner IC failed at HQA test XTLV
8593 if(u4ReadDQSINCTL>=3)
8594 {
8595 u4RankINCTL_ROOT = u4ReadDQSINCTL-3;
8596 }
8597 else
8598 {
8599 u4RankINCTL_ROOT=0;
8600 mcSHOW_ERR_MSG(("u4RankINCTL_ROOT <3, Risk for supporting 1066/RL8\n"));
8601 }
8602#endif
8603
8604 //DQSINCTL
8605 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSCTL), u4ReadDQSINCTL, SHURK0_DQSCTL_DQSINCTL); //Rank0 DQSINCTL
8606 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK1_DQSCTL), u4ReadDQSINCTL, SHURK1_DQSCTL_R1DQSINCTL); //Rank1 DQSINCTL
8607
8608 //No need to update RODT. If we update RODT, also need to update SELPH_ODTEN0_TXDLY
8609 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), u4ReadDQSINCTL, SHU_ODTCTRL_RODT); //RODT = DQSINCTL
8610
8611 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_RANKCTL), u4ReadDQSINCTL, SHU_RANKCTL_RANKINCTL_PHY); //RANKINCTL_PHY = DQSINCTL
8612 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_RANKCTL), u4RankINCTL_ROOT, SHU_RANKCTL_RANKINCTL); //RANKINCTL= DQSINCTL -3
8613 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_RANKCTL), u4RankINCTL_ROOT, SHU_RANKCTL_RANKINCTL_ROOT1); //RANKINCTL_ROOT1= DQSINCTL -3
8614#ifdef XRTR2R_PERFORM_ENHANCE_DQSG_RX_DLY
8615 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_RANKCTL), u4RankINCTL_ROOT, SHU_RANKCTL_RANKINCTL_RXDLY);
8616
8617 u4XRTR2R= u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ACTIM_XRT), SHU_ACTIM_XRT_XRTR2R);
8618
8619 mcSHOW_DBG_MSG2(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL));
8620 mcSHOW_DBG_MSG2(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R));
8621
8622#else
8623 //XRTR2R=A-phy forbidden margin(6T) + reg_TX_dly_DQSgated (max) +Roundup(tDQSCKdiff/MCK+0.25MCK)+1(05T sel_ph margin)-1(forbidden margin overlap part)
8624 //Roundup(tDQSCKdiff/MCK+1UI) =1~2 all LP3 and LP4 timing
8625 //u4XRTR2R= 8 + u1TXDLY_Cal_max; // 6+ u1TXDLY_Cal_max +2
8626
8627 //Modify for corner IC failed at HQA test XTLV @ 3200MHz
8628 u4XRTR2R= 8 + u1TXDLY_Cal_max + 1; // 6+ u1TXDLY_Cal_max +2
8629 if (u4XRTR2R > 12)
8630 {
8631 u4XRTR2R= 12;
8632 mcSHOW_ERR_MSG(("XRTR2R > 12, Max value is 12\n"));
8633 }
8634 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ACTIM_XRT), u4XRTR2R, SHU_ACTIM_XRT_XRTR2R);
8635
8636 mcSHOW_DBG_MSG2(("TX_dly_DQSgated check: min %d max %d, ChangeDQSINCTL=%d\n", u1TXDLY_Cal_min, u1TXDLY_Cal_max, s1ChangeDQSINCTL));
8637 mcSHOW_DBG_MSG2(("DQSINCTL=%d, RANKINCTL=%d, u4XRTR2R=%d\n", u4ReadDQSINCTL, u4RankINCTL_ROOT, u4XRTR2R));
8638
8639#endif
8640
8641#if 0//ENABLE_RODT_TRACKING
8642 //Because Kibo+,WE2,Bianco,Vinson...or behind project support WDQS, they need to apply the correct new setting
8643 //The following 2 items are indepentent
8644 //1. if TX_WDQS on(by vendor_id) or p->odt_onoff = 1, ROEN/RODTE/RODTE2 = 1
8645 //2. if ENABLE_RODT_TRACKING on, apply new setting and RODTEN_MCK_MODESEL = ROEN
8646 // LP4 support only
8647 if (u1IsLP4Family(p->dram_type))
8648 {
8649 U8 u1ReadROEN;
8650 u1ReadROEN = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_ODTCTRL), SHU_ODTCTRL_ROEN);
8651 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_RODTENSTB), P_Fld(0xff, SHU_RODTENSTB_RODTENSTB_EXT)|\
8652 P_Fld(9, SHU_RODTENSTB_RODTENSTB_OFFSET)|\
8653 P_Fld(u1ReadROEN, SHU_RODTENSTB_RODTEN_MCK_MODESEL));
8654 }
8655#endif
8656#ifdef XRTR2W_PERFORM_ENHANCE_RODTEN
8657 // LP4 support only
8658 if (u1IsLP4Family(p->dram_type))
8659 {
8660 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_RODTENSTB), P_Fld(0x0fff, SHU_RODTENSTB_RODTENSTB_EXT)|\
8661 P_Fld(1, SHU_RODTENSTB_RODTEN_P1_ENABLE)|\
8662 P_Fld(1, SHU_RODTENSTB_RODTEN_MCK_MODESEL));
8663 }
8664#endif
8665
8666
8667 vSetRank(p, backup_rank);
8668
8669
8670}
8671#endif
8672
8673
8674#if GATING_ADJUST_TXDLY_FOR_TRACKING
8675void DramcRxdqsGatingPreProcess(DRAMC_CTX_T *p)
8676{
8677 u1TXDLY_Cal_min =0xff;
8678 u1TXDLY_Cal_max=0;
8679}
8680#endif
8681#endif //SIMULATION_GATING
8682
8683//-------------------------------------------------------------------------
8684/** DramcRxWindowPerbitCal (v2 version)
8685 * start the rx dqs perbit sw calibration.
8686 * @param p Pointer of context created by DramcCtxCreate.
8687 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
8688 */
8689//-------------------------------------------------------------------------
8690// default RX vref is 0xe=14
8691static void DramcRxWinRDDQCInit(DRAMC_CTX_T *p)
8692{
8693 U8 *uiLPDDR_MRR_Mapping;
8694 U16 temp_value=0;
8695 U8 MR_GOLDEN_MR15_GOLDEN_value=0, MR_GOLDEN_MR20_GOLDEN_value=0;
8696 int i;
8697
8698 //U8 u1ReadDBIbak[2];
8699 //U32 u4MRS_reg_bak;
8700
8701 // Disable Read DBI
8702 //u1ReadDBIbak[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0);
8703 //u1ReadDBIbak[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7), SHU1_B1_DQ7_R_DMDQMDBI_SHU_B1);
8704 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), 0, SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0);
8705 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7), 0, SHU1_B1_DQ7_R_DMDQMDBI_SHU_B1);
8706 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 1, SPCMDCTRL_RDDQCDIS); Moved to "DramcRxWinRDDQCRun()"
8707
8708 //u4MRS_reg_bak = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_MRS));
8709 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
8710 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN);
8711 uiLPDDR_MRR_Mapping = (U8 *)uiLPDDR4_MRR_Mapping_POP[p->channel];
8712
8713 for(i=0; i<16; i++)
8714 {
8715 temp_value |= ((0x5555 >> i) & 0x1) << uiLPDDR_MRR_Mapping[i];
8716 }
8717 MR_GOLDEN_MR15_GOLDEN_value = (U8) temp_value & 0xff;
8718 MR_GOLDEN_MR20_GOLDEN_value = (U8) (temp_value>>8) & 0xff;
8719 //Set golden pattern from Shih-hsiu's suggestion. 2016/3/25 04:43pm, RE: [Olympus] RX per bit calibration.
8720 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_MR_GOLDEN), P_Fld(MR_GOLDEN_MR15_GOLDEN_value, MR_GOLDEN_MR15_GOLDEN) | P_Fld(MR_GOLDEN_MR20_GOLDEN_value, MR_GOLDEN_MR20_GOLDEN));
8721
8722 //MPC_RDDQC_SET_MRS
8723 //Write MR32 DQ calibration pattern A //skip it if you want default 5Ah
8724 //Write MR40 DQ calibration pattern B //skip it if you want default 3Ch
8725 //Write MR15 low byte inverter for DQ calibration (byte 0) //skip it if you want default 55h
8726 //Write MR20 uper byte inverter for DQ calibration (byte 1) //skip it if you want default aah
8727 //DramcModeRegWrite(p, 32, 0x86);
8728 //DramcModeRegWrite(p, 40, 0xC9);
8729 //DramcModeRegWrite(p, 32, 0xaa);
8730 //DramcModeRegWrite(p, 32, 0xbb);
8731}
8732
8733/* Issue "RD DQ Calibration"
8734 * 1. RDDQCEN = 1 for RDDQC
8735 * 2. RDDQCDIS = 1 to stop RDDQC burst
8736 * 3. Wait rddqc_response = 1
8737 * 4. Read compare result
8738 * 5. RDDQCEN = 0
8739 * 6. RDDQCDIS = 0 (Stops RDDQC request)
8740 */
8741static U32 DramcRxWinRDDQCRun(DRAMC_CTX_T *p)
8742{
8743 U32 u4Result, u4Response;
8744 U32 u4TimeCnt= TIME_OUT_CNT;
8745
8746 //Issue RD DQ calibration
8747 //R_DMRDDQCEN, 0x1E4[7]=1 for RDDQC, R_DMRDDQCDIS, 0x1EC[26]=1 to stop RDDQC burst
8748 //Wait rddqc_response=1, (dramc_conf_nao, 0x3b8[31])
8749 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 1, SPCMDCTRL_RDDQCDIS);
8750 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_RDDQCEN);
8751 do
8752 {
8753 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_RDDQC_RESPONSE);
8754 u4TimeCnt --;
8755 mcDELAY_US(1);
8756 }while((u4Response ==0) &&(u4TimeCnt>0));
8757
8758 if(u4TimeCnt==0)//time out
8759 {
8760 mcSHOW_DBG_MSG(("[RxWinRDDQC] Resp fail (time out)\n"));
8761 mcFPRINTF((fp_A60501, "[RxWinRDDQC] Resp fail (time out)\n"));
8762 //return DRAM_FAIL;
8763 }
8764
8765 //Then read RDDQC compare result (dramc_conf_nao, 0x36c)
8766 u4Result = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_RDQC_CMP));
8767 //R_DMRDDQCEN, 0x1E4[7]=0
8768 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_RDDQCEN);
8769 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 0, SPCMDCTRL_RDDQCDIS);
8770
8771 return u4Result;
8772}
8773
8774static void DramcRxWinRDDQCEnd(DRAMC_CTX_T *p)
8775{
8776 //Recover Read DBI
8777 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7), p->DBI_R_onoff, SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0);
8778 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7), p->DBI_R_onoff, SHU1_B1_DQ7_R_DMDQMDBI_SHU_B1);
8779
8780 // Recover MPC Rank
8781 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), 0, MRS_MRSRK);
8782}
8783
8784#ifdef MPC_SW_FIFO
8785void DramcMPC_FIFO(DRAMC_CTX_T *p)
8786{
8787 U32 u4Result3,u4Result2,u4Result1,u4Result0;
8788 U32 u4Result, u4Response;
8789 U32 u4TimeCnt= TIME_OUT_CNT;
8790 U32 u4RegBackupAddress[] =
8791 {
8792 (DRAMC_REG_ADDR(DRAMC_REG_LBWDAT3)),
8793 (DRAMC_REG_ADDR(DRAMC_REG_LBWDAT2)),
8794 (DRAMC_REG_ADDR(DRAMC_REG_LBWDAT1)),
8795 (DRAMC_REG_ADDR(DRAMC_REG_LBWDAT0)),
8796 (DRAMC_REG_ADDR(DRAMC_REG_REFCTRL0)),
8797 (DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL)),
8798 (DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV)),
8799 (DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0)),
8800 };
8801
8802
8803 mcSHOW_DBG_MSG(("[DramcMPC_FIFO]\n"));
8804 //Register backup
8805 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
8806
8807 //WRFIFO and RDFIFO's golden data
8808 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT3), 0xAAAAAAAA, LBWDAT3_LBWDATA3);
8809 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT2), 0x55555555, LBWDAT2_LBWDATA2);
8810 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT1), 0xAAAAAAAA, LBWDAT1_LBWDATA1);
8811 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT0), 0x55555555, LBWDAT0_LBWDATA0);
8812
8813 u4Result3 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT3));
8814 mcSHOW_DBG_MSG(("DRAMC_REG_LBWDAT3: 0x%x\n", u4Result3));
8815 mcFPRINTF((fp_A60501, "DRAMC_REG_LBWDAT3: 0x%x\n", u4Result3));
8816 u4Result2 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT2));
8817 mcSHOW_DBG_MSG(("DRAMC_REG_LBWDAT2: 0x%x\n", u4Result2));
8818 mcFPRINTF((fp_A60501, "DRAMC_REG_LBWDAT2: 0x%x\n", u4Result2));
8819 u4Result1 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT1));
8820 mcSHOW_DBG_MSG(("DRAMC_REG_LBWDAT1: 0x%x\n", u4Result1));
8821 mcFPRINTF((fp_A60501, "DRAMC_REG_LBWDAT1: 0x%x\n", u4Result1));
8822 u4Result0 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_LBWDAT0));
8823 mcSHOW_DBG_MSG(("DRAMC_REG_LBWDAT0: 0x%x\n", u4Result0));
8824 mcFPRINTF((fp_A60501, "DRAMC_REG_LBWDAT0: 0x%x\n", u4Result0));
8825
8826
8827 //Other command is not valid during "WRFIFO and RDFIFO" period.
8828 //Disable auto refresh: set R_DMREFDIS=1
8829 vAutoRefreshSwitch(p, DISABLE);
8830 //Disable MR4: set R_DMREFRDIS=1
8831 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 1, SPCMDCTRL_REFRDIS);
8832 //Disable ZQCAL/ZQLAT command: set R_DMZQCALDISB=0
8833 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDCTRL), 0, SPCMDCTRL_ZQCALDISB);
8834
8835
8836 //When R_DMWRFIFOEN=1, MPC WRFIFO can send single request or 5 requests by R_DMRDDQC_INTV[1:0] (0x8C8[12:11])
8837 //Set R_DMRDDQC_INTV=2'b00 and Set R_DMWRFIO_MODE2 = 1'b0 for single MPC WRFIFO (single mode)
8838 //Set R_DMRDDQC_INTV=2'b01 and Set R_DMWRFIO_MODE2 = 1'b1 for five MPC WRFIFO (burst mode)
8839 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_SCINTV), 0, SHU_SCINTV_RDDQC_INTV);
8840 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0), 0, PERFCTL0_WRFIO_MODE2);
8841
8842
8843 //Issue MPC RD FIFO
8844 //R_DMWRFIFOEN, 0x0C[31]=1 for WR FIFO
8845 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0), 1, PERFCTL0_WRFIFOEN);
8846
8847 //Wait wrfifo_response=1 (dramc_conf_nao, 0x88[31])
8848 do
8849 {
8850 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_WRFIFO_RESPONSE);
8851 u4TimeCnt --;
8852 mcDELAY_US(1);
8853 }while((u4Response ==0) &&(u4TimeCnt>0));
8854
8855 if(u4TimeCnt==0)//time out
8856 {
8857 mcSHOW_DBG_MSG(("[DramcMPC_FIFO] Resp fail (time out)\n"));
8858 mcFPRINTF((fp_A60501, "[DramcMPC_FIFO] Resp fail (time out)\n"));
8859 //return DRAM_FAIL;
8860 }
8861
8862 //R_DMWRFIFOEN, 0x0C[31]=0
8863 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0), 0, PERFCTL0_WRFIFOEN);
8864
8865
8866
8867 //Issue MPC RD FIFO
8868 //R_DMRDFIFOEN, 0x0C[30]=1 for RD FIFO
8869 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0), 1, PERFCTL0_RDFIFOEN);
8870
8871 //Wait wrfifo_response=1 (dramc_conf_nao, 0x88[31])
8872 do
8873 {
8874 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_RDFIFO_RESPONSE);
8875 u4TimeCnt --;
8876 mcDELAY_US(1);
8877 }while((u4Response ==0) &&(u4TimeCnt>0));
8878
8879 if(u4TimeCnt==0)//time out
8880 {
8881 mcSHOW_DBG_MSG(("[DramcMPC_FIFO] Resp fail (time out)\n"));
8882 mcFPRINTF((fp_A60501, "[DramcMPC_FIFO] Resp fail (time out)\n"));
8883 //return DRAM_FAIL;
8884 }
8885
8886 //Then read RDFIFO compare result (dramc_conf_nao, 0x124)
8887 //Must do WRFIO first, then do RDFIFO, then compare it.
8888 u4Result = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_CMP_ERR));
8889 mcSHOW_DBG_MSG(("[DramcMPC_FIFO] Read RDFIFO compare result: 0x%x\n", u4Result));
8890
8891 //R_DMRDFIFOEN, 0x0C[30]=0
8892 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PERFCTL0), 0, PERFCTL0_RDFIFOEN);
8893
8894 //Restore registers
8895 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
8896
8897}
8898#endif
8899
8900#ifdef ENABLE_POST_PACKAGE_REPAIR
8901U8 global_sk_ppr_channel[SK_CHANNEL_BITS] = {0, 1}; //CHB //base on SK hynix_Repair_Guide_20180411.pdf
8902U8 global_sk_ppr_rank[SK_RANK_BITS] = {0, 1}; //R1 of fail IC
8903U8 global_sk_ppr_bank[SK_BANK_BITS] = {0, 0, 0, 0, 1, 0, 0, 0}; //Bank 4
8904U8 global_sk_ppr_byte[SK_BYTE_BITS] = {0};
8905U8 global_sk_ppr_row[SK_ROW_BITS] = {0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1}; //0x7154
8906U8 global_sk_vendor_id = VENDOR_HYNIX;
8907
8908#ifdef POST_PACKAGE_REPAIR_LP4
8909U8 TrasformToFailAddr(U8 *pArray ,U8 u1Size)
8910{
8911 U8 ucIdx = 0;
8912 U8 ucFailAddr = 0xff;
8913
8914 for(ucIdx=0; ucIdx<u1Size; ucIdx++)//could only allow one channel/rank/bank wrong
8915 {
8916 if(pArray[ucIdx] == 1)
8917 {
8918 ucFailAddr = ucIdx;
8919 break;
8920 }
8921 }
8922
8923 return ucFailAddr;
8924}
8925
8926
8927void DramcPostPackageRepair(DRAMC_CTX_T *p)
8928{
8929 U32 u4Response=0;
8930 U32 u4TimeCnt= TIME_OUT_CNT;
8931 U16 u2Value=0;
8932 U16 u2FailRow = 0;
8933 U8 ucFailChannel = 0xff;
8934 U8 ucFailRK = 0xff;
8935 U8 ucFailBK = 0xff;
8936 U8 ucIdx = 0;
8937
8938 ucFailChannel = TrasformToFailAddr(global_sk_ppr_channel, SK_CHANNEL_BITS);
8939 ucFailRK = TrasformToFailAddr(global_sk_ppr_rank, SK_RANK_BITS);
8940 ucFailBK = TrasformToFailAddr(global_sk_ppr_bank, SK_BANK_BITS);
8941 if((ucFailChannel == 0xff) || (ucFailRK == 0xff) || (ucFailBK == 0xff))
8942 {
8943 mcSHOW_ERR_MSG(("PPR Not assign channel/rank/bank!!\n"));
8944 return;
8945 }
8946
8947 for(ucIdx=0; ucIdx<SK_ROW_BITS; ucIdx++)//could only allow one bank wrong
8948 {
8949 u2FailRow += (global_sk_ppr_row[ucIdx] << ucIdx);
8950 }
8951
8952 vSetPHY2ChannelMapping(p, ucFailChannel);//Based on usage; fail IC 1-18, LP4 need to assign channel && rank
8953 vSetRank(p, ucFailRK);//Based on usage; fail IC 1-18, LP4 need to assign channel && rank
8954
8955 mcSHOW_DBG_MSG(("ucFailBK=0x%x, u2FailRow=0x%x\n", ucFailBK, u2FailRow));
8956 mcSHOW_DBG_MSG(("[DramcPostPackageRepair]\n"
8957 "\n\tFreq=%d, CH=%d, Rank=%d\n", p->frequency, p->channel, p->rank));
8958 mcFPRINTF((fp_A60501, "[DramcPostPackageRepair]"
8959 "\n\tFreq=%d, CH=%d, Rank=%d\n", p->frequency, p->channel, p->rank));
8960
8961 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MRS), u1GetRank(p), MRS_MRSRK);
8962
8963 //1.DRAMC DCM freerun,
8964 //R_DMDCMEN2(dramc conf AO 0x38[1])=0
8965 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_DCMEN2);
8966
8967 //2.PHY DCM freerun,
8968 //R_DMPHYCLKDYNGEN(dramc conf AO 0x38[30])=0
8969 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_PHYCLKDYNGEN);
8970
8971 //3.Dram clock freerun,
8972 //R_DMMIOCKCTRLOFF(dramc conf AO 0x38[26])=1
8973 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF);
8974
8975#if MRW_CHECK_ONLY
8976 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
8977#endif
8978
8979 //MR25 contains one bit of readout per bank indicating that at least one resource is available for Post Package Repair programming.
8980 DramcModeRegRead(p, 25, &u2Value);
8981 mcSHOW_DBG_MSG(("Before PostPackageRepair, MR25 = 0x%x\n", u2Value & 0xFF));
8982 mcFPRINTF((fp_A60501, "Before PostPackageRepair, MR25 = 0x%x\n", u2Value & 0xFF));
8983
8984 //4.Fix CKE0 and CKE1 be high,
8985 //R_DMCKEFIXON(dramc conf AO 0x24[6], CKECTRL.CKEFIXON)=1
8986 //R_DMCKE1FIXON(dramc conf AO 0x24[4], CKECTRL.CKE1FIXON)=1
8987 CKEFixOnOff(p, CKE_WRITE_TO_ALL_RANK, CKE_FIXON, CKE_WRITE_TO_ALL_CHANNEL);
8988
8989 //Step 0: disable refresh for PPR
8990 //Let R_DMREFDIS=1
8991 vAutoRefreshSwitch(p, DISABLE);
8992
8993 //Step 1: before enter PPR mode, all banks must be precharged
8994 //Set R_DMPREAEN=1
8995 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_PREAEN);
8996 mcDELAY_US(1);
8997 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_PREAEN);
8998
8999 //wait dramc_conf_nao.prea_response=1
9000 u4TimeCnt= TIME_OUT_CNT;
9001 u4Response = 0;
9002 do
9003 {
9004 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_PREA_RESPONSE);
9005 u4TimeCnt --;
9006 mcDELAY_US(1);
9007 }while((u4Response ==0) &&(u4TimeCnt>0));
9008
9009 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_PREAEN);
9010
9011 if(u4TimeCnt==0)//time out
9012 {
9013 mcSHOW_DBG_MSG(("dramc_conf_nao.prea_response fail (time out)\n"));
9014 mcFPRINTF((fp_A60501, "dramc_conf_nao.prea_response fail (time out)\n"));
9015 //return DRAM_FAIL;
9016 }
9017
9018 //Step 2: enter PPR mode
9019 if(global_sk_vendor_id == VENDOR_HYNIX) //Skhynix Manufacturer ID
9020 {
9021 //Skhynix DRAM PPR Enable Sequence
9022 //Assumption: MR3 OP<2> - LOW
9023 //Skhynix 2z 6Gb/4Gb LPDDR4x PPR Guard key
9024 //PPR Guard Key, MR9 with following OP codes : B8 - E8 - 98 - BF - EF - 9F - B9 - E9 - 99 - 84 - A2 - 81
9025 //Skhynix 2z 8Gb LPDDR4x PPR Guard key
9026 //PPR Guard Key, MR9 with following OP codes : CD - AD -FD -C9 -A9 -F9 -C7 -A7 -F7
9027 DramcModeRegWrite(p, 9, 0xB8);
9028 DramcModeRegWrite(p, 9, 0xE8);
9029 DramcModeRegWrite(p, 9, 0x98);
9030 DramcModeRegWrite(p, 9, 0xBF);
9031 DramcModeRegWrite(p, 9, 0xEF);
9032 DramcModeRegWrite(p, 9, 0x9F);
9033 DramcModeRegWrite(p, 9, 0xB9);
9034 DramcModeRegWrite(p, 9, 0xE9);
9035 DramcModeRegWrite(p, 9, 0x99);
9036 DramcModeRegWrite(p, 9, 0x84);
9037 DramcModeRegWrite(p, 9, 0xA2);
9038 DramcModeRegWrite(p, 9, 0x81);
9039 }
9040
9041 //Set MR4[4]=1: PPR entry
9042 DramcModeRegWrite(p, 4, 0x10);
9043
9044 //Step 3: wait tMRD
9045 //mcDELAY_US(1000);
9046 mcDELAY_MS(1000);
9047
9048 //Step 4: issue ACT command with fail row address
9049 //Set R_DMACTEN_ROW, R_DMACTEN_BK, then set R_DMACTEN,
9050 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_MPC_OPTION), 1, MPC_OPTION_MPCRKEN);
9051
9052 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PPR_CTRL), u2FailRow, PPR_CTRL_ACTEN_ROW);
9053 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_PPR_CTRL), ucFailBK, PPR_CTRL_ACTEN_BK);
9054 mcSHOW_DBG_MSG(("PPR, Fail Row = 0x%x, Fail Bank = 0x%x\n", u2FailRow, ucFailBK));
9055 mcFPRINTF((fp_A60501, "PPR, Fail Row = 0x%x, Fail Bank = 0x%x\n", u2FailRow, ucFailBK));
9056
9057 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_ACTEN);
9058 mcDELAY_US(1);
9059 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_ACTEN);
9060
9061 //wait dramc_conf_nao.act_response=1
9062 u4TimeCnt= TIME_OUT_CNT;
9063 u4Response=0;
9064 do
9065 {
9066 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_ACT_RESPONSE);
9067 u4TimeCnt --;
9068 mcDELAY_US(1);
9069 }while((u4Response ==0) &&(u4TimeCnt>0));
9070
9071 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_ACTEN);
9072
9073 if(u4TimeCnt==0)//time out
9074 {
9075 mcSHOW_DBG_MSG(("dramc_conf_nao.act_response fail (time out)\n"));
9076 mcFPRINTF((fp_A60501, "dramc_conf_nao.act_response fail (time out)\n"));
9077 //return DRAM_FAIL;
9078 }
9079
9080 //Step 5: wait tPGM to allow DRAM repair internally
9081 mcDELAY_MS(3000);
9082
9083 //Step 6: issue PRE
9084 //Set R_DMPREAEN=1
9085 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 0, SPCMD_PREAEN);
9086 mcDELAY_US(1);
9087 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMD), 1, SPCMD_PREAEN);
9088
9089 //wait dramc_conf_nao.prea_response=1
9090 u4TimeCnt= TIME_OUT_CNT;
9091 u4Response=0;
9092 do
9093 {
9094 u4Response = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SPCMDRESP), SPCMDRESP_PREA_RESPONSE);
9095 u4TimeCnt --;
9096 mcDELAY_US(1);
9097 }while((u4Response ==0) &&(u4TimeCnt>0));
9098
9099 if(u4TimeCnt==0)//time out
9100 {
9101 mcSHOW_DBG_MSG(("dramc_conf_nao.prea_response fail (time out)\n"));
9102 mcFPRINTF((fp_A60501, "dramc_conf_nao.prea_response fail (time out)\n"));
9103 //return DRAM_FAIL;
9104 }
9105
9106 //Step 7: wait tPGM_Exit
9107 //mcDELAY_US(1000);
9108 mcDELAY_MS(1000);
9109
9110 //Step 8: exit PPR
9111 //Set MR4[4]=0: PPR exit
9112 DramcModeRegWrite(p, 4, 0x0);
9113
9114 //Step 9: wait tPGMPST, them dram is ready for any valid command
9115 //mcDELAY_US(1000);
9116 mcDELAY_MS(1000);
9117
9118 //MR25 contains one bit of readout per bank indicating that at least one resource is available for Post Package Repair programming.
9119 DramcModeRegRead(p, 25, &u2Value);
9120 mcSHOW_DBG_MSG(("After PostPackageRepair, MR25 = 0x%x\n", u2Value & 0xFF));
9121 mcFPRINTF((fp_A60501, "After PostPackageRepair, MR25 = 0x%x\n", u2Value & 0xFF));
9122}
9123#endif
9124
9125#ifdef SKH_POST_PACKAGE_REPAIR_LP3
9126static void DramcModeRegWriteByRankUsDelay(DRAMC_CTX_T *p, U8 u1MRIdx, U8 u1Value, U8 u1Delay)
9127{
9128 DramcModeRegWriteByRank(p, p->rank, u1MRIdx, u1Value);
9129 mcDELAY_US(u1Delay);
9130 mcSHOW_DBG_MSG(("SKPPR R<%d> MR<%d> Value<%x> delay<%d>\n", p->rank, u1MRIdx, u1Value, u1Delay));
9131
9132 return;
9133}
9134
9135
9136void SkRepairSequenceOp0(DRAMC_CTX_T *p)
9137{
9138 DRAM_RANK_T eOriRank = u1GetRank(p);
9139 U8 u1Mr9_Op = 0;
9140 int i = 0;
9141 U8 u1RankIdx = 0;
9142 U8 u1DQ = ((global_sk_ppr_byte[0] == 1) || (global_sk_ppr_byte[2] == 1)) ? 0 : 1;
9143 U8 u1BK[3] = {0};
9144
9145 for(i = 0; i<=SK_BANK_BITS; i++)
9146 {
9147 if(global_sk_ppr_bank[i] == 1)
9148 {
9149 u1BK[0] = i & 1;
9150 u1BK[1] = (i >> 1) & 1;
9151 u1BK[2] = (i >> 2) & 1;
9152 break;
9153 }
9154 }
9155 mcSHOW_DBG_MSG(("SKPPR BK0<%d> BK1<%d> BK2<%d>\n", u1BK[0], u1BK[1], u1BK[2]));
9156
9157 for(u1RankIdx=0; u1RankIdx<(U8)p->support_rank_num; u1RankIdx++)
9158 {
9159 if(global_sk_ppr_rank[u1RankIdx] == 1)
9160 {
9161 vSetRank(p, u1RankIdx);
9162
9163 //Iput Entry Code
9164 DramcModeRegWriteByRankUsDelay(p, 9, 0xB0, 3);
9165 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 3);
9166 DramcModeRegWriteByRankUsDelay(p, 9, 0x90, 3);
9167 DramcModeRegWriteByRankUsDelay(p, 9, 0xC8, 25);
9168 DramcModeRegWriteByRankUsDelay(p, 9, 0x90, 25);
9169 DramcModeRegWriteByRankUsDelay(p, 9, 0x8B, 25);
9170 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 25);
9171 DramcModeRegWriteByRankUsDelay(p, 9, 0xD8, 25);
9172 DramcModeRegWriteByRankUsDelay(p, 9, 0x88, 25);
9173 DramcModeRegWriteByRankUsDelay(p, 9, 0x93, 25);
9174 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 25);
9175
9176 //Input Fail Addr.
9177 u1Mr9_Op = ((u1DQ << 1) |
9178 (u1BK[0] << 2) |
9179 (1 << 3) |
9180 (global_sk_ppr_row[12] << 4) |
9181 (global_sk_ppr_row[8] << 5) |
9182 (global_sk_ppr_row[4] << 6) |
9183 (1 << 7));
9184 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9185
9186 u1Mr9_Op = ((u1BK[2] << 1) |
9187 (global_sk_ppr_row[14] << 2) |
9188 (global_sk_ppr_row[11] << 4) |
9189 (global_sk_ppr_row[7] << 5) |
9190 (global_sk_ppr_row[3] << 6));
9191 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9192
9193 u1Mr9_Op = ((u1BK[1] << 1) |
9194 (1 << 2) |
9195 (1 << 3) |
9196 (global_sk_ppr_row[10] << 4) |
9197 (global_sk_ppr_row[6] << 5) |
9198 (global_sk_ppr_row[2] << 6));
9199 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9200
9201 u1Mr9_Op = ((1 << 2) |
9202 (global_sk_ppr_row[9] << 4) |
9203 (global_sk_ppr_row[5] << 5) |
9204 (global_sk_ppr_row[1] << 6) |
9205 (1 << 7));
9206 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9207
9208 //Input additional TM
9209 DramcModeRegWriteByRankUsDelay(p, 9, 0xD4, 25);
9210 DramcModeRegWriteByRankUsDelay(p, 9, 0x84, 25);
9211 DramcModeRegWriteByRankUsDelay(p, 9, 0xE3, 25);
9212 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 25);
9213 DramcModeRegWriteByRankUsDelay(p, 9, 0xB4, 25);
9214 DramcModeRegWriteByRankUsDelay(p, 9, 0x8C, 25);
9215 DramcModeRegWriteByRankUsDelay(p, 9, 0x87, 25);
9216 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 25);
9217
9218 //Execute SKH Repair
9219 mcSHOW_DBG_MSG(("36 loop Start\n"));
9220 for(i=0; i<36; i++) //36 LOOP
9221 {
9222 DramcModeRegWriteByRankUsDelay(p, 9, 0xC4, 25);
9223 DramcModeRegWriteByRankUsDelay(p, 9, 0x9C, 25);
9224 DramcModeRegWriteByRankUsDelay(p, 9, 0x93, 25);
9225 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 25);
9226 }
9227 mcSHOW_DBG_MSG(("36 loop Stop\n"));
9228
9229 //Exit SKH repair mode
9230 DramcModeRegWriteByRankUsDelay(p, 9, 0x00, 25);
9231 }
9232 }
9233
9234 vSetRank(p, (U8)eOriRank);
9235 return;
9236}
9237
9238
9239void SkRepairSequenceOp1(DRAMC_CTX_T *p)
9240{
9241 DRAM_RANK_T eOriRank = u1GetRank(p);
9242 U8 u1Mr9_Op = 0;
9243 int i = 0;
9244 U8 u1RankIdx = 0;
9245 U8 u1DQ = ((global_sk_ppr_byte[0] == 1) || (global_sk_ppr_byte[2] == 1)) ? 0 : 1;
9246 U8 u1BK[3] = {0};
9247
9248 for(i = 0; i<=SK_BANK_BITS; i++)
9249 {
9250 if((global_sk_ppr_bank[0] == 1) || (global_sk_ppr_bank[1] == 1))
9251 {
9252 u1BK[2] = 0;
9253 u1BK[1] = 0;
9254 }
9255 else if((global_sk_ppr_bank[2] == 1) || (global_sk_ppr_bank[3] == 1))
9256 {
9257 u1BK[2] = 0;
9258 u1BK[1] = 1;
9259 }
9260 else if((global_sk_ppr_bank[4] == 1) || (global_sk_ppr_bank[5] == 1))
9261 {
9262 u1BK[2] = 1;
9263 u1BK[1] = 0;
9264 }
9265 else if((global_sk_ppr_bank[6] == 1) || (global_sk_ppr_bank[7] == 1))
9266 {
9267 u1BK[2] = 1;
9268 u1BK[1] = 1;
9269 }
9270 }
9271 mcSHOW_DBG_MSG(("SKPPR BK0<%d> BK1<%d> BK2<%d>\n", u1BK[0], u1BK[1], u1BK[2]));
9272
9273 for(u1RankIdx=0; u1RankIdx<(U8)p->support_rank_num; u1RankIdx++)
9274 {
9275 if(global_sk_ppr_rank[u1RankIdx] == 1)
9276 {
9277 vSetRank(p, u1RankIdx);
9278
9279 //Iput Entry Code
9280 DramcModeRegWriteByRankUsDelay(p, 9, 0xB0, 3);
9281 DramcModeRegWriteByRankUsDelay(p, 9, 0xE0, 3);
9282 DramcModeRegWriteByRankUsDelay(p, 9, 0x90, 3);
9283 DramcModeRegWriteByRankUsDelay(p, 9, 0xA8, 25);
9284 DramcModeRegWriteByRankUsDelay(p, 9, 0x8E, 25);
9285 DramcModeRegWriteByRankUsDelay(p, 9, 0x83, 25);
9286 DramcModeRegWriteByRankUsDelay(p, 9, 0xA8, 25);
9287 DramcModeRegWriteByRankUsDelay(p, 9, 0x84, 25);
9288 DramcModeRegWriteByRankUsDelay(p, 9, 0x86, 25);
9289 DramcModeRegWriteByRankUsDelay(p, 9, 0x83, 25);
9290 DramcModeRegWriteByRankUsDelay(p, 9, 0xA8, 25);
9291 DramcModeRegWriteByRankUsDelay(p, 9, 0x90, 25);
9292 DramcModeRegWriteByRankUsDelay(p, 9, 0x9E, 25);
9293 DramcModeRegWriteByRankUsDelay(p, 9, 0x83, 25);
9294
9295 //Input Fail Addr.
9296 u1Mr9_Op = ((global_sk_ppr_row[12] << 1) |
9297 (global_sk_ppr_row[11] << 3) |
9298 (global_sk_ppr_row[10] << 5) |
9299 (u1DQ << 6) |
9300 (global_sk_ppr_row[9] << 7));
9301 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9302
9303 u1Mr9_Op = ((global_sk_ppr_row[8] << 1) |
9304 (global_sk_ppr_row[7] << 3) |
9305 (u1BK[2] << 4) |
9306 (global_sk_ppr_row[6] << 5) |
9307 (u1BK[1] << 6)|
9308 (global_sk_ppr_row[5] << 7));
9309 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9310
9311 u1Mr9_Op = ((global_sk_ppr_row[14]) |
9312 (global_sk_ppr_row[4] << 1) |
9313 (global_sk_ppr_row[13] << 2) |
9314 (global_sk_ppr_row[3] << 3) |
9315 (global_sk_ppr_row[2] << 5) |
9316 (global_sk_ppr_row[1] << 7));
9317 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9318
9319 u1Mr9_Op = 0xD2;
9320 DramcModeRegWriteByRankUsDelay(p, 9, u1Mr9_Op, 25);
9321
9322 //Execute SKH Repair
9323 for(i=0; i<36; i++) //36 LOOP
9324 {
9325 DramcModeRegWriteByRankUsDelay(p, 9, 0xAC, 10);
9326 DramcModeRegWriteByRankUsDelay(p, 9, 0x88, 10);
9327 DramcModeRegWriteByRankUsDelay(p, 9, 0x86, 10);
9328 DramcModeRegWriteByRankUsDelay(p, 9, 0x83, 10);
9329 }
9330 //Exit SKH repair mode
9331 DramcModeRegWriteByRankUsDelay(p, 9, 0x00, 10);
9332 }
9333 }
9334
9335 vSetRank(p, (U8)eOriRank);
9336 return;
9337}
9338
9339
9340static U32 u4SKPostPackageRepairBackupAddress[] =
9341{
9342 (DRAMC_REG_DRAMC_PD_CTRL),
9343 (DRAMC_REG_REFCTRL0),
9344 (DRAMC_REG_SPCMDCTRL),
9345 (DRAMC_REG_SHU_SCINTV),
9346 (DRAMC_REG_SHU2_SCINTV),
9347 (DRAMC_REG_SHU3_SCINTV)
9348};
9349
9350
9351void SkPostPackageRepairLP3(DRAMC_CTX_T *p) //Backup restore
9352{
9353 //DRAM_CHANNEL_T eOriChannel = vGetPHY2ChannelMapping(p);
9354 //DRAM_RANK_T eOriRank = u1GetRank(p);
9355 U16 u2Mr7Op = 0;
9356
9357 mcSHOW_DBG_MSG(("SKPPR\n"
9358 "\nFreq=%d, CH=%d, Rank=%d\n", p->frequency, p->channel, p->rank));
9359
9360 //Backup regs
9361 DramcBackupRegisters(p, u4SKPostPackageRepairBackupAddress, sizeof(u4SKPostPackageRepairBackupAddress)/sizeof(U32));
9362
9363 //DRAMC DCM freerun,
9364 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_DCMEN2);
9365
9366 //PHY DCM freerun,
9367 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 0, DRAMC_PD_CTRL_PHYCLKDYNGEN);
9368
9369 //Dram clock freerun,
9370 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_DRAMC_PD_CTRL), 1, DRAMC_PD_CTRL_MIOCKCTRLOFF);
9371
9372 //Fix CKE0 and CKE1 be high,
9373 CKEFixOnOff(p, CKE_WRITE_TO_ALL_RANK, CKE_FIXON, CKE_WRITE_TO_ALL_CHANNEL);
9374
9375 //All banks must be precharged
9376 //Enter_Precharge_All(p);
9377 //vIO32WriteFldAlign(DRAMC_REG_SPCMD, 0, SPCMD_PREAEN);
9378
9379 //Disable MR4, refresh, ZQ_Cal, TX
9380 vIO32WriteFldAlign(DRAMC_REG_REFCTRL0, 1, REFCTRL0_REFDIS);
9381 vIO32WriteFldAlign(DRAMC_REG_SPCMDCTRL, 1, SPCMDCTRL_REFRDIS);
9382 vIO32WriteFldAlign(DRAMC_REG_SPCMDCTRL, 0, SPCMDCTRL_ZQCSDISB);
9383 vIO32WriteFldAlign(DRAMC_REG_SHU_SCINTV, 1, SHU_SCINTV_DQSOSCENDIS);
9384 vIO32WriteFldAlign(DRAMC_REG_SHU2_SCINTV, 1, SHU2_SCINTV_DQSOSCENDIS);
9385 vIO32WriteFldAlign(DRAMC_REG_SHU3_SCINTV, 1, SHU3_SCINTV_DQSOSCENDIS);
9386
9387 DramcModeRegReadByRank(p, RANK_0, 7, &u2Mr7Op);//CHA R0
9388 u2Mr7Op &= 0xff;
9389 mcSHOW_DBG_MSG(("Before SKPPR, MR7 = 0x%x\n", u2Mr7Op));//0: 1st 8G 1: 2rd 8G
9390
9391 if(u2Mr7Op == 0)
9392 {
9393 SkRepairSequenceOp0(p);
9394 }
9395 else
9396 {
9397 SkRepairSequenceOp1(p);
9398 }
9399 //Restore regs
9400 DramcRestoreRegisters(p, u4SKPostPackageRepairBackupAddress, sizeof(u4SKPostPackageRepairBackupAddress)/sizeof(U32));
9401 return;
9402}
9403#endif //SKH_POST_PACKAGE_REPAIR_LP3
9404
9405
9406extern DRAMC_CTX_T DramCtx_LPDDR4;
9407extern DRAMC_CTX_T DramCtx_LPDDR3;
9408void PostPackageRepair(void)
9409{
9410 BOOL bLp4 = u1IsLP4Family(mt_get_dram_type_from_hw_trap());
9411 DRAMC_CTX_T *p = (bLp4) ? (&DramCtx_LPDDR4) : (&DramCtx_LPDDR3);
9412 DRAM_CHANNEL_T eOriChannel = vGetPHY2ChannelMapping(p);
9413 DRAM_RANK_T eOriRank = u1GetRank(p);
9414
9415 if(bLp4)//Based on VDRAM to decide the DRAM type
9416 {
9417#ifdef POST_PACKAGE_REPAIR_LP4
9418 DramcPostPackageRepair(p);
9419#endif
9420 }
9421 else
9422 { // LPDDR3
9423#ifdef SKH_POST_PACKAGE_REPAIR_LP3
9424 p->support_rank_num = RANK_DUAL;//Based on usage
9425 SkPostPackageRepairLP3(p);
9426#endif
9427 }
9428
9429 vSetRank(p, eOriRank);
9430 vSetPHY2ChannelMapping(p, eOriChannel);
9431 return;
9432}
9433#endif //ENABLE_POST_PACKAGE_REPAIR
9434
9435
9436static void SetRxDqDqsDelay(DRAMC_CTX_T *p, S16 iDelay)
9437{
9438 U8 ii;
9439 U32 u4value;
9440#if ENABLE_LP3_SW
9441 U8 dl_value[8];
9442 U8 u1ByteIdx;
9443#endif
9444
9445 if (iDelay <=0)
9446 {
9447 if(u1IsLP4Family(p->dram_type))
9448 {
9449 // Set DQS delay
9450 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), \
9451 P_Fld((-iDelay+gu2RX_DQS_Duty_Offset[0][0]),SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_R_DLY_B0) |P_Fld((-iDelay+gu2RX_DQS_Duty_Offset[0][1]),SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_F_DLY_B0));
9452 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), \
9453 P_Fld((-iDelay+gu2RX_DQS_Duty_Offset[1][0]),SHU1_R0_B1_DQ6_RK0_RX_ARDQS0_R_DLY_B1) |P_Fld((-iDelay+gu2RX_DQS_Duty_Offset[1][1]),SHU1_R0_B1_DQ6_RK0_RX_ARDQS0_F_DLY_B1));
9454 }
9455#if ENABLE_LP3_SW
9456 else
9457 {
9458 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
9459 {
9460 vIO32WriteFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), -iDelay, SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_R_DLY_B0);
9461 vIO32WriteFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), -iDelay, SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_F_DLY_B0);
9462 }
9463 }
9464#endif
9465
9466 DramPhyReset(p);
9467 }
9468 else
9469 {
9470 // Adjust DQM output delay.
9471 if(u1IsLP4Family(p->dram_type))
9472 {
9473 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), \
9474 P_Fld(iDelay,SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_R_DLY_B0) |P_Fld(iDelay,SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_F_DLY_B0));
9475 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), \
9476 P_Fld(iDelay,SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_R_DLY_B1) |P_Fld(iDelay,SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_F_DLY_B1));
9477 }
9478 #if ENABLE_LP3_SW
9479 else
9480 {
9481 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
9482 {
9483 Set_RX_DQM_DelayLine_Phy_Byte(p, u1ByteIdx, iDelay);
9484 }
9485 }
9486 #endif
9487
9488 DramPhyReset(p);
9489
9490 // Adjust DQ output delay.
9491 if(u1IsLP4Family(p->dram_type))
9492 {
9493 u4value = ((U32) iDelay) | (((U32)iDelay)<<8) | (((U32)iDelay)<<16) | (((U32)iDelay)<<24);
9494 for (ii=0; ii<4; ii++)
9495 {
9496 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+ ii*4), u4value);//DQ0~DQ7
9497 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+ ii*4), u4value);//DQ8~DQ15
9498 }
9499
9500 #if PINMUX_AUTO_TEST_PER_BIT_RX
9501 if(gRX_check_per_bit_flag)
9502 {
9503 SetRxPerBitDelayCellForPinMuxCheck(p, gRX_Check_per_bit_idx);
9504 //CheckRXDelayCell(p);
9505 }
9506 #endif
9507
9508 }
9509 #if ENABLE_LP3_SW
9510 else//LPDDR3
9511 {
9512 //every 2bit dq have the same delay register address
9513 for (u1ByteIdx=0; u1ByteIdx<DQS_NUMBER; u1ByteIdx++)
9514 {
9515 dl_value[0] = iDelay;
9516 dl_value[1] = iDelay;
9517 dl_value[2] = iDelay;
9518 dl_value[3] = iDelay;
9519 dl_value[4] = iDelay;
9520 dl_value[5] = iDelay;
9521 dl_value[6] = iDelay;
9522 dl_value[7] = iDelay;
9523
9524 Set_RX_DQ_DelayLine_Phy_Byte(p, u1ByteIdx, dl_value);
9525 }
9526 #if PINMUX_AUTO_TEST_PER_BIT_RX_LP3
9527 if(gRX_check_per_bit_flag)
9528 {
9529 SetRxPerBitDelayCellForPinMuxCheckLp3(p, gRX_Check_per_bit_idx, iDelay);
9530 //CheckRXDelayCell(p);
9531 }
9532 #endif
9533 }
9534 #endif
9535 }
9536}
9537
9538
9539#if SIMULATION_RX_PERBIT
9540
9541#define RX_DELAY_PRE_CAL 1
9542#if RX_DELAY_PRE_CAL
9543S16 s2RxDelayPreCal=PASS_RANGE_NA;
9544#endif
9545DRAM_STATUS_T DramcRxWindowPerbitCal(DRAMC_CTX_T *p, U8 u1UseTestEngine)
9546{
9547 U8 ii, u1BitIdx, u1ByteIdx;
9548 U8 ucbit_first, ucbit_last;
9549 S16 iDelay=0, u4DelayBegin=0, u4DelayEnd, u4DelayStep=1;
9550 S16 iDutyOffset=0, u4DutyOffsetBegin, u4DutyOffsetEnd, u4DutyOffsetStep=4;
9551 U32 uiFinishCount;
9552 U32 u4err_value, u4fail_bit;
9553 PASS_WIN_DATA_T WinPerBit[DQ_DATA_WIDTH], FinalWinPerBit[DQ_DATA_WIDTH];
9554 S32 iDQSDlyPerbyte[DQS_NUMBER], iDQMDlyPerbyte[DQS_NUMBER];//, iFinalDQSDly[DQS_NUMBER];
9555 U8 u1VrefScanEnable;
9556 U16 u2VrefLevel, u2TempWinSum, u2TmpDQMSum, u2FinalVref=0xe;
9557 U16 u2VrefBegin, u2VrefEnd, u2VrefStep;
9558 U32 u4AddrOfst = 0x50;
9559 U8 u1RXEyeScanEnable;
9560#if ENABLE_LP3_SW
9561 U8 dl_value[8]={0,0,0,0,0,0,0,0};
9562#endif
9563 U8 backup_rank;
9564
9565#if 0//PPORT_SAVE_TIME_FOR_CALIBRATION
9566 S16 u1minfirst_pass=0xff,u1minlast_pass=0xff,u4Delayoffset;
9567 U8 u1AllBitPassCount;
9568#endif
9569
9570#if EYESCAN_LOG
9571 U8 EyeScan_index[DQ_DATA_WIDTH_LP4];
9572 U8 u1pass_in_this_vref_flag[DQ_DATA_WIDTH_LP4];
9573#endif
9574
9575
9576#if REG_ACCESS_PORTING_DGB
9577 RegLogEnable =1;
9578 mcSHOW_DBG_MSG(("\n[REG_ACCESS_PORTING_FUNC] DramcRxWindowPerbitCal\n"));
9579 mcFPRINTF((fp_A60501, "\n[REG_ACCESS_PORTING_FUNC] DramcRxWindowPerbitCal\n"));
9580#endif
9581
9582 // error handling
9583 if (!p)
9584 {
9585 mcSHOW_ERR_MSG(("context NULL\n"));
9586 return DRAM_FAIL;
9587 }
9588
9589#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
9590 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
9591 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
9592#endif
9593
9594 backup_rank = u1GetRank(p);
9595
9596 u1RXEyeScanEnable = (gRX_EYE_Scan_flag==1 && ((gRX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gRX_EYE_Scan_only_higheset_freq_flag==0));
9597
9598#if EYESCAN_LOG
9599 U32 u1vrefidx;
9600
9601 if (u1IsLP4Family(p->dram_type))
9602 {
9603 for(u1vrefidx=0; u1vrefidx<RX_VREF_RANGE_END+1;u1vrefidx++)
9604 {
9605 for (u1BitIdx = 0; u1BitIdx < DQ_DATA_WIDTH_LP4; u1BitIdx++)
9606 {
9607 for(ii=0; ii<EYESCAN_BROKEN_NUM; ii++)
9608 {
9609 gEyeScan_Min[u1vrefidx][u1BitIdx][ii] = EYESCAN_DATA_INVALID;
9610 gEyeScan_Max[u1vrefidx][u1BitIdx][ii] = EYESCAN_DATA_INVALID;
9611
9612 gEyeScan_ContinueVrefHeight[u1BitIdx] = 0;
9613 gEyeScan_TotalPassCount[u1BitIdx] = 0;
9614 }
9615 }
9616 }
9617 }
9618#endif
9619
9620
9621 //defult set result fail. When window found, update the result as oK
9622 if(u1UseTestEngine)
9623 {
9624 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_PERBIT, DRAM_FAIL);
9625 DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0);
9626 }
9627 else
9628 {
9629 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_RDDQC, DRAM_FAIL);
9630 DramcRxWinRDDQCInit(p);
9631 }
9632
9633
9634 // for loop, different Vref,
9635 u2rx_window_sum = 0;
9636
9637 if(u1IsLP4Family(p->dram_type) && (u1UseTestEngine==1) && (p->enable_rx_scan_vref==ENABLE) && (p->rank==RANK_0)) //only apply RX Vref Scan for Rank 0 (Rank 0 and 1 use the same Vref reg)
9638 u1VrefScanEnable =1;
9639 else
9640 u1VrefScanEnable =0;
9641
9642 if (gRX_EYE_Scan_flag==1 && u1VrefScanEnable==0)
9643 {
9644 if(u1IsLP4Family(p->dram_type) && (u1UseTestEngine==1) && (p->enable_rx_scan_vref==ENABLE) && (p->rank==RANK_1)) //also need to K rank1 for debug
9645 u1VrefScanEnable =1;
9646 }
9647
9648
9649 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
9650 if(p->femmc_Ready==1 && (p->Bypass_RDDQC || p->Bypass_RXWINDOW))
9651 {
9652 mcSHOW_DBG_MSG(("[FAST_K] Bypass RX Calibration\n"));
9653 }
9654 else
9655 #endif
9656 {
9657#if VENDER_JV_LOG
9658#if 0 //BU don't want customer knows our RX's ability
9659 if(u1UseTestEngine ==1)
9660 vPrintCalibrationBasicInfo_ForJV(p);
9661#endif
9662#else
9663 vPrintCalibrationBasicInfo(p);
9664#endif
9665 mcSHOW_DBG_MSG2(("Start DQ dly to find pass range UseTestEngine =%d\n", u1UseTestEngine));
9666 mcSHOW_DBG_MSG2(("x-axis: bit #, y-axis: DQ dly (%d~%d)\n", (-MAX_RX_DQSDLY_TAPS), MAX_RX_DQDLY_TAPS));
9667 mcFPRINTF((fp_A60501, "Start RX DQ/DQS calibration UseTestEngine =%d\n", u1UseTestEngine));
9668 mcFPRINTF((fp_A60501, "x-axis is bit #; y-axis is DQ delay\n"));
9669 }
9670
9671 mcSHOW_DBG_MSG(("RX Vref Scan = %d\n", u1VrefScanEnable));
9672 mcFPRINTF((fp_A60501, "RX Vref Scan= %d\n", u1VrefScanEnable));
9673
9674 if(u1VrefScanEnable)
9675 {
9676 #if (SW_CHANGE_FOR_SIMULATION ||FOR_DV_SIMULATION_USED)
9677 u2VrefBegin =RX_VREF_RANGE_BEGIN;
9678 #else
9679 if (gRX_EYE_Scan_flag==0)
9680 {
9681 if(p->odt_onoff)
9682 {
9683 u2VrefBegin = RX_VREF_RANGE_BEGIN_ODT_ON;
9684 }
9685 else
9686 {
9687 u2VrefBegin = RX_VREF_RANGE_BEGIN_ODT_OFF;
9688 }
9689 }
9690 else
9691 u2VrefBegin = 0;//Lewis@20160817: Enlarge RX Vref range for eye scan
9692 #endif
9693
9694 u2VrefEnd =RX_VREF_RANGE_END;
9695 u2VrefStep=RX_VREF_RANGE_STEP;
9696 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0);
9697 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1);
9698 }
9699 else //LPDDR3 or diable RX Vref
9700 {
9701 u2VrefBegin = 0;
9702 u2VrefEnd = 0; // SEL[4:0] = 01110
9703 u2VrefStep =1; //don't care, just make for loop break;
9704 }
9705
9706 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
9707 if(p->femmc_Ready==1 && (p->Bypass_RDDQC || p->Bypass_RXWINDOW))
9708 {
9709 if(u1VrefScanEnable)
9710 {
9711 // load RX Vref from eMMC
9712 #if ( SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL)
9713 //u2VrefBegin = p->pSavetimeData->u1RxWinPerbitVref_Save[p->channel];
9714 //u2VrefEnd=u2VrefBegin+1;
9715 u2FinalVref = p->pSavetimeData->u1RxWinPerbitVref_Save[p->channel];
9716 #endif
9717 }
9718
9719 // load RX DQS and DQM delay from eMMC
9720 for (u1ByteIdx=0; u1ByteIdx<DQS_NUMBER_LP4; u1ByteIdx++)
9721 {
9722 iDQSDlyPerbyte[u1ByteIdx]= p->pSavetimeData->u1RxWinPerbit_DQS[p->channel][p->rank][u1ByteIdx];
9723 iDQMDlyPerbyte[u1ByteIdx]= p->pSavetimeData->u1RxWinPerbit_DQM[p->channel][p->rank][u1ByteIdx];
9724 }
9725
9726 // load RX DQ delay from eMMC
9727 for (u1BitIdx=0; u1BitIdx<16; u1BitIdx++)
9728 {
9729 FinalWinPerBit[u1BitIdx].best_dqdly= p->pSavetimeData->u1RxWinPerbit_DQ[p->channel][p->rank][u1BitIdx];
9730 }
9731
9732 if(u1UseTestEngine)
9733 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_PERBIT, DRAM_OK);
9734 else
9735 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_RDDQC, DRAM_OK);
9736 }
9737 else
9738 #endif
9739 {
9740 if(u1IsLP4Family(p->dram_type))
9741 {
9742 #if RX_DELAY_PRE_CAL
9743 if(u1UseTestEngine==0)
9744 #endif
9745 {
9746 if(p->frequency >=1600)
9747 {
9748 u4DelayBegin= -26;
9749 }
9750 else if(p->frequency >= 1140)
9751 {
9752 u4DelayBegin= -30;
9753 }
9754 else if(p->frequency >=800)
9755 {
9756 u4DelayBegin= -48;
9757 }
9758 else
9759 {
9760 u4DelayBegin= -MAX_RX_DQSDLY_TAPS;
9761 }
9762
9763 s2RxDelayPreCal =PASS_RANGE_NA;
9764 }
9765 #if RX_DELAY_PRE_CAL
9766 else
9767 {
9768 u4DelayBegin = s2RxDelayPreCal -10; // for test engine
9769 }
9770 #endif
9771
9772 //mcSHOW_DBG_MSG(("RX_DELAY_PRE_CAL: RX delay begin = %d\n", u4DelayBegin));
9773
9774 u4DelayEnd = MAX_RX_DQDLY_TAPS;
9775
9776 if(p->frequency <850)
9777 u4DelayStep =2; //1600
9778 else
9779 u4DelayStep =1;//2667, 3200
9780
9781 if(u1UseTestEngine==0) //if RDDQD, roughly calibration
9782 u4DelayStep <<= 1;
9783 }
9784 #if ENABLE_LP3_SW
9785 else
9786 {
9787 if(p->frequency >=933)
9788 {
9789 u4DelayBegin= -48;
9790 }
9791 else if(p->frequency >=600)
9792 {
9793 u4DelayBegin= -70;
9794 }
9795 else if(p->frequency >=450)
9796 {
9797 u4DelayBegin= -110;
9798 }
9799 else
9800 {
9801 u4DelayBegin= -MAX_RX_DQSDLY_TAPS;
9802 }
9803 u4DelayEnd = MAX_RX_DQDLY_TAPS;
9804
9805 if(p->frequency <600)
9806 u4DelayStep =2; //1066
9807 else
9808 u4DelayStep =1;//1600, 1270
9809 }
9810 #endif
9811
9812 u4DutyOffsetBegin = 0;
9813 u4DutyOffsetEnd = 0;
9814 u4DutyOffsetStep = 1;
9815
9816 #if !REDUCE_LOG_FOR_PRELOADER
9817 mcSHOW_DBG_MSG(("\nRX DQS R/F Scan, iDutyOffset= %d\n", iDutyOffset));
9818 mcFPRINTF((fp_A60501, "\nRX DQS R/F Scan, iDutyOffset= %d\n", iDutyOffset));
9819 #endif
9820
9821 for(u2VrefLevel = u2VrefBegin; u2VrefLevel <= u2VrefEnd; u2VrefLevel += u2VrefStep)
9822 {
9823 if(u1VrefScanEnable ==1)
9824 {
9825 #if !REDUCE_LOG_FOR_PRELOADER
9826 mcSHOW_DBG_MSG(("\n\tRX VrefLevel=%d\n", u2VrefLevel));
9827 mcFPRINTF((fp_A60501, "\n\tRX VrefLevel=%d\n", u2VrefLevel));
9828 #endif
9829#if 0
9830 #if VENDER_JV_LOG
9831 if(u1UseTestEngine ==1)
9832 mcSHOW_DBG_MSG5(("\n\tRX VrefLevel=%d\n", u2VrefLevel));
9833 #endif
9834#endif
9835
9836 //Set RX Vref Here
9837 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), u2VrefLevel, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0); // LP4 and LP4x with term: 0xe
9838 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), u2VrefLevel, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1); // LP4 and LP4x with term: 0xe
9839 }
9840
9841 // 1.delay DQ ,find the pass widnow (left boundary).
9842 // 2.delay DQS find the pass window (right boundary).
9843 // 3.Find the best DQ / DQS to satify the middle value of the overall pass window per bit
9844 // 4.Set DQS delay to the max per byte, delay DQ to de-skew
9845
9846 for (iDutyOffset=u4DutyOffsetBegin; iDutyOffset<=u4DutyOffsetEnd; iDutyOffset+=u4DutyOffsetStep)
9847 {
9848 // initialize parameters
9849 u2TempWinSum =0;
9850 uiFinishCount =0;
9851
9852 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
9853 {
9854 WinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
9855 WinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
9856 FinalWinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
9857 FinalWinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
9858
9859 #if EYESCAN_LOG
9860 if (u1IsLP4Family(p->dram_type))
9861 {
9862 gEyeScan_CaliDelay[u1BitIdx/8] = 0;
9863 gEyeScan_DelayCellPI[u1BitIdx] = 0;
9864 EyeScan_index[u1BitIdx] = 0;
9865 u1pass_in_this_vref_flag[u1BitIdx] = 0;
9866 }
9867 #endif
9868 }
9869
9870 // Adjust DQM output delay to 0
9871 if(u1IsLP4Family(p->dram_type))
9872 {
9873 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), \
9874 P_Fld(0, SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_R_DLY_B0) |P_Fld(0, SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_F_DLY_B0));
9875 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), \
9876 P_Fld(0,SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_R_DLY_B1) |P_Fld(0, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_F_DLY_B1));
9877 }
9878 #if ENABLE_LP3_SW
9879 else
9880 {
9881 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
9882 {
9883 Set_RX_DQM_DelayLine_Phy_Byte(p, u1ByteIdx, 0);
9884 }
9885 }
9886 #endif
9887
9888 // Adjust DQ output delay to 0
9889 //every 2bit dq have the same delay register address
9890 if(u1IsLP4Family(p->dram_type))
9891 {
9892 for (ii=0; ii<4; ii++)
9893 {
9894 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+ ii*4), 0);//DQ0~DQ7
9895 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+ ii*4), 0);//DQ8~DQ15
9896 }
9897 }
9898 #if ENABLE_LP3_SW
9899 else//LPDDR3
9900 {
9901 for (u1ByteIdx=0; u1ByteIdx<DQS_NUMBER; u1ByteIdx++)
9902 {
9903 Set_RX_DQ_DelayLine_Phy_Byte(p, u1ByteIdx, dl_value);
9904 }
9905 }
9906 #endif
9907
9908 for (iDelay=u4DelayBegin; iDelay<=u4DelayEnd; iDelay+= u4DelayStep)
9909 {
9910 SetRxDqDqsDelay(p, iDelay);
9911
9912 if(u1UseTestEngine)
9913 {
9914 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern);
9915 }
9916 else
9917 {
9918 u4err_value = DramcRxWinRDDQCRun(p);
9919 }
9920
9921 if((u1VrefScanEnable==0) || u1RXEyeScanEnable)
9922 {
9923 #ifdef ETT_PRINT_FORMAT
9924 if(u4err_value !=0)
9925 {
9926 mcSHOW_DBG_MSG2(("%d, [0]", iDelay));
9927 }
9928 #else
9929 mcSHOW_DBG_MSG2(("iDelay= %4d, [0]", iDelay));
9930 #endif
9931 mcFPRINTF((fp_A60501, "iDelay= %4d, [0]", iDelay));
9932 //mcSHOW_DBG_MSG2(("u4err_value %x, u1MRRValue %x\n", u4err_value, u1MRRValue));
9933 //mcFPRINTF((fp_A60501, "u4err_value!! %x", u4err_value));
9934 }
9935
9936 // check fail bit ,0 ok ,others fail
9937 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
9938 {
9939 u4fail_bit = u4err_value&((U32)1<<u1BitIdx);
9940
9941 if(WinPerBit[u1BitIdx].first_pass== PASS_RANGE_NA)
9942 {
9943 if(u4fail_bit==0) //compare correct: pass
9944 {
9945 WinPerBit[u1BitIdx].first_pass = iDelay;
9946
9947 #if RX_DELAY_PRE_CAL
9948 if(u1UseTestEngine==0 && (s2RxDelayPreCal ==PASS_RANGE_NA))
9949 {
9950 s2RxDelayPreCal = iDelay;
9951 }
9952
9953 if(u1UseTestEngine==1 && iDelay==u4DelayBegin)
9954 {
9955 mcSHOW_ERR_MSG(("RX_DELAY_PRE_CAL: Warning, possible miss RX window boundary\n"));
9956 #if __ETT__
9957 while(1);
9958 #endif
9959 }
9960
9961 #endif
9962
9963 #if EYESCAN_LOG
9964 if (u1IsLP4Family(p->dram_type))
9965 {
9966 u1pass_in_this_vref_flag[u1BitIdx]=1;
9967 }
9968 #endif
9969 }
9970 }
9971 else if(WinPerBit[u1BitIdx].last_pass == PASS_RANGE_NA)
9972 {
9973 //mcSHOW_DBG_MSG(("fb%d \n", u4fail_bit));
9974
9975 if(u4fail_bit !=0) //compare error : fail
9976 {
9977 WinPerBit[u1BitIdx].last_pass = (iDelay-1);
9978 }
9979 else if (iDelay==u4DelayEnd)
9980 {
9981 WinPerBit[u1BitIdx].last_pass = iDelay;
9982 }
9983
9984 if(WinPerBit[u1BitIdx].last_pass !=PASS_RANGE_NA)
9985 {
9986 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >= (FinalWinPerBit[u1BitIdx].last_pass -FinalWinPerBit[u1BitIdx].first_pass))
9987 {
9988 #if 0 //for debug
9989 if(FinalWinPerBit[u1BitIdx].last_pass != PASS_RANGE_NA)
9990 {
9991 mcSHOW_DBG_MSG2(("Bit[%d] Bigger window update %d > %d\n", u1BitIdx, \
9992 (WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass), (FinalWinPerBit[u1BitIdx].last_pass -FinalWinPerBit[u1BitIdx].first_pass)));
9993 mcFPRINTF((fp_A60501,"Bit[%d] Bigger window update %d > %d\n", u1BitIdx, \
9994 (WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass), (FinalWinPerBit[u1BitIdx].last_pass -FinalWinPerBit[u1BitIdx].first_pass)));
9995 }
9996 #endif
9997
9998 //if window size bigger than 7, consider as real pass window. If not, don't update finish counte and won't do early break;
9999 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >7)
10000 uiFinishCount |= (1<<u1BitIdx);
10001
10002 //update bigger window size
10003 FinalWinPerBit[u1BitIdx].first_pass = WinPerBit[u1BitIdx].first_pass;
10004 FinalWinPerBit[u1BitIdx].last_pass = WinPerBit[u1BitIdx].last_pass;
10005 }
10006
10007 #if EYESCAN_LOG
10008 if(u1UseTestEngine && u1IsLP4Family(p->dram_type))
10009 {
10010 if (EyeScan_index[u1BitIdx] < EYESCAN_BROKEN_NUM)
10011 {
10012 gEyeScan_Min[u2VrefLevel][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].first_pass;
10013 gEyeScan_Max[u2VrefLevel][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].last_pass;
10014 mcSHOW_DBG_MSG3(("u2VrefLevel=%d, u1BitIdx=%d, index=%d (%d, %d)==\n",u2VrefLevel, u1BitIdx, EyeScan_index[u1BitIdx], gEyeScan_Min[u2VrefLevel][u1BitIdx][EyeScan_index[u1BitIdx]], gEyeScan_Max[u2VrefLevel][u1BitIdx][EyeScan_index[u1BitIdx]]));
10015 EyeScan_index[u1BitIdx]=EyeScan_index[u1BitIdx]+1;
10016 }
10017 }
10018 #endif
10019
10020 //reset tmp window
10021 WinPerBit[u1BitIdx].first_pass = PASS_RANGE_NA;
10022 WinPerBit[u1BitIdx].last_pass = PASS_RANGE_NA;
10023 }
10024 }
10025
10026 if((u1VrefScanEnable==0) || u1RXEyeScanEnable)
10027 {
10028 #ifdef ETT_PRINT_FORMAT
10029 if(u4err_value !=0)
10030 #endif
10031 {
10032 if(u1BitIdx%DQS_BIT_NUMBER ==0)
10033 {
10034 mcSHOW_DBG_MSG2((" "));
10035 mcFPRINTF((fp_A60501, " "));
10036 }
10037
10038 if (u4fail_bit == 0)
10039 {
10040 mcSHOW_DBG_MSG2(("o"));
10041 mcFPRINTF((fp_A60501, "o"));
10042 #if EYESCAN_LOG
10043 if (u1IsLP4Family(p->dram_type))
10044 {
10045 gEyeScan_TotalPassCount[u1BitIdx]+=u4DelayStep;
10046 }
10047 #endif
10048 }
10049 else
10050 {
10051 mcSHOW_DBG_MSG2(("x"));
10052 mcFPRINTF((fp_A60501, "x"));
10053 }
10054 }
10055#if EYESCAN_LOG
10056 #ifdef ETT_PRINT_FORMAT
10057 else
10058 #endif
10059 {
10060 if (u1IsLP4Family(p->dram_type))
10061 {
10062 gEyeScan_TotalPassCount[u1BitIdx]+=u4DelayStep;
10063 }
10064 }
10065#endif
10066 }
10067 }
10068
10069 if((u1VrefScanEnable==0) || u1RXEyeScanEnable)
10070 {
10071 #ifdef ETT_PRINT_FORMAT
10072 if(u4err_value !=0)
10073 #endif
10074 {
10075 mcSHOW_DBG_MSG2((" [MSB]\n"));
10076 mcFPRINTF((fp_A60501, " [MSB]\n"));
10077 }
10078 }
10079
10080 //if all bits widnow found and all bits turns to fail again, early break;
10081 if((u1IsLP4Family(p->dram_type) &&(uiFinishCount == 0xffff)) || \
10082 ((p->dram_type == TYPE_LPDDR3) &&(uiFinishCount == 0xffffffff)))
10083 {
10084 if(u1UseTestEngine)
10085 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_PERBIT, DRAM_OK);
10086 else
10087 vSetCalibrationResult(p, DRAM_CALIBRATION_RX_RDDQC, DRAM_OK);
10088
10089 if((u1VrefScanEnable==0) || u1RXEyeScanEnable)
10090 {
10091 if((u1IsLP4Family(p->dram_type) &&((u4err_value&0xffff) == 0xffff)) ||
10092 ((p->dram_type == TYPE_LPDDR3) &&(u4err_value == 0xffffffff)))
10093 {
10094 #if !REDUCE_LOG_FOR_PRELOADER
10095 mcSHOW_DBG_MSG(("\nRX all bits window found, early break!\n"));
10096 #endif
10097 break; //early break
10098 }
10099 }
10100 }
10101 }
10102
10103 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
10104 {
10105 FinalWinPerBit[u1BitIdx].win_size = FinalWinPerBit[u1BitIdx].last_pass - FinalWinPerBit[u1BitIdx].first_pass + (FinalWinPerBit[u1BitIdx].last_pass==FinalWinPerBit[u1BitIdx].first_pass?0:1);
10106
10107 #if (PINMUX_AUTO_TEST_PER_BIT_RX | PINMUX_AUTO_TEST_PER_BIT_RX_LP3)
10108 gFinalRXPerbitWinSiz[p->channel][u1BitIdx] = FinalWinPerBit[u1BitIdx].win_size;
10109 #endif
10110
10111 u2TempWinSum += FinalWinPerBit[u1BitIdx].win_size; //Sum of CA Windows for vref selection
10112
10113#if 0 //BU don't want customer knows our RX's ability
10114 #if VENDER_JV_LOG
10115 if(u1UseTestEngine ==1)
10116 {
10117 U8 shuffleIdx;
10118 shuffleIdx = get_shuffleIndex_by_Freq(p);
10119 mcSHOW_DBG_MSG5(("RX Bit%d, %d%%\n", u1BitIdx, ((FinalWinPerBit[u1BitIdx].win_size*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000));
10120 }
10121 #endif
10122#endif
10123#if EYESCAN_LOG
10124 if (u1IsLP4Family(p->dram_type))
10125 {
10126 gEyeScan_WinSize[u2VrefLevel][u1BitIdx] = FinalWinPerBit[u1BitIdx].win_size;
10127 }
10128#endif
10129 }
10130
10131 #if 1//!REDUCE_LOG_FOR_PRELOADER
10132 mcSHOW_DBG_MSG2(("RX Vref %d, Window Sum %d\n", u2VrefLevel, u2TempWinSum));
10133 mcFPRINTF((fp_A60501, "RX Vref %d, Window Sum %d\n", u2VrefLevel, u2TempWinSum));
10134 #endif
10135
10136 #if 0
10137 if((u1IsLP4Family(p->dram_type) &&(u2TempWinSum <250)) || \
10138 ((p->dram_type == TYPE_LPDDR3) &&(u2TempWinSum <1100)))
10139 {
10140 mcSHOW_DBG_MSG2(("\n\n[NOTICE] CH %d, TestEngine %d, RX_sum %d\n", p->channel, u1UseTestEngine, u2TempWinSum));
10141 mcFPRINTF((fp_A60501, "\n\n[NOTICE] CH %d, TestEngine %d, RX_sum %d\n", p->channel, u1UseTestEngine, u2TempWinSum));
10142 }
10143 #endif
10144
10145 if(u2TempWinSum >u2rx_window_sum)
10146 {
10147 mcSHOW_DBG_MSG3(("\nBetter RX Vref found %d, Window Sum %d > %d\n", u2VrefLevel, u2TempWinSum, u2rx_window_sum));
10148 mcFPRINTF((fp_A60501, "\nBetter RX Vref found %d, Window Sum %d > %d\n", u2VrefLevel, u2TempWinSum, u2rx_window_sum));
10149
10150 u2rx_window_sum =u2TempWinSum;
10151 u2FinalVref = u2VrefLevel;
10152
10153 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
10154 {
10155 FinalWinPerBit[u1BitIdx].win_center = (FinalWinPerBit[u1BitIdx].last_pass + FinalWinPerBit[u1BitIdx].first_pass)>>1; // window center of each DQ bit
10156
10157 if((u1VrefScanEnable==0) || u1RXEyeScanEnable)
10158 {
10159 #ifdef ETT_PRINT_FORMAT
10160 mcSHOW_DBG_MSG(("iDelay=%d, Bit %d, Center %d (%d ~ %d) %d\n", iDelay, u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, FinalWinPerBit[u1BitIdx].first_pass, FinalWinPerBit[u1BitIdx].last_pass, FinalWinPerBit[u1BitIdx].win_size));
10161 #else
10162 mcSHOW_DBG_MSG(("iDelay=%d, Bit %2d, Center %3d (%4d ~ %4d) %d\n", iDelay, u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, FinalWinPerBit[u1BitIdx].first_pass, FinalWinPerBit[u1BitIdx].last_pass, FinalWinPerBit[u1BitIdx].win_size));
10163 #endif
10164 mcFPRINTF((fp_A60501, "iDelay=%d, Bit %2d, Center %3d (%4d ~ %4d)\n", iDelay, u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, FinalWinPerBit[u1BitIdx].first_pass, FinalWinPerBit[u1BitIdx].last_pass, FinalWinPerBit[u1BitIdx].win_size));
10165 }
10166
10167#ifdef FOR_HQA_TEST_USED
10168 if(u1UseTestEngine ==1)
10169 {
10170 gFinalRXPerbitWin[p->channel][p->rank][u1BitIdx] = FinalWinPerBit[u1BitIdx].win_size;
10171 }
10172#endif
10173 }
10174 }
10175 }
10176
10177#if EYESCAN_LOG
10178 if (u1IsLP4Family(p->dram_type))
10179 {
10180 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
10181 {
10182 if (u1pass_in_this_vref_flag[u1BitIdx]) gEyeScan_ContinueVrefHeight[u1BitIdx]++; //count pass number of continue vref
10183 }
10184 }
10185#endif
10186
10187 if((u2TempWinSum < (u2rx_window_sum*95/100)) && gRX_EYE_Scan_flag == 0)
10188 {
10189 mcSHOW_DBG_MSG(("\nRX Vref found, early break!\n"));
10190 u2VrefLevel = u2VrefEnd;
10191 break;//max vref found, early break;
10192 }
10193 }
10194
10195 if(u1UseTestEngine)
10196 {
10197 DramcEngine2End(p);
10198 }
10199 else
10200 {
10201 DramcRxWinRDDQCEnd(p);
10202 }
10203
10204 // 3
10205 //As per byte, check max DQS delay in 8-bit. Except for the bit of max DQS delay, delay DQ to fulfill setup time = hold time
10206 for (u1ByteIdx = 0; u1ByteIdx < (p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
10207 {
10208 u2TmpDQMSum =0;
10209
10210 ucbit_first =DQS_BIT_NUMBER*u1ByteIdx;
10211 ucbit_last = DQS_BIT_NUMBER*u1ByteIdx+DQS_BIT_NUMBER-1;
10212 iDQSDlyPerbyte[u1ByteIdx] = MAX_RX_DQSDLY_TAPS;
10213
10214 for (u1BitIdx = ucbit_first; u1BitIdx <= ucbit_last; u1BitIdx++)
10215 {
10216 // find out max Center value
10217 if(FinalWinPerBit[u1BitIdx].win_center < iDQSDlyPerbyte[u1ByteIdx])
10218 {
10219 iDQSDlyPerbyte[u1ByteIdx] = FinalWinPerBit[u1BitIdx].win_center;
10220 }
10221
10222 //mcSHOW_DBG_MSG(("bit#%2d : center=(%2d)\n", u1BitIdx, FinalWinPerBit[u1BitIdx].win_center));
10223 //mcFPRINTF((fp_A60501, "bit#%2d : center=(%2d)\n", u1BitIdx, FinalWinPerBit[u1BitIdx].win_center));
10224 }
10225
10226 //mcSHOW_DBG_MSG(("----seperate line----\n"));
10227 //mcFPRINTF((fp_A60501, "----seperate line----\n"));
10228
10229 if (iDQSDlyPerbyte[u1ByteIdx] > 0) // Delay DQS=0, Delay DQ only
10230 {
10231 iDQSDlyPerbyte[u1ByteIdx] = 0;
10232 }
10233 else //Need to delay DQS
10234 {
10235 iDQSDlyPerbyte[u1ByteIdx] = -iDQSDlyPerbyte[u1ByteIdx] ;
10236 }
10237
10238 // we delay DQ or DQS to let DQS sample the middle of rx pass window for all the 8 bits,
10239 for (u1BitIdx = ucbit_first; u1BitIdx <= ucbit_last; u1BitIdx++)
10240 {
10241 FinalWinPerBit[u1BitIdx].best_dqdly = iDQSDlyPerbyte[u1ByteIdx] + FinalWinPerBit[u1BitIdx].win_center;
10242 u2TmpDQMSum += FinalWinPerBit[u1BitIdx].best_dqdly;
10243#if EYESCAN_LOG
10244 if (u1IsLP4Family(p->dram_type))
10245 {
10246 gEyeScan_DelayCellPI[u1BitIdx] = FinalWinPerBit[u1BitIdx].best_dqdly;
10247 }
10248#endif
10249 }
10250
10251 // calculate DQM as average of 8 DQ delay
10252 iDQMDlyPerbyte[u1ByteIdx] = u2TmpDQMSum/DQS_BIT_NUMBER;
10253
10254#ifdef FOR_HQA_REPORT_USED
10255 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "RX_Window_Center_DQS", u1ByteIdx, iDQSDlyPerbyte[u1ByteIdx], NULL);
10256 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "RX_Window_Center_DQM", u1ByteIdx, iDQMDlyPerbyte[u1ByteIdx], NULL);
10257 for (u1BitIdx = ucbit_first; u1BitIdx <= ucbit_last; u1BitIdx++)
10258 {
10259 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "RX_Window_Center_DQ", u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, NULL);
10260 }
10261#endif
10262 }
10263 }
10264
10265#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
10266 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
10267#endif
10268
10269 //Set RX Final Vref Here
10270 if(u1VrefScanEnable==1)
10271 {
10272#ifdef DEVIATION
10273 if (p->frequency == u2DFSGetHighestFreq(p) && gSetSpecificedVref_Enable[1]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[1]) || gSetSpecificedVref_All_ChRk[1]==ENABLE))
10274 {
10275 DeviationAddVrefOffset(1, NULL, &u2FinalVref, gSetSpecificedVref_Vref_Offset[1]);
10276 }
10277#endif
10278
10279 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), u2FinalVref, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0); // LP4 and LP4x with term: 0xe
10280 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), u2FinalVref, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1); // LP4 and LP4x with term: 0xe
10281
10282 mcSHOW_DBG_MSG(("\nFinal RX Vref %d, apply to both rank0 and 1\n", u2FinalVref));
10283 mcFPRINTF((fp_A60501, "\nFinal RX Vref %d, apply to both rank0 and 1\n", u2FinalVref));
10284#if 0 //BU don't want customer knows our RX's ability
10285#if VENDER_JV_LOG
10286 mcSHOW_DBG_MSG5(("\nFinal RX Vref %d, apply to both rank0 and 1\n", u2FinalVref));
10287#endif
10288#endif
10289
10290 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
10291 if(p->femmc_Ready==0)
10292 {
10293 p->pSavetimeData->u1RxWinPerbitVref_Save[p->channel]=u2FinalVref;
10294 }
10295 #endif
10296
10297 // When only calibrate RX Vref for Rank 0, apply the same value for Rank 1.
10298 gFinalRXVrefDQ[p->channel][p->rank] = (U8) u2FinalVref;
10299 }
10300
10301 #if REG_SHUFFLE_REG_CHECK
10302 ShuffleRegCheck =1;
10303 #endif
10304
10305 gu2RX_DQS_Duty_Offset[0][0]=gu2RX_DQS_Duty_Offset[0][1]=gu2RX_DQS_Duty_Offset[1][0]=gu2RX_DQS_Duty_Offset[1][1] = 0;
10306
10307 // set dqs delay, (dqm delay)
10308 for (u1ByteIdx = 0; u1ByteIdx < (p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
10309 {
10310 // Set DQS & DQM delay
10311 if(u1IsLP4Family(p->dram_type))
10312 {
10313 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6+ u4AddrOfst*u1ByteIdx), \
10314 P_Fld(((U32)iDQSDlyPerbyte[u1ByteIdx]+gu2RX_DQS_Duty_Offset[u1ByteIdx][0]),SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_R_DLY_B0) |P_Fld(((U32)iDQSDlyPerbyte[u1ByteIdx]+gu2RX_DQS_Duty_Offset[u1ByteIdx][1]),SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_F_DLY_B0) |
10315 P_Fld(((U32)iDQMDlyPerbyte[u1ByteIdx]),SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_R_DLY_B0) |P_Fld(((U32)iDQMDlyPerbyte[u1ByteIdx]),SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_F_DLY_B0));
10316
10317 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
10318 if(p->femmc_Ready==0)
10319 {
10320 p->pSavetimeData->u1RxWinPerbit_DQS[p->channel][p->rank][u1ByteIdx]=(U32)iDQSDlyPerbyte[u1ByteIdx];
10321 p->pSavetimeData->u1RxWinPerbit_DQM[p->channel][p->rank][u1ByteIdx]=(U32)iDQMDlyPerbyte[u1ByteIdx];
10322 }
10323 #endif
10324 }
10325#if ENABLE_LP3_SW
10326 else
10327 {
10328 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
10329 for(ii=p->rank; ii<RANK_MAX; ii++)
10330 {
10331 vSetRank(p,ii);
10332 vIO32WriteFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), (U32)iDQSDlyPerbyte[u1ByteIdx], SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_R_DLY_B0);
10333 vIO32WriteFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), (U32)iDQSDlyPerbyte[u1ByteIdx], SHU1_R0_B0_DQ6_RK0_RX_ARDQS0_F_DLY_B0);
10334 Set_RX_DQM_DelayLine_Phy_Byte(p, u1ByteIdx,(U32)iDQMDlyPerbyte[u1ByteIdx]);
10335 }
10336 vSetRank(p, backup_rank);
10337 }
10338#endif
10339 }
10340
10341 #if REG_SHUFFLE_REG_CHECK
10342 ShuffleRegCheck =0;
10343 #endif
10344
10345 #if REG_SHUFFLE_REG_CHECK
10346 ShuffleRegCheck =1;
10347 #endif
10348
10349 // set dq delay
10350 if(u1IsLP4Family(p->dram_type))
10351 {
10352 for (u1BitIdx=0; u1BitIdx<DQS_BIT_NUMBER; u1BitIdx+=2)
10353 {
10354 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+u1BitIdx*2), \
10355 P_Fld(((U32)FinalWinPerBit[u1BitIdx].best_dqdly),SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_R_DLY_B0) |\
10356 P_Fld(((U32)FinalWinPerBit[u1BitIdx].best_dqdly),SHU1_R0_B0_DQ2_RK0_RX_ARDQ0_F_DLY_B0)| \
10357 P_Fld(((U32)FinalWinPerBit[u1BitIdx+1].best_dqdly),SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_R_DLY_B0) |\
10358 P_Fld(((U32)FinalWinPerBit[u1BitIdx+1].best_dqdly),SHU1_R0_B0_DQ2_RK0_RX_ARDQ1_F_DLY_B0));
10359
10360 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+u1BitIdx*2), \
10361 P_Fld(((U32)FinalWinPerBit[u1BitIdx+8].best_dqdly),SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_R_DLY_B1) | \
10362 P_Fld((U32)FinalWinPerBit[u1BitIdx+8].best_dqdly,SHU1_R0_B1_DQ2_RK0_RX_ARDQ0_F_DLY_B1)| \
10363 P_Fld(((U32)FinalWinPerBit[u1BitIdx+9].best_dqdly),SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_R_DLY_B1) |\
10364 P_Fld((U32)FinalWinPerBit[u1BitIdx+9].best_dqdly,SHU1_R0_B1_DQ2_RK0_RX_ARDQ1_F_DLY_B1));
10365
10366 /*mcSHOW_DBG_MSG(("u1BitId %d Addr 0x%2x = %2d %2d %2d %2d \n", u1BitIdx, DRAMC_REG_ADDR(DDRPHY_RXDQ1+u1BitIdx*2), \
10367 * FinalWinPerBit[u1BitIdx].best_dqdly, FinalWinPerBit[u1BitIdx+1].best_dqdly, FinalWinPerBit[u1BitIdx+8].best_dqdly, FinalWinPerBit[u1BitIdx+9].best_dqdly));
10368 */
10369 }
10370
10371 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
10372 if(p->femmc_Ready==0)
10373 {
10374 for (u1BitIdx=0; u1BitIdx<16; u1BitIdx++)
10375 {
10376 p->pSavetimeData->u1RxWinPerbit_DQ[p->channel][p->rank][u1BitIdx]=(U32)FinalWinPerBit[u1BitIdx].best_dqdly;
10377
10378 }
10379 }
10380 #endif
10381 }
10382#if ENABLE_LP3_SW
10383 else //LPDDR3
10384 {
10385 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
10386 for(ii=p->rank; ii<RANK_MAX; ii++)
10387 {
10388 vSetRank(p,ii);
10389
10390 //every 2bit dq have the same delay register address
10391 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
10392 {
10393 u1BitIdx = u1ByteIdx *DQS_BIT_NUMBER;
10394
10395 dl_value[0] = FinalWinPerBit[u1BitIdx].best_dqdly;
10396 dl_value[1] = FinalWinPerBit[u1BitIdx+1].best_dqdly;
10397 dl_value[2] = FinalWinPerBit[u1BitIdx+2].best_dqdly;
10398 dl_value[3] = FinalWinPerBit[u1BitIdx+3].best_dqdly;
10399 dl_value[4] = FinalWinPerBit[u1BitIdx+4].best_dqdly;
10400 dl_value[5] = FinalWinPerBit[u1BitIdx+5].best_dqdly;
10401 dl_value[6] = FinalWinPerBit[u1BitIdx+6].best_dqdly;
10402 dl_value[7] = FinalWinPerBit[u1BitIdx+7].best_dqdly;
10403 Set_RX_DQ_DelayLine_Phy_Byte(p, u1ByteIdx, dl_value);
10404 }
10405 }
10406 vSetRank(p, backup_rank);
10407 }
10408#endif
10409
10410 DramPhyReset(p);
10411
10412 vPrintCalibrationBasicInfo(p);
10413
10414#ifdef ETT_PRINT_FORMAT
10415 if(u1IsLP4Family(p->dram_type))
10416 {
10417 mcSHOW_DBG_MSG(("DQS Delay:\nDQS0 = %d, DQS1 = %d\n"
10418 "DQM Delay:\nDQM0 = %d, DQM1 = %d\n",
10419 iDQSDlyPerbyte[0], iDQSDlyPerbyte[1],
10420 iDQMDlyPerbyte[0], iDQMDlyPerbyte[1]));
10421 }
10422#if ENABLE_LP3_SW
10423 else
10424 {
10425 mcSHOW_DBG_MSG(("DQS Delay:\nDQS0 = %d, DQS1 = %d, DQS2 = %d, DQS3 = %d\n"
10426 "DQM Delay:\nDQM0 = %d, DQM1 = %d, DQM2 = %d, DQM3 = %d\n",
10427 iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQSDlyPerbyte[2], iDQSDlyPerbyte[3],
10428 iDQMDlyPerbyte[0], iDQMDlyPerbyte[1], iDQMDlyPerbyte[2], iDQMDlyPerbyte[3]));
10429 }
10430#endif /* ENABLE_LP3_SW */
10431#else
10432 if(u1IsLP4Family(p->dram_type))
10433 {
10434 mcSHOW_DBG_MSG(("DQS Delay:\nDQS0 = %2d, DQS1 = %2d\n"
10435 "DQM Delay:\nDQM0 = %2d, DQM1 = %2d\n",
10436 iDQSDlyPerbyte[0], iDQSDlyPerbyte[1],
10437 iDQMDlyPerbyte[0], iDQMDlyPerbyte[1]));
10438 }
10439#if ENABLE_LP3_SW
10440 else
10441 {
10442 mcSHOW_DBG_MSG(("DQS Delay:\nDQS0 = %2d, DQS1 = %2d, DQS2 = %2d, DQS3 = %2d\n"
10443 "DQM Delay:\nDQM0 = %2d, DQM1 = %2d, DQM2 = %2d, DQM3 = %2d\n",
10444 iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQSDlyPerbyte[2], iDQSDlyPerbyte[3],
10445 iDQMDlyPerbyte[0], iDQMDlyPerbyte[1], iDQMDlyPerbyte[2], iDQMDlyPerbyte[3]));
10446 }
10447#endif /* ENABLE_LP3_SW */
10448#endif
10449 mcSHOW_DBG_MSG(("DQ Delay:\n"));
10450
10451 mcFPRINTF((fp_A60501, "\tdramc_rxdqs_perbit_swcal\n"));
10452 mcFPRINTF((fp_A60501, "\tchannel=%d(1:cha) \n", p->channel));
10453 mcFPRINTF((fp_A60501, "\tbus width=%d\n\n", p->data_width));
10454
10455 if(u1IsLP4Family(p->dram_type))
10456 {
10457 mcFPRINTF((fp_A60501, "DQS Delay:\n DQS0 = %2d DQS1 = %2d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1]));
10458 mcFPRINTF((fp_A60501, "DQM Delay:\n DQM0 = %2d DQM1 = %2d\n", iDQMDlyPerbyte[0], iDQMDlyPerbyte[1]));
10459 }
10460#if ENABLE_LP3_SW
10461 else
10462 {
10463 mcFPRINTF((fp_A60501, "DQS Delay:\n DQS0 = %2d DQS1 = %2d DQS2 = %2d DQS3 = %2d\n", iDQSDlyPerbyte[0], iDQSDlyPerbyte[1], iDQSDlyPerbyte[2], iDQSDlyPerbyte[3]));
10464 mcFPRINTF((fp_A60501, "DQM Delay:\n DQM0 = %2d DQM1 = %2d DQM2 = %2d DQM3 = %2d\n", iDQMDlyPerbyte[0], iDQMDlyPerbyte[1], iDQMDlyPerbyte[2], iDQMDlyPerbyte[3]));
10465 }
10466#endif /* ENABLE_LP3_SW */
10467 mcFPRINTF((fp_A60501, "DQ Delay:\n"));
10468
10469 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx=u1BitIdx+4)
10470 {
10471 #ifdef ETT_PRINT_FORMAT
10472 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));
10473 #else
10474 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));
10475 #endif
10476 mcFPRINTF((fp_A60501, "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));
10477 }
10478 mcSHOW_DBG_MSG(("\n\n"));
10479 mcFPRINTF((fp_A60501, "\n\n"));
10480
10481 // BU request RX & TX window size log.
10482#if 0//def RELEASE // for parsing tool
10483 if(u1UseTestEngine==1)
10484 {
10485 mcSHOW_DBG_MSG4(("RX CH%d R%d ,Freq %d\n", p->channel, p->rank, p->frequency));
10486 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
10487 {
10488 mcSHOW_DBG_MSG4(("%d: %d\n", u1BitIdx, gFinalRXPerbitWin[p->channel][p->rank][u1BitIdx]));
10489 }
10490 }
10491#endif
10492
10493 #if REG_SHUFFLE_REG_CHECK
10494 ShuffleRegCheck =0;
10495 #endif
10496 mcSHOW_DBG_MSG3(("[DramcRxWindowPerbitCal] Done\n"));
10497 mcFPRINTF((fp_A60501, "[DramcRxWindowPerbitCal] Done\n"));
10498
10499#if REG_ACCESS_PORTING_DGB
10500 RegLogEnable =0;
10501#endif
10502
10503return DRAM_OK;
10504
10505 // Log example ==> Neec to update
10506 /*
10507------------------------------------------------------
10508Start calculate dq time and dqs time /
10509Find max DQS delay per byte / Adjust DQ delay to align DQS...
10510------------------------------------------------------
10511bit# 0 : dq time=11 dqs time= 8
10512bit# 1 : dq time=11 dqs time= 8
10513bit# 2 : dq time=11 dqs time= 6
10514bit# 3 : dq time=10 dqs time= 8
10515bit# 4 : dq time=11 dqs time= 8
10516bit# 5 : dq time=10 dqs time= 8
10517bit# 6 : dq time=11 dqs time= 8
10518bit# 7 : dq time= 9 dqs time= 6
10519----seperate line----
10520bit# 8 : dq time=12 dqs time= 7
10521bit# 9 : dq time=10 dqs time= 8
10522bit#10 : dq time=11 dqs time= 8
10523bit#11 : dq time=10 dqs time= 8
10524bit#12 : dq time=11 dqs time= 8
10525bit#13 : dq time=11 dqs time= 8
10526bit#14 : dq time=11 dqs time= 8
10527bit#15 : dq time=12 dqs time= 8
10528----seperate line----
10529bit#16 : dq time=11 dqs time= 7
10530bit#17 : dq time=10 dqs time= 8
10531bit#18 : dq time=11 dqs time= 7
10532bit#19 : dq time=11 dqs time= 6
10533bit#20 : dq time=10 dqs time= 9
10534bit#21 : dq time=11 dqs time=10
10535bit#22 : dq time=11 dqs time=10
10536bit#23 : dq time= 9 dqs time= 9
10537----seperate line----
10538bit#24 : dq time=12 dqs time= 6
10539bit#25 : dq time=13 dqs time= 6
10540bit#26 : dq time=13 dqs time= 7
10541bit#27 : dq time=11 dqs time= 7
10542bit#28 : dq time=12 dqs time= 8
10543bit#29 : dq time=10 dqs time= 8
10544bit#30 : dq time=13 dqs time= 7
10545bit#31 : dq time=11 dqs time= 8
10546----seperate line----
10547==================================================
10548 dramc_rxdqs_perbit_swcal_v2
10549 channel=2(2:cha, 3:chb) apply = 1
10550==================================================
10551DQS Delay :
10552 DQS0 = 0 DQS1 = 0 DQS2 = 0 DQS3 = 0
10553DQ Delay :
10554DQ 0 = 1 DQ 1 = 1 DQ 2 = 2 DQ 3 = 1
10555DQ 4 = 1 DQ 5 = 1 DQ 6 = 1 DQ 7 = 1
10556DQ 8 = 2 DQ 9 = 1 DQ10 = 1 DQ11 = 1
10557DQ12 = 1 DQ13 = 1 DQ14 = 1 DQ15 = 2
10558DQ16 = 2 DQ17 = 1 DQ18 = 2 DQ19 = 2
10559DQ20 = 0 DQ21 = 0 DQ22 = 0 DQ23 = 0
10560DQ24 = 3 DQ25 = 3 DQ26 = 3 DQ27 = 2
10561DQ28 = 2 DQ29 = 1 DQ30 = 3 DQ31 = 1
10562_______________________________________________________________
10563 */
10564}
10565#endif //SIMULATION_RX_PERBIT
10566
10567#if SIMULATION_DATLAT
10568static void dle_factor_handler(DRAMC_CTX_T *p, U8 curr_val, U8 pip_num)
10569{
10570 U8 u1DATLAT_DSEL=0;
10571 U8 u1DLECG_OptionEXT1 = 0;
10572 U8 u1DLECG_OptionEXT2 = 0;
10573 U8 u1DLECG_OptionEXT3 = 0;
10574
10575#if REG_ACCESS_PORTING_DGB
10576 RegLogEnable =1;
10577 mcSHOW_DBG_MSG(("\n[REG_ACCESS_PORTING_FUNC] dle_factor_handler\n"));
10578 mcFPRINTF((fp_A60501, "\n[REG_ACCESS_PORTING_FUNC] dle_factor_handler\n"));
10579#endif
10580
10581 #if REG_SHUFFLE_REG_CHECK
10582 ShuffleRegCheck =1;
10583 #endif
10584
10585 if(curr_val<2)
10586 curr_val =2;
10587
10588#if RX_PIPE_BYPASS_EN
10589 /* if rx pipe bypass en, then datlat will less 1 pipe. So DSEL minus 1, not minus 2 */
10590 u1DATLAT_DSEL = curr_val - 1;
10591#else
10592 u1DATLAT_DSEL = curr_val - 2;
10593#endif
10594
10595 // Datlat_dsel = datlat -1, only 1 TX pipe
10596 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF1),
10597 P_Fld(curr_val, SHU_CONF1_DATLAT) |
10598 P_Fld(u1DATLAT_DSEL, SHU_CONF1_DATLAT_DSEL) |
10599 P_Fld(u1DATLAT_DSEL, SHU_CONF1_DATLAT_DSEL_PHY));
10600
10601 //(>=8 & <14) set EXT1 =1, EXT2=0, EXT3=0
10602 //(>= 14 & <19) set EXT1=1, EXT2=1, EXT3=0
10603 //(>=19) set EXT1=1, EXT2=1, EXT3=1
10604 u1DLECG_OptionEXT1 = (curr_val >= 8)? (1): (0);
10605 u1DLECG_OptionEXT2 = (curr_val >= 14)? (1): (0);
10606 u1DLECG_OptionEXT3 = (curr_val >= 19)? (1): (0);
10607 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU_PIPE), P_Fld(u1DLECG_OptionEXT1, SHU_PIPE_READ_START_EXTEND1)
10608 | P_Fld(u1DLECG_OptionEXT1, SHU_PIPE_DLE_LAST_EXTEND1)
10609 | P_Fld((u1DLECG_OptionEXT2), SHU_PIPE_READ_START_EXTEND2)
10610 | P_Fld((u1DLECG_OptionEXT2), SHU_PIPE_DLE_LAST_EXTEND2)
10611 | P_Fld((u1DLECG_OptionEXT3), SHU_PIPE_READ_START_EXTEND3)
10612 | P_Fld((u1DLECG_OptionEXT3), SHU_PIPE_DLE_LAST_EXTEND3));
10613
10614 #if REG_SHUFFLE_REG_CHECK
10615 ShuffleRegCheck =0;
10616 #endif
10617
10618 DramPhyReset(p);
10619
10620#if REG_ACCESS_PORTING_DGB
10621 RegLogEnable =0;
10622#endif
10623}
10624
10625//-------------------------------------------------------------------------
10626/** Dramc_ta2_rx_scan
10627 */
10628//-------------------------------------------------------------------------
10629static U32 Dramc_ta2_rx_scan(DRAMC_CTX_T *p, U8 u1UseTestEngine)
10630{
10631 U32 ii, u4err_value;
10632 S16 iDelay;
10633#if ENABLE_LP3_SW
10634 U8 u1ByteIdx;
10635 U8 dl_value[8]={0,0,0,0,0,0,0,0};
10636#endif
10637
10638 // reg backup
10639#if 0
10640 U32 u4RegBak_DDRPHY_RXDQ_RK0[DQS_NUMBER][5]; // rank 0
10641 for (ii=0; ii<5; ii++)
10642 {
10643 if(u1IsLP4Family(p->dram_type))
10644 {
10645 u4RegBak_DDRPHY_RXDQ_RK0[0][ii] =(u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+ii*4), PHY_FLD_FULL)); // rank 0, byte 0
10646 u4RegBak_DDRPHY_RXDQ_RK0[1][ii] =(u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+ii*4), PHY_FLD_FULL)); // rank 0, byte 1
10647 }
10648#if ENABLE_LP3_SW
10649 else //LPDDR3 , only record rank 0, will not modify rank1
10650 {
10651#if 0 //LP3 no need to backup DQ delay line reg
10652 for(u1ByteIdx=0; u1ByteIdx<4; u1ByteIdx++)
10653 {
10654 u4RegBak_DDRPHY_RXDQ_RK0[u1ByteIdx][ii] =u4IO32ReadFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU2_R0_B0_DQ2+ii*4), PHY_FLD_FULL);
10655 }
10656#endif
10657 }
10658#endif
10659 }
10660#endif
10661
10662 // Adjust DQM output delay to 0
10663 if(u1IsLP4Family(p->dram_type))
10664 {
10665 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ6), \
10666 P_Fld(0,SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_R_DLY_B0) |P_Fld(0, SHU1_R0_B0_DQ6_RK0_RX_ARDQM0_F_DLY_B0));
10667 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ6), \
10668 P_Fld(0,SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_R_DLY_B1) |P_Fld(0, SHU1_R0_B1_DQ6_RK0_RX_ARDQM0_F_DLY_B1));
10669 }
10670#if ENABLE_LP3_SW
10671 else
10672 {
10673 for(u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
10674 {
10675 Set_RX_DQM_DelayLine_Phy_Byte(p, u1ByteIdx, 0);
10676 }
10677 }
10678#endif
10679
10680 // Adjust DQ output delay to 0
10681 //every 2bit dq have the same delay register address
10682 if(u1IsLP4Family(p->dram_type))
10683 {
10684 for (ii=0; ii<4; ii++)
10685 {
10686 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+ii*4), 0); //DQ0~DQ7
10687 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+ii*4), 0);//DQ8~DQ15
10688 }
10689 }
10690#if ENABLE_LP3_SW
10691 else //LPDDR3
10692 {
10693 for (u1ByteIdx=0; u1ByteIdx<DQS_NUMBER; u1ByteIdx++)
10694 {
10695 Set_RX_DQ_DelayLine_Phy_Byte(p, u1ByteIdx, dl_value);
10696 }
10697 }
10698#endif
10699
10700 if(u1UseTestEngine)
10701 DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0);
10702
10703 // quick rx dqs search
10704 //mcSHOW_DBG_MSG(("quick rx dqs search\n"));
10705 //mcFPRINTF((fp_A60817, "quick rx dqs search\n", iDelay));
10706 for (iDelay=-32; iDelay<=32; iDelay+=4)
10707 {
10708 //mcSHOW_DBG_MSG(("%2d, ", iDelay));
10709 //mcFPRINTF((fp_A60817,"%2d, ", iDelay));
10710 SetRxDqDqsDelay(p, iDelay);
10711
10712 if(u1UseTestEngine)
10713 {
10714 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern);
10715 }
10716 else
10717 {
10718 //sagy: no definition of DramcRxWinRDDQC, u4err_value = DramcRxWinRDDQC(p);
10719 }
10720
10721 if(u4err_value ==0)// rx dqs found.
10722 break;
10723 }
10724
10725 if(u1UseTestEngine)
10726 DramcEngine2End(p);
10727
10728 #ifdef ETT_PRINT_FORMAT
10729 mcSHOW_DBG_MSG(("RX DQS dly = %d, ", iDelay));
10730 #else
10731 mcSHOW_DBG_MSG(("RX DQS dly = %2d, ", iDelay));
10732 #endif
10733 mcFPRINTF((fp_A60501, "RX DQS dly = %2d, ", iDelay));
10734
10735#if 0
10736 // restore registers
10737 for (ii=0; ii<5; ii++)
10738 {
10739 if(u1IsLP4Family(p->dram_type))
10740 {
10741 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ2+ ii*4), u4RegBak_DDRPHY_RXDQ_RK0[0][ii] , PHY_FLD_FULL);
10742 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ2+ ii*4), u4RegBak_DDRPHY_RXDQ_RK0[1][ii] , PHY_FLD_FULL);
10743 }
10744#if ENABLE_LP3_SW
10745 else //LPDDR3
10746 {
10747#if 0 //LP3 no need to restore backup DQ delay line reg
10748 for(u1ByteIdx=0; u1ByteIdx<4; u1ByteIdx++)
10749 {
10750 vIO32WriteFldAlign_Phy_Byte(u1ByteIdx, DRAMC_REG_ADDR(DDRPHY_SHU2_R0_B0_DQ2+ ii*4), u4RegBak_DDRPHY_RXDQ_RK0[u1ByteIdx][ii] , PHY_FLD_FULL);
10751 }
10752#endif
10753 }
10754#endif
10755 }
10756#endif
10757
10758 return u4err_value;
10759}
10760
10761
10762static U8 aru1RxDatlatResult[CHANNEL_NUM][RANK_MAX];
10763
10764U8 DramcRxdatlatScan(DRAMC_CTX_T *p, DRAM_DATLAT_CALIBRATION_TYTE_T use_rxtx_scan)
10765{
10766 U8 ii;
10767 U32 u4prv_register_080;
10768 U32 u4err_value= 0xffffffff;
10769 U8 ucfirst, ucbegin, ucsum, ucbest_step, ucpipe_num =0;
10770 U16 u2DatlatBegin;
10771
10772 // error handling
10773 if (!p)
10774 {
10775 mcSHOW_ERR_MSG(("context NULL\n"));
10776 return DRAM_FAIL;
10777 }
10778#if REG_ACCESS_PORTING_DGB
10779 RegLogEnable =1;
10780 mcSHOW_DBG_MSG(("\n[REG_ACCESS_PORTING_FUNC] DramcRxdatlatCal\n"));
10781 mcFPRINTF((fp_A60501, "\n[REG_ACCESS_PORTING_FUNC] DramcRxdatlatCal\n"));
10782#endif
10783
10784 mcSHOW_DBG_MSG(("\n[DATLAT]\n"
10785 "Freq=%d, CH%d RK%d, use_rxtx_scan=%d\n\n",
10786 p->frequency, p->channel, p->rank, use_rxtx_scan));
10787
10788 mcFPRINTF((fp_A60501, "\n\tDATLAT calibration\n"));
10789 mcFPRINTF((fp_A60501, "\tch=%d(1:cha), rank=%d, use_rxtx_scan=%d\n\n",
10790 p->channel, p->rank, use_rxtx_scan));
10791
10792 // [11:10] DQIENQKEND 01 -> 00 for DATLAT calibration issue, DQS input enable will refer to DATLAT
10793 // if need to enable this (for power saving), do it after all calibration done
10794 //u4prv_register_0d8 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_MCKDLY));
10795 //vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), P_Fld(0, PADCTRL_DQIENQKEND) | P_Fld(0, PADCTRL_DQIENLATEBEGIN));
10796
10797 // pre-save
10798 // 0x07c[6:4] DATLAT bit2-bit0
10799 u4prv_register_080 = u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF1));
10800
10801 // init best_step to default
10802 ucbest_step = (U8) u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF1), SHU_CONF1_DATLAT);
10803 mcSHOW_DBG_MSG(("DATLAT Default: 0x%x\n", ucbest_step));
10804 mcFPRINTF((fp_A60501, "DATLAT Default: 0x%x\n", ucbest_step));
10805
10806#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
10807 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
10808 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
10809#endif
10810
10811 // 1.set DATLAT 0-15 (0-21 for MT6595)
10812 // 2.enable engine1 or engine2
10813 // 3.check result ,3~4 taps pass
10814 // 4.set DATLAT 2nd value for optimal
10815
10816 // Initialize
10817 ucfirst = 0xff;
10818 ucbegin = 0;
10819 ucsum = 0;
10820
10821 DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0);
10822#if (FOR_DV_SIMULATION_USED==0)
10823 u2DatlatBegin=7;
10824#else
10825 u2DatlatBegin=0;
10826#endif
10827
10828 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_DATLAT)
10829 if(p->femmc_Ready==1)
10830 {
10831 ucbest_step = p->pSavetimeData->u1RxDatlat_Save[p->channel][p->rank];
10832 }
10833 else
10834 #endif
10835 {
10836 for (ii = u2DatlatBegin; ii < DATLAT_TAP_NUMBER; ii++)
10837 {
10838 // 1
10839 dle_factor_handler(p, ii, ucpipe_num);
10840
10841 // 2
10842 if(use_rxtx_scan == fcDATLAT_USE_DEFAULT)
10843 {
10844 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, p->test_pattern);
10845 }
10846#if ENABLE_LP3_SW
10847 else //if(use_rxtx_scan == fcDATLAT_USE_RX_SCAN)//LPDDR3, LP4 Should not enter if datlat calibration is after RDDQC
10848 {
10849 u4err_value = Dramc_ta2_rx_scan(p, 1);
10850 }
10851#endif
10852
10853 // 3
10854 if (u4err_value == 0)
10855 {
10856 if (ucbegin == 0)
10857 {
10858 // first tap which is pass
10859 ucfirst = ii;
10860 ucbegin = 1;
10861 }
10862 if (ucbegin == 1)
10863 {
10864 ucsum++;
10865
10866 if(ucsum >4)
10867 break; //early break.
10868 }
10869 }
10870 else
10871 {
10872 if (ucbegin == 1)
10873 {
10874 // pass range end
10875 ucbegin = 0xff;
10876 }
10877 }
10878
10879 #ifdef ETT_PRINT_FORMAT
10880 mcSHOW_DBG_MSG(("%d, 0x%X, sum=%d\n", ii, u4err_value, ucsum));
10881 #else
10882 mcSHOW_DBG_MSG(("TAP=%2d, err_value=0x%8x, sum=%d\n", ii, u4err_value, ucsum));
10883 #endif
10884 mcFPRINTF((fp_A60501, "TAP=%2d, err_value=0x%8x, begin=%d, first=%3d, sum=%d\n", ii, u4err_value, ucbegin, ucfirst, ucsum));
10885 }
10886
10887 DramcEngine2End(p);
10888
10889 // 4
10890 if (ucsum == 0)
10891 {
10892 mcSHOW_ERR_MSG(("no DATLAT taps pass, DATLAT calibration fail!\n"));
10893 }
10894 else if (ucsum <= 3)
10895 {
10896 ucbest_step = ucfirst + (ucsum>>1);
10897 }
10898 else // window is larger htan 3
10899 {
10900 ucbest_step = ucfirst + 2;
10901 }
10902 }
10903 aru1RxDatlatResult[p->channel][p->rank] = ucbest_step;
10904
10905 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
10906 if(p->femmc_Ready==0)
10907 {
10908 p->pSavetimeData->u1RxDatlat_Save[p->channel][p->rank] = ucbest_step;
10909 }
10910 #endif
10911
10912 mcSHOW_DBG_MSG(("best_step=%d\n\n", ucbest_step));
10913 mcFPRINTF((fp_A60501, "best_step=%d\n", ucbest_step));
10914
10915
10916#ifdef FOR_HQA_TEST_USED
10917 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "DATLAT", 0, ucbest_step, NULL);
10918#endif
10919
10920#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
10921 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
10922#endif
10923
10924 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_DATLAT)
10925 if(p->femmc_Ready==1)
10926 {
10927 dle_factor_handler(p, ucbest_step, ucpipe_num);
10928 vSetCalibrationResult(p, DRAM_CALIBRATION_DATLAT, DRAM_OK);
10929 }
10930 else
10931 #endif
10932 {
10933 if(ucsum <4)
10934 {
10935 mcSHOW_DBG_MSG2(("[NOTICE] CH%d, DatlatSum %d\n", p->channel, ucsum));
10936 mcFPRINTF((fp_A60501, "[NOTICE] CH%d, DatlatSum %d\n", p->channel, ucsum));
10937 }
10938
10939 if (ucsum == 0)
10940 {
10941 mcSHOW_ERR_MSG(("DATLAT calibration fail, write back to default values!\n"));
10942 vIO32Write4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_CONF1), u4prv_register_080);
10943 vSetCalibrationResult(p, DRAM_CALIBRATION_DATLAT, DRAM_FAIL);
10944 }
10945 else
10946 {
10947 dle_factor_handler(p, ucbest_step, ucpipe_num);
10948 vSetCalibrationResult(p, DRAM_CALIBRATION_DATLAT, DRAM_OK);
10949 }
10950 }
10951 // [11:10] DQIENQKEND 01 -> 00 for DATLAT calibration issue, DQS input enable will refer to DATLAT
10952 // if need to enable this (for power saving), do it after all calibration done
10953 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_PADCTRL), P_Fld(1, PADCTRL_DQIENQKEND) | P_Fld(1, PADCTRL_DQIENLATEBEGIN));
10954
10955 mcSHOW_DBG_MSG3(("[DramcRxdatlatCal] Done\n"));
10956 mcFPRINTF((fp_A60501, "[DramcRxdatlatCal] Done\n"));
10957
10958#if REG_ACCESS_PORTING_DGB
10959 RegLogEnable =0;
10960#endif
10961
10962 return ucsum;
10963}
10964
10965void DramcRxdatlatCal(DRAMC_CTX_T *p)
10966{
10967 U8 u1DatlatWindowSum;
10968
10969 u1DatlatWindowSum = DramcRxdatlatScan(p, fcDATLAT_USE_DEFAULT);
10970
10971 if((p->dram_type == TYPE_LPDDR3) &&(u1DatlatWindowSum <5))
10972 {
10973 mcSHOW_DBG_MSG(("\nDatlatWindowSum %d too small(<5), Start RX + Datlat scan\n", u1DatlatWindowSum));
10974 DramcRxdatlatScan(p, fcDATLAT_USE_RX_SCAN);
10975 }
10976}
10977
10978DRAM_STATUS_T DramcDualRankRxdatlatCal(DRAMC_CTX_T *p)
10979{
10980 U8 u1FinalDatlat, u1Datlat0, u1Datlat1;
10981
10982 u1Datlat0 = aru1RxDatlatResult[p->channel][0];
10983 u1Datlat1 = aru1RxDatlatResult[p->channel][1];
10984
10985 if(u1Datlat0> u1Datlat1)
10986 {
10987 u1FinalDatlat= u1Datlat0;
10988 }
10989 else
10990 {
10991 u1FinalDatlat= u1Datlat1;
10992 }
10993
10994 #if ENABLE_READ_DBI
10995 if(p->DBI_R_onoff[p->dram_fsp])
10996 {
10997 u1FinalDatlat++;
10998 }
10999 #endif
11000
11001 dle_factor_handler(p, u1FinalDatlat, 3);
11002 mcSHOW_DBG_MSG(("[DualRankRxdatlatCal] RK0: %d, RK1: %d, Final_Datlat %d\n", u1Datlat0, u1Datlat1, u1FinalDatlat));
11003 mcFPRINTF((fp_A60501, "[DualRankRxdatlatCal] RK0: %d, RK1: %d, Final_Datlat %d\n", u1Datlat0, u1Datlat1, u1FinalDatlat));
11004
11005 return DRAM_OK;
11006
11007}
11008#endif //SIMULATION_DATLAT
11009
11010#if SIMULATION_TX_PERBIT
11011
11012#if TX_OE_CALIBATION
11013#define TX_OE_PATTERN_USE_TA2 1
11014#define TX_OE_SCAN_FULL_RANGE 0
11015
11016void DramcTxOECalibration(DRAMC_CTX_T *p)
11017{
11018 U8 u1ByteIdx, ucBegin[2]={0}, ucEnd[2]={0xff, 0xff}, ucbest_step[2];
11019 //U8 ucbegin=0xff, , ucfirst, ucsum, ucbest_step;
11020 U32 u4RegValue_TXDLY, u4RegValue_dly, u4err_value;
11021 U16 u2Delay, u2TempVirtualDelay, u2SmallestVirtualDelay=0xffff;
11022 U16 u2DQOEN_DelayBegin, u2DQEN_DelayEnd;
11023 U8 ucdq_ui_large_bak[DQS_NUMBER], ucdq_ui_small_bak[DQS_NUMBER];
11024 U8 ucdq_oen_ui_large[2], ucdq_oen_ui_small[2];
11025 U8 ucdq_current_ui_large, ucdq_current_ui_small;
11026 //U8 ucdq_ui_large_reg_value=0xff, ucdq_ui_small_reg_value=0xff;
11027
11028 if(!u1IsLP4Family(p->dram_type))
11029 return; //only apply in LP4
11030
11031 #if TX_OE_PATTERN_USE_TA2
11032 mcSHOW_DBG_MSG(("\n[DramC_TX_OE_Calibration] TA2\n"));
11033 #else
11034 mcSHOW_DBG_MSG(("\n[DramC_TX_OE_Calibration] DMA\n"));
11035 #endif
11036
11037 #ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
11038 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
11039 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
11040 #endif
11041
11042
11043#if (SUPPORT_SAVE_TIME_FOR_CALIBRATION)
11044 if(p->femmc_Ready==1)
11045 {
11046 for(u1ByteIdx=0; u1ByteIdx<DQS_NUMBER_LP4; u1ByteIdx++)
11047 {
11048 ucdq_oen_ui_large[u1ByteIdx]= p->pSavetimeData->u1TX_OE_DQ_MCK[p->channel][p->rank][u1ByteIdx];
11049 ucdq_oen_ui_small[u1ByteIdx]= p->pSavetimeData->u1TX_OE_DQ_UI[p->channel][p->rank][u1ByteIdx];
11050 }
11051 }
11052 else
11053#endif
11054 {
11055 u4RegValue_TXDLY= u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0));
11056 u4RegValue_dly= u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2));
11057
11058 // find smallest DQ byte delay
11059 for(u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
11060 {
11061 ucdq_ui_large_bak[u1ByteIdx] = (u4RegValue_TXDLY >> (u1ByteIdx*4)) &0x7;
11062 ucdq_ui_small_bak[u1ByteIdx] = (u4RegValue_dly >> (u1ByteIdx*4)) &0x7;
11063
11064 u2TempVirtualDelay = (ucdq_ui_large_bak[u1ByteIdx] <<3) + ucdq_ui_small_bak[u1ByteIdx];
11065 if(u2TempVirtualDelay < u2SmallestVirtualDelay)
11066 {
11067 u2SmallestVirtualDelay = u2TempVirtualDelay;
11068 }
11069
11070 mcSHOW_DBG_MSG(("Original DQ_B%d (%d %d) =%d, OEN = %d\n", u1ByteIdx, ucdq_ui_large_bak[u1ByteIdx], ucdq_ui_small_bak[u1ByteIdx], u2TempVirtualDelay, u2TempVirtualDelay-TX_DQ_OE_SHIFT_LP4));
11071 }
11072
11073 #if TX_OE_PATTERN_USE_TA2
11074 DramcEngine2Init(p, p->test2_1, p->test2_2, TEST_AUDIO_PATTERN, 0);
11075 #else
11076 DramcDmaEngine((DRAMC_CTX_T *)p, 0x50000000, 0x60000000, 0xff00, 8, DMA_PREPARE_DATA_ONLY, p->support_channel_num);
11077 #endif
11078
11079 #if TX_OE_SCAN_FULL_RANGE
11080 // -17~+8 UI
11081 if(u2SmallestVirtualDelay >= 17)
11082 u2DQOEN_DelayBegin = u2SmallestVirtualDelay -17;
11083 else
11084 u2DQOEN_DelayBegin =0;
11085
11086 u2DQEN_DelayEnd = u2DQOEN_DelayBegin +25;
11087
11088 #else // reduce range to speed up
11089 if(u2SmallestVirtualDelay >= 7)
11090 u2DQOEN_DelayBegin = u2SmallestVirtualDelay -7;
11091 else
11092 u2DQOEN_DelayBegin =0;
11093
11094 u2DQEN_DelayEnd = u2DQOEN_DelayBegin +10;
11095 #endif
11096
11097 for (u2Delay = u2DQOEN_DelayBegin; u2Delay <= u2DQEN_DelayEnd; u2Delay++)
11098 {
11099 ucdq_current_ui_large= (u2Delay >>3);
11100 ucdq_current_ui_small = u2Delay & 0x7;
11101 //mcSHOW_DBG_MSG(("\nucdq_oen_ui %d %d ", ucdq_oen_ui_large, ucdq_oen_ui_small));
11102
11103 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), \
11104 P_Fld(ucdq_current_ui_large, SHURK0_SELPH_DQ0_TXDLY_OEN_DQ0) | \
11105 P_Fld(ucdq_current_ui_large, SHURK0_SELPH_DQ0_TXDLY_OEN_DQ1) );
11106
11107 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), \
11108 P_Fld(ucdq_current_ui_large, SHURK0_SELPH_DQ1_TXDLY_OEN_DQM0) | \
11109 P_Fld(ucdq_current_ui_large, SHURK0_SELPH_DQ1_TXDLY_OEN_DQM1));
11110
11111 // DLY_DQ[2:0]
11112 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), \
11113 P_Fld(ucdq_current_ui_small, SHURK0_SELPH_DQ2_DLY_OEN_DQ0) | \
11114 P_Fld(ucdq_current_ui_small, SHURK0_SELPH_DQ2_DLY_OEN_DQ1) );
11115
11116 // DLY_DQM[2:0]
11117 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), \
11118 P_Fld(ucdq_current_ui_small, SHURK0_SELPH_DQ3_DLY_OEN_DQM0) | \
11119 P_Fld(ucdq_current_ui_small, SHURK0_SELPH_DQ3_DLY_OEN_DQM1));
11120
11121 #if TX_OE_PATTERN_USE_TA2
11122 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_AUDIO_PATTERN);
11123 #else
11124 u4err_value= DramcDmaEngine((DRAMC_CTX_T *)p, 0x50000000, 0x60000000, 0xff00, 8, DMA_CHECK_DATA_ACCESS_AND_COMPARE, p->support_channel_num);
11125 #endif
11126
11127 // 3
11128 for(u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
11129 {
11130 if (((u4err_value >> (u1ByteIdx<<3)) & 0xff) == 0)
11131 {
11132 if(ucBegin[u1ByteIdx]==0)
11133 ucBegin[u1ByteIdx]=1;
11134
11135 ucEnd[u1ByteIdx] = u2Delay;
11136 }
11137 }
11138
11139#ifdef ETT_PRINT_FORMAT
11140 mcSHOW_DBG_MSG(("%d, 0x%X, End_B0=%d End_B1=%d\n", u2Delay, u4err_value, ucEnd[0], ucEnd[1]));
11141#else
11142 mcSHOW_DBG_MSG(("TAP=%2d, err_value=0x%8x, End_B0=%d End_B1=%d\n", u2Delay, u4err_value, ucEnd[0], ucEnd[1]));
11143#endif
11144 mcFPRINTF((fp_A60501, "TAP=%2d, err_value=0x%8x, End_B0=%d End_B1=%d\n", u2Delay, u4err_value, ucEnd[0], ucEnd[1]));
11145
11146 if(((u4err_value & 0xffff) !=0) && ucBegin[0]==1 && ucBegin[1]==1)
11147 break; // early break;
11148 }
11149
11150 #if TX_OE_PATTERN_USE_TA2
11151 DramcEngine2End(p);
11152 #endif
11153
11154 // 4
11155 for(u1ByteIdx=0; u1ByteIdx<DQS_NUMBER_LP4; u1ByteIdx++)
11156 {
11157 if (ucEnd[u1ByteIdx] == 0xff)
11158 {
11159 ucbest_step[u1ByteIdx] = u2SmallestVirtualDelay - TX_DQ_OE_SHIFT_LP4; //bakcup original delay, will be uesed if Pass window not found.
11160 mcSHOW_ERR_MSG(("Byte %d no TX OE taps pass, calibration fail!\n", u1ByteIdx));
11161 }
11162 else // window is larger htan 3
11163 {
11164 ucbest_step[u1ByteIdx] = ucEnd[u1ByteIdx] - 3;
11165 }
11166 mcSHOW_DBG_MSG(("Byte%d end_step=%d best_step=%d\n", u1ByteIdx, ucEnd[u1ByteIdx], ucbest_step[u1ByteIdx]));
11167 mcFPRINTF((fp_A60501, "Byte%d first_step=%d best_step=%d\n", u1ByteIdx, ucEnd[u1ByteIdx], ucbest_step[u1ByteIdx]));
11168
11169 ucdq_oen_ui_large[u1ByteIdx]= (ucbest_step[u1ByteIdx] >>3);
11170 ucdq_oen_ui_small[u1ByteIdx] = ucbest_step[u1ByteIdx] & 0x7;
11171 }
11172 }
11173
11174 #ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
11175 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
11176 #endif
11177
11178 for(u1ByteIdx=0; u1ByteIdx<DQS_NUMBER_LP4; u1ByteIdx++)
11179 {
11180 mcSHOW_DBG_MSG(("Byte%d TX OE(2T, 0.5T) = (%d, %d)\n", u1ByteIdx, ucdq_oen_ui_large[u1ByteIdx], ucdq_oen_ui_small[u1ByteIdx]));
11181 }
11182 mcSHOW_DBG_MSG(("\n\n"));
11183
11184 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), \
11185 P_Fld(ucdq_oen_ui_large[0], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ0) | \
11186 P_Fld(ucdq_oen_ui_large[1], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ1));
11187
11188 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), \
11189 P_Fld(ucdq_oen_ui_large[0], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM0) | \
11190 P_Fld(ucdq_oen_ui_large[1], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM1));
11191 // DLY_DQ[2:0]
11192 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), \
11193 P_Fld(ucdq_oen_ui_small[0], SHURK0_SELPH_DQ2_DLY_OEN_DQ0) | \
11194 P_Fld(ucdq_oen_ui_small[1], SHURK0_SELPH_DQ2_DLY_OEN_DQ1) );
11195 // DLY_DQM[2:0]
11196 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), \
11197 P_Fld(ucdq_oen_ui_small[0], SHURK0_SELPH_DQ3_DLY_OEN_DQM0) | \
11198 P_Fld(ucdq_oen_ui_small[1], SHURK0_SELPH_DQ3_DLY_OEN_DQM1));
11199
11200 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION)
11201 if(p->femmc_Ready==0)
11202 {
11203 for(u1ByteIdx=0; u1ByteIdx<DQS_NUMBER_LP4; u1ByteIdx++)
11204 {
11205 p->pSavetimeData->u1TX_OE_DQ_MCK[p->channel][p->rank][u1ByteIdx] = ucdq_oen_ui_large[u1ByteIdx];
11206 p->pSavetimeData->u1TX_OE_DQ_UI[p->channel][p->rank][u1ByteIdx] = ucdq_oen_ui_small[u1ByteIdx];
11207 }
11208 }
11209 #endif
11210
11211}
11212#endif
11213
11214
11215
11216//=============================================================
11217///// DramC TX perbi calibration ----------Begin--------------
11218//=============================================================
11219//-------------------------------------------------------------------------
11220/** DramcTxWindowPerbitCal (v2)
11221 * TX DQS per bit SW calibration.
11222 * @param p Pointer of context created by DramcCtxCreate.
11223 * @param apply (U8): 0 don't apply the register we set 1 apply the register we set ,default don't apply.
11224 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
11225 */
11226//-------------------------------------------------------------------------
11227#if (SW_CHANGE_FOR_SIMULATION ||FOR_DV_SIMULATION_USED)
11228#define TX_VREF_RANGE_BEGIN 0
11229#define TX_VREF_RANGE_END 2 // binary 110010
11230#define TX_VREF_RANGE_STEP 2
11231#else
11232#define TX_VREF_RANGE_BEGIN 16
11233#define TX_VREF_RANGE_END 50 // binary 110010
11234#define TX_VREF_RANGE_STEP 2
11235#endif
11236
11237#define TX_DQ_UI_TO_PI_TAP 64 // 1 PI = tCK/64, total 128 PI, 1UI = 32 PI
11238#define LP4_TX_VREF_DATA_NUM 50
11239#define LP4_TX_VREF_PASS_CONDITION 0
11240#define LP4_TX_VREF_BOUNDARY_NOT_READY 0xff
11241
11242typedef struct _PASS_WIN_DATA_BY_VREF_T
11243{
11244 U16 u2VrefUsed;
11245 U16 u2WinSum_byVref;
11246 U16 u2MinWinSize_byVref;
11247} PASS_WIN_DATA_BY_VREF_T;
11248
11249U16 u2TX_DQ_PreCal_LP4[DQS_NUMBER]; // LP4 only
11250
11251
11252void TxWinTransferDelayToUIPI(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U16 uiDelay, U8 u1AdjustPIToCenter, U8* pu1UILarge_DQ, U8* pu1UISmall_DQ, U8* pu1PI, U8* pu1UILarge_DQOE, U8* pu1UISmall_DQOE)
11253{
11254 U8 u1Small_ui_to_large, u1PI, u164PIto1UI;
11255 U16 u2TmpValue;
11256
11257#if (fcFOR_PINMUX == fcLaurel) //LP2 is full rate
11258 //in LP4, 8 small UI = 1 large UI
11259 //in LP3, 4 small UI = 1 large UI
11260 if(u1IsLP4Family(p->dram_type))
11261 {
11262 u1Small_ui_to_large = 3;
11263 u164PIto1UI = 1;
11264 }
11265 else //LPDDR3
11266 {
11267 u1Small_ui_to_large = 2;
11268 u164PIto1UI = 0;
11269 }
11270#endif
11271
11272 if(pu1PI != NULL)
11273 {
11274 #if 0
11275 u1PI = uiDelay% TX_DQ_UI_TO_PI_TAP;
11276 #else
11277 u1PI = uiDelay & (TX_DQ_UI_TO_PI_TAP-1);
11278 #endif
11279
11280 *pu1PI =u1PI;
11281 }
11282
11283 u2TmpValue = (uiDelay /TX_DQ_UI_TO_PI_TAP)<<u164PIto1UI;
11284
11285 if(u1AdjustPIToCenter && (pu1PI!=NULL))
11286 {
11287 if(u1PI<10)
11288 {
11289 u1PI += (TX_DQ_UI_TO_PI_TAP)>>1;
11290 u2TmpValue --;
11291 }
11292 else if(u1PI>TX_DQ_UI_TO_PI_TAP-10)
11293 {
11294 u1PI -= (TX_DQ_UI_TO_PI_TAP)>>1;
11295 u2TmpValue ++;
11296 }
11297
11298 *pu1PI =u1PI;
11299 }
11300
11301 #if 0
11302 *pu1UISmall_DQ = u2TmpValue % u1Small_ui_to_large;
11303 *pu1UILarge_DQ = u2TmpValue / u1Small_ui_to_large;
11304 #else
11305 *pu1UISmall_DQ = u2TmpValue - ((u2TmpValue >> u1Small_ui_to_large) <<u1Small_ui_to_large);
11306 *pu1UILarge_DQ = (u2TmpValue >> u1Small_ui_to_large);
11307 #endif
11308
11309 // calculate DQ OE according to DQ UI
11310 if(u1IsLP4Family(p->dram_type))
11311 {
11312 u2TmpValue -= TX_DQ_OE_SHIFT_LP4;
11313
11314 if(((u1MR03Value[p->dram_fsp]&0x80)>>7)==1) //if WDBI is on, OE_DLY don't need to shift 1 MCK with DLY
11315 {
11316 u2TmpValue += 8;
11317 }
11318
11319 }
11320 else
11321 {
11322 u2TmpValue -= TX_DQ_OE_SHIFT_LP3;
11323 }
11324
11325 *pu1UISmall_DQOE = u2TmpValue - ((u2TmpValue >> u1Small_ui_to_large) <<u1Small_ui_to_large);
11326 *pu1UILarge_DQOE = (u2TmpValue >> u1Small_ui_to_large);
11327}
11328
11329static void TxPrintWidnowInfo(DRAMC_CTX_T *p, PASS_WIN_DATA_T WinPerBitData[])
11330{
11331 U8 u1BitIdx;
11332
11333 for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++)
11334 {
11335 #ifdef ETT_PRINT_FORMAT
11336 mcSHOW_DBG_MSG(("TX Bit%d (%d~%d) %d %d, Bit%d (%d~%d) %d %d,", \
11337 u1BitIdx, WinPerBitData[u1BitIdx].first_pass, WinPerBitData[u1BitIdx].last_pass, WinPerBitData[u1BitIdx].win_size, WinPerBitData[u1BitIdx].win_center, \
11338 u1BitIdx+8, WinPerBitData[u1BitIdx+8].first_pass, WinPerBitData[u1BitIdx+8].last_pass, WinPerBitData[u1BitIdx+8].win_size, WinPerBitData[u1BitIdx+8].win_center));
11339 #else
11340 mcSHOW_DBG_MSG(("TX Bit%2d (%2d~%2d) %2d %2d, Bit%2d (%2d~%2d) %2d %2d,", \
11341 u1BitIdx, WinPerBitData[u1BitIdx].first_pass, WinPerBitData[u1BitIdx].last_pass, WinPerBitData[u1BitIdx].win_size, WinPerBitData[u1BitIdx].win_center, \
11342 u1BitIdx+8, WinPerBitData[u1BitIdx+8].first_pass, WinPerBitData[u1BitIdx+8].last_pass, WinPerBitData[u1BitIdx+8].win_size, WinPerBitData[u1BitIdx+8].win_center));
11343 #endif
11344 mcFPRINTF((fp_A60501,"TX Bit%2d (%2d~%2d) %2d %2d, Bit%2d (%2d~%2d) %2d %2d,", \
11345 u1BitIdx, WinPerBitData[u1BitIdx].first_pass, WinPerBitData[u1BitIdx].last_pass, WinPerBitData[u1BitIdx].win_size, WinPerBitData[u1BitIdx].win_center, \
11346 u1BitIdx+8, WinPerBitData[u1BitIdx+8].first_pass, WinPerBitData[u1BitIdx+8].last_pass, WinPerBitData[u1BitIdx+8].win_size, WinPerBitData[u1BitIdx+8].win_center));
11347
11348 if(u1IsLP4Family(p->dram_type))
11349 {
11350 mcSHOW_DBG_MSG(("\n"));
11351 mcFPRINTF((fp_A60501,"\n"));
11352 }
11353 #if ENABLE_LP3_SW
11354 else //LPDDR3
11355 {
11356 #ifdef ETT_PRINT_FORMAT
11357 mcSHOW_DBG_MSG((" %d (%d~%d) %d %d, %d (%d~%d) %d %d\n", \
11358 u1BitIdx+16, WinPerBitData[u1BitIdx+16].first_pass, WinPerBitData[u1BitIdx+16].last_pass, WinPerBitData[u1BitIdx+16].win_size, WinPerBitData[u1BitIdx+16].win_center, \
11359 u1BitIdx+24, WinPerBitData[u1BitIdx+24].first_pass, WinPerBitData[u1BitIdx+24].last_pass, WinPerBitData[u1BitIdx+24].win_size, WinPerBitData[u1BitIdx+24].win_center ));
11360 #else
11361 mcSHOW_DBG_MSG((" %2d (%2d~%2d) %2d %2d, %2d (%2d~%2d) %2d %2d\n", \
11362 u1BitIdx+16, WinPerBitData[u1BitIdx+16].first_pass, WinPerBitData[u1BitIdx+16].last_pass, WinPerBitData[u1BitIdx+16].win_size, WinPerBitData[u1BitIdx+16].win_center, \
11363 u1BitIdx+24, WinPerBitData[u1BitIdx+24].first_pass, WinPerBitData[u1BitIdx+24].last_pass, WinPerBitData[u1BitIdx+24].win_size, WinPerBitData[u1BitIdx+24].win_center ));
11364 #endif
11365
11366 mcFPRINTF((fp_A60501," %2d (%2d~%2d) %2d %2d, %2d (%2d~%2d) %2d %2d\n", \
11367 u1BitIdx+16, WinPerBitData[u1BitIdx+16].first_pass, WinPerBitData[u1BitIdx+16].last_pass, WinPerBitData[u1BitIdx+16].win_size, WinPerBitData[u1BitIdx+16].win_center, \
11368 u1BitIdx+24, WinPerBitData[u1BitIdx+24].first_pass, WinPerBitData[u1BitIdx+24].last_pass, WinPerBitData[u1BitIdx+24].win_size, WinPerBitData[u1BitIdx+24].win_center ));
11369 }
11370 #endif//ENABLE_LP3_SW
11371 }
11372 mcSHOW_DBG_MSG(("\n"));
11373 mcFPRINTF((fp_A60501,"\n"));
11374}
11375
11376
11377static void TXPerbitCalibrationInit(DRAMC_CTX_T *p, U8 calType)
11378{
11379 //Set TX delay chain to 0
11380 if(u1IsLP4Family(p->dram_type) && (calType !=TX_DQ_DQS_MOVE_DQM_ONLY))
11381 {
11382 #if 1
11383 #if PINMUX_AUTO_TEST_PER_BIT_TX
11384 if(gTX_check_per_bit_flag == 1)
11385 {
11386 //not reset delay cell
11387 }
11388 else
11389 #endif
11390 {
11391 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), 0);
11392 vIO32Write4B(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ0), 0);
11393 }
11394 #else
11395 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0), P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0)
11396 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0)
11397 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0)
11398 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0)
11399 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0)
11400 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0)
11401 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0)
11402 | P_Fld(0x0, SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0));
11403 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ0), P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ7_DLY_B1)
11404 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ6_DLY_B1)
11405 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ5_DLY_B1)
11406 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ4_DLY_B1)
11407 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ3_DLY_B1)
11408 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ2_DLY_B1)
11409 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ1_DLY_B1)
11410 | P_Fld(0x0, SHU1_R0_B1_DQ0_RK0_TX_ARDQ0_DLY_B1));
11411 #endif
11412 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ1), 0x0, SHU1_R0_B0_DQ1_RK0_TX_ARDQM0_DLY_B0);
11413 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ1), 0x0, SHU1_R0_B1_DQ1_RK0_TX_ARDQM0_DLY_B1);
11414 }
11415
11416
11417 //Use HW TX tracking value
11418 //R_DMARPIDQ_SW :drphy_conf (0x170[7])(default set 1)
11419 // 0: DQS2DQ PI setting controlled by HW
11420 //R_DMARUIDQ_SW : Dramc_conf(0x156[15])(default set 1)
11421 // 0: DQS2DQ UI setting controlled by HW
11422 ///TODO: need backup original setting?
11423 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 1, MISC_CTRL1_R_DMARPIDQ_SW);
11424 //vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQSOSCR), 1, DQSOSCR_ARUIDQ_SW);
11425
11426}
11427
11428#define TX_TDQS2DQ_PRE_CAL 1
11429#if TX_TDQS2DQ_PRE_CAL
11430U16 u2DQS2DQ_Pre_Cal[CHANNEL_NUM][RANK_MAX]={0};
11431#endif
11432
11433static void TXScanRange_PI(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U16 *pu2Begin, U16 *pu2End)
11434{
11435 U8 u1MCK2UI, u1ByteIdx, u1UI2PI;
11436 U32 u4RegValue_TXDLY, u4RegValue_dly;
11437 U8 ucdq_ui_large_bak[DQS_NUMBER], ucdq_ui_small_bak[DQS_NUMBER];
11438 U16 u2TempVirtualDelay, u2SmallestVirtualDelay=0xffff;
11439 U16 u2DQDelayBegin=0, u2DQDelayEnd=0, u2TX_DQ_PreCal_LP4_Samll;
11440
11441 u4RegValue_TXDLY= u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS0));
11442 u4RegValue_dly= u4IO32Read4B(DRAMC_REG_ADDR(DRAMC_REG_SHU_SELPH_DQS1));
11443
11444#if (fcFOR_PINMUX == fcLaurel) //LP2 is full rate
11445 if(u1IsLP4Family(p->dram_type))
11446 {
11447 u1MCK2UI= 3;
11448 u1UI2PI = 5;
11449 }
11450 else
11451 {
11452 u1MCK2UI =2;
11453 u1UI2PI = 6;
11454 }
11455#endif
11456
11457 // find smallest DQS delay
11458 for(u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
11459 {
11460 ucdq_ui_large_bak[u1ByteIdx] = (u4RegValue_TXDLY >> (u1ByteIdx<<2)) &0x7;// MCK
11461 ucdq_ui_small_bak[u1ByteIdx] = (u4RegValue_dly >> (u1ByteIdx<<2)) &0x7;// UI
11462 //wrlevel_dqs_final_delay[u1ByteIdx] ==> PI
11463
11464 //LP4 : Virtual Delay = 256 * MCK + 32*UI + PI;
11465 //LP3 : Virtual Delay = 128 * MCK + 32*UI + PI;
11466 u2TempVirtualDelay = (((ucdq_ui_large_bak[u1ByteIdx] <<u1MCK2UI) + ucdq_ui_small_bak[u1ByteIdx])<<u1UI2PI) + wrlevel_dqs_final_delay[u1ByteIdx];
11467 if(u2TempVirtualDelay < u2SmallestVirtualDelay)
11468 {
11469 u2SmallestVirtualDelay = u2TempVirtualDelay;
11470 }
11471
11472 /*mcSHOW_DBG_MSG2(("Original DQS_B%d VirtualDelay %d = (%d %d %d)\n", u1ByteIdx, u2TempVirtualDelay,\
11473 * ucdq_ui_large_bak[u1ByteIdx], ucdq_ui_small_bak[u1ByteIdx], wrlevel_dqs_final_delay[u1ByteIdx]));
11474 */
11475 }
11476
11477 if(u1IsLP4Family(p->dram_type))
11478 {
11479 // (1)LP4 will calibration DQM at the first time, K full range, and then rember the TX position.
11480 // (2)The sencod time will calibrate DQ+Vref, reference TX postion of (1)
11481 if(calType==TX_DQ_DQS_MOVE_DQ_DQM)
11482 {
11483 u2DQDelayBegin = u2SmallestVirtualDelay;
11484
11485 #if TX_TDQS2DQ_PRE_CAL
11486 if(p->frequency == LP4_LOWEST_FREQ)
11487 {
11488 // Save first freqency DQS2DQ, but skip MDL_UESED. Therefore, clean this value.
11489 u2DQS2DQ_Pre_Cal[p->channel][p->rank]=0;
11490 }
11491 else if(u2DQS2DQ_Pre_Cal[p->channel][p->rank]> 0)
11492 {
11493 mcSHOW_DBG_MSG(("TX_TDQS2DQ_PRE_CAL : change DQ begin %d -->", u2DQDelayBegin));
11494 u2DQDelayBegin += (u2DQS2DQ_Pre_Cal[p->channel][p->rank]* p->frequency /1000);
11495 mcSHOW_DBG_MSG(("%d\n", u2DQDelayBegin));
11496 }
11497 #endif
11498 u2DQDelayEnd = u2DQDelayBegin + 256;
11499 }
11500 else //if(calType==TX_DQ_DQS_MOVE_DQ_ONLY)
11501 {
11502 if(u2TX_DQ_PreCal_LP4[0] < u2TX_DQ_PreCal_LP4[1])
11503 u2TX_DQ_PreCal_LP4_Samll = u2TX_DQ_PreCal_LP4[0];
11504 else
11505 u2TX_DQ_PreCal_LP4_Samll = u2TX_DQ_PreCal_LP4[1];
11506
11507 if(u2TX_DQ_PreCal_LP4_Samll >24)
11508 u2DQDelayBegin = u2TX_DQ_PreCal_LP4_Samll-24;
11509 else
11510 u2DQDelayBegin =0;
11511
11512 #if TX_K_DQM_WITH_WDBI
11513 if(calType==TX_DQ_DQS_MOVE_DQM_ONLY)
11514 {
11515 // DBI on, calibration range -1MCK
11516 u2DQDelayBegin -=(1<<(u1MCK2UI+5));
11517 }
11518 #endif
11519 u2DQDelayEnd = u2DQDelayBegin + 64;
11520 }
11521
11522 }
11523 else
11524 {
11525 u2DQDelayBegin = (u2SmallestVirtualDelay > 16)? (u2SmallestVirtualDelay - 16) : 0;
11526 u2DQDelayEnd = u2SmallestVirtualDelay + 96;
11527 }
11528
11529 *pu2Begin = u2DQDelayBegin;
11530 *pu2End = u2DQDelayEnd;
11531
11532 #if 0//TX_TDQS2DQ_PRE_CAL
11533 mcSHOW_DBG_MSG(("TXScanRange_PI %d~%d\n", u2DQDelayBegin,u2DQDelayEnd));
11534 #endif
11535}
11536
11537
11538static void TXScanRange_Vref(DRAMC_CTX_T *p, U8 u1VrefScanEnable, U16* pu2Range, U16 *pu2Begin, U16 *pu2End, U16 *pu2Setp)
11539{
11540 U16 u2VrefBegin, u2VrefEnd;
11541 U16 u2VrefRange=!p->odt_onoff;
11542
11543 if(u1VrefScanEnable==ENABLE_VREF_SCAN)
11544 {
11545 #if (SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL)
11546 if(p->femmc_Ready==1)
11547 {
11548 // if fast K, use TX Vref that saved.
11549 u2VrefBegin = p->pSavetimeData->u1TxWindowPerbitVref_Save[p->channel][p->rank];
11550 u2VrefEnd = u2VrefBegin+1;
11551 }
11552 else
11553 #endif
11554 {
11555 if (p->odt_onoff == ODT_OFF)
11556 {
11557 if (p->dram_type == TYPE_LPDDR4)
11558 {
11559 //range 1
11560 u2VrefBegin = 13 - 5; // 300/1100(VDDQ) = 27.2%
11561 u2VrefEnd = 13 + 5;
11562 }
11563 else
11564 {
11565 //range 1
11566 u2VrefBegin = 27 - 5; // 290/600(VDDQ)=48.3%
11567 u2VrefEnd = 27 + 5;
11568 }
11569 }
11570 else
11571 {
11572 if (p->dram_type == TYPE_LPDDR4)
11573 {
11574 // range 0
11575 u2VrefBegin = 12;
11576 }
11577 else
11578 {
11579 // range 0
11580 u2VrefBegin = TX_VREF_RANGE_BEGIN;
11581 }
11582 u2VrefEnd = TX_VREF_RANGE_END;
11583 }
11584 }
11585 }
11586 else //LPDDR3, the for loop will only excute u2VrefLevel=TX_VREF_RANGE_END/2.
11587 {
11588 u2VrefBegin = 0;
11589 u2VrefEnd = 0;
11590 }
11591
11592 *pu2Range = u2VrefRange;
11593 *pu2Begin = u2VrefBegin;
11594 *pu2End = u2VrefEnd;
11595 *pu2Setp = TX_VREF_RANGE_STEP;
11596
11597}
11598
11599static U16 TxChooseVref(DRAMC_CTX_T *p, PASS_WIN_DATA_BY_VREF_T pVrefInfo[], U8 u1VrefNum)
11600{
11601 U8 u1VrefIdx;
11602 U16 u2MaxMinSize=0, u2MaxWinSum=0;
11603 U16 u2FinalVref=0;
11604
11605#if LP4_TX_VREF_PASS_CONDITION
11606 U8 u1TempPassNum=0;
11607 U8 u1VrefPassBegin=LP4_TX_VREF_BOUNDARY_NOT_READY;
11608 U8 u1VrefPassEnd=LP4_TX_VREF_BOUNDARY_NOT_READY;
11609 U8 u1MaxVerfPassNum=0;
11610 U8 u1VrefPassBegin_Final=LP4_TX_VREF_BOUNDARY_NOT_READY;
11611 U8 u1VrefPassEnd_Final=LP4_TX_VREF_BOUNDARY_NOT_READY;
11612#endif
11613
11614 for(u1VrefIdx=0; u1VrefIdx < u1VrefNum; u1VrefIdx++)
11615 {
11616 mcSHOW_DBG_MSG(("Vref=%d, minWin=%d, winSum=%d\n",
11617 pVrefInfo[u1VrefIdx].u2VrefUsed,
11618 pVrefInfo[u1VrefIdx].u2MinWinSize_byVref,
11619 pVrefInfo[u1VrefIdx].u2WinSum_byVref));
11620
11621 #if LP4_TX_VREF_PASS_CONDITION
11622 if((pVrefInfo[u1VrefIdx].u2MinWinSize_byVref > LP4_TX_VREF_PASS_CONDITION))
11623 {
11624 if(u1VrefPassBegin ==LP4_TX_VREF_BOUNDARY_NOT_READY)
11625 {
11626 u1VrefPassBegin = pVrefInfo[u1VrefIdx].u2VrefUsed;
11627 u1TempPassNum =1;
11628 }
11629 else
11630 u1TempPassNum ++;
11631
11632 if(u1VrefIdx==u1VrefNum-1)
11633 {
11634 u1VrefPassEnd = pVrefInfo[u1VrefIdx].u2VrefUsed;
11635 if(u1TempPassNum > u1MaxVerfPassNum)
11636 {
11637 u1VrefPassBegin_Final= u1VrefPassBegin;
11638 u1VrefPassEnd_Final = u1VrefPassEnd;
11639 u1MaxVerfPassNum= u1TempPassNum;
11640 }
11641 }
11642 }
11643 else
11644 {
11645 if((u1VrefPassBegin != LP4_TX_VREF_BOUNDARY_NOT_READY) && (u1VrefPassEnd==LP4_TX_VREF_BOUNDARY_NOT_READY))
11646 {
11647 u1VrefPassEnd = pVrefInfo[u1VrefIdx].u2VrefUsed-TX_VREF_RANGE_STEP;
11648 if(u1TempPassNum > u1MaxVerfPassNum)
11649 {
11650 u1VrefPassBegin_Final= u1VrefPassBegin;
11651 u1VrefPassEnd_Final = u1VrefPassEnd;
11652 u1MaxVerfPassNum= u1TempPassNum;
11653 }
11654 u1VrefPassBegin=0xff;
11655 u1VrefPassEnd=0xff;
11656 u1TempPassNum =0;
11657 }
11658 }
11659 #endif
11660 }
11661
11662 #if LP4_TX_VREF_PASS_CONDITION
11663 //if((u1VrefPassBegin_Final !=LP4_TX_VREF_BOUNDARY_NOT_READY) && (u1VrefPassEnd_Final!=LP4_TX_VREF_BOUNDARY_NOT_READY))
11664 if(u1MaxVerfPassNum>0)
11665 {
11666 // vref pass window found
11667 u2FinalVref = (u1VrefPassBegin_Final + u1VrefPassEnd_Final) >>1;
11668 mcSHOW_DBG_MSG(("[TxChooseVref] Window > %d, Vref (%d~%d), Final Vref %d\n",LP4_TX_VREF_PASS_CONDITION, u1VrefPassBegin_Final, u1VrefPassEnd_Final, u2FinalVref));
11669 }
11670 else
11671 #endif
11672 {
11673 // not vref found
11674 for(u1VrefIdx=0; u1VrefIdx < u1VrefNum; u1VrefIdx++)
11675 {
11676 if((pVrefInfo[u1VrefIdx].u2MinWinSize_byVref > u2MaxMinSize) ||
11677 ((pVrefInfo[u1VrefIdx].u2MinWinSize_byVref == u2MaxMinSize) && (pVrefInfo[u1VrefIdx].u2WinSum_byVref > u2MaxWinSum)))
11678 {
11679 u2MaxMinSize = pVrefInfo[u1VrefIdx].u2MinWinSize_byVref;
11680 u2MaxWinSum = pVrefInfo[u1VrefIdx].u2WinSum_byVref;
11681 u2FinalVref = pVrefInfo[u1VrefIdx].u2VrefUsed;
11682 }
11683 }
11684
11685 mcSHOW_DBG_MSG(("[TxChooseVref] Min win %d, Win sum %d, Final Vref %d\n", u2MaxMinSize, u2MaxWinSum, u2FinalVref));
11686 }
11687
11688 return u2FinalVref;
11689}
11690
11691
11692void DramcTXSetVref(DRAMC_CTX_T *p, U8 u1VrefRange, U8 u1VrefValue)
11693{
11694 U8 u1TempOPValue = ((u1VrefValue & 0x3f) | (u1VrefRange<<6));
11695
11696 u1MR14Value[p->channel][p->rank][p->dram_fsp] = u1TempOPValue;
11697 DramcModeRegWriteByRank(p, p->rank, 14, u1TempOPValue);
11698}
11699
11700
11701static void TXSetFinalVref(DRAMC_CTX_T *p, U16 u2FinalRange, U16 u2FinalVref)
11702{
11703 // SET tx Vref (DQ) = u2FinalVref, LP3 no need to set this.
11704 if(!u1IsLP4Family(p->dram_type))
11705 return;
11706
11707 DramcTXSetVref(p, u2FinalRange, u2FinalVref);
11708
11709#ifdef FOR_HQA_TEST_USED
11710 gFinalTXVrefDQ[p->channel][p->rank] = (U8) u2FinalVref;
11711#endif
11712
11713#if VENDER_JV_LOG
11714 mcSHOW_DBG_MSG5(("\nFinal TX Range %d Vref %d\n\n", u2FinalRange, u2FinalVref));
11715#else
11716 mcSHOW_DBG_MSG(("\nFinal TX Range %d Vref %d\n\n", u2FinalRange, u2FinalVref));
11717 mcFPRINTF((fp_A60501, "\nFinal TX Range %d Vref %d\n\n", u2FinalRange, u2FinalVref));
11718#endif
11719}
11720
11721
11722#if ENABLE_TX_TRACKING
11723static void TXUpdateTXTracking(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U8 ucdq_pi[], U8 ucdqm_pi[])
11724{
11725 if(u1IsLP4Family(p->dram_type) && (calType == TX_DQ_DQS_MOVE_DQ_ONLY ||calType ==TX_DQ_DQS_MOVE_DQM_ONLY))
11726 {
11727 //make a copy to dramc reg for TX DQ tracking used
11728 if(calType ==TX_DQ_DQS_MOVE_DQ_ONLY)
11729 {
11730 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI),
11731 P_Fld(ucdq_pi[0], SHU1RK0_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_pi[1], SHU1RK0_PI_RK0_ARPI_DQ_B1));
11732
11733 // Source DQ
11734 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQS2DQ_CAL1),
11735 P_Fld(ucdq_pi[1], SHU1RK0_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ1) |
11736 P_Fld(ucdq_pi[0], SHU1RK0_DQS2DQ_CAL1_BOOT_ORIG_UI_RK0_DQ0));
11737 // Target DQ
11738 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQS2DQ_CAL2),
11739 P_Fld(ucdq_pi[1], SHU1RK0_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ1) |
11740 P_Fld(ucdq_pi[0], SHU1RK0_DQS2DQ_CAL2_BOOT_TARG_UI_RK0_DQ0));
11741 }
11742
11743 //if(calType ==TX_DQ_DQS_MOVE_DQM_ONLY || (calType ==TX_DQ_DQS_MOVE_DQ_ONLY))
11744 {
11745 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_PI),
11746 P_Fld(ucdqm_pi[0], SHU1RK0_PI_RK0_ARPI_DQM_B0) | P_Fld(ucdqm_pi[1], SHU1RK0_PI_RK0_ARPI_DQM_B1));
11747
11748 // Target DQM
11749 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHU1RK0_DQS2DQ_CAL5),
11750 P_Fld(ucdqm_pi[1], SHU1RK0_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM1) |
11751 P_Fld(ucdqm_pi[0], SHU1RK0_DQS2DQ_CAL5_BOOT_TARG_UI_RK0_DQM0));
11752 }
11753 }
11754
11755
11756#if 0// for LP3 , TX tracking will be disable, don't need to set DQ delay in DramC.
11757 ///TODO: check LP3 byte mapping of dramC
11758 vIO32WriteFldMulti(DRAMC_REG_SHU1RK0_PI+(CHANNEL_A<< POS_BANK_NUM), \
11759 P_Fld(ucdq_final_pi[0], SHU1RK0_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_final_pi[1], SHU1RK0_PI_RK0_ARPI_DQ_B1));
11760
11761 vIO32WriteFldMulti(DRAMC_REG_SHU1RK0_PI+SHIFT_TO_CHB_ADDR, \
11762 P_Fld(ucdq_final_pi[2], SHU1RK0_PI_RK0_ARPI_DQ_B0) | P_Fld(ucdq_final_pi[3], SHU1RK0_PI_RK0_ARPI_DQ_B1));
11763#endif
11764
11765}
11766#endif //End ENABLE_TX_TRACKING
11767
11768
11769static 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[])
11770{
11771 if(u1UpdateRegUI)
11772 {
11773 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), \
11774 P_Fld(ucdq_ui_large[0], SHURK0_SELPH_DQ0_TXDLY_DQ0) |
11775 P_Fld(ucdq_ui_large[1], SHURK0_SELPH_DQ0_TXDLY_DQ1) |
11776 P_Fld(ucdq_ui_large[2], SHURK0_SELPH_DQ0_TXDLY_DQ2) |
11777 P_Fld(ucdq_ui_large[3], SHURK0_SELPH_DQ0_TXDLY_DQ3) |
11778 P_Fld(ucdq_oen_ui_large[0], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ0) |
11779 P_Fld(ucdq_oen_ui_large[1], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ1) |
11780 P_Fld(ucdq_oen_ui_large[2], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ2) |
11781 P_Fld(ucdq_oen_ui_large[3], SHURK0_SELPH_DQ0_TXDLY_OEN_DQ3));
11782
11783 // DLY_DQ[2:0]
11784 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), \
11785 P_Fld(ucdq_ui_small[0], SHURK0_SELPH_DQ2_DLY_DQ0) |
11786 P_Fld(ucdq_ui_small[1], SHURK0_SELPH_DQ2_DLY_DQ1) |
11787 P_Fld(ucdq_ui_small[2], SHURK0_SELPH_DQ2_DLY_DQ2) |
11788 P_Fld(ucdq_ui_small[3], SHURK0_SELPH_DQ2_DLY_DQ3) |
11789 P_Fld(ucdq_oen_ui_small[0], SHURK0_SELPH_DQ2_DLY_OEN_DQ0) |
11790 P_Fld(ucdq_oen_ui_small[1], SHURK0_SELPH_DQ2_DLY_OEN_DQ1) |
11791 P_Fld(ucdq_oen_ui_small[2], SHURK0_SELPH_DQ2_DLY_OEN_DQ2) |
11792 P_Fld(ucdq_oen_ui_small[3], SHURK0_SELPH_DQ2_DLY_OEN_DQ3));
11793 }
11794
11795 if(u1IsLP4Family(p->dram_type))
11796 {
11797 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdql_pi[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
11798 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), ucdql_pi[1], SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1);
11799 }
11800 #if ENABLE_LP3_SW
11801 else
11802 {
11803 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdql_pi[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
11804 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdql_pi[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
11805 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdql_pi[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
11806 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdql_pi[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
11807 }
11808 #endif
11809}
11810
11811
11812static 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[])
11813{
11814 if(u1UpdateRegUI)
11815 {
11816 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1),
11817 P_Fld(ucdqm_ui_large[0], SHURK0_SELPH_DQ1_TXDLY_DQM0) |
11818 P_Fld(ucdqm_ui_large[1], SHURK0_SELPH_DQ1_TXDLY_DQM1) |
11819 P_Fld(ucdqm_ui_large[2], SHURK0_SELPH_DQ1_TXDLY_DQM2) |
11820 P_Fld(ucdqm_ui_large[3], SHURK0_SELPH_DQ1_TXDLY_DQM3) |
11821 P_Fld(ucdqm_oen_ui_large[0], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM0) |
11822 P_Fld(ucdqm_oen_ui_large[1], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM1) |
11823 P_Fld(ucdqm_oen_ui_large[2], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM2) |
11824 P_Fld(ucdqm_oen_ui_large[3], SHURK0_SELPH_DQ1_TXDLY_OEN_DQM3));
11825
11826 // DLY_DQM[2:0]
11827 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3),
11828 P_Fld(ucdqm_ui_small[0], SHURK0_SELPH_DQ3_DLY_DQM0) |
11829 P_Fld(ucdqm_ui_small[1], SHURK0_SELPH_DQ3_DLY_DQM1) |
11830 P_Fld(ucdqm_ui_small[2], SHURK0_SELPH_DQ3_DLY_DQM2) |
11831 P_Fld(ucdqm_ui_small[3], SHURK0_SELPH_DQ3_DLY_DQM3) |
11832 P_Fld(ucdqm_oen_ui_small[0], SHURK0_SELPH_DQ3_DLY_OEN_DQM0) |
11833 P_Fld(ucdqm_oen_ui_small[1], SHURK0_SELPH_DQ3_DLY_OEN_DQM1) |
11834 P_Fld(ucdqm_oen_ui_small[2], SHURK0_SELPH_DQ3_DLY_OEN_DQM2) |
11835 P_Fld(ucdqm_oen_ui_small[3], SHURK0_SELPH_DQ3_DLY_OEN_DQM3));
11836 }
11837
11838 if(u1IsLP4Family(p->dram_type))
11839 {
11840 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdqm_pi[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
11841 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), ucdqm_pi[1], SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1);
11842 }
11843 #if ENABLE_LP3_SW
11844 else
11845 {
11846 vIO32WriteFldAlign_Phy_Byte(0, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdqm_pi[0], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
11847 vIO32WriteFldAlign_Phy_Byte(1, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdqm_pi[1], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
11848 vIO32WriteFldAlign_Phy_Byte(2, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdqm_pi[2], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
11849 vIO32WriteFldAlign_Phy_Byte(3, DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdqm_pi[3], SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
11850 }
11851 #endif
11852}
11853
11854DRAM_STATUS_T DramcTxWindowPerbitCal(DRAMC_CTX_T *p, DRAM_TX_PER_BIT_CALIBRATION_TYTE_T calType, U8 u1VrefScanEnable)
11855{
11856 U8 u1BitTemp, u1BitIdx, u1ByteIdx, u1RankIdx, backup_rank;
11857 U32 uiFinishCount;
11858 PASS_WIN_DATA_T WinPerBit[DQ_DATA_WIDTH] = {{0,0,0,0,0}};
11859 PASS_WIN_DATA_T VrefWinPerBit[DQ_DATA_WIDTH] = {{0,0,0,0,0}};
11860 PASS_WIN_DATA_T FinalWinPerBit[DQ_DATA_WIDTH] = {{0,0,0,0,0}};
11861
11862 U16 uiDelay, u2DQDelayBegin, u2DQDelayEnd;
11863
11864 U8 ucdq_pi, ucdq_ui_small, ucdq_ui_large,ucdq_oen_ui_small, ucdq_oen_ui_large;
11865 U8 ucdq_ui_small_reg_value, u1UpdateRegUI; // for UI and TXDLY change check, if different , set reg.
11866
11867 U8 ucdq_reg_pi[DQS_NUMBER], ucdq_reg_ui_large[DQS_NUMBER], ucdq_reg_ui_small[DQS_NUMBER];
11868 U8 ucdq_reg_oen_ui_large[DQS_NUMBER], ucdq_reg_oen_ui_small[DQS_NUMBER];
11869
11870 U8 ucdq_reg_dqm_pi[DQS_NUMBER] = {0}, ucdq_reg_dqm_ui_large[DQS_NUMBER] = {0}, ucdq_reg_dqm_ui_small[DQS_NUMBER] = {0};
11871 U8 ucdq_reg_dqm_oen_ui_large[DQS_NUMBER] = {0}, ucdq_reg_dqm_oen_ui_small[DQS_NUMBER] = {0};
11872
11873 #if 1//TX_DQM_CALC_MAX_MIN_CENTER
11874 U16 u2Center_min[DQS_NUMBER],u2Center_max[DQS_NUMBER];
11875 #endif
11876 U8 u1EnableDelayCell=0, u1DelayCellOfst[DQ_DATA_WIDTH]={0};
11877 U32 u4err_value, u4fail_bit;
11878 U16 u2FinalRange=0, u2FinalVref=0xd;
11879 U16 u2VrefLevel, u2VrefBegin, u2VrefEnd, u2VrefStep;
11880 U16 u2TempWinSum, u2MaxWindowSum=0;//, u2tx_window_sum[LP4_TX_VREF_DATA_NUM]={0};
11881 U8 u1min_bit, u1min_winsize=0;
11882 U8 u1VrefIdx =0;
11883 U8 u1PIDiff;
11884 PASS_WIN_DATA_BY_VREF_T VrefInfo[LP4_TX_VREF_DATA_NUM];
11885
11886 if (!p)
11887 {
11888 mcSHOW_ERR_MSG(("context NULL\n"));
11889 return DRAM_FAIL;
11890 }
11891
11892#if VENDER_JV_LOG
11893 if((calType ==TX_DQ_DQS_MOVE_DQ_ONLY && u1IsLP4Family(p->dram_type)) || (calType ==TX_DQ_DQS_MOVE_DQ_DQM && !u1IsLP4Family(p->dram_type)))
11894 vPrintCalibrationBasicInfo_ForJV(p);
11895#else
11896 vPrintCalibrationBasicInfo(p);
11897#endif
11898
11899 backup_rank = u1GetRank(p);
11900
11901 TXPerbitCalibrationInit(p, calType);
11902 TXScanRange_PI(p, calType, &u2DQDelayBegin, &u2DQDelayEnd);
11903 TXScanRange_Vref(p, u1VrefScanEnable, &u2FinalRange, &u2VrefBegin, &u2VrefEnd, &u2VrefStep);
11904
11905#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
11906 U8 u1GUMP_INIT_RG_LOG_TO_DE_bak = gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag;
11907 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag=0;
11908#endif
11909
11910 vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_FAIL);
11911
11912#if 0
11913 mcSHOW_DBG_MSG(("[TxWindowPerbitCal] calType=%d, VrefScanEnable %d (Range %d, VrefBegin %d, u2VrefEnd %d)\n"
11914 "\nBegin, DQ Scan Range %d~%d\n",
11915 calType, u1VrefScanEnable, u2FinalRange, u2VrefBegin, u2VrefEnd, u2DQDelayBegin, u2DQDelayEnd));
11916
11917 mcFPRINTF((fp_A60501, "[TxWindowPerbitCal] calType=%d, VrefScanEnable %d\n"
11918 "\nBegin, DQ Scan Range %d~%d\n",
11919 calType, u1VrefScanEnable, u2DQDelayBegin, u2DQDelayEnd));
11920#endif
11921
11922 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
11923 if(p->femmc_Ready==1 && (p->Bypass_TXWINDOW))
11924 {
11925 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
11926 {
11927 u2Center_min[u1ByteIdx]=p->pSavetimeData->u1TxCenter_min_Save[p->channel][p->rank][u1ByteIdx];
11928 u2Center_max[u1ByteIdx]=p->pSavetimeData->u1TxCenter_max_Save[p->channel][p->rank][u1ByteIdx];
11929
11930 for (u1BitIdx=0; u1BitIdx<DQS_BIT_NUMBER; u1BitIdx++)
11931 {
11932 u1BitTemp = u1ByteIdx*DQS_BIT_NUMBER+u1BitIdx;
11933 FinalWinPerBit[u1BitTemp].win_center= p->pSavetimeData->u1Txwin_center_Save[p->channel][p->rank][u1BitTemp];
11934 }
11935 }
11936
11937 vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_OK);
11938 }
11939 else
11940 #endif
11941 {
11942 DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0);
11943
11944 for(u2VrefLevel = u2VrefBegin; u2VrefLevel <= u2VrefEnd; u2VrefLevel += u2VrefStep)
11945 {
11946 // SET tx Vref (DQ) here, LP3 no need to set this.
11947 if(u1VrefScanEnable)
11948 {
11949 #if 0//(!REDUCE_LOG_FOR_PRELOADER)
11950 mcSHOW_DBG_MSG(("\n\n\tLP4 TX VrefRange %d, VrefLevel=%d\n", u2FinalRange, u2VrefLevel));
11951 mcFPRINTF((fp_A60501, "\n\n\tLP4 TX VrefRange %d,VrefLevel=%d\n", u2FinalRange, u2VrefLevel));
11952 #endif
11953
11954 #if VENDER_JV_LOG
11955 if(calType ==TX_DQ_DQS_MOVE_DQ_ONLY)
11956 {
11957 mcSHOW_DBG_MSG5(("\n\n\tLP4 TX VrefRange %d, VrefLevel=%d\n", u2FinalRange, u2VrefLevel));
11958 }
11959 #endif
11960
11961 DramcTXSetVref(p, u2FinalRange, u2VrefLevel);
11962 }
11963 else
11964 {
11965 mcSHOW_DBG_MSG(("\n\n\tTX Vref Scan disable\n"));
11966 mcFPRINTF((fp_A60501, "\n\n\tTX Vref Scan disable\n"));
11967 }
11968
11969 // initialize parameters
11970 uiFinishCount = 0;
11971 u2TempWinSum =0;
11972 ucdq_ui_small_reg_value = 0xff;
11973
11974 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
11975 {
11976 WinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
11977 WinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
11978 VrefWinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
11979 VrefWinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
11980 }
11981
11982 //Move DQ delay , 1 PI = tCK/64, total 128 PI, 1UI = 32 PI
11983 //For data rate 3200, max tDQS2DQ is 2.56UI (82 PI)
11984 //For data rate 4266, max tDQS2DQ is 3.41UI (109 PI)
11985 for (uiDelay = u2DQDelayBegin; uiDelay <u2DQDelayEnd; uiDelay++)
11986 {
11987 TxWinTransferDelayToUIPI(p, calType, uiDelay, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small);
11988
11989 // Check if TX UI changed, if not change , don't need to set reg again
11990 if(ucdq_ui_small_reg_value != ucdq_ui_small)
11991 {
11992 u1UpdateRegUI=1;
11993 ucdq_ui_small_reg_value = ucdq_ui_small;
11994 }
11995 else
11996 u1UpdateRegUI=0;
11997
11998 for(u1ByteIdx=0; u1ByteIdx < DQS_NUMBER; u1ByteIdx++)
11999 {
12000 if(u1UpdateRegUI)
12001 {
12002 ucdq_reg_ui_large[u1ByteIdx] = ucdq_ui_large;
12003 ucdq_reg_ui_small[u1ByteIdx] = ucdq_ui_small;
12004 ucdq_reg_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large;
12005 ucdq_reg_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small;
12006
12007 ucdq_reg_dqm_ui_large[u1ByteIdx] = ucdq_ui_large;
12008 ucdq_reg_dqm_ui_small[u1ByteIdx] = ucdq_ui_small;
12009 ucdq_reg_dqm_oen_ui_large[u1ByteIdx] = ucdq_oen_ui_large;
12010 ucdq_reg_dqm_oen_ui_small[u1ByteIdx] = ucdq_oen_ui_small;
12011 }
12012
12013 ucdq_reg_pi[u1ByteIdx] = ucdq_pi;
12014 ucdq_reg_dqm_pi[u1ByteIdx] = ucdq_pi;
12015 }
12016
12017 if(calType ==TX_DQ_DQS_MOVE_DQ_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM)
12018 {
12019 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);
12020 }
12021
12022 if(calType ==TX_DQ_DQS_MOVE_DQM_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM)
12023 {
12024 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);
12025 }
12026
12027 // audio +xtalk pattern
12028 //u4err_value=0;
12029 DramcEngine2SetPat(p,TEST_AUDIO_PATTERN, 0,0);
12030 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_AUDIO_PATTERN);
12031 DramcEngine2SetPat(p,TEST_XTALK_PATTERN, 0,0);
12032 u4err_value |= DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_XTALK_PATTERN);
12033
12034 if(u1VrefScanEnable==0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY))
12035 {
12036 //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));
12037 #ifdef ETT_PRINT_FORMAT
12038 if(u4err_value !=0)
12039 {
12040 mcSHOW_DBG_MSG2(("%d |%d %d %d|[0]", uiDelay, ucdq_ui_large, ucdq_ui_small, ucdq_pi));
12041 }
12042 #else
12043 mcSHOW_DBG_MSG2(("Delay=%3d |%2d %2d %3d| 0x%8x [0]", uiDelay, ucdq_ui_large, ucdq_ui_small, ucdq_pi, u4err_value));
12044 #endif
12045 mcFPRINTF((fp_A60501, "Delay=%3d | %2d %2d %3d| 0x%8x [0]", uiDelay, ucdq_ui_large,ucdq_ui_small, ucdq_pi, u4err_value));
12046 }
12047
12048 // check fail bit ,0 ok ,others fail
12049 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12050 {
12051 u4fail_bit = u4err_value&((U32)1<<u1BitIdx);
12052
12053 if(u1VrefScanEnable==0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY))
12054 {
12055 if(u4err_value != 0)
12056 {
12057 if(u1BitIdx%DQS_BIT_NUMBER ==0)
12058 {
12059 mcSHOW_DBG_MSG2((" "));
12060 mcFPRINTF((fp_A60501, " "));
12061 }
12062
12063 if (u4fail_bit == 0)
12064 {
12065 mcSHOW_DBG_MSG2(("o"));
12066 mcFPRINTF((fp_A60501, "o"));
12067 }
12068 else
12069 {
12070 mcSHOW_DBG_MSG2(("x"));
12071 mcFPRINTF((fp_A60501, "x"));
12072 }
12073 }
12074 }
12075
12076 if(WinPerBit[u1BitIdx].first_pass== PASS_RANGE_NA)
12077 {
12078 if(u4fail_bit==0) //compare correct: pass
12079 {
12080 WinPerBit[u1BitIdx].first_pass = uiDelay;
12081
12082 #if TX_TDQS2DQ_PRE_CAL
12083 if((p->frequency == LP4_LOWEST_FREQ) && (u2DQS2DQ_Pre_Cal[p->channel][p->rank]==0))
12084 {
12085 u2DQS2DQ_Pre_Cal[p->channel][p->rank] = (uiDelay - u2DQDelayBegin) *850 / p->frequency;
12086 }
12087
12088 if(uiDelay==u2DQDelayBegin)
12089 {
12090 mcSHOW_ERR_MSG(("TX_TDQS2DQ_PRE_CAL: Warning, possible miss TX window boundary\n"));
12091 #if __ETT__
12092 while(1);
12093 #endif
12094 }
12095 #endif
12096 }
12097 }
12098 else if(WinPerBit[u1BitIdx].last_pass == PASS_RANGE_NA)
12099 {
12100 if(u4fail_bit !=0) //compare error : fail
12101 {
12102 WinPerBit[u1BitIdx].last_pass = (uiDelay-1);
12103 }
12104 else if (uiDelay==u2DQDelayEnd)
12105 {
12106 WinPerBit[u1BitIdx].last_pass = uiDelay;
12107 }
12108
12109 if(WinPerBit[u1BitIdx].last_pass !=PASS_RANGE_NA)
12110 {
12111 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >= (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass))
12112 {
12113 if((VrefWinPerBit[u1BitIdx].last_pass != PASS_RANGE_NA) && (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass)>0)
12114 {
12115 mcSHOW_DBG_MSG2(("Bit[%d] Bigger window update %d > %d, window broken?\n", u1BitIdx, \
12116 (WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass), (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass)));
12117 mcFPRINTF((fp_A60501,"Bit[%d] Bigger window update %d > %d\n", u1BitIdx, \
12118 (WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass), (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass)));
12119
12120 }
12121
12122 //if window size bigger than 7, consider as real pass window. If not, don't update finish counte and won't do early break;
12123 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >7)
12124 uiFinishCount |= (1<<u1BitIdx);
12125
12126 //update bigger window size
12127 VrefWinPerBit[u1BitIdx].first_pass = WinPerBit[u1BitIdx].first_pass;
12128 VrefWinPerBit[u1BitIdx].last_pass = WinPerBit[u1BitIdx].last_pass;
12129 }
12130
12131 //reset tmp window
12132 WinPerBit[u1BitIdx].first_pass = PASS_RANGE_NA;
12133 WinPerBit[u1BitIdx].last_pass = PASS_RANGE_NA;
12134 }
12135 }
12136 }
12137
12138 if(u1VrefScanEnable==0 && (calType != TX_DQ_DQS_MOVE_DQM_ONLY))
12139 {
12140 if(u4err_value != 0)
12141 {
12142 mcSHOW_DBG_MSG2((" [MSB]\n"));
12143 mcFPRINTF((fp_A60501, " [MSB]\n"));
12144 }
12145 }
12146
12147 //if all bits widnow found and all bits turns to fail again, early break;
12148 if((u1IsLP4Family(p->dram_type) &&(uiFinishCount == 0xffff)) || \
12149 ((p->dram_type == TYPE_LPDDR3) &&(uiFinishCount == 0xffffffff)))
12150 {
12151 vSetCalibrationResult(p, DRAM_CALIBRATION_TX_PERBIT, DRAM_OK);
12152
12153 #if !REDUCE_LOG_FOR_PRELOADER
12154 #ifdef ETT_PRINT_FORMAT
12155 mcSHOW_DBG_MSG2(("TX calibration finding left boundary early break. PI DQ delay=0x%B\n", uiDelay));
12156 #else
12157 mcSHOW_DBG_MSG2(("TX calibration finding left boundary early break. PI DQ delay=0x%2x\n", uiDelay));
12158 #endif
12159 #endif
12160 break; //early break
12161 }
12162 }
12163
12164
12165 // (1) calculate per bit window size
12166 // (2) find out min win of all DQ bits
12167 // (3) calculate perbit window center
12168 u1min_winsize = 0xff;
12169 u1min_bit = 0xff;
12170 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12171 {
12172 //if(VrefWinPerBit[u1BitIdx].last_pass == VrefWinPerBit[u1BitIdx].first_pass)
12173 if(VrefWinPerBit[u1BitIdx].first_pass == PASS_RANGE_NA)
12174 VrefWinPerBit[u1BitIdx].win_size = 0;
12175 else
12176 VrefWinPerBit[u1BitIdx].win_size= VrefWinPerBit[u1BitIdx].last_pass- VrefWinPerBit[u1BitIdx].first_pass +1;
12177
12178 if (VrefWinPerBit[u1BitIdx].win_size < u1min_winsize)
12179 {
12180 u1min_bit = u1BitIdx;
12181 u1min_winsize = VrefWinPerBit[u1BitIdx].win_size;
12182 }
12183
12184 u2TempWinSum += VrefWinPerBit[u1BitIdx].win_size; //Sum of CA Windows for vref selection
12185
12186 #if VENDER_JV_LOG
12187 if((calType ==TX_DQ_DQS_MOVE_DQ_ONLY && u1IsLP4Family(p->dram_type)) || (calType ==TX_DQ_DQS_MOVE_DQ_DQM && !u1IsLP4Family(p->dram_type)))
12188 {
12189 mcSHOW_DBG_MSG5(("TX Bit%d, %d%%\n", u1BitIdx, (VrefWinPerBit[u1BitIdx].win_size*100+31)/32));
12190 }
12191 #endif
12192
12193
12194 // calculate per bit window position and print
12195 VrefWinPerBit[u1BitIdx].win_center= (VrefWinPerBit[u1BitIdx].first_pass + VrefWinPerBit[u1BitIdx].last_pass) >> 1;
12196
12197 #if PINMUX_AUTO_TEST_PER_BIT_TX
12198 gFinalTXPerbitFirstPass[p->channel][u1BitIdx] = VrefWinPerBit[u1BitIdx].first_pass;
12199 #endif
12200 }
12201
12202 mcSHOW_DBG_MSG3(("Min Bit=%d, winsize=%d\n",u1min_bit, u1min_winsize));
12203 #if __ETT__
12204 if(u1VrefScanEnable==0)
12205 {
12206 //mcSHOW_DBG_MSG(("\n\tCH=%d, VrefRange= %d, VrefLevel = %d\n", p->channel, u2FinalRange, u2VrefLevel));
12207 //mcFPRINTF((fp_A60501,"\n\tchannel=%d(2:cha, 3:chb) u2VrefLevel = %d\n", p->channel, u2VrefLevel));
12208 TxPrintWidnowInfo(p, VrefWinPerBit);
12209 }
12210 #endif
12211
12212 if(u1VrefScanEnable==1)
12213 {
12214 if(u2TempWinSum > u2MaxWindowSum)
12215 u2MaxWindowSum= u2TempWinSum;
12216
12217 VrefInfo[u1VrefIdx].u2VrefUsed = u2VrefLevel;
12218 VrefInfo[u1VrefIdx].u2MinWinSize_byVref= u1min_winsize;
12219 VrefInfo[u1VrefIdx].u2WinSum_byVref = u2TempWinSum;
12220 u1VrefIdx ++;
12221 }
12222
12223 #if LP4_TX_VREF_PASS_CONDITION
12224 if(u1VrefScanEnable && (u2TempWinSum < (u2MaxWindowSum*95/100)) &&(u1min_winsize < LP4_TX_VREF_PASS_CONDITION))
12225 #else
12226 if(u1VrefScanEnable && (u2TempWinSum < (u2MaxWindowSum*95/100)))
12227 #endif
12228 {
12229 mcSHOW_DBG_MSG(("\nTX Vref early break, caculate TX vref\n"));
12230 break;
12231 }
12232 }
12233
12234 DramcEngine2End(p);
12235
12236 if(u1VrefScanEnable==0)// ..if time domain (not vref scan) , calculate window center of all bits.
12237 {
12238 // Calculate the center of DQ pass window
12239 // Record center sum of each byte
12240 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
12241 {
12242 #if 1//TX_DQM_CALC_MAX_MIN_CENTER
12243 u2Center_min[u1ByteIdx] = 0xffff;
12244 u2Center_max[u1ByteIdx] = 0;
12245 #endif
12246
12247 for (u1BitIdx=0; u1BitIdx<DQS_BIT_NUMBER; u1BitIdx++)
12248 {
12249 u1BitTemp = u1ByteIdx * DQS_BIT_NUMBER + u1BitIdx;
12250 memcpy(FinalWinPerBit, VrefWinPerBit, sizeof(PASS_WIN_DATA_T)*DQ_DATA_WIDTH);
12251
12252 if(FinalWinPerBit[u1BitTemp].win_center < u2Center_min[u1ByteIdx])
12253 u2Center_min[u1ByteIdx] = FinalWinPerBit[u1BitTemp].win_center;
12254
12255 if(FinalWinPerBit[u1BitTemp].win_center > u2Center_max[u1ByteIdx])
12256 u2Center_max[u1ByteIdx] = FinalWinPerBit[u1BitTemp].win_center;
12257
12258 #ifdef FOR_HQA_TEST_USED
12259 if((u1IsLP4Family(p->dram_type) && calType == TX_DQ_DQS_MOVE_DQ_ONLY && (u1VrefScanEnable==0))
12260 || (!u1IsLP4Family(p->dram_type) && (calType == TX_DQ_DQS_MOVE_DQ_DQM)))
12261 {
12262 gFinalTXPerbitWin[p->channel][p->rank][u1BitTemp] = FinalWinPerBit[u1BitTemp].win_size;
12263 }
12264 #endif
12265 }
12266 }
12267
12268 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
12269 if(p->femmc_Ready==0)//save firtst run pass value
12270 {
12271 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
12272 {
12273 if(calType == TX_DQ_DQS_MOVE_DQ_ONLY) // && u1VrefScanEnable==0
12274 {
12275 p->pSavetimeData->u1TxCenter_min_Save[p->channel][p->rank][u1ByteIdx]=u2Center_min[u1ByteIdx];
12276 p->pSavetimeData->u1TxCenter_max_Save[p->channel][p->rank][u1ByteIdx]=u2Center_max[u1ByteIdx];
12277
12278 for (u1BitIdx=0; u1BitIdx<DQS_BIT_NUMBER; u1BitIdx++)
12279 {
12280 u1BitTemp = u1ByteIdx*DQS_BIT_NUMBER+u1BitIdx;
12281 p->pSavetimeData->u1Txwin_center_Save[p->channel][p->rank][u1BitTemp]=FinalWinPerBit[u1BitTemp].win_center;
12282 }
12283 }
12284 }
12285 }
12286 #endif
12287 }
12288 }
12289
12290 // SET tx Vref (DQ) = u2FinalVref, LP3 no need to set this.
12291 if(u1IsLP4Family(p->dram_type) && (u1VrefScanEnable!=DISABLE_VREF_SCAN))
12292 {
12293 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_VREF_CAL
12294 if(p->femmc_Ready==1 && (p->Bypass_TXWINDOW) && u1VrefScanEnable!=SET_VREF_AND_DISABLE_VREF_SCAN)
12295 {
12296 u2FinalVref = p->pSavetimeData->u1TxWindowPerbitVref_Save[p->channel][p->rank];
12297 }
12298 else
12299 #endif
12300 {
12301 if (u1VrefScanEnable==ENABLE_VREF_SCAN)
12302 {
12303 u2FinalVref = TxChooseVref(p, VrefInfo, u1VrefIdx);
12304
12305#ifdef DEVIATION
12306 if (p->frequency == u2DFSGetHighestFreq(p) && gSetSpecificedVref_Enable[2]==ENABLE && ((p->channel==gSetSpecificedVref_Channel[2] && p->rank==gSetSpecificedVref_Rank[2]) || gSetSpecificedVref_All_ChRk[2]==ENABLE))
12307 {
12308 DeviationAddVrefOffset(2, &u2FinalRange, &u2FinalVref, gSetSpecificedVref_Vref_Offset[2]);
12309 }
12310#endif
12311 }
12312
12313 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
12314 if(p->femmc_Ready==0)////save firtst run Vref value
12315 {
12316 p->pSavetimeData->u1TxWindowPerbitVref_Save[p->channel][p->rank]=u2FinalVref;
12317 }
12318 #endif
12319 }
12320 #ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
12321 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
12322 #endif
12323
12324 TXSetFinalVref(p, u2FinalRange, u2FinalVref);
12325 return DRAM_OK;
12326 }
12327
12328
12329#ifdef FOR_HQA_TEST_USED
12330 // LP4 DQ time domain || LP3 DQ_DQM time domain
12331 if((u1IsLP4Family(p->dram_type) && (calType == TX_DQ_DQS_MOVE_DQ_ONLY)) ||
12332 (!u1IsLP4Family(p->dram_type) && (calType == TX_DQ_DQS_MOVE_DQ_DQM)))
12333 {
12334 gFinalTXPerbitWin_min_max[p->channel][p->rank] = u1min_winsize;
12335 }
12336#endif
12337
12338 // LP3 only use "TX_DQ_DQS_MOVE_DQ_DQM" scan
12339 // first freq 800(LP4-1600) doesn't support jitter meter(data < 1T), therefore, don't use delay cell
12340 if((calType == TX_DQ_DQS_MOVE_DQ_ONLY) && (p->frequency >= gu4TermFreq) && (p->u2DelayCellTimex100!=0))
12341 {
12342 u1EnableDelayCell =1;
12343 mcSHOW_DBG_MSG(("[TX_PER_BIT_DELAY_CELL] DelayCellTimex100 =%d/100 ps\n", p->u2DelayCellTimex100));
12344 }
12345
12346 //Calculate the center of DQ pass window
12347 //average the center delay
12348 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
12349 {
12350 mcSHOW_DBG_MSG((" == TX Byte %d ==\n", u1ByteIdx));
12351 if(u1EnableDelayCell==0)
12352 {
12353 uiDelay = ((u2Center_min[u1ByteIdx] + u2Center_max[u1ByteIdx])>>1); //(max +min)/2
12354 u2TX_DQ_PreCal_LP4[u1ByteIdx] = uiDelay; //LP4 only, for tDQS2DQ
12355 }
12356 else // if(calType == TX_DQ_DQS_MOVE_DQ_ONLY)
12357 {
12358 uiDelay = u2Center_min[u1ByteIdx]; // for DQ PI delay , will adjust with delay cell
12359 u2TX_DQ_PreCal_LP4[u1ByteIdx] = ((u2Center_min[u1ByteIdx] + u2Center_max[u1ByteIdx])>>1); // for DQM PI delay
12360
12361 #if 0//SUPPORT_SAVE_TIME_FOR_CALIBRATION//BYPASS_TX_PER_BIT_DELAY_CELL
12362 if(p->femmc_Ready==1 && (p->Bypass_TXWINDOW))
12363 {
12364 for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++)
12365 {
12366 u1BitTemp = u1ByteIdx*DQS_BIT_NUMBER+u1BitIdx;
12367 u1DelayCellOfst[u1BitTemp] = p->pSavetimeData->u1TX_PerBit_DelayLine_Save[p->channel][p->rank][u1BitTemp];
12368 }
12369 }
12370 else
12371 #endif
12372 {
12373 // calculate delay cell perbit
12374 for (u1BitIdx = 0; u1BitIdx < DQS_BIT_NUMBER; u1BitIdx++)
12375 {
12376 u1BitTemp = u1ByteIdx*DQS_BIT_NUMBER+u1BitIdx;
12377 u1PIDiff = FinalWinPerBit[u1BitTemp].win_center - u2Center_min[u1ByteIdx];
12378 if(p->u2DelayCellTimex100 !=0)
12379 {
12380 u1DelayCellOfst[u1BitTemp] = (u1PIDiff*100000000/(p->frequency<<6))/p->u2DelayCellTimex100;
12381 #if 0//SUPPORT_SAVE_TIME_FOR_CALIBRATION
12382 p->pSavetimeData->u1TX_PerBit_DelayLine_Save[p->channel][p->rank][u1BitTemp] = u1DelayCellOfst[u1BitTemp];
12383 #endif
12384 mcSHOW_DBG_MSG(("u1DelayCellOfst[%d]=%d cells (%d PI)\n", u1BitTemp, u1DelayCellOfst[u1BitTemp], u1PIDiff));
12385 }
12386 else
12387 {
12388 mcSHOW_ERR_MSG(("Error: Cell time (p->u2DelayCellTimex100) is 0 \n"));
12389 break;
12390 }
12391 }
12392 }
12393 }
12394
12395 TxWinTransferDelayToUIPI(p, calType, uiDelay, 1, &ucdq_reg_ui_large[u1ByteIdx], &ucdq_reg_ui_small[u1ByteIdx], &ucdq_reg_pi[u1ByteIdx],\
12396 &ucdq_reg_oen_ui_large[u1ByteIdx], &ucdq_reg_oen_ui_small[u1ByteIdx]);
12397
12398 TxWinTransferDelayToUIPI(p, calType, u2TX_DQ_PreCal_LP4[u1ByteIdx], 1, &ucdq_reg_dqm_ui_large[u1ByteIdx], &ucdq_reg_dqm_ui_small[u1ByteIdx], &ucdq_reg_dqm_pi[u1ByteIdx],\
12399 &ucdq_reg_dqm_oen_ui_large[u1ByteIdx], &ucdq_reg_dqm_oen_ui_small[u1ByteIdx]);
12400
12401 if(calType ==TX_DQ_DQS_MOVE_DQ_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM)
12402 {
12403 mcSHOW_DBG_MSG(("Update DQ dly =%d (%d ,%d, %d) DQ OEN =(%d ,%d)\n",
12404 uiDelay, ucdq_reg_ui_large[u1ByteIdx], ucdq_reg_ui_small[u1ByteIdx], ucdq_reg_pi[u1ByteIdx],\
12405 ucdq_reg_oen_ui_large[u1ByteIdx], ucdq_reg_oen_ui_small[u1ByteIdx]));
12406
12407 mcFPRINTF((fp_A60501,"Byte%d, PI DQ dly %d\n", u1ByteIdx, uiDelay));
12408 mcFPRINTF((fp_A60501,"Final DQ PI dly(LargeUI, SmallUI, PI) =(%d ,%d, %d)\n", ucdq_reg_ui_large[u1ByteIdx], ucdq_reg_ui_small[u1ByteIdx], ucdq_reg_pi[u1ByteIdx]));
12409 mcFPRINTF((fp_A60501,"OEN DQ PI dly(LargeUI, SmallUI, PI) =(%d ,%d, %d)\n\n", ucdq_reg_oen_ui_large[u1ByteIdx], ucdq_reg_oen_ui_small[u1ByteIdx], ucdq_reg_pi[u1ByteIdx]));
12410 }
12411
12412 //if(calType ==TX_DQ_DQS_MOVE_DQM_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM)
12413 {
12414 mcSHOW_DBG_MSG(("Update DQM dly =%d (%d ,%d, %d) DQM OEN =(%d ,%d)",
12415 u2TX_DQ_PreCal_LP4[u1ByteIdx], ucdq_reg_dqm_ui_large[u1ByteIdx], ucdq_reg_dqm_ui_small[u1ByteIdx], ucdq_reg_dqm_pi[u1ByteIdx], \
12416 ucdq_reg_dqm_oen_ui_large[u1ByteIdx], ucdq_reg_dqm_oen_ui_small[u1ByteIdx]));
12417 }
12418 mcSHOW_DBG_MSG(("\n"));
12419
12420#ifdef FOR_HQA_REPORT_USED
12421 if(calType == TX_DQ_DQS_MOVE_DQ_ONLY)
12422 {
12423 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12424 {
12425 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "TX_Window_Center_DQ", u1BitIdx, FinalWinPerBit[u1BitIdx].win_center, NULL);
12426 }
12427 }
12428
12429 if(calType == TX_DQ_DQS_MOVE_DQM_ONLY)
12430 {
12431 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_DQM", u1ByteIdx, u2TX_DQ_PreCal_LP4[u1ByteIdx], NULL);
12432 }
12433#if 0
12434 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT1, "TX_Window_Center_LargeUI", u1ByteIdx, ucdq_reg_ui_large[u1ByteIdx], NULL);
12435 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_SmallUI", u1ByteIdx, ucdq_reg_ui_small[u1ByteIdx], NULL);
12436 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0, "TX_Window_Center_PI", u1ByteIdx, ucdq_reg_pi[u1ByteIdx], NULL);
12437#endif
12438#endif
12439
12440 }
12441
12442#ifdef DUMP_INIT_AND_K_RG_LOG_TO_DE
12443 gDUMP_INIT_RG_LOG_TO_DE_RG_log_flag = u1GUMP_INIT_RG_LOG_TO_DE_bak;
12444#endif
12445
12446#if REG_ACCESS_PORTING_DGB
12447 RegLogEnable =1;
12448#endif
12449
12450 /* p->rank = RANK_0, save to Reg Rank0 and Rank1, p->rank = RANK_1, save to Reg Rank1 */
12451 for(u1RankIdx=p->rank; u1RankIdx<RANK_MAX; u1RankIdx++)
12452 {
12453 vSetRank(p,u1RankIdx);
12454
12455 if(calType ==TX_DQ_DQS_MOVE_DQ_ONLY || calType== TX_DQ_DQS_MOVE_DQ_DQM)
12456 {
12457 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);
12458 }
12459
12460 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);
12461
12462
12463 if(u1IsLP4Family(p->dram_type))
12464 {
12465 if(u1EnableDelayCell)
12466 {
12467 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ0),
12468 P_Fld(u1DelayCellOfst[7] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ7_DLY_B0)
12469 | P_Fld(u1DelayCellOfst[6] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ6_DLY_B0)
12470 | P_Fld(u1DelayCellOfst[5] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ5_DLY_B0)
12471 | P_Fld(u1DelayCellOfst[4] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ4_DLY_B0)
12472 | P_Fld(u1DelayCellOfst[3] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ3_DLY_B0)
12473 | P_Fld(u1DelayCellOfst[2] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ2_DLY_B0)
12474 | P_Fld(u1DelayCellOfst[1] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ1_DLY_B0)
12475 | P_Fld(u1DelayCellOfst[0] , SHU1_R0_B0_DQ0_RK0_TX_ARDQ0_DLY_B0));
12476 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ0),
12477 P_Fld(u1DelayCellOfst[15] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ7_DLY_B1)
12478 | P_Fld(u1DelayCellOfst[14] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ6_DLY_B1)
12479 | P_Fld(u1DelayCellOfst[13] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ5_DLY_B1)
12480 | P_Fld(u1DelayCellOfst[12] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ4_DLY_B1)
12481 | P_Fld(u1DelayCellOfst[11] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ3_DLY_B1)
12482 | P_Fld(u1DelayCellOfst[10] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ2_DLY_B1)
12483 | P_Fld(u1DelayCellOfst[9] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ1_DLY_B1)
12484 | P_Fld(u1DelayCellOfst[8] , SHU1_R0_B1_DQ0_RK0_TX_ARDQ0_DLY_B1));
12485 }
12486 }
12487
12488 #if ENABLE_TX_TRACKING
12489 TXUpdateTXTracking(p, calType, ucdq_reg_pi, ucdq_reg_dqm_pi);
12490 #endif
12491 }
12492
12493 vSetRank(p, backup_rank);
12494
12495#if REG_ACCESS_PORTING_DGB
12496 RegLogEnable =0;
12497#endif
12498
12499 mcSHOW_DBG_MSG3(("[TxWindowPerbitCal] Done\n\n"));
12500 mcFPRINTF((fp_A60501, "[TxWindowPerbitCal] Done\n\n"));
12501
12502 #if 0
12503 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DRAMC_REG_PADCTL4), 1, PADCTL4_CKEFIXON); // test only
12504 #endif
12505
12506 return DRAM_OK;
12507}
12508#endif //SIMULATION_TX_PERBIT
12509
12510#if EYESCAN_LOG
12511void Dramc_K_TX_EyeScan_Log(DRAMC_CTX_T *p)
12512{
12513 U8 ucindex, u1BitIdx, u1ByteIdx;
12514 U8 ii, u1vrefidx;
12515 PASS_WIN_DATA_T WinPerBit[DQ_DATA_WIDTH], VrefWinPerBit[DQ_DATA_WIDTH], FinalWinPerBit[DQ_DATA_WIDTH];
12516 U16 tx_pi_delay[4], tx_dqm_pi_delay[4];
12517 U16 u2DQDelayBegin, uiDelay;
12518 U16 u2VrefLevel, u2VrefBegin, u2VrefEnd, u2VrefStep, u2VrefRange;
12519 U8 ucdq_pi, ucdq_ui_small, ucdq_ui_large,ucdq_oen_ui_small, ucdq_oen_ui_large;
12520 U32 uiFinishCount;
12521 U16 u2TempWinSum, u2tx_window_sum=0;
12522 U32 u4err_value, u4fail_bit;
12523 #if 1//TX_DQM_CALC_MAX_MIN_CENTER
12524 U16 u2Center_min[DQS_NUMBER],u2Center_max[DQS_NUMBER];
12525 #endif
12526
12527 U16 TXPerbitWin_min_max = 0;
12528 U32 min_bit, min_winsize;
12529
12530 U16 u2FinalVref=0xd;
12531 U16 u2FinalRange=0;
12532
12533 U8 EyeScan_index[DQ_DATA_WIDTH];
12534
12535 U8 backup_u1MR14Value;
12536 U8 u1pass_in_this_vref_flag[DQ_DATA_WIDTH];
12537
12538 U32 u4RegBackupAddress[] =
12539 {
12540 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0)),
12541 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2)),
12542 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1)),
12543 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3)),
12544 (DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7)),
12545 (DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7)),
12546 };
12547
12548 if(gTX_EYE_Scan_flag==0) return;
12549
12550 if (gTX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency != u2DFSGetHighestFreq(p)) return;
12551
12552
12553 //backup register value
12554 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
12555
12556 backup_u1MR14Value = u1MR14Value[p->channel][p->rank][p->dram_fsp];
12557
12558 //set initial values
12559 for(u1vrefidx=0; u1vrefidx<VREF_TOTAL_NUM_WITH_RANGE;u1vrefidx++)
12560 {
12561 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12562 {
12563 for(ii=0; ii<EYESCAN_BROKEN_NUM; ii++)
12564 {
12565 gEyeScan_Min[u1vrefidx][u1BitIdx][ii] = EYESCAN_DATA_INVALID;
12566 gEyeScan_Max[u1vrefidx][u1BitIdx][ii] = EYESCAN_DATA_INVALID;
12567 }
12568 gEyeScan_ContinueVrefHeight[u1BitIdx] = 0;
12569 gEyeScan_TotalPassCount[u1BitIdx] = 0;
12570 }
12571 }
12572
12573 for(u1ByteIdx=0; u1ByteIdx < p->data_width/DQS_BIT_NUMBER; u1ByteIdx++)
12574 {
12575 if (u1ByteIdx == 0)
12576 {
12577 tx_pi_delay[u1ByteIdx] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ0) * 256 +
12578 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), SHURK0_SELPH_DQ2_DLY_DQ0) * 32 +
12579 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
12580
12581 tx_dqm_pi_delay[u1ByteIdx] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM0) * 256 +
12582 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), SHURK0_SELPH_DQ3_DLY_DQM0) * 32 +
12583 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
12584 }
12585 else
12586 {
12587 tx_pi_delay[u1ByteIdx] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ1) * 256 +
12588 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), SHURK0_SELPH_DQ2_DLY_DQ1) * 32 +
12589 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1);
12590
12591 tx_dqm_pi_delay[u1ByteIdx] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM1) * 256 +
12592 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), SHURK0_SELPH_DQ3_DLY_DQM1) * 32 +
12593 u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1);
12594 }
12595 }
12596
12597 if (tx_pi_delay[0] < tx_pi_delay[1])
12598 {
12599 u2DQDelayBegin = tx_pi_delay[0]-32;
12600 }
12601 else
12602 {
12603 u2DQDelayBegin = tx_pi_delay[1]-32;
12604 }
12605
12606 u2VrefRange = 0;
12607 u2VrefBegin = 0;
12608 u2VrefEnd = 50;
12609 u2VrefStep = 1;
12610
12611 DramcEngine2Init(p, p->test2_1, p->test2_2, p->test_pattern, 0);
12612
12613 for(u2VrefLevel = u2VrefBegin; u2VrefLevel <= u2VrefEnd; u2VrefLevel += u2VrefStep)
12614 {
12615 //set vref
12616//fra u1MR14Value[p->channel][p->rank][p->dram_fsp] = (u2VrefLevel | (u2VrefRange<<6));
12617 DramcModeRegWriteByRank(p, p->rank, 14, u2VrefLevel | (u2VrefRange<<6));
12618
12619 // initialize parameters
12620 uiFinishCount = 0;
12621 u2TempWinSum =0;
12622
12623 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12624 {
12625 WinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
12626 WinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
12627 VrefWinPerBit[u1BitIdx].first_pass = (S16)PASS_RANGE_NA;
12628 VrefWinPerBit[u1BitIdx].last_pass = (S16)PASS_RANGE_NA;
12629
12630 gEyeScan_DelayCellPI[u1BitIdx] = 0;
12631
12632 EyeScan_index[u1BitIdx] = 0;
12633 u1pass_in_this_vref_flag[u1BitIdx] = 0;
12634 }
12635
12636 for (uiDelay=0; uiDelay<64; uiDelay++)
12637 {
12638 TxWinTransferDelayToUIPI(p, TX_DQ_DQS_MOVE_DQ_DQM, tx_pi_delay[0]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small);
12639 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), \
12640 P_Fld(ucdq_ui_large, SHURK0_SELPH_DQ0_TXDLY_DQ0) | \
12641 P_Fld(ucdq_oen_ui_large, SHURK0_SELPH_DQ0_TXDLY_OEN_DQ0));
12642 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), \
12643 P_Fld(ucdq_ui_small, SHURK0_SELPH_DQ2_DLY_DQ0) | \
12644 P_Fld(ucdq_oen_ui_small, SHURK0_SELPH_DQ2_DLY_OEN_DQ0));
12645 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdq_pi, SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
12646
12647 TxWinTransferDelayToUIPI(p, TX_DQ_DQS_MOVE_DQ_DQM, tx_pi_delay[1]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small);
12648 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), \
12649 P_Fld(ucdq_ui_large, SHURK0_SELPH_DQ0_TXDLY_DQ1) | \
12650 P_Fld(ucdq_oen_ui_large, SHURK0_SELPH_DQ0_TXDLY_OEN_DQ1));
12651 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ2), \
12652 P_Fld(ucdq_ui_small, SHURK0_SELPH_DQ2_DLY_DQ1) | \
12653 P_Fld(ucdq_oen_ui_small, SHURK0_SELPH_DQ2_DLY_OEN_DQ1));
12654 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), ucdq_pi, SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1);
12655
12656 TxWinTransferDelayToUIPI(p, TX_DQ_DQS_MOVE_DQ_DQM, tx_dqm_pi_delay[0]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small);
12657 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), \
12658 P_Fld(ucdq_ui_large, SHURK0_SELPH_DQ1_TXDLY_DQM0) | \
12659 P_Fld(ucdq_oen_ui_large, SHURK0_SELPH_DQ1_TXDLY_OEN_DQM0));
12660 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), \
12661 P_Fld(ucdq_ui_small, SHURK0_SELPH_DQ3_DLY_DQM0) | \
12662 P_Fld(ucdq_oen_ui_small, SHURK0_SELPH_DQ3_DLY_OEN_DQM0));
12663 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), ucdq_pi, SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
12664
12665 TxWinTransferDelayToUIPI(p, TX_DQ_DQS_MOVE_DQ_DQM, tx_dqm_pi_delay[1]+uiDelay-32, 0, &ucdq_ui_large, &ucdq_ui_small, &ucdq_pi, &ucdq_oen_ui_large, &ucdq_oen_ui_small);
12666 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), \
12667 P_Fld(ucdq_ui_large, SHURK0_SELPH_DQ1_TXDLY_DQM1) | \
12668 P_Fld(ucdq_oen_ui_large, SHURK0_SELPH_DQ1_TXDLY_OEN_DQM1));
12669 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ3), \
12670 P_Fld(ucdq_ui_small, SHURK0_SELPH_DQ3_DLY_DQM1) | \
12671 P_Fld(ucdq_oen_ui_small, SHURK0_SELPH_DQ3_DLY_OEN_DQM1));
12672 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), ucdq_pi, SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1);
12673
12674
12675 // audio +xtalk pattern
12676 u4err_value=0;
12677 DramcEngine2SetPat(p,TEST_AUDIO_PATTERN, 0,0);
12678 u4err_value = DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_AUDIO_PATTERN);
12679 DramcEngine2SetPat(p,TEST_XTALK_PATTERN, 0,0);
12680 u4err_value |= DramcEngine2Run(p, TE_OP_WRITE_READ_CHECK, TEST_XTALK_PATTERN);
12681
12682 // check fail bit ,0 ok ,others fail
12683 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12684 {
12685 u4fail_bit = u4err_value&((U32)1<<u1BitIdx);
12686
12687 if (u4fail_bit == 0)
12688 {
12689 gEyeScan_TotalPassCount[u1BitIdx]++;
12690 }
12691
12692 if(WinPerBit[u1BitIdx].first_pass== PASS_RANGE_NA)
12693 {
12694 if(u4fail_bit==0) //compare correct: pass
12695 {
12696 WinPerBit[u1BitIdx].first_pass = uiDelay;
12697 u1pass_in_this_vref_flag[u1BitIdx] = 1;
12698 }
12699 }
12700 else if(WinPerBit[u1BitIdx].last_pass == PASS_RANGE_NA)
12701 {
12702 if(u4fail_bit !=0) //compare error : fail
12703 {
12704 WinPerBit[u1BitIdx].last_pass = (uiDelay-1);
12705 }
12706 else if (uiDelay==64)
12707 {
12708 WinPerBit[u1BitIdx].last_pass = uiDelay;
12709 }
12710
12711 if(WinPerBit[u1BitIdx].last_pass !=PASS_RANGE_NA)
12712 {
12713 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >= (VrefWinPerBit[u1BitIdx].last_pass -VrefWinPerBit[u1BitIdx].first_pass))
12714 {
12715 //if window size bigger than 7, consider as real pass window. If not, don't update finish counte and won't do early break;
12716 if((WinPerBit[u1BitIdx].last_pass -WinPerBit[u1BitIdx].first_pass) >7)
12717 uiFinishCount |= (1<<u1BitIdx);
12718
12719 //update bigger window size
12720 VrefWinPerBit[u1BitIdx].first_pass = WinPerBit[u1BitIdx].first_pass;
12721 VrefWinPerBit[u1BitIdx].last_pass = WinPerBit[u1BitIdx].last_pass;
12722 }
12723
12724#if EYESCAN_LOG
12725 if (EyeScan_index[u1BitIdx] < EYESCAN_BROKEN_NUM)
12726 {
12727#if VENDER_JV_LOG || defined(RELEASE)
12728 gEyeScan_Min[u2VrefLevel+u2VrefRange*30][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].first_pass;
12729 gEyeScan_Max[u2VrefLevel+u2VrefRange*30][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].last_pass;
12730#else
12731 gEyeScan_Min[u2VrefLevel+u2VrefRange*30][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].first_pass + tx_pi_delay[u1BitIdx/8]-32;
12732 gEyeScan_Max[u2VrefLevel+u2VrefRange*30][u1BitIdx][EyeScan_index[u1BitIdx]] = WinPerBit[u1BitIdx].last_pass + tx_pi_delay[u1BitIdx/8]-32;
12733#endif
12734 EyeScan_index[u1BitIdx]=EyeScan_index[u1BitIdx]+1;
12735 }
12736#endif
12737
12738 //reset tmp window
12739 WinPerBit[u1BitIdx].first_pass = PASS_RANGE_NA;
12740 WinPerBit[u1BitIdx].last_pass = PASS_RANGE_NA;
12741 }
12742 }
12743 }
12744 }
12745
12746 min_winsize = 0xffff;
12747 min_bit = 0xff;
12748 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12749 {
12750 VrefWinPerBit[u1BitIdx].win_size = VrefWinPerBit[u1BitIdx].last_pass- VrefWinPerBit[u1BitIdx].first_pass +(VrefWinPerBit[u1BitIdx].last_pass==VrefWinPerBit[u1BitIdx].first_pass?0:1);
12751
12752 if (VrefWinPerBit[u1BitIdx].win_size < min_winsize)
12753 {
12754 min_bit = u1BitIdx;
12755 min_winsize = VrefWinPerBit[u1BitIdx].win_size;
12756 }
12757
12758 u2TempWinSum += VrefWinPerBit[u1BitIdx].win_size; //Sum of CA Windows for vref selection
12759
12760#if EYESCAN_LOG
12761 gEyeScan_WinSize[u2VrefLevel+u2VrefRange*30][u1BitIdx] = VrefWinPerBit[u1BitIdx].win_size;
12762#endif
12763
12764#ifdef FOR_HQA_TEST_USED
12765 if((((u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&1) == u2VrefRange) && ((u1MR14Value[p->channel][p->rank][p->dram_fsp]&0x3f)==u2VrefLevel))
12766 {
12767 gFinalTXPerbitWin[p->channel][p->rank][u1BitIdx] = VrefWinPerBit[u1BitIdx].win_size;
12768 }
12769#endif
12770 }
12771
12772 if ((min_winsize > TXPerbitWin_min_max) || ((min_winsize == TXPerbitWin_min_max) && (u2TempWinSum >u2tx_window_sum)))
12773 {
12774 TXPerbitWin_min_max = min_winsize;
12775 u2tx_window_sum =u2TempWinSum;
12776 u2FinalRange = u2VrefRange;
12777 u2FinalVref = u2VrefLevel;
12778
12779 //Calculate the center of DQ pass window
12780 // Record center sum of each byte
12781 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
12782 {
12783 #if 1//TX_DQM_CALC_MAX_MIN_CENTER
12784 u2Center_min[u1ByteIdx] = 0xffff;
12785 u2Center_max[u1ByteIdx] = 0;
12786 #endif
12787
12788 for (u1BitIdx=0; u1BitIdx<DQS_BIT_NUMBER; u1BitIdx++)
12789 {
12790 ucindex = u1ByteIdx * DQS_BIT_NUMBER + u1BitIdx;
12791 FinalWinPerBit[ucindex].first_pass = VrefWinPerBit[ucindex].first_pass;
12792 FinalWinPerBit[ucindex].last_pass = VrefWinPerBit[ucindex].last_pass;
12793 FinalWinPerBit[ucindex].win_size = VrefWinPerBit[ucindex].win_size;
12794 FinalWinPerBit[ucindex].win_center = (FinalWinPerBit[ucindex].first_pass + FinalWinPerBit[ucindex].last_pass) >> 1;
12795
12796 if(FinalWinPerBit[ucindex].win_center < u2Center_min[u1ByteIdx])
12797 u2Center_min[u1ByteIdx] = FinalWinPerBit[ucindex].win_center;
12798
12799 if(FinalWinPerBit[ucindex].win_center > u2Center_max[u1ByteIdx])
12800 u2Center_max[u1ByteIdx] = FinalWinPerBit[ucindex].win_center;
12801 }
12802 }
12803 }
12804
12805
12806 if(u2VrefRange==0 && u2VrefLevel ==50)
12807 {
12808 u2VrefRange = 1;
12809 u2VrefLevel = 20;
12810 }
12811
12812 for (u1BitIdx = 0; u1BitIdx < p->data_width; u1BitIdx++)
12813 {
12814 if (u1pass_in_this_vref_flag[u1BitIdx]) gEyeScan_ContinueVrefHeight[u1BitIdx]++; //count pass number of continue vref
12815 }
12816 }
12817
12818 DramcEngine2End(p);
12819
12820 //Calculate the center of DQ pass window
12821 //average the center delay
12822 for (u1ByteIdx=0; u1ByteIdx<(p->data_width/DQS_BIT_NUMBER); u1ByteIdx++)
12823 {
12824 uiDelay = ((u2Center_min[u1ByteIdx] + u2Center_max[u1ByteIdx])>>1); //(max +min)/2
12825
12826#if EYESCAN_LOG
12827#if VENDER_JV_LOG || defined(RELEASE)
12828 gEyeScan_CaliDelay[u1ByteIdx] = uiDelay;
12829#else
12830 gEyeScan_CaliDelay[u1ByteIdx] = uiDelay + tx_pi_delay[u1ByteIdx]-32;
12831#endif
12832#endif
12833 }
12834
12835
12836 //restore to orignal value
12837 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
12838
12839 DramcModeRegWriteByRank(p, p->rank, 14, backup_u1MR14Value);
12840 u1MR14Value[p->channel][p->rank][p->dram_fsp] = backup_u1MR14Value;
12841
12842}
12843#endif
12844
12845
12846#ifdef FOR_HQA_TEST_USED
12847void HQA_measure_message_reset_all_data(DRAMC_CTX_T *p)
12848{
12849 U32 u1BitIdx, u1RankIdx, u1ChannelIdx;
12850
12851 for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<CHANNEL_NUM; u1ChannelIdx++)
12852 {
12853 for(u1RankIdx=RANK_0; u1RankIdx<RANK_MAX; u1RankIdx++)
12854 {
12855 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
12856 {
12857 gFinalRXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx] =0;
12858 gFinalTXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx] =0;
12859 }
12860 }
12861 }
12862}
12863#endif
12864
12865#ifdef FOR_HQA_REPORT_USED
12866void print_EyeScanVcent_for_HQA_report_used(DRAMC_CTX_T *p, U8 print_type, U8 u1ChannelIdx, U8 u1RankIdx, U8 *EyeScanVcent, U8 EyeScanVcentUpperBound, U8 EyeScanVcentUpperBound_bit, U8 EyeScanVcentLowerBound, U8 EyeScanVcentLowerBound_bit)
12867{
12868 U32 uiCA, u1BitIdx;
12869 U16 *pCBTVref_Voltage_Table[VREF_VOLTAGE_TABLE_NUM];
12870 U16 *pTXVref_Voltage_Table[VREF_VOLTAGE_TABLE_NUM];
12871 U8 CBTVrefRange;
12872 U8 TXVrefRange;
12873 U32 vddq;
12874 U8 local_channel_num=2;
12875 U8 shuffleIdx;
12876 U8 u1CBTEyeScanEnable, u1RXEyeScanEnable, u1TXEyeScanEnable;
12877
12878 mcSHOW_DBG_MSG(("\n"));
12879
12880 if(u1IsLP4Family(p->dram_type))
12881 {
12882 local_channel_num = p->support_channel_num;
12883 }
12884 else
12885 {
12886 //LP3
12887 local_channel_num = 1;
12888 }
12889
12890 u1CBTEyeScanEnable = (gCBT_EYE_Scan_flag==1 && ((gCBT_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gCBT_EYE_Scan_only_higheset_freq_flag==0));
12891 u1RXEyeScanEnable = (gRX_EYE_Scan_flag==1 && ((gRX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gRX_EYE_Scan_only_higheset_freq_flag==0));
12892 u1TXEyeScanEnable = (gTX_EYE_Scan_flag==1 && ((gTX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gTX_EYE_Scan_only_higheset_freq_flag==0));
12893
12894 shuffleIdx = get_shuffleIndex_by_Freq(p);
12895
12896 if (gHQALog_flag==1 && print_type==0)
12897 {
12898 if (u1CBTEyeScanEnable)
12899 {
12900 if (p->dram_type == TYPE_LPDDR4)
12901 {
12902 pCBTVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_0];
12903 pCBTVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_1];
12904 }
12905 if (p->dram_type == TYPE_LPDDR4X)
12906 {
12907 pCBTVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_0];
12908 pCBTVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_1];
12909 }
12910
12911 CBTVrefRange = (u1MR12Value[p->channel][p->rank][p->dram_fsp]>>6)&1;
12912 vddq=vGetVoltage(p, 2)/1000; //mv
12913
12914 mcSHOW_DBG_MSG(("\n\n\n[HQA] information for measurement, "));
12915 mcSHOW_DBG_MSG(("\tDram Data rate = %d\n",p->frequency*2));
12916
12917 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent Voltage\n"));
12918 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Final_Vref Vcent", 0, pCBTVref_Voltage_Table[EyeScanVcent[0]][EyeScanVcent[1]]*vddq/100, NULL);
12919 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_VdlVWHigh_Upper Vcent", 0, pCBTVref_Voltage_Table[EyeScanVcent[2]][EyeScanVcent[3]]*vddq/100, NULL);
12920 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_VdlVWHigh_Lower Vcent", 0, pCBTVref_Voltage_Table[EyeScanVcent[4]][EyeScanVcent[5]]*vddq/100, NULL);
12921
12922 mcSHOW_DBG_MSG(("\n"));
12923
12924 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_UpperBound window\n"));
12925 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_UpperBound_Window", 0, EyeScanVcentUpperBound, NULL);
12926 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_UpperBound_Window worse bit\n"));
12927 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_UpperBound_Window_bit", 0, EyeScanVcentUpperBound_bit, NULL);
12928 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_UpperBound Min Window(%%)\n"));
12929 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_UpperBound_Window(%)", 0, (EyeScanVcentUpperBound * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32), NULL);
12930 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_UpperBound Min Window PASS/FAIL\n"));
12931 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "CBT_Vcent_UpperBound_Window_PF", 0, 0, (EyeScanVcentUpperBound * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32) >= 25 ? "PASS" : "FAIL");
12932
12933 mcSHOW_DBG_MSG(("\n"));
12934
12935
12936 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_LowerBound window\n"));
12937 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_LowerBound_Window", 0, EyeScanVcentLowerBound, NULL);
12938 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_LowerBound_Window worse bit\n"));
12939 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_LowerBound_Window_bit", 0, EyeScanVcentLowerBound_bit, NULL);
12940 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_UpperBound Min Window(%%)\n"));
12941 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "CBT_Vcent_LowerBound_Window(%)", 0, (EyeScanVcentLowerBound * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32), NULL);
12942 mcSHOW_DBG_MSG(("CBT Eye Scan Vcent_LowerBound Min Window PASS/FAIL\n"));
12943 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "CBT_Vcent_LowerBound_Window_PF", 0, 0, (EyeScanVcentLowerBound * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32) >= 25 ? "PASS" : "FAIL");
12944
12945 mcSHOW_DBG_MSG(("\n"));
12946 mcSHOW_DBG_MSG(("CA Eye Scan per_bit window(%%)\n"));
12947 for (uiCA=0; uiCA<CATRAINING_NUM_LP4; uiCA++)
12948 {
12949#if EYESCAN_LOG
12950 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Window(%)", uiCA, ((gEyeScan_WinSize[EyeScanVcent[0]*30+EyeScanVcent[1]][uiCA]) * 100 + 31) / 32, NULL);
12951 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_BestWindow(%)", uiCA, ((gEyeScan_WinSize[EyeScanVcent[10+uiCA*2]*30+EyeScanVcent[10+uiCA*2+1]][uiCA]) * 100 + 31) / 32, NULL);
12952 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Window_Upperbond(%)", uiCA, ((gEyeScan_WinSize[EyeScanVcent[2]*30+EyeScanVcent[3]][uiCA]) * 100 + 31) / 32, NULL);
12953 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Window_Lowerbond(%) ", uiCA, ((gEyeScan_WinSize[EyeScanVcent[4]*30+EyeScanVcent[5]][uiCA]) * 100 + 31) / 32, NULL);
12954 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Eye_Height", uiCA, (gEyeScan_ContinueVrefHeight[uiCA]-1)*6*vddq/1000, NULL);
12955// HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Eye_Area", uiCA, gEyeScan_TotalPassCount[uiCA]*1000*3*vddq/(32*DDRPhyFMeter()), NULL); //total count*1/32UI*(1/freq*10^6 ps)*(0.6%vddq)
12956 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_2, "CA_Perbit_Eye_Area", uiCA, (gEyeScan_TotalPassCount[uiCA]*10*3*vddq/(32*DDRPhyFMeter()))*100, NULL); //total count*1/32UI*(1/freq*10^6 ps)*(0.6%vddq)
12957#endif
12958 }
12959 }
12960 }
12961
12962 if (gHQALog_flag==1 && print_type==1)
12963 {
12964 if (u1RXEyeScanEnable)
12965 {
12966 mcSHOW_DBG_MSG(("\n\n\n[HQA] information for measurement, "));
12967 mcSHOW_DBG_MSG(("\tDram Data rate = %d\n",p->frequency*2));
12968
12969 mcSHOW_DBG_MSG(("RX Eye Scan Vcent Voltage\n"));
12970 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Final_Vref Vcent", 0, gRXVref_Voltage_Table_LP4[EyeScanVcent[0]], NULL);
12971 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_VdlVWHigh_Upper Vcent", 0, gRXVref_Voltage_Table_LP4[EyeScanVcent[1]], NULL);
12972 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_VdlVWHigh_Lower Vcent", 0, gRXVref_Voltage_Table_LP4[EyeScanVcent[2]], NULL);
12973
12974 mcSHOW_DBG_MSG(("\n"));
12975
12976 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_UpperBound window\n"));
12977 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_UpperBound_Window", 0, EyeScanVcentUpperBound, NULL);
12978 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_UpperBound_Window worse bit\n"));
12979 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_UpperBound_Window_bit", 0, EyeScanVcentUpperBound_bit, NULL);
12980 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_UpperBound Min Window(%%)\n"));
12981 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_UpperBound_Window(%)", 0, ((EyeScanVcentUpperBound * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
12982 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_UpperBound Min Window PASS/FAIL\n"));
12983 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "RX_Vcent_UpperBound_Window_PF", 0, 0, ((EyeScanVcentUpperBound * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000 >= 20 ? "PASS" : "FAIL");
12984
12985 mcSHOW_DBG_MSG(("\n"));
12986
12987
12988 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_LowerBound window\n"));
12989 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_LowerBound_Window", 0, EyeScanVcentLowerBound, NULL);
12990 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_LowerBound_Window worse bit\n"));
12991 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_LowerBound_Window_bit", 0, EyeScanVcentLowerBound_bit, NULL);
12992 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_UpperBound Min Window(%%)\n"));
12993 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "RX_Vcent_LowerBound_Window(%)", 0, ((EyeScanVcentLowerBound * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
12994 mcSHOW_DBG_MSG(("RX Eye Scan Vcent_LowerBound Min Window PASS/FAIL\n"));
12995 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "RX_Vcent_LowerBound_Window_PF", 0, 0, ((EyeScanVcentLowerBound * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000 >= 20 ? "PASS" : "FAIL");
12996
12997
12998 mcSHOW_DBG_MSG(("\n"));
12999 mcSHOW_DBG_MSG(("RX Eye Scan per_bit window(%%)\n"));
13000 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
13001 {
13002#if EYESCAN_LOG
13003 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_Window(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[0]][u1BitIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
13004 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_BestWindow(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[10+u1BitIdx]][u1BitIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
13005 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_Window_Upperbond(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[1]][u1BitIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
13006 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_Window_Lowerbond(%) ", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[2]][u1BitIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
13007 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_Eye_Height", u1BitIdx, (gEyeScan_ContinueVrefHeight[u1BitIdx]-1)*1330/100, NULL); //RX vref height 1225 ~ 1440, use 1330mv
13008 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "RX_Perbit_Eye_Area", u1BitIdx, gEyeScan_TotalPassCount[u1BitIdx]*u2gdelay_cell_ps_all[get_shuffleIndex_by_Freq(p)][u1ChannelSet[0]]*133/1000, NULL); //total count*jitter metter delay cell*(1/freq*10^6 ps)*(1330mv)
13009#endif
13010 }
13011 }
13012 }
13013
13014 if (gHQALog_flag==1 && print_type==2)
13015 {
13016 if (u1TXEyeScanEnable)
13017 {
13018 if (p->dram_type == TYPE_LPDDR4)
13019 {
13020 pTXVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_0];
13021 pTXVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_1];
13022 }
13023 if (p->dram_type == TYPE_LPDDR4X)
13024 {
13025 pTXVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_0];
13026 pTXVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_1];
13027 }
13028
13029 TXVrefRange = (u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&1;
13030 vddq=vGetVoltage(p, 2)/1000; //mv
13031
13032 mcSHOW_DBG_MSG(("\n\n\n[HQA] information for measurement, "));
13033 mcSHOW_DBG_MSG(("\tDram Data rate = %d\n",p->frequency*2));
13034
13035 mcSHOW_DBG_MSG(("TX Eye Scan Vcent Voltage\n"));
13036 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Final_Vref Vcent", 0, pTXVref_Voltage_Table[EyeScanVcent[0]][EyeScanVcent[1]]*vddq/100, NULL);
13037 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_VdlVWHigh_Upper Vcent", 0, pTXVref_Voltage_Table[EyeScanVcent[2]][EyeScanVcent[3]]*vddq/100, NULL);
13038 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_VdlVWHigh_Lower Vcent", 0, pTXVref_Voltage_Table[EyeScanVcent[4]][EyeScanVcent[5]]*vddq/100, NULL);
13039
13040 mcSHOW_DBG_MSG(("\n"));
13041
13042 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_UpperBound window\n"));
13043 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_UpperBound_Window", 0, EyeScanVcentUpperBound, NULL);
13044 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_UpperBound_Window worse bit\n"));
13045 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_UpperBound_Window_bit", 0, EyeScanVcentUpperBound_bit, NULL);
13046 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_UpperBound Min Window(%%)\n"));
13047 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_UpperBound_Window(%)", 0, (EyeScanVcentUpperBound * 100 + 31) / 32, NULL);
13048 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_UpperBound Min Window PASS/FAIL\n"));
13049 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "TX_Vcent_UpperBound_Window_PF", 0, 0, (EyeScanVcentUpperBound * 100 + 31) / 32 >= 20 ? "PASS" : "FAIL");
13050
13051 mcSHOW_DBG_MSG(("\n"));
13052
13053 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_LowerBound window\n"));
13054 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_LowerBound_Window", 0, EyeScanVcentLowerBound, NULL);
13055 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_LowerBound_Window worse bit\n"));
13056 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_LowerBound_Window_bit", 0, EyeScanVcentLowerBound_bit, NULL);
13057 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_UpperBound Min Window(%%)\n"));
13058 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT2, "TX_Vcent_LowerBound_Window(%)", 0, (EyeScanVcentLowerBound * 100 + 31) / 32, NULL);
13059 mcSHOW_DBG_MSG(("TX Eye Scan Vcent_LowerBound Min Window PASS/FAIL\n"));
13060 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT4, "TX_Vcent_LowerBound_Window_PF", 0, 0, (EyeScanVcentLowerBound * 100 + 31) / 32 >= 20 ? "PASS" : "FAIL");
13061
13062 mcSHOW_DBG_MSG(("\n"));
13063 mcSHOW_DBG_MSG(("TX Eye Scan per_bit window(%%)\n"));
13064 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
13065 {
13066#if EYESCAN_LOG
13067 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Window(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[0]*30+EyeScanVcent[1]][u1BitIdx]) * 100 + 31) / 32, NULL);
13068 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_BestWindow(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[10+u1BitIdx*2]*30+EyeScanVcent[10+u1BitIdx*2+1]][u1BitIdx]) * 100 + 31) / 32, NULL);
13069 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Window_Upperbond(%)", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[2]*30+EyeScanVcent[3]][u1BitIdx]) * 100 + 31) / 32, NULL);
13070 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Window_Lowerbond(%) ", u1BitIdx, ((gEyeScan_WinSize[EyeScanVcent[4]*30+EyeScanVcent[5]][u1BitIdx]) * 100 + 31) / 32, NULL);
13071 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Eye_Height", u1BitIdx, (gEyeScan_ContinueVrefHeight[u1BitIdx]-1)*6*vddq/1000, NULL);
13072// HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Eye_Area", u1BitIdx, gEyeScan_TotalPassCount[u1BitIdx]*1000*3*vddq/(32*DDRPhyFMeter()), NULL); //total count*1/32UI*(1/freq*10^6 ps)*(0.6%vddq)
13073 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT0_1, "TX_Perbit_Eye_Area", u1BitIdx, (gEyeScan_TotalPassCount[u1BitIdx]*10*3*vddq/(32*DDRPhyFMeter()))*100, NULL); //total count*1/32UI*(1/freq*10^6 ps)*(0.6%vddq)
13074#endif
13075 }
13076 }
13077 }
13078
13079 mcSHOW_DBG_MSG(("\n"));
13080}
13081#endif
13082
13083
13084#ifdef FOR_HQA_REPORT_USED
13085void HQA_Log_Message_for_Report(DRAMC_CTX_T *p, U8 u1ChannelIdx, U8 u1RankIdx, U32 who_am_I, U8 *main_str, U8 byte_bit_idx, S32 value1, U8 *ans_str)
13086{
13087 // HQA_REPORT_FORMAT0 : [HQALOG] 3200 Gating_Center_2T Channel0 Rank0 Byte0 3
13088 // HQA_REPORT_FORMAT0_1:[HQALOG] 3200 Gating_Center_2T Channel0 Rank0 Bit0 3
13089 // HQA_REPORT_FORMAT0_2:[HQALOG] 3200 Gating_Center_2T Channel0 Rank0 CA0 3
13090 // HQA_REPORT_FORMAT1 : [HQALOG] 3200 WriteLeveling_DQS0 Channel0 Rank0 35
13091 // HQA_REPORT_FORMAT2 : [HQALOG] 3200 TX_Final_Vref Vcent Channel0 Rank0 16860
13092 // HQA_REPORT_FORMAT3 : [HQALOG] 3200 DUTY CLK_MAX Channel0 5171
13093 // HQA_REPORT_FORMAT4 : [HQALOG] 3200 TX_Vcent_LowerBound_Window_PF Channel0 Rank0 PASS
13094 // HQA_REPORT_FORMAT5 : [HQALOG] 3200 AAAAAAAAAAAA BBBBB
13095 // HQA_REPORT_FORMAT6 : [HQALOG] 3200 AAAAAAAAAAAA 0
13096
13097 if (gHQALog_flag==1)
13098 {
13099 mcSHOW_DBG_MSG(("[HQALOG] %d %s", p->frequency*2, main_str ));
13100 switch (who_am_I)
13101 {
13102 case HQA_REPORT_FORMAT1:
13103 mcSHOW_DBG_MSG(("%d", byte_bit_idx));
13104 break;
13105 }
13106
13107 if (who_am_I == HQA_REPORT_FORMAT3)
13108 {
13109 mcSHOW_DBG_MSG((" Channel%d ", u1ChannelIdx));
13110 }
13111 else if (who_am_I != HQA_REPORT_FORMAT5 && who_am_I != HQA_REPORT_FORMAT6)
13112 {
13113 mcSHOW_DBG_MSG((" Channel%d Rank%d ", u1ChannelIdx, u1RankIdx));
13114 }
13115
13116 switch (who_am_I)
13117 {
13118 case HQA_REPORT_FORMAT0:
13119 mcSHOW_DBG_MSG(("Byte%d %d\n", byte_bit_idx, value1));
13120 break;
13121 case HQA_REPORT_FORMAT0_1:
13122 mcSHOW_DBG_MSG(("Bit%x %d\n", byte_bit_idx, value1));
13123 break;
13124 case HQA_REPORT_FORMAT0_2:
13125 mcSHOW_DBG_MSG(("CA%x %d\n", byte_bit_idx, value1));
13126 break;
13127 case HQA_REPORT_FORMAT1:
13128 case HQA_REPORT_FORMAT2:
13129 case HQA_REPORT_FORMAT3:
13130 case HQA_REPORT_FORMAT6:
13131 mcSHOW_DBG_MSG(("%d\n", value1));
13132 break;
13133 case HQA_REPORT_FORMAT4:
13134 case HQA_REPORT_FORMAT5:
13135 mcSHOW_DBG_MSG((" %s\n", ans_str));
13136 break;
13137 }
13138 }
13139}
13140
13141#endif
13142
13143
13144#ifdef FOR_HQA_TEST_USED
13145#ifdef RELEASE
13146#undef mcSHOW_DBG_MSG
13147#define mcSHOW_DBG_MSG(_x_) opt_print _x_
13148#endif
13149void print_HQA_measure_message(DRAMC_CTX_T *p)
13150{
13151 U32 uiCA, u1BitIdx, u1RankIdx;
13152 U32 min_ca_value[CHANNEL_NUM][RANK_MAX], min_ca_bit[CHANNEL_NUM][RANK_MAX];
13153 U32 min_rx_value[CHANNEL_NUM][RANK_MAX], min_tx_value[CHANNEL_NUM][RANK_MAX];
13154 U32 min_RX_DQ_bit[CHANNEL_NUM][RANK_MAX], min_TX_DQ_bit[CHANNEL_NUM][RANK_MAX];
13155 U8 shuffleIdx, local_channel_num=2, shuffle_index;
13156 U8 print_imp_option[2]={FALSE, FALSE};
13157 U8 u1ChannelIdx, u1Channel;
13158 int i;
13159
13160 mcSHOW_DBG_MSG(("\n\n\n[HQA] information for measurement, "));
13161 mcSHOW_DBG_MSG(("\tDram Data rate = %d\n",p->frequency*2));
13162 vPrintCalibrationBasicInfo(p);
13163 mcSHOW_DBG_MSG(("[HQALOG] %d Frequency = %u\n", p->frequency*2, DDRPhyFMeter()));
13164
13165 shuffleIdx = get_shuffleIndex_by_Freq(p);
13166
13167 if(u1IsLP4Family(p->dram_type))
13168 {
13169 local_channel_num = p->support_channel_num;
13170 }
13171#if ENABLE_LP3_SW
13172 else
13173 {
13174 //LP3
13175 local_channel_num = 1;
13176 }
13177#endif
13178
13179 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13180 {
13181 u1ChannelIdx = u1ChannelSet[u1Channel];
13182
13183 for(u1RankIdx=RANK_0; u1RankIdx<p->support_rank_num; u1RankIdx++)
13184 {
13185 min_ca_value[u1ChannelIdx][u1RankIdx] = 0xffff;
13186 min_rx_value[u1ChannelIdx][u1RankIdx] = 0xffff;
13187 min_tx_value[u1ChannelIdx][u1RankIdx] = 0xffff;
13188 min_RX_DQ_bit[u1ChannelIdx][u1RankIdx] = 0xffff;
13189 min_TX_DQ_bit[u1ChannelIdx][u1RankIdx] = 0xffff;
13190
13191 for (uiCA=0; uiCA<((u1IsLP4Family(p->dram_type)==1) ? CATRAINING_NUM_LP4 : CATRAINING_NUM_LP3); uiCA++)
13192 {
13193 if (gFinalCBTCA[u1ChannelIdx][u1RankIdx][uiCA] < min_ca_value[u1ChannelIdx][u1RankIdx])
13194 {
13195 min_ca_value[u1ChannelIdx][u1RankIdx] = gFinalCBTCA[u1ChannelIdx][u1RankIdx][uiCA];
13196 min_ca_bit[u1ChannelIdx][u1RankIdx] = uiCA;
13197 }
13198 }
13199
13200 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
13201 {
13202 if (gFinalRXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx] < min_rx_value[u1ChannelIdx][u1RankIdx])
13203 {
13204 min_rx_value[u1ChannelIdx][u1RankIdx] = gFinalRXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx];
13205 min_RX_DQ_bit[u1ChannelIdx][u1RankIdx] = u1BitIdx;
13206 }
13207 if (gFinalTXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx] < min_tx_value[u1ChannelIdx][u1RankIdx])
13208 {
13209 min_tx_value[u1ChannelIdx][u1RankIdx] = gFinalTXPerbitWin[u1ChannelIdx][u1RankIdx][u1BitIdx];
13210 min_TX_DQ_bit[u1ChannelIdx][u1RankIdx] = u1BitIdx;
13211 }
13212 }
13213 }
13214 }
13215
13216
13217 if (p->support_rank_num==RANK_DUAL)
13218 {
13219 //Preloader LP3 RX/TX only K Rank0, so Rank1 use Rank0's value
13220 if(!u1IsLP4Family(p->dram_type))
13221 {
13222#ifndef LP3_DUAL_RANK_RX_K
13223 min_rx_value[0][1] = min_rx_value[0][0];
13224 min_RX_DQ_bit[0][1] = min_RX_DQ_bit[0][0];
13225#endif
13226
13227#ifndef LP3_DUAL_RANK_TX_K
13228 min_tx_value[0][1] = min_tx_value[0][0];
13229 gFinalTXPerbitWin_min_max[0][1] = gFinalTXPerbitWin_min_max[0][0];
13230 min_TX_DQ_bit[0][1] = min_TX_DQ_bit[0][0];
13231#endif
13232
13233 #if 0//(TX_PER_BIT_DELAY_CELL==0)
13234 gFinalTXPerbitWin_min_margin[0][1] = gFinalTXPerbitWin_min_margin[0][0];
13235 gFinalTXPerbitWin_min_margin_bit[0][1] = gFinalTXPerbitWin_min_margin_bit[0][0];
13236 #endif
13237 }
13238 }
13239
13240
13241#if defined(DRAM_HQA)
13242 mcSHOW_DBG_MSG(("[Read Voltage]\n"));
13243 mcSHOW_DBG_MSG(("[HQALOG] %d Vcore_HQA = %d\n", p->frequency*2, vGetVoltage(p, 0)));
13244
13245 if (u1IsLP4Family(p->dram_type)) {
13246 /* LPDDR4 */
13247 mcSHOW_DBG_MSG(("[HQALOG] %d Vdram_HQA = %d\n", p->frequency*2, vGetVoltage(p, 1)));
13248 mcSHOW_DBG_MSG(("[HQALOG] %d Vddq_HQA = %d\n", p->frequency*2, vGetVoltage(p, 2)));
13249 mcSHOW_DBG_MSG(("[HQALOG] %d Vdd1_HQA = %d\n", p->frequency*2, vGetVoltage(p, 3)));
13250 } else {
13251 /* LPDDR3 */
13252 mcSHOW_DBG_MSG(("[HQALOG] %d Vdram_HQA = %d\n", p->frequency*2, vGetVoltage(p, 1)));
13253 mcSHOW_DBG_MSG(("[HQALOG] %d Vdd1_HQA = %d\n", p->frequency*2, vGetVoltage(p, 3)));
13254 }
13255 mcSHOW_DBG_MSG(("\n"));
13256#endif
13257
13258 /*
13259 [Impedance Calibration]
13260
13261 term_option=0
13262 [HQALOG] Impedance term_option=0 DRVP 11
13263 [HQALOG] Impedance term_option=0 DRVN 7
13264
13265 term_option=1
13266 [HQALOG] Impedance term_option=1 DRVP 13
13267 [HQALOG] Impedance term_option=1 ODTN 15
13268 */
13269 if (p->dram_type == TYPE_LPDDR4)
13270 {
13271 print_imp_option[1] = TRUE;
13272 }
13273 else if (p->dram_type == TYPE_LPDDR4X)
13274 {
13275 print_imp_option[0] = TRUE;
13276 print_imp_option[1] = TRUE;
13277 }
13278 else
13279 {
13280 //TYPE_LPDDR4P, TYPE_LPDDR3
13281 print_imp_option[0] = TRUE;
13282 }
13283
13284#ifdef FOR_HQA_REPORT_USED
13285if (gHQALog_flag==1)
13286{
13287 mcSHOW_DBG_MSG(("[Impedance Calibration]\n"));
13288 for(i=0; i<2; i++)
13289 {
13290 mcSHOW_DBG_MSG(("term_option=%d\n", i));
13291 if (print_imp_option[i]==FALSE || (print_imp_option[i]==TRUE && p->odt_onoff==ODT_OFF && i==1) || (print_imp_option[i]==TRUE && p->odt_onoff==ODT_ON && i==0))
13292 {
13293 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT5, i==0 ? "Impedance term_option=0 DRVP" : "Impedance term_option=1 DRVP", 0, 0, "NA");
13294 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT5, i==0 ? "Impedance term_option=0 DRVN" : "Impedance term_option=1 ODTN", 0, 0, "NA");
13295 }
13296 else
13297 {
13298 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT6, i==0 ? "Impedance term_option=0 DRVP" : "Impedance term_option=1 DRVP", 0, gDramcSwImpedanceResule[i][DRVP], NULL);
13299 HQA_Log_Message_for_Report(p, p->channel, p->rank, HQA_REPORT_FORMAT6, i==0 ? "Impedance term_option=0 DRVN" : "Impedance term_option=1 ODTN", 0, i==0 ? gDramcSwImpedanceResule[i][DRVN] : gDramcSwImpedanceResule[i][ODTN], NULL);
13300 }
13301 }
13302 mcSHOW_DBG_MSG(("\n"));
13303}
13304#endif
13305
13306
13307
13308
13309if(u1IsLP4Family(p->dram_type))
13310{
13311 mcSHOW_DBG_MSG(("\n[Cmd Bus Training window]\n"));
13312 if(u1IsLP4Family(p->dram_type))
13313 {
13314 mcSHOW_DBG_MSG(("VrefCA Range : %d\n", gCBT_VREF_RANGE_SEL));
13315 /*
13316 VrefCA
13317 [HQALOG] 1600 VrefCA Channel0 Rank0 32
13318 [HQALOG] 1600 VrefCA Channel0 Rank1 24
13319 [HQALOG] 1600 VrefCA Channel1 Rank0 26
13320 [HQALOG] 1600 VrefCA Channel1 Rank1 30
13321 */
13322 mcSHOW_DBG_MSG(("VrefCA\n"));
13323 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13324 {
13325 u1ChannelIdx = u1ChannelSet[u1Channel];
13326
13327 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13328 {
13329 mcSHOW_DBG_MSG(("[HQALOG] %d VrefCA Channel%d "
13330 "Rank%d %d\n",
13331 p->frequency*2,
13332 u1ChannelIdx,
13333 u1RankIdx,
13334 gFinalCBTVrefCA[u1ChannelIdx][u1RankIdx]));
13335 }
13336 }
13337 }
13338
13339#if 0//(SUPPORT_SAVE_TIME_FOR_CALIBRATION && BYPASS_CBT)
13340 if(p->femmc_Ready==1 )
13341 {
13342 mcSHOW_DBG_MSG(("\n[Cmd Bus Training window bypass calibration]\n"));
13343 }
13344 else
13345#endif
13346 {
13347 /*
13348 CA_Window
13349 [HQALOG] 1600 CA_Window Channel0 Rank0 61(bit 2)
13350 [HQALOG] 1600 CA_Window Channel0 Rank1 62(bit 1)
13351 [HQALOG] 1600 CA_Window Channel1 Rank0 60(bit 5)
13352 [HQALOG] 1600 CA_Window Channel1 Rank1 60(bit 5)
13353 */
13354 mcSHOW_DBG_MSG(("CA_Window\n"));
13355#ifdef FOR_HQA_REPORT_USED
13356if (gHQALog_flag==1)
13357{
13358 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13359 {
13360 u1ChannelIdx = u1ChannelSet[u1Channel];
13361
13362 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13363 {
13364 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "CA_Window", 0, min_ca_value[u1ChannelIdx][u1RankIdx], NULL);
13365 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "CA_Window_bit", 0, min_ca_bit[u1ChannelIdx][u1RankIdx], NULL);
13366 }
13367 }
13368 mcSHOW_DBG_MSG(("\n"));
13369}
13370else
13371#endif
13372{
13373 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13374 {
13375 u1ChannelIdx = u1ChannelSet[u1Channel];
13376
13377 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13378 {
13379 mcSHOW_DBG_MSG(("[HQALOG] %d CA_Window Channel%d "
13380 "Rank%d %d (bit %d)\n",
13381 p->frequency*2,
13382 u1ChannelIdx,
13383 u1RankIdx,
13384 min_ca_value[u1ChannelIdx][u1RankIdx], min_ca_bit[u1ChannelIdx][u1RankIdx]));
13385 }
13386 }
13387}
13388
13389 /*
13390 CA Min Window(%)
13391 [HQALOG] 1600 CA_Window(%) Channel0 Rank0 96%(PASS)
13392 [HQALOG] 1600 CA_Window(%) Channel0 Rank1 97%(PASS)
13393 [HQALOG] 1600 CA_Window(%) Channel1 Rank0 94%(PASS)
13394 [HQALOG] 1600 CA_Window(%) Channel1 Rank1 94%(PASS)
13395 */
13396 mcSHOW_DBG_MSG(("CA Min Window(%%)\n"));
13397#ifdef FOR_HQA_REPORT_USED
13398if (gHQALog_flag==1)
13399{
13400 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13401 {
13402 u1ChannelIdx = u1ChannelSet[u1Channel];
13403
13404 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13405 {
13406 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "CA_Window(%)", 0, ((min_ca_value[u1ChannelIdx][u1RankIdx] * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32)), NULL);
13407 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT4, "CA_Window_PF", 0, 0, ((((min_ca_value[u1ChannelIdx][u1RankIdx] * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32)) >= 30) ? "PASS" : "FAIL"));
13408 }
13409 }
13410 mcSHOW_DBG_MSG(("\n"));
13411}
13412else
13413#endif
13414{
13415 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13416 {
13417 u1ChannelIdx = u1ChannelSet[u1Channel];
13418
13419 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13420 {
13421 mcSHOW_DBG_MSG(("[HQALOG] %d CA_Window(%%) Channel%d "
13422 "Rank%d %d%% (%s)\n",
13423 p->frequency*2,
13424 u1ChannelIdx,
13425 u1RankIdx,
13426 ((min_ca_value[u1ChannelIdx][u1RankIdx] * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32)),
13427 ((((min_ca_value[u1ChannelIdx][u1RankIdx] * 100 + (u1IsLP4Family(p->dram_type)==1?63:31)) / (u1IsLP4Family(p->dram_type)==1?64:32)) >= 30) ? "PASS" : "FAIL")));
13428 }
13429 }
13430}
13431 }
13432 mcSHOW_DBG_MSG(("\n"));
13433}
13434
13435
13436 /*
13437 [RX minimum per bit window]
13438 Delay cell measurement (/100ps)
13439 [HQALOG] 3200 delaycell 892
13440 */
13441 mcSHOW_DBG_MSG(("\n[RX minimum per bit window]\n"));
13442 mcSHOW_DBG_MSG(("Delaycell measurement(/100ps)\n"));
13443#if !defined(RELEASE) && (VENDER_JV_LOG==0)
13444 mcSHOW_DBG_MSG(("[HQALOG] %d delaycell %d\n",
13445 p->frequency*2,
13446 u2gdelay_cell_ps_all[shuffleIdx][u1ChannelSet[0]]));
13447#endif
13448 /*
13449 VrefDQ
13450 [HQALOG] 1600 VrefRX Channel0 24
13451 [HQALOG] 1600 VrefRX Channel1 24
13452 */
13453
13454 if(u1IsLP4Family(p->dram_type))
13455 {
13456 if (p->enable_rx_scan_vref == ENABLE)
13457 {
13458 mcSHOW_DBG_MSG(("VrefRX\n"));
13459 if (gRX_EYE_Scan_flag==1)
13460 {
13461 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13462 {
13463 u1ChannelIdx = u1ChannelSet[u1Channel];
13464
13465 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13466 {
13467 mcSHOW_DBG_MSG(("[HQALOG] %d VrefRX Channel%d Rank%d %d\n",
13468 p->frequency*2,
13469 u1ChannelIdx,
13470 u1RankIdx,
13471 gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]));
13472 }
13473 }
13474 }
13475 else
13476 {
13477 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13478 {
13479 u1ChannelIdx = u1ChannelSet[u1Channel];
13480
13481 mcSHOW_DBG_MSG(("[HQALOG] %d VrefRX Channel%d %d\n",
13482 p->frequency*2,
13483 u1ChannelIdx,
13484 gFinalRXVrefDQ[u1ChannelIdx][RANK_0]));
13485 }
13486 }
13487 }
13488 else
13489 {
13490 mcSHOW_DBG_MSG(("RX DQ Vref Scan : Disable\n"));
13491 }
13492 }
13493
13494#if 0//(SUPPORT_SAVE_TIME_FOR_CALIBRATION )
13495 if(p->femmc_Ready==1 && ( p->Bypass_RXWINDOW))
13496 {
13497 mcSHOW_DBG_MSG(("\n[RX minimum per bit window bypass calibration]\n"));
13498 }
13499 else
13500#endif
13501 {
13502 /*
13503 RX_Window
13504 [HQALOG] 1600 RX_Window Channel0 Rank0 52(bit 2)
13505 [HQALOG] 1600 RX_Window Channel0 Rank1 52(bit 2)
13506 [HQALOG] 1600 RX_Window Channel1 Rank0 60(bit 12)
13507 [HQALOG] 1600 RX_Window Channel1 Rank1 62(bit 9)
13508 */
13509 mcSHOW_DBG_MSG(("RX_Window\n"));
13510#ifdef FOR_HQA_REPORT_USED
13511if (gHQALog_flag==1)
13512{
13513 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13514 {
13515 u1ChannelIdx = u1ChannelSet[u1Channel];
13516
13517 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13518 {
13519 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "RX_Window", 0, min_rx_value[u1ChannelIdx][u1RankIdx], NULL);
13520 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "RX_Window_bit", 0, min_RX_DQ_bit[u1ChannelIdx][u1RankIdx], NULL);
13521 }
13522 }
13523}
13524else
13525#endif
13526{
13527 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13528 {
13529 u1ChannelIdx = u1ChannelSet[u1Channel];
13530
13531 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13532 {
13533 mcSHOW_DBG_MSG(("[HQALOG] %d RX_Window Channel%d "
13534 "Rank%d %d (bit %d)\n",
13535 p->frequency*2,
13536 u1ChannelIdx,
13537 u1RankIdx,
13538 min_rx_value[u1ChannelIdx][u1RankIdx], min_RX_DQ_bit[u1ChannelIdx][u1RankIdx]));
13539 }
13540 }
13541}
13542
13543 /*
13544 RX Min Window(%)
13545 [HQALOG] 1600 RX_Window(%) Channel0 Rank0 43316/100ps(70%)(PASS)
13546 [HQALOG] 1600 RX_Window(%) Channel0 Rank1 43316/100ps(70%)(PASS)
13547 [HQALOG] 1600 RX_Window(%) Channel1 Rank0 49980/100ps(80%)(PASS)
13548 [HQALOG] 1600 RX_Window(%) Channel1 Rank1 51646/100ps(83%)(PASS)
13549 */
13550 mcSHOW_DBG_MSG(("RX Window(%%)\n"));
13551#ifdef FOR_HQA_REPORT_USED
13552if (gHQALog_flag==1)
13553{
13554 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13555 {
13556 u1ChannelIdx = u1ChannelSet[u1Channel];
13557
13558 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13559 {
13560 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "RX_Window(%)", 0, ((min_rx_value[u1ChannelIdx][u1RankIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000, NULL);
13561 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT4, "RX_Window_PF", 0, 0, (min_rx_value[u1ChannelIdx][u1RankIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) / 1000000 >= 40 ? "PASS" : "FAIL");
13562 }
13563 }
13564}
13565else
13566#endif
13567{
13568 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13569 {
13570 u1ChannelIdx = u1ChannelSet[u1Channel];
13571
13572 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13573 {
13574 mcSHOW_DBG_MSG(("[HQALOG] %d RX_Window(%%) Channel%d "
13575 "Rank%d "
13576 "%d/100ps (%d%%) (%s)\n",
13577 p->frequency*2,
13578 u1ChannelIdx,
13579 u1RankIdx,
13580 min_rx_value[u1ChannelIdx][u1RankIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx],
13581 ((min_rx_value[u1ChannelIdx][u1RankIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000,
13582 ((min_rx_value[u1ChannelIdx][u1RankIdx] * u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx] * p->frequency * 2) + (1000000 - 1)) / 1000000 >= 40 ? "PASS" : "FAIL"));
13583 }
13584 }
13585}
13586
13587 mcSHOW_DBG_MSG(("\n"));
13588 }
13589
13590
13591
13592
13593
13594
13595 /* [TX minimum per bit window]
13596 VrefDQ Range : 1
13597 VrefDQ
13598 [HQALOG] 1600 VrefTX Channel0 Rank0 30
13599 [HQALOG] 1600 VrefTX Channel0 Rank1 25
13600 [HQALOG] 1600 VrefTX Channel1 Rank0 24
13601 [HQALOG] 1600 VrefTX Channel1 Rank1 23
13602 */
13603 mcSHOW_DBG_MSG(("\n[TX minimum per bit window]\n"));
13604 if(u1IsLP4Family(p->dram_type))
13605 {
13606 if (p->enable_tx_scan_vref == ENABLE_VREF_SCAN)
13607 {
13608 mcSHOW_DBG_MSG(("VrefDQ Range : %d\n",(u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&1));
13609 mcSHOW_DBG_MSG(("VrefDQ\n"));
13610 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13611 {
13612 u1ChannelIdx = u1ChannelSet[u1Channel];
13613
13614 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13615 {
13616 mcSHOW_DBG_MSG(("[HQALOG] %d VrefDQ Channel%d "
13617 "Rank%d %d\n",
13618 p->frequency*2,
13619 u1ChannelIdx,
13620 u1RankIdx,
13621 gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx]));
13622 }
13623 }
13624 }
13625 else
13626 {
13627 mcSHOW_DBG_MSG(("TX DQ Vref Scan : Disable\n"));
13628 }
13629 }
13630#if 0//(SUPPORT_SAVE_TIME_FOR_CALIBRATION )
13631 if(p->femmc_Ready==1 && (p->Bypass_TXWINDOW))
13632 {
13633 mcSHOW_DBG_MSG(("\n[TX minimum per bit window bypass calibration]\n"));
13634 }
13635 else
13636#endif
13637 {
13638 /*
13639 TX_Window
13640 [HQALOG] 1600 TX_Window Channel0 Rank0 25(bit 2)
13641 [HQALOG] 1600 TX_Window Channel0 Rank1 25(bit 2)
13642 [HQALOG] 1600 TX_Window Channel1 Rank0 22(bit 9)
13643 [HQALOG] 1600 TX_Window Channel1 Rank1 23(bit 9)
13644 */
13645 mcSHOW_DBG_MSG(("TX_Window\n"));
13646#ifdef FOR_HQA_REPORT_USED
13647if (gHQALog_flag==1)
13648{
13649 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13650 {
13651 u1ChannelIdx = u1ChannelSet[u1Channel];
13652
13653 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13654 {
13655 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "TX_Window", 0, gFinalTXPerbitWin_min_max[u1ChannelIdx][u1RankIdx], NULL);
13656 HQA_Log_Message_for_Report(p,u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "TX_Window_bit", 0, min_TX_DQ_bit[u1ChannelIdx][u1RankIdx], NULL);
13657 }
13658 }
13659}
13660else
13661#endif
13662{
13663 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13664 {
13665 u1ChannelIdx = u1ChannelSet[u1Channel];
13666
13667 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13668 {
13669 mcSHOW_DBG_MSG(("[HQALOG] %d TX_Window Channel%d "
13670 "Rank%d %d (bit %d)\n",
13671 p->frequency*2,
13672 u1ChannelIdx,
13673 u1RankIdx,
13674 gFinalTXPerbitWin_min_max[u1ChannelIdx][u1RankIdx], min_TX_DQ_bit[u1ChannelIdx][u1RankIdx]));
13675 }
13676 }
13677}
13678#if 0//(TX_PER_BIT_DELAY_CELL==0)
13679 mcSHOW_DBG_MSG(("min DQ margin\n"));
13680 for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<local_channel_num; u1ChannelIdx++)
13681 {
13682 for(u1RankIdx = RANK_0; u1RankIdx < 2; u1RankIdx++)
13683 {
13684 mcSHOW_DBG_MSG(("[HQALOG] %d min_DQ_margin Channel%d "
13685 "Rank%d %d (bit %d)\n",
13686 p->frequency*2,
13687 u1ChannelIdx,
13688 u1RankIdx,
13689 gFinalTXPerbitWin_min_margin[u1ChannelIdx][u1RankIdx], gFinalTXPerbitWin_min_margin_bit[u1ChannelIdx][u1RankIdx]));
13690 }
13691 }
13692#endif
13693
13694
13695 /*
13696 TX Min Window(%)
13697 [HQALOG] 1600 TX_Window(%) Channel0 Rank0 79%(PASS)
13698 [HQALOG] 1600 TX_Window(%) Channel0 Rank1 79%(PASS)
13699 [HQALOG] 1600 TX_Window(%) Channel1 Rank0 69%(PASS)
13700 [HQALOG] 1600 TX_Window(%) Channel1 Rank1 72%(PASS)
13701 */
13702 mcSHOW_DBG_MSG(("TX Min Window(%%)\n"));
13703#ifdef FOR_HQA_REPORT_USED
13704if (gHQALog_flag==1)
13705{
13706 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13707 {
13708 u1ChannelIdx = u1ChannelSet[u1Channel];
13709
13710 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13711 {
13712 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT2, "TX_Window(%)", 0, (min_tx_value[u1ChannelIdx][u1RankIdx] * 100 + 31) / (u1IsLP4Family(p->dram_type)==1?32:64), NULL);
13713 HQA_Log_Message_for_Report(p, u1ChannelIdx, u1RankIdx, HQA_REPORT_FORMAT4, "TX_Window_PF", 0, 0, (min_tx_value[u1ChannelIdx][u1RankIdx] * 100 + 31) / (u1IsLP4Family(p->dram_type)==1?32:64) >= 45 ? "PASS" : "FAIL");
13714 }
13715 }
13716}
13717else
13718#endif
13719{
13720 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13721 {
13722 u1ChannelIdx = u1ChannelSet[u1Channel];
13723
13724 for(u1RankIdx = RANK_0; u1RankIdx < p->support_rank_num; u1RankIdx++)
13725 {
13726 mcSHOW_DBG_MSG(("[HQALOG] %d TX_Window(%%) Channel%d "
13727 "Rank%d %d%% (%s)\n",
13728 p->frequency*2,
13729 u1ChannelIdx,
13730 u1RankIdx,
13731 (min_tx_value[u1ChannelIdx][u1RankIdx] * 100 + 31) / (u1IsLP4Family(p->dram_type)==1?32:64),
13732 (min_tx_value[u1ChannelIdx][u1RankIdx] * 100 + 31) / (u1IsLP4Family(p->dram_type)==1?32:64) >= 45 ? "PASS" : "FAIL"));
13733 }
13734 }
13735}
13736
13737 mcSHOW_DBG_MSG(("\n"));
13738 }
13739
13740
13741
13742 /*
13743 [Duty Calibration]
13744 CLK Duty Final Delay Cell
13745 [HQALOG] DUTY CLK_Final_Delay Channel0 0
13746 [HQALOG] DUTY CLK_Final_Delay Channel1 -2
13747 */
13748#if !defined(RELEASE) && (VENDER_JV_LOG==0)
13749 if (u1IsLP4Family(p->dram_type))
13750 {
13751 mcSHOW_DBG_MSG(("[duty Calibration]\n"));
13752 mcSHOW_DBG_MSG(("CLK Duty Final Delay Cell\n"));
13753 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13754 {
13755 u1ChannelIdx = u1ChannelSet[u1Channel];
13756 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY CLK_Final_Delay Channel%d %d\n", p->frequency*2, u1ChannelIdx, gFinalClkDuty[u1ChannelIdx]));
13757 }
13758
13759 /*
13760 CLK Duty MAX
13761 [HQALOG] DUTY CLK_MAX Channel0 4765%(X100)
13762 [HQALOG] DUTY CLK_MAX Channel1 5212%(X100)
13763 */
13764 mcSHOW_DBG_MSG(("CLK Duty MAX\n"));
13765 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13766 {
13767 u1ChannelIdx = u1ChannelSet[u1Channel];
13768#ifdef FOR_HQA_REPORT_USED
13769 if (gHQALog_flag==1)
13770 {
13771 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT3, "DUTY CLK_MAX", 0, gFinalClkDutyMinMax[u1ChannelIdx][1], NULL);
13772 }
13773 else
13774#endif
13775 {
13776 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY CLK_MAX Channel%d %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalClkDutyMinMax[u1ChannelIdx][1]));
13777 }
13778 }
13779
13780 /*
13781 CLK Duty MIN
13782 [HQALOG] DUTY CLK_MIN Channel0 4565%(X100)
13783 [HQALOG] DUTY CLK_MIN Channel1 5012%(X100)
13784 */
13785 mcSHOW_DBG_MSG(("CLK Duty MIN\n"));
13786 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13787 {
13788 u1ChannelIdx = u1ChannelSet[u1Channel];
13789#ifdef FOR_HQA_REPORT_USED
13790 if (gHQALog_flag==1)
13791 {
13792 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT3, "DUTY CLK_MIN", 0, gFinalClkDutyMinMax[u1ChannelIdx][0], NULL);
13793 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT3, "DUTY CLK_MAX-MIN", 0, gFinalClkDutyMinMax[u1ChannelIdx][1]-gFinalClkDutyMinMax[u1ChannelIdx][0], NULL);
13794 }
13795 else
13796#endif
13797 {
13798 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY CLK_MIN Channel%d %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalClkDutyMinMax[u1ChannelIdx][0]));
13799 }
13800 }
13801
13802 mcSHOW_DBG_MSG(("\n"));
13803 }
13804
13805
13806
13807
13808 /*
13809 DQS Duty Final Delay Cell
13810 [HQALOG] DUTY DQS_Final_Delay Channel0 DQS0 0
13811 [HQALOG] DUTY DQS_Final_Delay Channel0 DQS1 1
13812 [HQALOG] DUTY DQS_Final_Delay Channel1 DQS0 -2
13813 [HQALOG] DUTY DQS_Final_Delay Channel1 DQS1 -1
13814 */
13815 if (u1IsLP4Family(p->dram_type))
13816 {
13817 mcSHOW_DBG_MSG(("DQS Duty Final Delay Cell\n"));
13818 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13819 {
13820 u1ChannelIdx = u1ChannelSet[u1Channel];
13821
13822 if (p->frequency == u2DFSGetHighestFreq(p))
13823 {
13824 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_Final_Delay Channel%d DQS0 %d\n", p->frequency*2, u1ChannelIdx, gFinalDQSDuty[u1ChannelIdx][0]));
13825 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_Final_Delay Channel%d DQS1 %d\n", p->frequency*2, u1ChannelIdx, gFinalDQSDuty[u1ChannelIdx][1]));
13826 }
13827 }
13828
13829 /*
13830 DQS Duty MAX
13831 [HQALOG] DUTY DQS_MAX Channel0 DQS0 4765%(X100)
13832 [HQALOG] DUTY DQS_MAX Channel0 DQS1 5212%(X100)
13833 [HQALOG] DUTY DQS_MAX Channel1 DQS0 4765%(X100)
13834 [HQALOG] DUTY DQS_MAX Channel1 DQS1 5212%(X100)
13835 */
13836 mcSHOW_DBG_MSG(("DQS Duty MAX\n"));
13837 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13838 {
13839 u1ChannelIdx = u1ChannelSet[u1Channel];
13840#ifdef FOR_HQA_REPORT_USED
13841 if (gHQALog_flag==1)
13842 {
13843 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MAX", 0, gFinalDQSDutyMinMax[u1ChannelIdx][0][1], NULL);
13844 HQA_Log_Message_for_Report(p,u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MAX", 1, gFinalDQSDutyMinMax[u1ChannelIdx][1][1], NULL);
13845 }
13846 else
13847#endif
13848 {
13849 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_MAX Channel%d DQS0 %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalDQSDutyMinMax[u1ChannelIdx][0][1]));
13850 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_MAX Channel%d DQS1 %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalDQSDutyMinMax[u1ChannelIdx][1][1]));
13851 }
13852 }
13853
13854 /*
13855 DQS Duty MIN
13856 [HQALOG] DUTY DQS_MIN Channel0 DQS0 4765%(X100)
13857 [HQALOG] DUTY DQS_MIN Channel0 DQS1 5212%(X100)
13858 [HQALOG] DUTY DQS_MIN Channel1 DQS0 4765%(X100)
13859 [HQALOG] DUTY DQS_MIN Channel1 DQS1 5212%(X100)
13860 */
13861 mcSHOW_DBG_MSG(("DQS Duty MIN\n"));
13862 for(u1Channel=CHANNEL_A; u1Channel<local_channel_num; u1Channel++)
13863 {
13864 u1ChannelIdx = u1ChannelSet[u1Channel];
13865#ifdef FOR_HQA_REPORT_USED
13866 if (gHQALog_flag==1)
13867 {
13868 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MIN", 0, gFinalDQSDutyMinMax[u1ChannelIdx][0][0], NULL);
13869 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MIN", 1, gFinalDQSDutyMinMax[u1ChannelIdx][1][0], NULL);
13870 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MAX-MIN", 0, gFinalDQSDutyMinMax[u1ChannelIdx][0][1]-gFinalDQSDutyMinMax[u1ChannelIdx][0][0], NULL);
13871 HQA_Log_Message_for_Report(p, u1ChannelIdx, 0, HQA_REPORT_FORMAT0, "DUTY DQS_MAX-MIN", 1, gFinalDQSDutyMinMax[u1ChannelIdx][1][1]-gFinalDQSDutyMinMax[u1ChannelIdx][1][0], NULL);
13872 }
13873 else
13874#endif
13875 {
13876 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_MIN Channel%d DQS0 %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalDQSDutyMinMax[u1ChannelIdx][0][0]));
13877 mcSHOW_DBG_MSG(("[HQALOG] %d DUTY DQS_MIN Channel%d DQS1 %d%%(X100)\n", p->frequency*2, u1ChannelIdx, gFinalDQSDutyMinMax[u1ChannelIdx][1][0]));
13878 }
13879 }
13880
13881 mcSHOW_DBG_MSG(("\n"));
13882 }
13883#endif
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895 #if defined(ENABLE_MIOCK_JMETER) && !defined(RELEASE)
13896 //if(p->frequency == u2DFSGetHighestFreq(p))
13897 {
13898 if(u1IsLP4Family(p->dram_type)) //LP4 Series
13899 {
13900 mcSHOW_DBG_MSG(("\n[DramcMiockJmeter]\n"
13901 "Channel\tVCORE\t\t1 delay cell\n"));
13902
13903 for(shuffle_index=DRAM_DFS_SHUFFLE_1; shuffle_index<DRAM_DFS_SHUFFLE_MAX; shuffle_index++)
13904 {
13905 mcSHOW_DBG_MSG(("\nSHUFFLE %d\n", shuffle_index+1));
13906
13907 for (u1Channel = 0; u1Channel < local_channel_num; u1Channel++)
13908 {
13909 u1ChannelIdx = u1ChannelSet[u1Channel];
13910 mcSHOW_DBG_MSG(("CH%d\t%d\t\t%d/100 ps\n", u1ChannelIdx, u4gVcore[shuffle_index], u2gdelay_cell_ps_all[shuffle_index][u1ChannelIdx]));
13911 }
13912 }
13913 }
13914 }
13915 #endif
13916
13917 mcSHOW_DBG_MSG(("\n\n\n"));
13918
13919
13920
13921#if VENDER_JV_LOG
13922 mcSHOW_DBG_MSG5(("\n\n\n[Summary] information for measurement\n"));
13923 //mcSHOW_DBG_MSG5(("\tDram Data rate = %d\n",p->frequency*2));
13924 vPrintCalibrationBasicInfo_ForJV(p);
13925
13926 if(u1IsLP4Family(p->dram_type))
13927 {
13928 mcSHOW_DBG_MSG5(("[Cmd Bus Training window]\n"));
13929 mcSHOW_DBG_MSG5(("VrefCA Range : %d\n", gCBT_VREF_RANGE_SEL));
13930#if CHANNEL_NUM==4
13931 mcSHOW_DBG_MSG5(("CHA_VrefCA_Rank0 CHB_VrefCA_Rank0 CHC_VrefCA_Rank0 CHD_VrefCA_Rank0\n"));
13932 mcSHOW_DBG_MSG5(("%d %d %d %d\n", gFinalCBTVrefCA[0][0], gFinalCBTVrefCA[1][0], gFinalCBTVrefCA[2][0], gFinalCBTVrefCA[3][0]));
13933#else
13934 mcSHOW_DBG_MSG5(("CHA_VrefCA_Rank0 CHB_VrefCA_Rank0\n"));
13935 mcSHOW_DBG_MSG5(("%d %d\n", gFinalCBTVrefCA[0][0], gFinalCBTVrefCA[1][0]));
13936#endif
13937 mcSHOW_DBG_MSG5(("CHA_CA_window_Rank0 CHB_CA_winow_Rank0\n"));
13938 mcSHOW_DBG_MSG5(("%d%%(bit %d) %d%%(bit %d) \n\n",(min_ca_value[0][0]*100+63)/64, min_ca_bit[0][0],
13939 (min_ca_value[1][0]*100+63)/64, min_ca_bit[1][0]));
13940 }
13941#if 0
13942 else
13943 {
13944 mcSHOW_DBG_MSG5(("[CA Training window]\n"));
13945 mcSHOW_DBG_MSG5(("CHA_CA_win_Rank0\n"));
13946 mcSHOW_DBG_MSG5(("%d%%(bit %d)\n\n",(min_ca_value[0][0]*100+63)/64, min_ca_bit[0][0]));
13947 }
13948#endif
13949
13950 mcSHOW_DBG_MSG5(("[RX minimum per bit window]\n"));
13951 if (p->enable_rx_scan_vref == ENABLE)
13952 {
13953#if CHANNEL_NUM==4
13954 mcSHOW_DBG_MSG5(("CHA_VrefDQ CHB_VrefDQ CHC_VrefDQ CHD_VrefDQ\n"));
13955 mcSHOW_DBG_MSG5(("%d %d %d %d \n", gFinalRXVrefDQ[CHANNEL_A][RANK_0], gFinalRXVrefDQ[CHANNEL_B][RANK_0], gFinalRXVrefDQ[CHANNEL_C][RANK_0], gFinalRXVrefDQ[CHANNEL_D][RANK_0]));
13956#else
13957 mcSHOW_DBG_MSG5(("CHA_VrefDQ CHB_VrefDQ\n"));
13958 mcSHOW_DBG_MSG5(("%d %d \n", gFinalRXVrefDQ[CHANNEL_A][RANK_0], gFinalRXVrefDQ[CHANNEL_B][RANK_0]));
13959#endif
13960 }
13961 else
13962 {
13963 mcSHOW_DBG_MSG5(("RX DQ Vref Scan : Disable\n"));
13964
13965 }
13966
13967 if(u1IsLP4Family(p->dram_type))
13968 {
13969#if CHANNEL_NUM==4
13970 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1 CHB_Rank0 CHB_Rank1 CHC_Rank0 CHC_Rank1 CHD_Rank0 CHD_Rank1\n"));
13971 mcSHOW_DBG_MSG5(("%d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d)\n\n",
13972 ((min_rx_value[0][0]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][0],
13973 ((min_rx_value[0][1]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][1],
13974 ((min_rx_value[1][0]*u2gdelay_cell_ps_all[shuffleIdx][1]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[1][0],
13975 ((min_rx_value[1][1]*u2gdelay_cell_ps_all[shuffleIdx][1]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[1][1],
13976 ((min_rx_value[2][0]*u2gdelay_cell_ps_all[shuffleIdx][2]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[2][0],
13977 ((min_rx_value[2][1]*u2gdelay_cell_ps_all[shuffleIdx][2]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[2][1],
13978 ((min_rx_value[3][0]*u2gdelay_cell_ps_all[shuffleIdx][3]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[3][0],
13979 ((min_rx_value[3][1]*u2gdelay_cell_ps_all[shuffleIdx][3]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[3][1]));
13980#else
13981 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1 CHB_Rank0 CHB_Rank1\n"));
13982 mcSHOW_DBG_MSG5(("%d%%(bit %d) %d%%(bit %d) %d%%(bit %d) %d%%(bit %d)\n\n",
13983 ((min_rx_value[0][0]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][0],
13984 ((min_rx_value[0][1]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][1],
13985 ((min_rx_value[1][0]*u2gdelay_cell_ps_all[shuffleIdx][1]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[1][0],
13986 ((min_rx_value[1][1]*u2gdelay_cell_ps_all[shuffleIdx][1]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[1][1]));
13987#endif
13988 }
13989 else
13990 {
13991 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1\n"));
13992 mcSHOW_DBG_MSG5(("%d%%(bit %d) %d%%(bit %d)\n\n",
13993 ((min_rx_value[0][0]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][0],
13994 ((min_rx_value[0][1]*u2gdelay_cell_ps_all[shuffleIdx][0]*p->frequency*2)+(1000000-1))/1000000, min_RX_DQ_bit[0][1]));
13995 }
13996
13997
13998 mcSHOW_DBG_MSG5(("[TX minimum per bit window]\n"));
13999 if (p->enable_tx_scan_vref == ENABLE_VREF_SCAN)
14000 {
14001 mcSHOW_DBG_MSG5(("VrefDQ Range : %d\n",(u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&1));
14002#if CHANNEL_NUM==4
14003 mcSHOW_DBG_MSG5(("CHA_VrefDQ_Rank0 CHA_VrefDQ_Rank1 CHB_VrefDQ_Rank0 CHB_VrefDQ_Rank1 CHC_VrefDQ_Rank0 CHC_VrefDQ_Rank1 CHD_VrefDQ_Rank0 CHD_VrefDQ_Rank1\n"));
14004 mcSHOW_DBG_MSG5(("%d %d %d %d %d %d %d %d\n"
14005 , gFinalTXVrefDQ[0][0], gFinalTXVrefDQ[0][1], gFinalTXVrefDQ[1][0], gFinalTXVrefDQ[1][1]
14006 , gFinalTXVrefDQ[2][0], gFinalTXVrefDQ[2][1], gFinalTXVrefDQ[3][0], gFinalTXVrefDQ[3][1]
14007 ));
14008#else
14009 mcSHOW_DBG_MSG5(("CHA_VrefDQ_Rank0 CHA_VrefDQ_Rank1 CHB_VrefDQ_Rank0 CHB_VrefDQ_Rank1\n"));
14010 mcSHOW_DBG_MSG5(("%d %d %d %d\n", gFinalTXVrefDQ[0][0], gFinalTXVrefDQ[0][1], gFinalTXVrefDQ[1][0], gFinalTXVrefDQ[1][1]));
14011#endif
14012 }
14013 else
14014 {
14015 mcSHOW_DBG_MSG5(("TX DQ Vref Scan : Disable\n"));
14016 }
14017
14018 if(u1IsLP4Family(p->dram_type))
14019 {
14020#if CHANNEL_NUM==4
14021 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1 CHB_Rank0 CHB_Rank1 CHC_Rank0 CHC_Rank1 CHD_Rank0 CHD_Rank1\n"));
14022 mcSHOW_DBG_MSG5(("%d%% %d%% %d%% %d%% %d%% %d%% %d%% %d%%\n",
14023 (min_tx_value[0][0]*100+31)/32,
14024 (min_tx_value[0][1]*100+31)/32,
14025 (min_tx_value[1][0]*100+31)/32,
14026 (min_tx_value[1][1]*100+31)/32,
14027 (min_tx_value[2][0]*100+31)/32,
14028 (min_tx_value[2][1]*100+31)/32,
14029 (min_tx_value[3][0]*100+31)/32,
14030 (min_tx_value[3][1]*100+31)/32
14031 ));
14032#else
14033 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1 CHB_Rank0 CHB_Rank1\n"));
14034 mcSHOW_DBG_MSG5(("%d%% %d%% %d%% %d%%\n",
14035 (min_tx_value[0][0]*100+31)/32,
14036 (min_tx_value[0][1]*100+31)/32,
14037 (min_tx_value[1][0]*100+31)/32,
14038 (min_tx_value[1][1]*100+31)/32));
14039#endif
14040 }
14041 else
14042 {
14043 mcSHOW_DBG_MSG5(("CHA_Rank0 CHA_Rank1\n"));
14044 mcSHOW_DBG_MSG5(("%d%% %d%%\n",
14045 (min_tx_value[0][0]*100+31)/32,
14046 (min_tx_value[0][1]*100+31)/32));
14047 }
14048#endif
14049
14050
14051 // reset all data
14052 HQA_measure_message_reset_all_data(p);
14053}
14054#ifdef RELEASE
14055#undef mcSHOW_DBG_MSG
14056#define mcSHOW_DBG_MSG(_x_)
14057#endif
14058#endif
14059
14060
14061#if EYESCAN_LOG
14062#ifdef RELEASE
14063#undef mcSHOW_DBG_MSG
14064#define mcSHOW_DBG_MSG(_x_) opt_print _x_
14065#endif
14066
14067#if FOR_DV_SIMULATION_USED
14068const U16 gRXVref_Voltage_Table_LP4[RX_VREF_RANGE_END+1]={0};
14069#else
14070const U16 gRXVref_Voltage_Table_LP4[RX_VREF_RANGE_END+1]={
14071 1363,
14072 2590,
14073 3815,
14074 5040,
14075 6264,
14076 7489,
14077 8714,
14078 9938,
14079 11160,
14080 12390,
14081 13610,
14082 14840,
14083 16060,
14084 17290,
14085 18510,
14086 19740,
14087 20670,
14088 22100,
14089 23530,
14090 24970,
14091 26400,
14092 27830,
14093 29260,
14094 30700,
14095 32130,
14096 33560,
14097 34990,
14098 36430,
14099 37860,
14100 39290,
14101 40720,
14102 42160
14103};
14104#endif
14105const U16 gVref_Voltage_Table_LP4X[VREF_RANGE_MAX][VREF_VOLTAGE_TABLE_NUM]={
14106 {1500,1560,1620,1680,1740,1800,1860,1920,1980,2040,2100,2160,2220,2280,2340,2400,2460,2510,2570,2630,2690,2750,2810,2870,2930,2990,3050,3110,3170,3230,3290,3350,3410,3470,3530,3590,3650,3710,3770,3830,3890,3950,4010,4070,4130,4190,4250,4310,4370,4430,4490},
14107 {3290,3350,3410,3470,3530,3590,3650,3710,3770,3830,3890,3950,4010,4070,4130,4190,4250,4310,4370,4430,4490,4550,4610,4670,4730,4790,4850,4910,4970,5030,5090,5150,5210,5270,5330,5390,5450,5510,5570,5630,5690,5750,5810,5870,5930,5990,6050,6110,6170,6230,6290}
14108};
14109const U16 gVref_Voltage_Table_LP4[VREF_RANGE_MAX][VREF_VOLTAGE_TABLE_NUM]={
14110 {1000,1040,1080,1120,1160,1200,1240,1280,1320,1360,1400,1440,1480,1520,1560,1600,1640,1680,1720,1760,1800,1840,1880,1920,1960,2000,2040,2080,2120,2160,2200,2240,2280,2320,2360,2400,2440,2480,2520,2560,2600,2640,2680,2720,2760,2800,2840,2880,2920,2960,3000},
14111 {2200,2240,2280,2320,2360,2400,2440,2480,2520,2560,2600,2640,2680,2720,2760,2800,2840,2880,2920,2960,3000,3040,3080,3120,3160,3200,3240,3280,3320,3360,3400,3440,3480,3520,3560,3600,3640,3680,3720,3760,3880,3840,3880,3920,3960,4000,4040,4080,4120,4160,4200}
14112};
14113#define EyeScan_Pic_draw_line_Mirror 1
14114#define EysScan_Pic_draw_1UI_line 1
14115void EyeScan_Pic_draw_line(DRAMC_CTX_T *p, U8 draw_type, U8 u1VrefRange, U8 u1VrefIdx, U8 u1BitIdx, S16 u2DQDelayBegin, S16 u2DQDelayEnd, U8 u1FinalVrefRange, U16 Final_Vref_val, U8 VdlVWHigh_Upper_Vcent_Range, U32 VdlVWHigh_Upper_Vcent, U8 VdlVWHigh_Lower_Vcent_Range, U32 VdlVWHigh_Lower_Vcent, U16 FinalDQCaliDelay, S8 EyeScan_DelayCellPI_value, U16 delay_cell_ps, U16 Max_EyeScan_Min_val)
14116{
14117 int i;
14118 int local_VrefIdx, local_Upper_Vcent, local_Lower_Vcent, local_Final_VrefIdx;
14119 S8 EyeScan_Index;
14120 S16 EyeScan_Min_val, EyeScan_Max_val, Final_EyeScan_Min_val=EYESCAN_DATA_INVALID, Final_EyeScan_Max_val=EYESCAN_DATA_INVALID, Final_EyeScan_winsize=1;
14121 U16 *pVref_Voltage_Table[VREF_VOLTAGE_TABLE_NUM];
14122 U32 PI_of_1_UI;
14123
14124 if (draw_type == 1)
14125 {
14126 pVref_Voltage_Table[VREF_RANGE_0]= (U16 *)gRXVref_Voltage_Table_LP4;
14127 if(p->u2DelayCellTimex100!=0)
14128 {
14129 PI_of_1_UI = (50000000/(p->frequency*p->u2DelayCellTimex100));
14130
14131 FinalDQCaliDelay = (U16)EyeScan_DelayCellPI_value;
14132 EyeScan_DelayCellPI_value = 0;
14133 }
14134 else
14135 {
14136 PI_of_1_UI = 0;
14137 mcSHOW_ERR_MSG(("DelayCell is 0\n"));
14138 }
14139 }
14140 else
14141 {
14142 if (p->dram_type == TYPE_LPDDR4)
14143 {
14144 pVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_0];
14145 pVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_1];
14146 }
14147 if (p->dram_type == TYPE_LPDDR4X)
14148 {
14149 pVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_0];
14150 pVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_1];
14151 }
14152
14153 PI_of_1_UI = 32;
14154 }
14155
14156 if (u1VrefRange==1 && u1VrefIdx <=20)
14157 {
14158 u1VrefRange=0;
14159 u1VrefIdx += 30;
14160 }
14161 if (u1FinalVrefRange==1 && Final_Vref_val <=20)
14162 {
14163 u1FinalVrefRange=0;
14164 Final_Vref_val += 30;
14165 }
14166 if (u1VrefRange != u1FinalVrefRange)
14167 {
14168 Final_Vref_val = 0xff;
14169 }
14170
14171 local_Upper_Vcent = VdlVWHigh_Upper_Vcent_Range*VREF_VOLTAGE_TABLE_NUM+VdlVWHigh_Upper_Vcent;
14172 local_Lower_Vcent = VdlVWHigh_Lower_Vcent_Range*VREF_VOLTAGE_TABLE_NUM+VdlVWHigh_Lower_Vcent;
14173 local_VrefIdx = u1VrefRange*VREF_VOLTAGE_TABLE_NUM+u1VrefIdx;
14174 local_Final_VrefIdx = u1FinalVrefRange*VREF_VOLTAGE_TABLE_NUM+Final_Vref_val;
14175
14176 if (VdlVWHigh_Upper_Vcent_Range==VREF_RANGE_1 && VdlVWHigh_Upper_Vcent<=20) local_Upper_Vcent = VdlVWHigh_Upper_Vcent_Range*VREF_VOLTAGE_TABLE_NUM+VdlVWHigh_Upper_Vcent-20;
14177 if (VdlVWHigh_Lower_Vcent_Range==VREF_RANGE_1 && VdlVWHigh_Lower_Vcent<=20) local_Lower_Vcent = VdlVWHigh_Lower_Vcent_Range*VREF_VOLTAGE_TABLE_NUM+VdlVWHigh_Lower_Vcent-20;
14178
14179 mcSHOW_EYESCAN_MSG(("Vref-"));
14180
14181 if (draw_type == 1 && u1VrefIdx <= 7)
14182 {
14183 mcSHOW_EYESCAN_MSG((" "));
14184 }
14185
14186 mcSHOW_EYESCAN_MSG(("%d.%d%d",pVref_Voltage_Table[u1VrefRange][u1VrefIdx]/100, ((pVref_Voltage_Table[u1VrefRange][u1VrefIdx]%100)/10), pVref_Voltage_Table[u1VrefRange][u1VrefIdx]%10));
14187
14188 if (draw_type == 1)
14189 {
14190 mcSHOW_EYESCAN_MSG(("m|"));
14191 }
14192 else
14193 {
14194 mcSHOW_EYESCAN_MSG(("%%|"));
14195 }
14196
14197
14198
14199
14200#if VENDER_JV_LOG || defined(RELEASE)
14201#if EyeScan_Pic_draw_line_Mirror
14202 EyeScan_DelayCellPI_value = 0-EyeScan_DelayCellPI_value;
14203#endif
14204#endif
14205
14206#if EyeScan_Pic_draw_line_Mirror
14207 EyeScan_Index=EYESCAN_BROKEN_NUM-1;
14208 EyeScan_Min_val = gEyeScan_Min[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14209 EyeScan_Max_val = gEyeScan_Max[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14210
14211 while(EyeScan_Min_val==EYESCAN_DATA_INVALID && EyeScan_Index>0)
14212 {
14213 EyeScan_Index--;
14214 EyeScan_Min_val = gEyeScan_Min[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14215 EyeScan_Max_val = gEyeScan_Max[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14216 }
14217#else
14218 EyeScan_Index=0;
14219 EyeScan_Min_val = gEyeScan_Min[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14220 EyeScan_Max_val = gEyeScan_Max[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14221#endif
14222
14223 if ((EyeScan_Max_val - EyeScan_Min_val + 1) > Final_EyeScan_winsize)
14224 {
14225#if EyeScan_Pic_draw_line_Mirror
14226 Final_EyeScan_Max_val = EyeScan_Max_val;
14227 Final_EyeScan_Min_val = EyeScan_Min_val;
14228#else
14229 Final_EyeScan_Max_val = EyeScan_Max_val;
14230 Final_EyeScan_Min_val = EyeScan_Min_val;
14231#endif
14232 Final_EyeScan_winsize = (EyeScan_Max_val - EyeScan_Min_val + 1);
14233 }
14234
14235#if VENDER_JV_LOG || defined(RELEASE)
14236#if EyeScan_Pic_draw_line_Mirror
14237 for(i=(Max_EyeScan_Min_val+PI_of_1_UI+EyeScan_DelayCellPI_value)*delay_cell_ps/100; i>(Max_EyeScan_Min_val+EyeScan_DelayCellPI_value)*delay_cell_ps/100; i-=10)
14238#else
14239 for(i=(Max_EyeScan_Min_val+EyeScan_DelayCellPI_value)*delay_cell_ps/100; i<(Max_EyeScan_Min_val+PI_of_1_UI+EyeScan_DelayCellPI_value)*delay_cell_ps/100; i+=10)
14240#endif
14241#else
14242#if EyeScan_Pic_draw_line_Mirror
14243 for(i=u2DQDelayEnd; i>=u2DQDelayBegin; i--)
14244#else
14245 for(i=u2DQDelayBegin; i<=u2DQDelayEnd; i++)
14246#endif
14247#endif
14248 {
14249
14250#if VENDER_JV_LOG || defined(RELEASE)
14251#if EyeScan_Pic_draw_line_Mirror
14252 if (i<=((EyeScan_Min_val+EyeScan_DelayCellPI_value)*delay_cell_ps/100) && EyeScan_Index!= 0)
14253 {
14254 EyeScan_Index--;
14255 EyeScan_Min_val = gEyeScan_Min[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14256 EyeScan_Max_val = gEyeScan_Max[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14257
14258 if ((EyeScan_Max_val - EyeScan_Min_val + 1) > Final_EyeScan_winsize)
14259 {
14260 Final_EyeScan_Max_val = EyeScan_Max_val;
14261 Final_EyeScan_Min_val = EyeScan_Min_val;
14262 Final_EyeScan_winsize = (EyeScan_Max_val - EyeScan_Min_val + 1);
14263 }
14264
14265 }
14266#endif
14267#else
14268#if EyeScan_Pic_draw_line_Mirror
14269 if (i==(EyeScan_Min_val) && EyeScan_Index!= 0)
14270 {
14271 EyeScan_Index--;
14272 EyeScan_Min_val = gEyeScan_Min[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14273 EyeScan_Max_val = gEyeScan_Max[u1VrefIdx+u1VrefRange*30][u1BitIdx][EyeScan_Index];
14274
14275 if ((EyeScan_Max_val - EyeScan_Min_val + 1) > Final_EyeScan_winsize)
14276 {
14277 Final_EyeScan_Max_val = EyeScan_Max_val;
14278 Final_EyeScan_Min_val = EyeScan_Min_val;
14279 Final_EyeScan_winsize = (EyeScan_Max_val - EyeScan_Min_val + 1);
14280 }
14281
14282 }
14283#endif
14284#endif
14285
14286#if VENDER_JV_LOG || defined(RELEASE)
14287 if (i>=((EyeScan_Min_val+EyeScan_DelayCellPI_value)*delay_cell_ps/100) && i<=((EyeScan_Max_val+EyeScan_DelayCellPI_value)*delay_cell_ps/100))
14288#else
14289 if (i>=(EyeScan_Min_val) && i<=(EyeScan_Max_val))
14290#endif
14291 {
14292#if !VENDER_JV_LOG && !defined(RELEASE)
14293 if (i==FinalDQCaliDelay+EyeScan_DelayCellPI_value) //Final DQ delay
14294 {
14295 if (gEye_Scan_color_flag)
14296 {
14297 mcSHOW_EYESCAN_MSG(("\033[0;105mH\033[m"));
14298 }
14299 else
14300 {
14301 mcSHOW_EYESCAN_MSG(("H"));
14302 }
14303 }
14304 else
14305 if (local_VrefIdx==local_Final_VrefIdx) //Final Vref
14306 {
14307 if (gEye_Scan_color_flag)
14308 {
14309 mcSHOW_EYESCAN_MSG(("\033[0;105mV\033[m"));
14310 }
14311 else
14312 {
14313 mcSHOW_EYESCAN_MSG(("V"));
14314 }
14315 }
14316 else //spec in margin
14317 if (local_VrefIdx<=local_Upper_Vcent && local_VrefIdx>=local_Lower_Vcent && i>=(FinalDQCaliDelay+EyeScan_DelayCellPI_value-3) && i<=(FinalDQCaliDelay+EyeScan_DelayCellPI_value+3))
14318 {
14319 if (gEye_Scan_color_flag)
14320 {
14321 mcSHOW_EYESCAN_MSG(("\033[0;103mQ\033[m"));
14322 }
14323 else
14324 {
14325 mcSHOW_EYESCAN_MSG(("Q"));
14326 }
14327 }
14328 else //pass margin
14329#endif
14330 {
14331#if VENDER_JV_LOG || defined(RELEASE)
14332 if (gEye_Scan_color_flag)
14333 {
14334 mcSHOW_EYESCAN_MSG(("\033[0;102mO\033[m"));
14335 }
14336 else
14337 {
14338 mcSHOW_EYESCAN_MSG(("O"));
14339 }
14340#else
14341 if (gEye_Scan_color_flag)
14342 {
14343 mcSHOW_EYESCAN_MSG(("\033[0;102mO\033[m"));
14344 }
14345 else
14346 {
14347 mcSHOW_EYESCAN_MSG(("O"));
14348 }
14349#endif
14350 }
14351 }
14352 else
14353 {
14354#if !VENDER_JV_LOG && !defined(RELEASE)
14355#if EysScan_Pic_draw_1UI_line
14356 if (i==(int)(Max_EyeScan_Min_val) || i==(int)(Max_EyeScan_Min_val+PI_of_1_UI))
14357 {
14358 if (gEye_Scan_color_flag)
14359 {
14360 mcSHOW_EYESCAN_MSG(("\033[0;107m.\033[m"));
14361 }
14362 else
14363 {
14364 mcSHOW_EYESCAN_MSG(("."));
14365 }
14366 }
14367 else
14368#endif
14369#endif
14370 {
14371 //not valid
14372#if VENDER_JV_LOG || defined(RELEASE)
14373 if (gEye_Scan_color_flag)
14374 {
14375 mcSHOW_EYESCAN_MSG(("\033[0;100m.\033[m"));
14376 }
14377 else
14378 {
14379 mcSHOW_EYESCAN_MSG(("."));
14380 }
14381#else
14382 if (gEye_Scan_color_flag)
14383 {
14384 mcSHOW_EYESCAN_MSG(("\033[0;100m.\033[m"));
14385 }
14386 else
14387 {
14388 mcSHOW_EYESCAN_MSG(("."));
14389 }
14390#endif
14391 }
14392 }
14393 }
14394
14395
14396#if EyeScan_Pic_draw_line_Mirror
14397 if (Final_EyeScan_Min_val!=EYESCAN_DATA_INVALID && Final_EyeScan_Max_val!=EYESCAN_DATA_INVALID)
14398 {
14399#if !VENDER_JV_LOG && !defined(RELEASE)
14400 if (Final_EyeScan_Max_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value) && (FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Min_val)
14401 {
14402 mcSHOW_EYESCAN_MSG((" -%d ",(Final_EyeScan_Max_val-(FinalDQCaliDelay+EyeScan_DelayCellPI_value))));
14403 mcSHOW_EYESCAN_MSG(("%d ", ((FinalDQCaliDelay+EyeScan_DelayCellPI_value)-Final_EyeScan_Min_val)));
14404 }
14405 else if (Final_EyeScan_Max_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value) && Final_EyeScan_Min_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value))
14406 {
14407 mcSHOW_EYESCAN_MSG((" -%d ",(Final_EyeScan_Max_val-Final_EyeScan_Min_val)));
14408 mcSHOW_EYESCAN_MSG((" --- "));
14409 }
14410 else if ((FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Max_val && (FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Min_val)
14411 {
14412 mcSHOW_EYESCAN_MSG((" --- "));
14413 mcSHOW_EYESCAN_MSG(("%d ", (Final_EyeScan_Max_val-Final_EyeScan_Min_val)));
14414 }
14415 else
14416 {
14417 mcSHOW_EYESCAN_MSG((" --- "));
14418 mcSHOW_EYESCAN_MSG((" --- "));
14419 }
14420#endif
14421 //window
14422#if VENDER_JV_LOG || defined(RELEASE)
14423 mcSHOW_EYESCAN_MSG(("%dps", Final_EyeScan_winsize*delay_cell_ps/100));
14424#else
14425 mcSHOW_EYESCAN_MSG(("%d", Final_EyeScan_winsize));
14426#endif
14427 }
14428#else
14429 if (Final_EyeScan_Max_val != Final_EyeScan_Min_val && Final_EyeScan_Max_val!=EYESCAN_DATA_INVALID)
14430 {
14431#if !VENDER_JV_LOG && !defined(RELEASE)
14432 if (Final_EyeScan_Max_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value) && (FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Min_val)
14433 {
14434 mcSHOW_EYESCAN_MSG((" -%d ", ((FinalDQCaliDelay+EyeScan_DelayCellPI_value)-Final_EyeScan_Min_val)));
14435 mcSHOW_EYESCAN_MSG(("%d ",(Final_EyeScan_Max_val-(FinalDQCaliDelay+EyeScan_DelayCellPI_value))));
14436 }
14437 else if (Final_EyeScan_Max_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value) && Final_EyeScan_Min_val>(FinalDQCaliDelay+EyeScan_DelayCellPI_value))
14438 {
14439 mcSHOW_EYESCAN_MSG((" --- "));
14440 mcSHOW_EYESCAN_MSG(("%d ",(Final_EyeScan_Max_val-Final_EyeScan_Min_val)));
14441 }
14442 else if ((FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Max_val && (FinalDQCaliDelay+EyeScan_DelayCellPI_value)>Final_EyeScan_Min_val)
14443 {
14444 mcSHOW_EYESCAN_MSG((" -%d ", (Final_EyeScan_Max_val-Final_EyeScan_Min_val)));
14445 mcSHOW_EYESCAN_MSG((" --- "));
14446 }
14447 else
14448 {
14449 mcSHOW_EYESCAN_MSG((" --- "));
14450 mcSHOW_EYESCAN_MSG((" --- "));
14451 }
14452#endif
14453 //window
14454#if VENDER_JV_LOG || defined(RELEASE)
14455 mcSHOW_EYESCAN_MSG(("%dps", Final_EyeScan_winsize*delay_cell_ps/100));
14456#else
14457 mcSHOW_EYESCAN_MSG(("%d", Final_EyeScan_winsize));
14458#endif
14459 }
14460#endif
14461
14462 mcSHOW_EYESCAN_MSG(("\n"));
14463
14464
14465}
14466
14467void print_EYESCAN_LOG_message(DRAMC_CTX_T *p, U8 print_type)
14468{
14469 U32 u1ChannelIdx=p->channel, u1RankIdx=p->rank;
14470 S8 u1VrefIdx;
14471 U8 u1VrefRange;
14472 U8 u1BitIdx, u1CA;
14473 U32 VdlVWTotal, Vcent_DQ;
14474 U32 VdlVWHigh_Upper_Vcent=VREF_VOLTAGE_TABLE_NUM-1, VdlVWHigh_Lower_Vcent=0, VdlVWBest_Vcent=0;
14475 U32 VdlVWHigh_Upper_Vcent_Range=1, VdlVWHigh_Lower_Vcent_Range=0, VdlVWBest_Vcent_Range=1;;
14476 U8 Upper_Vcent_pass_flag=0, Lower_Vcent_pass_flag=0;
14477 S32 i, vrefrange_i;
14478 U8 local_channel_num=2;
14479 U8 shuffleIdx;
14480 U8 TXVrefRange, CBTVrefRange;
14481 U32 vddq;
14482 U8 Min_Value_1UI_Line;
14483 S8 EyeScan_Index;
14484 U16 *pVref_Voltage_Table[VREF_VOLTAGE_TABLE_NUM];
14485 S8 EyeScan_DelayCellPI_value;
14486 U8 EyeScanVcent[10+DQ_DATA_WIDTH_LP4*2], max_winsize;
14487 U8 minCBTEyeScanVcentUpperBound=0xff, minCBTEyeScanVcentUpperBound_bit=0;
14488 U8 minCBTEyeScanVcentLowerBound=0xff, minCBTEyeScanVcentLowerBound_bit=0;
14489 U8 minRXEyeScanVcentUpperBound=0xff, minRXEyeScanVcentUpperBound_bit=0;
14490 U8 minRXEyeScanVcentLowerBound=0xff, minRXEyeScanVcentLowerBound_bit=0;
14491 U8 minTXEyeScanVcentUpperBound=0xff, minTXEyeScanVcentUpperBound_bit=0;
14492 U8 minTXEyeScanVcentLowerBound=0xff, minTXEyeScanVcentLowerBound_bit=0;
14493 U16 one_pi_ps=100000000/(p->frequency*2*32);
14494 U8 u1CBTEyeScanEnable, u1RXEyeScanEnable, u1TXEyeScanEnable;
14495
14496 U16 u2DQDelayBegin, u2DQDelayEnd;
14497
14498 if(u1IsLP4Family(p->dram_type))
14499 {
14500 local_channel_num = p->support_channel_num;
14501 }
14502 else
14503 {
14504 //LP3
14505 local_channel_num = 1;
14506 }
14507
14508 if (p->dram_type == TYPE_LPDDR4)
14509 {
14510 pVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_0];
14511 pVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4[VREF_RANGE_1];
14512 }
14513 if (p->dram_type == TYPE_LPDDR4X)
14514 {
14515 pVref_Voltage_Table[VREF_RANGE_0] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_0];
14516 pVref_Voltage_Table[VREF_RANGE_1] = (U16 *)gVref_Voltage_Table_LP4X[VREF_RANGE_1];
14517 }
14518
14519 u1CBTEyeScanEnable = (gCBT_EYE_Scan_flag==1 && ((gCBT_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gCBT_EYE_Scan_only_higheset_freq_flag==0));
14520 u1RXEyeScanEnable = (gRX_EYE_Scan_flag==1 && ((gRX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gRX_EYE_Scan_only_higheset_freq_flag==0));
14521 u1TXEyeScanEnable = (gTX_EYE_Scan_flag==1 && ((gTX_EYE_Scan_only_higheset_freq_flag==1 && p->frequency == u2DFSGetHighestFreq(p)) || gTX_EYE_Scan_only_higheset_freq_flag==0));
14522
14523
14524
14525
14526/**************************************************************************************
14527 CBT EYESCAN log
14528***************************************************************************************/
14529 if (p->frequency <=934) VdlVWTotal = 17500; //VcIVW 175mv
14530 else if (p->frequency <= 1600) VdlVWTotal = 15500; //VcIVW 155mv
14531 else VdlVWTotal = 14500; //VcIVW 145mv
14532
14533 CBTVrefRange = (u1MR12Value[p->channel][p->rank][p->dram_fsp]>>6)&1;
14534
14535#if !VENDER_JV_LOG && !defined(RELEASE)
14536 if (print_type==0)
14537 if (u1CBTEyeScanEnable)
14538 {
14539 mcSHOW_DBG_MSG(("[EYESCAN_LOG] CBT Window\n"));
14540 vddq=vGetVoltage(p, 2)/1000; //mv
14541 mcSHOW_DBG_MSG(("[EYESCAN_LOG] VDDQ=%dmV\n",vddq));
14542// for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<local_channel_num; u1ChannelIdx++)
14543 {
14544// for(u1RankIdx = RANK_0; u1RankIdx < 2; u1RankIdx++)
14545 {
14546 mcSHOW_DBG_MSG(("[EYESCAN_LOG] CBT Channel%d Range %d Final_Vref Vcent=%d(%dmV(X100))\n",
14547 u1ChannelIdx,
14548 CBTVrefRange,
14549 gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx],
14550 pVref_Voltage_Table[CBTVrefRange][gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]]*vddq/100));
14551
14552 Vcent_DQ = pVref_Voltage_Table[CBTVrefRange][gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]]*vddq/100;
14553
14554 //find VdlVWHigh first
14555 VdlVWHigh_Upper_Vcent_Range = 1;
14556 VdlVWHigh_Upper_Vcent = VREF_VOLTAGE_TABLE_NUM-1;
14557 vrefrange_i = CBTVrefRange;
14558 for(i=(gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]); i<VREF_VOLTAGE_TABLE_NUM; i++)
14559 {
14560 if (((pVref_Voltage_Table[vrefrange_i][i]*vddq/100 - Vcent_DQ)) >= VdlVWTotal/2)
14561 {
14562 /* find VdlVWHigh upper bound */
14563 VdlVWHigh_Upper_Vcent = i;
14564 VdlVWHigh_Upper_Vcent_Range = vrefrange_i;
14565 break;
14566 }
14567 if (i==(VREF_VOLTAGE_TABLE_NUM-1) && vrefrange_i==0)
14568 {
14569 vrefrange_i=1;
14570 i=20;
14571 }
14572 }
14573 mcSHOW_DBG_MSG(("[EYESCAN_LOG] CBT VdlVWHigh_Upper Range=%d Vcent=%d(%dmV(X100))\n",
14574 VdlVWHigh_Upper_Vcent_Range,
14575 VdlVWHigh_Upper_Vcent,
14576 pVref_Voltage_Table[VdlVWHigh_Upper_Vcent_Range][VdlVWHigh_Upper_Vcent]*vddq/100));
14577
14578 //find VldVWLow first
14579 VdlVWHigh_Lower_Vcent_Range = 0;
14580 VdlVWHigh_Lower_Vcent = 0;
14581 vrefrange_i = CBTVrefRange;
14582 for(i=(gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]); i>=0; i--)
14583 {
14584 if (((Vcent_DQ - pVref_Voltage_Table[vrefrange_i][i]*vddq/100)) >= VdlVWTotal/2)
14585 {
14586 /* find VdlVWHigh lower bound */
14587 VdlVWHigh_Lower_Vcent = i;
14588 VdlVWHigh_Lower_Vcent_Range = vrefrange_i;
14589 break;
14590 }
14591 if (i<=21 && vrefrange_i==1)
14592 {
14593 vrefrange_i=0;
14594 i=VREF_VOLTAGE_TABLE_NUM-(21-i);
14595 }
14596 }
14597 mcSHOW_DBG_MSG(("[EYESCAN_LOG] CBT VdlVWHigh_Lower Range=%d Vcent=%d(%dmV(X100))\n",
14598 VdlVWHigh_Lower_Vcent_Range,
14599 VdlVWHigh_Lower_Vcent,
14600 pVref_Voltage_Table[VdlVWHigh_Lower_Vcent_Range][VdlVWHigh_Lower_Vcent]*vddq/100));
14601
14602#ifdef FOR_HQA_TEST_USED
14603 EyeScanVcent[0] = CBTVrefRange;
14604 EyeScanVcent[1] = gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx];
14605 EyeScanVcent[2] = VdlVWHigh_Upper_Vcent_Range;
14606 EyeScanVcent[3] = VdlVWHigh_Upper_Vcent;
14607 EyeScanVcent[4] = VdlVWHigh_Lower_Vcent_Range;
14608 EyeScanVcent[5] = VdlVWHigh_Lower_Vcent;
14609#endif
14610
14611 shuffleIdx = get_shuffleIndex_by_Freq(p);
14612
14613 // mcSHOW_DBG_MSG(("[EYESCAN_LOG] delay cell %d/100ps\n", u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx]));
14614
14615 for (u1CA=0; u1CA<CATRAINING_NUM_LP4; u1CA++)
14616 {
14617
14618 // compare Upper/Lower Vcent pass criterion is pass or fail?
14619 for(u1VrefIdx=gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]+CBTVrefRange*30; u1VrefIdx<=(S8)(VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30); u1VrefIdx++)
14620 {
14621 Upper_Vcent_pass_flag = 0;
14622 for (EyeScan_Index=0; EyeScan_Index<EYESCAN_BROKEN_NUM; EyeScan_Index++)
14623 {
14624 if ((((gEyeScan_CaliDelay[0]+gEyeScan_DelayCellPI[u1CA]) - gEyeScan_Min[u1VrefIdx][u1CA][EyeScan_Index]) >=4 ) && ((gEyeScan_Max[u1VrefIdx][u1CA][EyeScan_Index] - (gEyeScan_CaliDelay[0]+gEyeScan_DelayCellPI[u1CA])) >=4 ))
14625 {
14626 Upper_Vcent_pass_flag = 1;
14627 }
14628 }
14629 if (Upper_Vcent_pass_flag == 0) break; // fail!!
14630 }
14631 for(u1VrefIdx=VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30; u1VrefIdx<=(S8)(gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx]+CBTVrefRange*30); u1VrefIdx++)
14632 {
14633 Lower_Vcent_pass_flag = 0;
14634 for (EyeScan_Index=0; EyeScan_Index<EYESCAN_BROKEN_NUM; EyeScan_Index++)
14635 {
14636 if ((((gEyeScan_CaliDelay[0]+gEyeScan_DelayCellPI[u1CA]) - gEyeScan_Min[u1VrefIdx][u1CA][EyeScan_Index]) >=4 ) && ((gEyeScan_Max[u1VrefIdx][u1CA][EyeScan_Index] - (gEyeScan_CaliDelay[0]+gEyeScan_DelayCellPI[u1CA])) >=4 ))
14637 {
14638 Lower_Vcent_pass_flag = 1;
14639 }
14640 }
14641 if (Lower_Vcent_pass_flag == 0) break; //fail!!
14642 }
14643
14644 mcSHOW_DBG_MSG(("[EYESCAN_LOG] %d Channel%d Rank%d CA%d\tHigher VdlTW=%dPI(%d/100ps)(%s)\tLower VdlTW=%dpi(%d/100ps)(%s)\n",
14645 p->frequency*2,
14646 u1ChannelIdx,
14647 u1RankIdx,
14648 u1CA,
14649 gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1CA],
14650 gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1CA]*one_pi_ps,
14651 Upper_Vcent_pass_flag==1 ? "PASS" : "FAIL",
14652 gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1CA],
14653 gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1CA]*one_pi_ps,
14654 Lower_Vcent_pass_flag==1 ? "PASS" : "FAIL"
14655 ));
14656
14657#ifdef FOR_HQA_TEST_USED
14658 //find VdlVWBest Vref Range and Vref
14659 VdlVWBest_Vcent_Range = 1;
14660 VdlVWBest_Vcent = VREF_VOLTAGE_TABLE_NUM-1;
14661 vrefrange_i = 1;
14662 max_winsize = 0;
14663 for(i=VREF_VOLTAGE_TABLE_NUM-1; i>=0; i--)
14664 {
14665 if (gEyeScan_WinSize[i+vrefrange_i*30][u1CA] > max_winsize)
14666 {
14667 max_winsize = gEyeScan_WinSize[i+vrefrange_i*30][u1CA];
14668 VdlVWBest_Vcent_Range = vrefrange_i;
14669 VdlVWBest_Vcent = i;
14670 }
14671 if (i==21 && vrefrange_i==1)
14672 {
14673 vrefrange_i=0;
14674 i=VREF_VOLTAGE_TABLE_NUM;
14675 }
14676 }
14677
14678 EyeScanVcent[10+u1CA*2] = VdlVWBest_Vcent_Range;
14679 EyeScanVcent[10+u1CA*2+1] = VdlVWBest_Vcent;
14680#endif
14681
14682 if (gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1CA] < minCBTEyeScanVcentUpperBound)
14683 {
14684 minCBTEyeScanVcentUpperBound = gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1CA];
14685 minCBTEyeScanVcentUpperBound_bit = u1CA;
14686 }
14687 if (gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1CA] < minCBTEyeScanVcentLowerBound)
14688 {
14689 minCBTEyeScanVcentLowerBound = gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1CA];
14690 minCBTEyeScanVcentLowerBound_bit = u1CA;
14691 }
14692 }
14693#ifdef FOR_HQA_TEST_USED
14694#ifdef FOR_HQA_REPORT_USED
14695 print_EyeScanVcent_for_HQA_report_used(p, print_type, u1ChannelIdx, u1RankIdx, EyeScanVcent, minCBTEyeScanVcentUpperBound, minCBTEyeScanVcentUpperBound_bit, minCBTEyeScanVcentLowerBound, minCBTEyeScanVcentLowerBound_bit);
14696#endif
14697#endif
14698 }
14699 }
14700 }
14701#endif
14702
14703
14704
14705
14706
14707 if (print_type==0)
14708 if (u1CBTEyeScanEnable)
14709 {
14710 mcSHOW_DBG_MSG(("\n\n"));
14711
14712 for (u1CA=0; u1CA<CATRAINING_NUM_LP4; u1CA++)
14713 {
14714 EyeScan_Index = 0;
14715
14716#if EyeScan_Pic_draw_line_Mirror
14717 EyeScan_DelayCellPI_value = 0-gEyeScan_DelayCellPI[u1CA];
14718#else
14719 EyeScan_DelayCellPI_value = gEyeScan_DelayCellPI[u1CA];
14720#endif
14721 Min_Value_1UI_Line = gEyeScan_CaliDelay[0]-16-EyeScan_DelayCellPI_value;
14722
14723
14724 mcSHOW_EYESCAN_MSG(("[EYESCAN_LOG] CBT EYESCAN Channel%d, Rank%d, CA%d ===\n",p->channel, p->rank, u1CA));
14725
14726#if VENDER_JV_LOG || defined(RELEASE)
14727 for(i=0; i<8+one_pi_ps*32/1000; i++) mcSHOW_EYESCAN_MSG((" "));
14728 mcSHOW_EYESCAN_MSG(("window\n"));
14729#else
14730 for(i=0; i<8+one_pi_ps*32/1000; i++) mcSHOW_EYESCAN_MSG((" "));
14731 mcSHOW_EYESCAN_MSG(("first last window\n"));
14732#endif
14733
14734 u1VrefRange=1;
14735 for (u1VrefIdx=VREF_VOLTAGE_TABLE_NUM-1; u1VrefIdx>=0; u1VrefIdx--)
14736 {
14737
14738 EyeScan_Pic_draw_line(p, 0, u1VrefRange, u1VrefIdx, u1CA, 0, 64, CBTVrefRange, gFinalCBTVrefDQ[u1ChannelIdx][u1RankIdx], VdlVWHigh_Upper_Vcent_Range, VdlVWHigh_Upper_Vcent, VdlVWHigh_Lower_Vcent_Range, VdlVWHigh_Lower_Vcent, gEyeScan_CaliDelay[0], gEyeScan_DelayCellPI[u1CA], one_pi_ps, Min_Value_1UI_Line);
14739
14740 if (u1VrefRange==VREF_RANGE_1 && u1VrefIdx==21)
14741 {
14742 u1VrefRange=VREF_RANGE_0;
14743 u1VrefIdx=VREF_VOLTAGE_TABLE_NUM;
14744 }
14745 }
14746 mcSHOW_EYESCAN_MSG(("\n\n"));
14747
14748 }
14749 }
14750
14751
14752
14753
14754
14755/**************************************************************************************
14756 RX EYESCAN log
14757***************************************************************************************/
14758 if (p->frequency <=1600) VdlVWTotal = 10000; //14000; //140mv
14759 else VdlVWTotal = 10000; //12000; //120mv
14760
14761#if !VENDER_JV_LOG && !defined(RELEASE)
14762 if (print_type==1)
14763 if (u1RXEyeScanEnable)
14764 {
14765 mcSHOW_DBG_MSG(("[EYESCAN_LOG] RX Window\n"));
14766 {
14767 mcSHOW_DBG_MSG(("[EYESCAN_LOG] RX Final_Vref Vcent Channel%d %d(%dmV(X100))\n",
14768 u1ChannelIdx,
14769 gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx],
14770 gRXVref_Voltage_Table_LP4[gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]]));
14771
14772 Vcent_DQ = gRXVref_Voltage_Table_LP4[gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]];
14773
14774 //find VdlVWHigh first
14775 VdlVWHigh_Upper_Vcent_Range = 0;
14776 VdlVWHigh_Upper_Vcent = RX_VREF_RANGE_END;
14777 for(i=gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]; i<=RX_VREF_RANGE_END; i++)
14778 {
14779 if (gRXVref_Voltage_Table_LP4[i] - Vcent_DQ >= VdlVWTotal/2)
14780 {
14781 /* find VdlVWHigh upper bound */
14782 VdlVWHigh_Upper_Vcent = i;
14783 break;
14784 }
14785 }
14786 mcSHOW_DBG_MSG(("[EYESCAN_LOG] RX VdlVWHigh_Upper Vcent=%d(%dmV(X100))\n", VdlVWHigh_Upper_Vcent, gRXVref_Voltage_Table_LP4[VdlVWHigh_Upper_Vcent]));
14787
14788 //find VldVWLow first
14789 VdlVWHigh_Lower_Vcent_Range = 0;
14790 VdlVWHigh_Lower_Vcent = 0;
14791 for(i=gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]; i>=0; i--)
14792 {
14793 if (Vcent_DQ - gRXVref_Voltage_Table_LP4[i] >= VdlVWTotal/2)
14794 {
14795 /* find VdlVWHigh lower bound */
14796 VdlVWHigh_Lower_Vcent = i;
14797 break;
14798 }
14799 }
14800 mcSHOW_DBG_MSG(("[EYESCAN_LOG] RX VdlVWHigh_Lower Vcent=%d(%dmV(X100))\n", VdlVWHigh_Lower_Vcent, gRXVref_Voltage_Table_LP4[VdlVWHigh_Lower_Vcent]));
14801
14802#ifdef FOR_HQA_TEST_USED
14803 EyeScanVcent[0] = gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx];
14804 EyeScanVcent[1] = VdlVWHigh_Upper_Vcent;
14805 EyeScanVcent[2] = VdlVWHigh_Lower_Vcent;
14806#endif
14807
14808 shuffleIdx = get_shuffleIndex_by_Freq(p);
14809
14810 mcSHOW_DBG_MSG(("[EYESCAN_LOG] delay cell %d/100ps\n", u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx]));
14811
14812 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
14813 {
14814 mcSHOW_DBG_MSG(("[EYESCAN_LOG] %d Channel%d Bit%d(DRAM DQ%d)\tHigher VdlTW=%d/100ps\tLower VdlTW=%d/100ps\n",
14815 p->frequency*2,
14816 u1ChannelIdx,
14817 u1BitIdx,
14818 uiLPDDR4_O1_Mapping_POP[p->channel][u1BitIdx],
14819 gEyeScan_WinSize[VdlVWHigh_Upper_Vcent][u1BitIdx]*u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx],
14820 gEyeScan_WinSize[VdlVWHigh_Lower_Vcent][u1BitIdx]*u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx]
14821 ));
14822
14823#ifdef FOR_HQA_TEST_USED
14824 //find VdlVWBest Vref Range and Vref
14825 VdlVWBest_Vcent = VREF_VOLTAGE_TABLE_NUM-1;
14826 max_winsize = 0;
14827 for(i=RX_VREF_RANGE_END; i>=0; i--)
14828 {
14829 if (gEyeScan_WinSize[i][u1BitIdx] > max_winsize)
14830 {
14831 max_winsize = gEyeScan_WinSize[i][u1BitIdx];
14832 VdlVWBest_Vcent = i;
14833 }
14834 }
14835
14836 EyeScanVcent[10+u1BitIdx] = VdlVWBest_Vcent;
14837#endif
14838
14839 if (gEyeScan_WinSize[VdlVWHigh_Upper_Vcent][u1BitIdx] < minRXEyeScanVcentUpperBound)
14840 {
14841 minRXEyeScanVcentUpperBound = gEyeScan_WinSize[VdlVWHigh_Upper_Vcent][u1BitIdx];
14842 minRXEyeScanVcentUpperBound_bit = u1BitIdx;
14843 }
14844 if (gEyeScan_WinSize[VdlVWHigh_Lower_Vcent][u1BitIdx] < minRXEyeScanVcentLowerBound)
14845 {
14846 minRXEyeScanVcentLowerBound = gEyeScan_WinSize[VdlVWHigh_Lower_Vcent][u1BitIdx];
14847 minRXEyeScanVcentLowerBound_bit = u1BitIdx;
14848 }
14849 }
14850
14851#ifdef FOR_HQA_TEST_USED
14852#ifdef FOR_HQA_REPORT_USED
14853 print_EyeScanVcent_for_HQA_report_used(p, print_type, u1ChannelIdx, u1RankIdx, EyeScanVcent, minRXEyeScanVcentUpperBound, minRXEyeScanVcentUpperBound_bit, minRXEyeScanVcentLowerBound, minRXEyeScanVcentLowerBound_bit);
14854#endif
14855#endif
14856 }
14857 }
14858#endif
14859
14860
14861
14862 if (print_type==1)
14863 if (u1RXEyeScanEnable)
14864 {
14865 int drawend, drawbegin;
14866
14867 mcSHOW_DBG_MSG(("\n\n"));
14868
14869 for (u1BitIdx=0; u1BitIdx<p->data_width; u1BitIdx++)
14870 {
14871 EyeScan_Index = 0;
14872
14873 Min_Value_1UI_Line = gEyeScan_DelayCellPI[u1BitIdx]-16;
14874
14875 mcSHOW_EYESCAN_MSG(("[EYESCAN_LOG] RX EYESCAN Channel%d, Rank%d, DQ%d ===\n",p->channel, p->rank, u1BitIdx));
14876
14877#if VENDER_JV_LOG || defined(RELEASE)
14878 for(i=0; i<8+one_pi_ps*32/1000; i++) mcSHOW_EYESCAN_MSG((" "));
14879 mcSHOW_EYESCAN_MSG(("window\n"));
14880#else
14881 for(i=0; i<8+one_pi_ps*32/1000; i++) mcSHOW_EYESCAN_MSG((" "));
14882 mcSHOW_EYESCAN_MSG(("first last window\n"));
14883#endif
14884
14885 drawbegin = -32 ;//gEyeScan_Min[gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx]][u1BitIdx][EyeScan_Index]-5;
14886 drawend = 64;
14887
14888 u1VrefRange=0;
14889 for (u1VrefIdx=RX_VREF_RANGE_END; u1VrefIdx>=0; u1VrefIdx--)
14890 {
14891//fra EyeScan_Pic_draw_line(p, 1, u1VrefRange, u1VrefIdx, u1BitIdx, p->odt_onoff==ODT_ON ? 0 : -32, 64, u1VrefRange, gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx], VdlVWHigh_Upper_Vcent_Range, VdlVWHigh_Upper_Vcent, VdlVWHigh_Lower_Vcent_Range, VdlVWHigh_Lower_Vcent, gEyeScan_CaliDelay[u1BitIdx/8], gEyeScan_DelayCellPI[u1BitIdx], one_pi_ps, Min_Value_1UI_Line);
14892 EyeScan_Pic_draw_line(p, 1, u1VrefRange, u1VrefIdx, u1BitIdx, drawbegin, drawend, u1VrefRange, gFinalRXVrefDQ[u1ChannelIdx][u1RankIdx], VdlVWHigh_Upper_Vcent_Range, VdlVWHigh_Upper_Vcent, VdlVWHigh_Lower_Vcent_Range, VdlVWHigh_Lower_Vcent, gEyeScan_CaliDelay[u1BitIdx/8], gEyeScan_DelayCellPI[u1BitIdx], one_pi_ps, Min_Value_1UI_Line);
14893 }
14894 mcSHOW_EYESCAN_MSG(("\n\n"));
14895
14896 }
14897//fra while(1);
14898 }
14899
14900
14901
14902
14903
14904/**************************************************************************************
14905 TX EYESCAN log
14906***************************************************************************************/
14907 TXVrefRange = (u1MR14Value[p->channel][p->rank][p->dram_fsp]>>6)&1;
14908
14909#if !VENDER_JV_LOG && !defined(RELEASE)
14910 if (print_type==2)
14911 if (u1TXEyeScanEnable)
14912 { U8 cal_length;
14913 U16 finalTXVref;
14914
14915 if (print_type==2)
14916 {
14917 mcSHOW_DBG_MSG(("[EYESCAN_LOG] TX DQ Window\n"));
14918 cal_length = p->data_width;
14919 finalTXVref = gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx];
14920 }
14921
14922 vddq=vGetVoltage(p, 2)/1000; //mv
14923 mcSHOW_DBG_MSG(("[EYESCAN_LOG] VDDQ=%dmV\n",vddq));
14924// for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<local_channel_num; u1ChannelIdx++)
14925 {
14926// for(u1RankIdx = RANK_0; u1RankIdx < 2; u1RankIdx++)
14927 {
14928 if (print_type==2)
14929 {
14930 mcSHOW_DBG_MSG(("[EYESCAN_LOG] TX Channel%d Range %d Final_Vref Vcent=%d(%dmV(X100))\n",
14931 u1ChannelIdx,
14932 TXVrefRange,
14933 gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx],
14934 pVref_Voltage_Table[TXVrefRange][gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx]]*vddq/100));
14935
14936 Vcent_DQ = pVref_Voltage_Table[TXVrefRange][gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx]]*vddq/100;
14937 }
14938
14939 //find VdlVWHigh first
14940 VdlVWHigh_Upper_Vcent_Range = 1;
14941 VdlVWHigh_Upper_Vcent = VREF_VOLTAGE_TABLE_NUM-1;
14942 vrefrange_i = TXVrefRange;
14943 for(i=(finalTXVref); i<VREF_VOLTAGE_TABLE_NUM; i++)
14944 {
14945 if (((pVref_Voltage_Table[vrefrange_i][i]*vddq/100 - Vcent_DQ)) >= VdlVWTotal/2)
14946 {
14947 /* find VdlVWHigh upper bound */
14948 VdlVWHigh_Upper_Vcent = i;
14949 VdlVWHigh_Upper_Vcent_Range = vrefrange_i;
14950 break;
14951 }
14952 if (i==(VREF_VOLTAGE_TABLE_NUM-1) && vrefrange_i==0)
14953 {
14954 vrefrange_i=1;
14955 i=20;
14956 }
14957 }
14958 mcSHOW_DBG_MSG(("[EYESCAN_LOG] TX VdlVWHigh_Upper Range=%d Vcent=%d(%dmV(X100))\n",
14959 VdlVWHigh_Upper_Vcent_Range,
14960 VdlVWHigh_Upper_Vcent,
14961 pVref_Voltage_Table[VdlVWHigh_Upper_Vcent_Range][VdlVWHigh_Upper_Vcent]*vddq/100));
14962
14963 //find VldVWLow first
14964 VdlVWHigh_Lower_Vcent_Range = 0;
14965 VdlVWHigh_Lower_Vcent = 0;
14966 vrefrange_i = TXVrefRange;
14967 for(i=(finalTXVref); i>=0; i--)
14968 {
14969 if (((Vcent_DQ - pVref_Voltage_Table[vrefrange_i][i]*vddq/100)) >= VdlVWTotal/2)
14970 {
14971 /* find VdlVWHigh lower bound */
14972 VdlVWHigh_Lower_Vcent = i;
14973 VdlVWHigh_Lower_Vcent_Range = vrefrange_i;
14974 break;
14975 }
14976 if (i<=21 && vrefrange_i==1)
14977 {
14978 vrefrange_i=0;
14979 i=VREF_VOLTAGE_TABLE_NUM-(21-i);
14980 }
14981 }
14982 mcSHOW_DBG_MSG(("[EYESCAN_LOG] TX VdlVWHigh_Lower Range=%d Vcent=%d(%dmV(X100))\n",
14983 VdlVWHigh_Lower_Vcent_Range,
14984 VdlVWHigh_Lower_Vcent,
14985 pVref_Voltage_Table[VdlVWHigh_Lower_Vcent_Range][VdlVWHigh_Lower_Vcent]*vddq/100));
14986
14987#ifdef FOR_HQA_TEST_USED
14988 EyeScanVcent[0] = TXVrefRange;
14989 EyeScanVcent[1] = gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx];
14990 EyeScanVcent[2] = VdlVWHigh_Upper_Vcent_Range;
14991 EyeScanVcent[3] = VdlVWHigh_Upper_Vcent;
14992 EyeScanVcent[4] = VdlVWHigh_Lower_Vcent_Range;
14993 EyeScanVcent[5] = VdlVWHigh_Lower_Vcent;
14994#endif
14995
14996 shuffleIdx = get_shuffleIndex_by_Freq(p);
14997
14998 // mcSHOW_DBG_MSG(("[EYESCAN_LOG] delay cell %d/100ps\n", u2gdelay_cell_ps_all[shuffleIdx][u1ChannelIdx]));
14999
15000 for (u1BitIdx=0; u1BitIdx<cal_length; u1BitIdx++)
15001 {
15002
15003 // compare Upper/Lower Vcent pass criterion is pass or fail?
15004#if 1
15005 for(u1VrefIdx=finalTXVref+TXVrefRange*30; u1VrefIdx<=(S8)(VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30); u1VrefIdx++)
15006 {
15007 Upper_Vcent_pass_flag = 0;
15008 for (EyeScan_Index=0; EyeScan_Index<EYESCAN_BROKEN_NUM; EyeScan_Index++)
15009 {
15010 if (print_type==2)
15011 if ((((gEyeScan_CaliDelay[u1BitIdx/8]+gEyeScan_DelayCellPI[u1BitIdx]) - gEyeScan_Min[u1VrefIdx][u1BitIdx][EyeScan_Index]) >=4 ) && ((gEyeScan_Max[u1VrefIdx][u1BitIdx][EyeScan_Index] - (gEyeScan_CaliDelay[u1BitIdx/8]+gEyeScan_DelayCellPI[u1BitIdx])) >=4 ))
15012 {
15013 Upper_Vcent_pass_flag = 1;
15014 }
15015 }
15016 if (Upper_Vcent_pass_flag == 0) break; // fail!!
15017 }
15018 for(u1VrefIdx=VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30; u1VrefIdx<=(S8)(finalTXVref+TXVrefRange*30); u1VrefIdx++)
15019 {
15020 Lower_Vcent_pass_flag = 0;
15021 for (EyeScan_Index=0; EyeScan_Index<EYESCAN_BROKEN_NUM; EyeScan_Index++)
15022 {
15023 if (print_type==2)
15024 if ((((gEyeScan_CaliDelay[u1BitIdx/8]+gEyeScan_DelayCellPI[u1BitIdx]) - gEyeScan_Min[u1VrefIdx][u1BitIdx][EyeScan_Index]) >=4 ) && ((gEyeScan_Max[u1VrefIdx][u1BitIdx][EyeScan_Index] - (gEyeScan_CaliDelay[u1BitIdx/8]+gEyeScan_DelayCellPI[u1BitIdx])) >=4 ))
15025 {
15026 Lower_Vcent_pass_flag = 1;
15027 }
15028 }
15029 if (Lower_Vcent_pass_flag == 0) break; //fail!!
15030 }
15031
15032#else
15033 Upper_Vcent_pass_flag = 0;
15034 Lower_Vcent_pass_flag = 0;
15035 for (EyeScan_Index=0; EyeScan_Index<EYESCAN_BROKEN_NUM; EyeScan_Index++)
15036 {
15037 if ((EyeScan_Min[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx][EyeScan_Index] <= (EyeScan_CaliDelay[u1BitIdx/8]-4+EyeScan_DelayCellPI[u1BitIdx])) && ((EyeScan_CaliDelay[u1BitIdx/8]+4+EyeScan_DelayCellPI[u1BitIdx]) <= EyeScan_Max[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx][EyeScan_Index]))
15038 {
15039 Upper_Vcent_pass_flag = 1;
15040 }
15041
15042 if ((EyeScan_Min[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx][EyeScan_Index] <= (EyeScan_CaliDelay[u1BitIdx/8]-4+EyeScan_DelayCellPI[u1BitIdx])) && ((EyeScan_CaliDelay[u1BitIdx/8]+4+EyeScan_DelayCellPI[u1BitIdx]) <= EyeScan_Max[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx][EyeScan_Index]))
15043 {
15044 Lower_Vcent_pass_flag = 1;
15045 }
15046 }
15047#endif
15048
15049#ifdef FOR_HQA_TEST_USED
15050 //find VdlVWBest Vref Range and Vref
15051 VdlVWBest_Vcent_Range = 1;
15052 VdlVWBest_Vcent = VREF_VOLTAGE_TABLE_NUM-1;
15053 vrefrange_i = 1;
15054 max_winsize = 0;
15055 for(i=VREF_VOLTAGE_TABLE_NUM-1; i>=0; i--)
15056 {
15057 if (gEyeScan_WinSize[i+vrefrange_i*30][u1BitIdx] > max_winsize)
15058 {
15059 max_winsize = gEyeScan_WinSize[i+vrefrange_i*30][u1BitIdx];
15060 VdlVWBest_Vcent_Range = vrefrange_i;
15061 VdlVWBest_Vcent = i;
15062 }
15063 if (i==21 && vrefrange_i==1)
15064 {
15065 vrefrange_i=0;
15066 i=VREF_VOLTAGE_TABLE_NUM;
15067 }
15068 }
15069
15070 EyeScanVcent[10+u1BitIdx*2] = VdlVWBest_Vcent_Range;
15071 EyeScanVcent[10+u1BitIdx*2+1] = VdlVWBest_Vcent;
15072#endif
15073
15074 if (print_type==2)
15075 {
15076 mcSHOW_DBG_MSG(("[EYESCAN_LOG] %d Channel%d Rank%d Bit%d(DRAM DQ%d)\tHigher VdlTW=%dPI(%d/100ps)(%s)\tLower VdlTW=%dpi(%d/100ps)(%s)\n",
15077 p->frequency*2,
15078 u1ChannelIdx,
15079 u1RankIdx,
15080 u1BitIdx,
15081 uiLPDDR4_O1_Mapping_POP[p->channel][u1BitIdx],
15082 gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx],
15083 gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx]*one_pi_ps,
15084 Upper_Vcent_pass_flag==1 ? "PASS" : "FAIL",
15085 gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx],
15086 gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx]*one_pi_ps,
15087 Lower_Vcent_pass_flag==1 ? "PASS" : "FAIL"
15088 ));
15089
15090 if (gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx] < minTXEyeScanVcentUpperBound)
15091 {
15092 minTXEyeScanVcentUpperBound = gEyeScan_WinSize[VdlVWHigh_Upper_Vcent+VdlVWHigh_Upper_Vcent_Range*30][u1BitIdx];
15093 minTXEyeScanVcentUpperBound_bit = u1BitIdx;
15094 }
15095 if (gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx] < minTXEyeScanVcentLowerBound)
15096 {
15097 minTXEyeScanVcentLowerBound = gEyeScan_WinSize[VdlVWHigh_Lower_Vcent+VdlVWHigh_Lower_Vcent_Range*30][u1BitIdx];
15098 minTXEyeScanVcentLowerBound_bit = u1BitIdx;
15099 }
15100 }
15101 }
15102#ifdef FOR_HQA_TEST_USED
15103#ifdef FOR_HQA_REPORT_USED
15104 print_EyeScanVcent_for_HQA_report_used(p, print_type, u1ChannelIdx, u1RankIdx, EyeScanVcent, minTXEyeScanVcentUpperBound, minTXEyeScanVcentUpperBound_bit, minTXEyeScanVcentLowerBound, minTXEyeScanVcentLowerBound_bit);
15105#endif
15106#endif
15107 }
15108 }
15109 }
15110#endif
15111
15112
15113 if (print_type==2)
15114 if (u1TXEyeScanEnable)
15115 { U8 cal_length;
15116
15117 mcSHOW_DBG_MSG(("\n\n"));
15118
15119 if (print_type==2) cal_length = p->data_width;
15120
15121 if(gEyeScan_CaliDelay[0] <gEyeScan_CaliDelay[1])
15122 u2DQDelayBegin = gEyeScan_CaliDelay[0]-24;
15123 else
15124 u2DQDelayBegin = gEyeScan_CaliDelay[1]-24;
15125
15126
15127 u2DQDelayEnd = u2DQDelayBegin + 64;
15128
15129
15130 for (u1BitIdx=0; u1BitIdx<cal_length; u1BitIdx++)
15131 {
15132 EyeScan_Index = 0;
15133
15134#if EyeScan_Pic_draw_line_Mirror
15135 EyeScan_DelayCellPI_value = 0-gEyeScan_DelayCellPI[u1BitIdx];
15136#else
15137 EyeScan_DelayCellPI_value = gEyeScan_DelayCellPI[u1BitIdx];
15138#endif
15139 if (print_type==2) Min_Value_1UI_Line = gEyeScan_CaliDelay[u1BitIdx/8]-16-EyeScan_DelayCellPI_value;
15140
15141 if (print_type==2)
15142 {
15143 mcSHOW_EYESCAN_MSG(("[EYESCAN_LOG] TX DQ EYESCAN Channel%d, Rank%d, Bit%d(DRAM DQ%d) ===\n",p->channel, p->rank, u1BitIdx, uiLPDDR4_O1_Mapping_POP[p->channel][u1BitIdx]));
15144 }
15145
15146#if VENDER_JV_LOG
15147 for(i=0; i<8+one_pi_ps*32/1000; i++)
15148 {
15149 mcSHOW_DBG_MSG5((" "));
15150 }
15151 mcSHOW_EYESCAN_MSG(("window\n"));
15152#else
15153 for(i=0; i<15+u2DQDelayEnd-u2DQDelayBegin+2; i++) mcSHOW_DBG_MSG((" "));
15154 mcSHOW_EYESCAN_MSG(("first last window\n"));
15155#endif
15156
15157 u1VrefRange=VREF_RANGE_1;
15158 for (u1VrefIdx=VREF_VOLTAGE_TABLE_NUM-1; u1VrefIdx>=0; u1VrefIdx--)
15159 {
15160 if (print_type == 2)
15161 EyeScan_Pic_draw_line(p, print_type, u1VrefRange, u1VrefIdx, u1BitIdx, u2DQDelayBegin, u2DQDelayEnd, TXVrefRange, gFinalTXVrefDQ[u1ChannelIdx][u1RankIdx], VdlVWHigh_Upper_Vcent_Range, VdlVWHigh_Upper_Vcent, VdlVWHigh_Lower_Vcent_Range, VdlVWHigh_Lower_Vcent, gEyeScan_CaliDelay[u1BitIdx/8], gEyeScan_DelayCellPI[u1BitIdx], one_pi_ps, Min_Value_1UI_Line);
15162
15163 if (u1VrefRange==VREF_RANGE_1 && u1VrefIdx==21)
15164 {
15165 u1VrefRange=VREF_RANGE_0;
15166 u1VrefIdx=VREF_VOLTAGE_TABLE_NUM;
15167 }
15168 }
15169 mcSHOW_EYESCAN_MSG(("\n\n"));
15170
15171 }
15172 }
15173}
15174#ifdef RELEASE
15175#undef mcSHOW_DBG_MSG
15176#define mcSHOW_DBG_MSG(_x_)
15177#endif
15178#endif
15179
15180
15181
15182
15183
15184
15185
15186
15187//-------------------------------------------------------------------------
15188/** DramcMiockJmeter
15189 * start MIOCK jitter meter.
15190 * @param p Pointer of context created by DramcCtxCreate.
15191 * @param block_no (U8): block 0 or 1.
15192 * @retval status (DRAM_STATUS_T): DRAM_OK or DRAM_FAIL
15193 */
15194//-------------------------------------------------------------------------
15195
15196#ifdef ENABLE_MIOCK_JMETER
15197DRAM_STATUS_T DramcMiockJmeter(DRAMC_CTX_T *p)
15198{
15199 U8 ucsearch_state, ucdqs_dly, fgcurrent_value, fginitial_value, ucstart_period=0, ucmiddle_period=0, ucend_period=0;
15200 U32 u4sample_cnt, u4ones_cnt[DQS_NUMBER];
15201 U16 u2real_freq, u2real_period;
15202
15203 U8 u1ShuLevel;
15204 U32 u4PLL5_ADDR;
15205 U32 u4PLL8_ADDR;
15206 U32 u4CA_CMD6;
15207 U32 u4SDM_PCW;
15208 U32 u4PREDIV;
15209 U32 u4POSDIV;
15210 U32 u4CKDIV4;
15211 U32 u4VCOFreq;
15212 U32 u4DataRate;
15213 U8 u1RxGatingPI=0, u1RxGatingPI_start=12, u1RxGatingPI_end=63;
15214
15215 // error handling
15216 if (!p)
15217 {
15218 mcSHOW_ERR_MSG(("context NULL\n"));
15219 return DRAM_FAIL;
15220 }
15221
15222#if (fcFOR_CHIP_ID == fcLaurel)
15223 if(u1IsLP4Family(p->dram_type))
15224 {
15225 u1RxGatingPI_start = 0; //0x10;
15226 u1RxGatingPI_end = 63; //u1RxGatingPI_start + 1;
15227 }
15228 else
15229 {
15230 u1RxGatingPI_start = 10;
15231 u1RxGatingPI_end = 63;
15232 }
15233#endif
15234
15235 u2gdelay_cell_ps=0;
15236
15237 U32 u4RegBackupAddress[] =
15238 {
15239 (DRAMC_REG_ADDR(DRAMC_REG_EYESCAN)),
15240 (DRAMC_REG_ADDR(DRAMC_REG_STBCAL1)),
15241 (DRAMC_REG_ADDR(DDRPHY_B0_DQ6)),
15242 (DRAMC_REG_ADDR(DDRPHY_B1_DQ6)),
15243 (DRAMC_REG_ADDR(DDRPHY_B0_DQ5)),
15244 (DRAMC_REG_ADDR(DDRPHY_B1_DQ5)),
15245 (DRAMC_REG_ADDR(DDRPHY_B0_DQ3)),
15246 (DRAMC_REG_ADDR(DDRPHY_B1_DQ3)),
15247 (DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7)),
15248 (DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7)),
15249 (DRAMC_REG_ADDR(DDRPHY_B0_DQ4)),
15250 (DRAMC_REG_ADDR(DDRPHY_B1_DQ4)),
15251 (DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1)),
15252 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSIEN)),
15253 ((DDRPHY_CA_DLL_ARPI2)),
15254 ((DDRPHY_B0_DLL_ARPI2)),
15255 ((DDRPHY_B1_DLL_ARPI2)),
15256 ((DDRPHY_CA_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15257 ((DDRPHY_B0_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15258 ((DDRPHY_B1_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15259 };
15260
15261#if ENABLE_LP3_SW
15262 U32 u4RegBackupAddress_LP3[] =
15263 {
15264 (DRAMC_REG_ADDR(DRAMC_REG_EYESCAN)),
15265 (DRAMC_REG_ADDR(DRAMC_REG_STBCAL1)),
15266 (DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSIEN)),
15267
15268 (DRAMC_REG_ADDR(DDRPHY_B0_DQ6)),
15269 (DRAMC_REG_ADDR(DDRPHY_B1_DQ6)),
15270 (DRAMC_REG_ADDR(DDRPHY_B0_DQ5)),
15271 (DRAMC_REG_ADDR(DDRPHY_B1_DQ5)),
15272 (DRAMC_REG_ADDR(DDRPHY_B0_DQ3)),
15273 (DRAMC_REG_ADDR(DDRPHY_B1_DQ3)),
15274 (DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7)),
15275 (DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7)),
15276 (DRAMC_REG_ADDR(DDRPHY_B0_DQ4)),
15277 (DRAMC_REG_ADDR(DDRPHY_B1_DQ4)),
15278 (DRAMC_REG_ADDR(DDRPHY_CA_CMD4)),
15279 (DRAMC_REG_ADDR(DDRPHY_CA_CMD6)),
15280 (DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1)),
15281
15282
15283 (DRAMC_REG_ADDR(DDRPHY_B0_DQ6)+SHIFT_TO_CHB_ADDR),
15284 (DRAMC_REG_ADDR(DDRPHY_B1_DQ6)+SHIFT_TO_CHB_ADDR),
15285 (DRAMC_REG_ADDR(DDRPHY_B0_DQ5)+SHIFT_TO_CHB_ADDR),
15286 (DRAMC_REG_ADDR(DDRPHY_B1_DQ5)+SHIFT_TO_CHB_ADDR),
15287 (DRAMC_REG_ADDR(DDRPHY_B0_DQ3)+SHIFT_TO_CHB_ADDR),
15288 (DRAMC_REG_ADDR(DDRPHY_B1_DQ3)+SHIFT_TO_CHB_ADDR),
15289 (DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ7)+SHIFT_TO_CHB_ADDR),
15290 (DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ7)+SHIFT_TO_CHB_ADDR),
15291 (DRAMC_REG_ADDR(DDRPHY_B0_DQ4)+SHIFT_TO_CHB_ADDR),
15292 (DRAMC_REG_ADDR(DDRPHY_B1_DQ4)+SHIFT_TO_CHB_ADDR),
15293 (DRAMC_REG_ADDR(DDRPHY_CA_CMD4)+SHIFT_TO_CHB_ADDR),
15294 (DRAMC_REG_ADDR(DDRPHY_CA_CMD6)+SHIFT_TO_CHB_ADDR),
15295 (DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1)+SHIFT_TO_CHB_ADDR),
15296
15297 ((DDRPHY_CA_DLL_ARPI2)),
15298 ((DDRPHY_B0_DLL_ARPI2)),
15299 ((DDRPHY_B1_DLL_ARPI2)),
15300 ((DDRPHY_CA_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15301 ((DDRPHY_B0_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15302 ((DDRPHY_B1_DLL_ARPI2)+SHIFT_TO_CHB_ADDR),
15303 };
15304#endif
15305
15306 //backup register value
15307 if(u1IsLP4Family(p->dram_type))
15308 {
15309 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
15310 }
15311#if ENABLE_LP3_SW
15312 else
15313 {
15314 DramcBackupRegisters(p, u4RegBackupAddress_LP3, sizeof(u4RegBackupAddress_LP3)/sizeof(U32));
15315 }
15316#endif
15317
15318 //DLL off to fix middle transion from high to low or low to high at high vcore
15319 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_CA_DLL_ARPI2), 0x0, CA_DLL_ARPI2_RG_ARDLL_PHDET_EN_CA);
15320 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B0_DLL_ARPI2), 0x0, B0_DLL_ARPI2_RG_ARDLL_PHDET_EN_B0);
15321 vIO32WriteFldAlign_All(DRAMC_REG_ADDR(DDRPHY_B1_DLL_ARPI2), 0x0, B1_DLL_ARPI2_RG_ARDLL_PHDET_EN_B1);
15322
15323 if(u1IsLP4Family(p->dram_type))
15324 {
15325 //MCK4X CG
15326 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMDQSIENCG_EN);
15327
15328 // Bypass DQS glitch-free mode
15329 // RG_RX_*RDQ_EYE_DLY_DQS_BYPASS_B**
15330 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), 1, B0_DQ6_RG_RX_ARDQ_EYE_DLY_DQS_BYPASS_B0);
15331 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), 1, B1_DQ6_RG_RX_ARDQ_EYE_DLY_DQS_BYPASS_B1);
15332
15333 //Enable DQ eye scan
15334 //RG_??_RX_EYE_SCAN_EN
15335 //RG_??_RX_VREF_EN
15336 //RG_??_RX_SMT_EN
15337 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 1, EYESCAN_RG_RX_EYE_SCAN_EN);
15338 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), P_Fld(0x1, EYESCAN_EYESCAN_DQS_SYNC_EN)
15339 | P_Fld(0x1, EYESCAN_EYESCAN_NEW_DQ_SYNC_EN)
15340 | P_Fld(0x1, EYESCAN_EYESCAN_DQ_SYNC_EN));
15341 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_EYE_EN_B0);
15342 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_EYE_EN_B1);
15343 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0);
15344 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1);
15345 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 1, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0);
15346 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 1, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1);
15347
15348 //JM_SEL
15349 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), 1, B0_DQ6_RG_RX_ARDQ_JM_SEL_B0);
15350 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), 1, B1_DQ6_RG_RX_ARDQ_JM_SEL_B1);
15351 }
15352#if ENABLE_LP3_SW
15353 else
15354 {
15355 //MCK4X CG
15356 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_MISC_CTRL1), 0, MISC_CTRL1_R_DMDQSIENCG_EN);
15357
15358 // Bypass DQS glitch-free mode
15359 // RG_RX_*RDQ_EYE_DLY_DQS_BYPASS_B**
15360 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), 1, B0_DQ6_RG_RX_ARDQ_EYE_DLY_DQS_BYPASS_B0);
15361 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), 1, B1_DQ6_RG_RX_ARDQ_EYE_DLY_DQS_BYPASS_B1);
15362
15363 //Enable DQ eye scan
15364 //RG_??_RX_EYE_SCAN_EN
15365 //RG_??_RX_VREF_EN
15366 //RG_??_RX_SMT_EN
15367 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 1, EYESCAN_RG_RX_EYE_SCAN_EN);
15368 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), P_Fld(0x1, EYESCAN_EYESCAN_DQS_SYNC_EN)
15369 | P_Fld(0x1, EYESCAN_EYESCAN_NEW_DQ_SYNC_EN)
15370 | P_Fld(0x1, EYESCAN_EYESCAN_DQ_SYNC_EN));
15371 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_EYE_EN_B0);
15372 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_EYE_EN_B1);
15373 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), 1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0);
15374 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), 1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1);
15375 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), 1, B0_DQ3_RG_RX_ARDQ_SMT_EN_B0);
15376 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), 1, B1_DQ3_RG_RX_ARDQ_SMT_EN_B1);
15377
15378 //JM_SEL
15379 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), 1, B0_DQ6_RG_RX_ARDQ_JM_SEL_B0);
15380 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), 1, B1_DQ6_RG_RX_ARDQ_JM_SEL_B1);
15381 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD6), 1, CA_CMD6_RG_RX_ARCMD_JM_SEL);
15382 }
15383#endif
15384
15385
15386 //Enable MIOCK jitter meter mode ( RG_RX_MIOCK_JIT_EN=1)
15387 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 1, EYESCAN_RG_RX_MIOCK_JIT_EN);
15388
15389 //Disable DQ eye scan (b'1), for counter clear
15390 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 0, EYESCAN_RG_RX_EYE_SCAN_EN);
15391 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL1), 0, STBCAL1_DQSERRCNT_DIS);
15392
15393 //Using test engine to switch back to RK0, or the gating PI cannont be adjust successfully.
15394 DramcEngine2Run(p, TE_OP_READ_CHECK, p->test_pattern);
15395
15396 for (u1RxGatingPI=u1RxGatingPI_start; u1RxGatingPI<u1RxGatingPI_end; u1RxGatingPI+=4)
15397 {
15398 mcSHOW_DBG_MSG(("\n[DramcMiockJmeter] u1RxGatingPI = %d\n", u1RxGatingPI));
15399
15400 ucsearch_state = 0;
15401
15402 //to see 1T(H,L) or 1T(L,H) from delaycell=0 to 127
15403 vIO32WriteFldMulti(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_DQSIEN), P_Fld(u1RxGatingPI, SHURK0_DQSIEN_R0DQS0IEN) | P_Fld(u1RxGatingPI, SHURK0_DQSIEN_R0DQS1IEN)
15404 | P_Fld(u1RxGatingPI, SHURK0_DQSIEN_R0DQS2IEN) | P_Fld(u1RxGatingPI, SHURK0_DQSIEN_R0DQS3IEN));
15405
15406 for (ucdqs_dly=0; ucdqs_dly<128; ucdqs_dly++)
15407 {
15408
15409 //Set DQS delay (RG_??_RX_DQS_EYE_DLY)
15410 if(u1IsLP4Family(p->dram_type))
15411 {
15412 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ4), ucdqs_dly, B0_DQ4_RG_RX_ARDQS_EYE_R_DLY_B0);
15413 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ4), ucdqs_dly, B0_DQ4_RG_RX_ARDQS_EYE_F_DLY_B0);
15414 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ4), ucdqs_dly, B1_DQ4_RG_RX_ARDQS_EYE_R_DLY_B1);
15415 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ4), ucdqs_dly, B1_DQ4_RG_RX_ARDQS_EYE_F_DLY_B1);
15416 }
15417#if ENABLE_LP3_SW
15418 else //LPDDR3
15419 {
15420 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ4), ucdqs_dly, B0_DQ4_RG_RX_ARDQS_EYE_R_DLY_B0);
15421 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B0_DQ4), ucdqs_dly, B0_DQ4_RG_RX_ARDQS_EYE_F_DLY_B0);
15422 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ4), ucdqs_dly, B1_DQ4_RG_RX_ARDQS_EYE_R_DLY_B1);
15423 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_B1_DQ4), ucdqs_dly, B1_DQ4_RG_RX_ARDQS_EYE_F_DLY_B1);
15424 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD4), ucdqs_dly, CA_CMD4_RG_RX_ARCLK_EYE_R_DLY);
15425 vIO32WriteFldAlign_Phy_All(DRAMC_REG_ADDR(DDRPHY_CA_CMD4), ucdqs_dly, CA_CMD4_RG_RX_ARCLK_EYE_F_DLY);
15426 }
15427#endif
15428 DramPhyReset(p);
15429
15430 //Reset eye scan counters (reg_sw_rst): 1 to 0
15431 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 1, EYESCAN_REG_SW_RST);
15432 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 0, EYESCAN_REG_SW_RST);
15433
15434 //Enable DQ eye scan (b'1)
15435 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 1, EYESCAN_RG_RX_EYE_SCAN_EN);
15436
15437 //2ns/sample, here we delay 1ms about 500 samples
15438 mcDELAY_US(10);
15439
15440 //Disable DQ eye scan (b'1), for counter latch
15441 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_EYESCAN), 0, EYESCAN_RG_RX_EYE_SCAN_EN);
15442
15443 //Read the counter values from registers (toggle_cnt*, dqs_err_cnt*);
15444 u4sample_cnt = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_TOGGLE_CNT), TOGGLE_CNT_TOGGLE_CNT);
15445 u4ones_cnt[0] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQS0_ERR_CNT), DQS0_ERR_CNT_DQS0_ERR_CNT);
15446 u4ones_cnt[1] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQS1_ERR_CNT), DQS1_ERR_CNT_DQS1_ERR_CNT);
15447 u4ones_cnt[2] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQS2_ERR_CNT), DQS2_ERR_CNT_DQS2_ERR_CNT);
15448 u4ones_cnt[3] = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_DQS3_ERR_CNT), DQS3_ERR_CNT_DQS3_ERR_CNT);
15449 #ifdef ETT_PRINT_FORMAT
15450 mcSHOW_DBG_MSG(("%d : %d, %d, %d, %d, %d\n", ucdqs_dly, u4sample_cnt, u4ones_cnt[0],u4ones_cnt[1],u4ones_cnt[2],u4ones_cnt[3]));
15451 #else
15452 mcSHOW_DBG_MSG(("%3d : %8d, %8d, %8d, %8d, %8d\n", ucdqs_dly, u4sample_cnt, u4ones_cnt[0],u4ones_cnt[2],u4ones_cnt[3]));
15453 #endif
15454
15455 /*
15456 //Disable DQ eye scan (RG_RX_EYE_SCAN_EN=0, RG_RX_*RDQ_VREF_EN_B*=0, RG_RX_*RDQ_EYE_VREF_EN_B*=0, RG_RX_*RDQ_SMT_EN_B*=0)
15457 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_STBCAL_F), 0, STBCAL_F_RG_EX_EYE_SCAN_EN);
15458 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_EYE2), 0, EYE2_RG_RX_ARDQ_VREF_EN_B0);
15459 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_EYEB1_2), 0, EYEB1_2_RG_RX_ARDQ_VREF_EN_B1);
15460 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_EYE2), 0, EYE2_RG_RX_ARDQ_EYE_VREF_EN_B0);
15461 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_EYEB1_2), 0, EYEB1_2_RG_RX_ARDQ_EYE_VREF_EN_B1);
15462 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_TXDQ3), 0, TXDQ3_RG_RX_ARDQ_SMT_EN_B0);
15463 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_RXDQ13),0, RXDQ13_RG_RX_ARDQ_SMT_EN_B1);
15464 */
15465
15466 //change to boolean value
15467 if (u4ones_cnt[0] < (u4sample_cnt/2))
15468 {
15469 fgcurrent_value = 0;
15470 }
15471 else
15472 {
15473 fgcurrent_value = 1;
15474 }
15475
15476 #if 1//more than 1T data
15477 {
15478 if (ucsearch_state==0)
15479 {
15480 //record initial value at the beginning
15481 fginitial_value = fgcurrent_value;
15482 ucsearch_state = 1;
15483 }
15484 else if (ucsearch_state==1)
15485 {
15486 // check if change value
15487 if (fgcurrent_value != fginitial_value)
15488 {
15489 // start of the period
15490 fginitial_value = fgcurrent_value;
15491 ucstart_period = ucdqs_dly;
15492 ucsearch_state = 2;
15493 }
15494 }
15495 else if (ucsearch_state==2)
15496 {
15497 // check if change value
15498 if (fgcurrent_value != fginitial_value)
15499 {
15500 fginitial_value = fgcurrent_value;
15501 ucmiddle_period = ucdqs_dly;
15502 ucsearch_state = 3;
15503 }
15504 }
15505 else if (ucsearch_state==3)
15506 {
15507 // check if change value
15508 if (fgcurrent_value != fginitial_value)
15509 {
15510 // end of the period, break the loop
15511 ucend_period = ucdqs_dly;
15512 ucsearch_state = 4;
15513 break;
15514 }
15515 }
15516 else
15517 {
15518 //nothing
15519 }
15520 }
15521 #else //only 0.5T data
15522 {
15523 if (ucsearch_state==0)
15524 {
15525 //record initial value at the beginning
15526 fginitial_value = fgcurrent_value;
15527 ucsearch_state = 1;
15528 }
15529 else if (ucsearch_state==1)
15530 {
15531 // check if change value
15532 if (fgcurrent_value != fginitial_value)
15533 {
15534 // start of the period
15535 fginitial_value = fgcurrent_value;
15536 ucstart_period = ucdqs_dly;
15537 ucsearch_state = 2;
15538 }
15539 }
15540 else if (ucsearch_state==2)
15541 {
15542 // check if change value
15543 if (fgcurrent_value != fginitial_value)
15544 {
15545 // end of the period, break the loop
15546 ucend_period = ucdqs_dly;
15547 ucsearch_state = 4;
15548 break;
15549 }
15550 }
15551 }
15552 #endif
15553 }
15554
15555 if((ucsearch_state==4) || (ucsearch_state==3))
15556 break;
15557 }
15558
15559 //restore to orignal value
15560 if(u1IsLP4Family(p->dram_type))
15561 {
15562 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
15563 }
15564#if ENABLE_LP3_SW
15565 else
15566 {
15567 DramcRestoreRegisters(p, u4RegBackupAddress_LP3, sizeof(u4RegBackupAddress_LP3)/sizeof(U32));
15568 }
15569#endif
15570
15571 if(ucsearch_state!=4)
15572 {
15573 if (ucsearch_state!=3)
15574 {
15575 mcSHOW_DBG_MSG(("\n\tMIOCK jitter meter - ch=%d\n", p->channel));
15576 mcSHOW_DBG_MSG(("\tLess than 0.5T data. Cannot calculate delay cell time\n\n"));
15577
15578 ucg_num_dlycell_perT = 0; //for LP3/4 lookup table used
15579
15580 return DRAM_FAIL;
15581 }
15582 else
15583 {
15584 //Calculate 1 delay cell = ? ps
15585 // 1T = ? delay cell
15586 ucg_num_dlycell_perT = (ucmiddle_period - ucstart_period)*2;
15587 // 1T = ? ps
15588 }
15589 }
15590 else
15591 {
15592 //Calculate 1 delay cell = ? ps
15593 // 1T = ? delay cell
15594 ucg_num_dlycell_perT = (ucend_period - ucstart_period);
15595 // 1T = ? ps
15596 }
15597
15598 u1ShuLevel = u4IO32ReadFldAlign(DRAMC_REG_SHUSTATUS, SHUSTATUS_SHUFFLE_LEVEL);
15599 u4PLL5_ADDR = DDRPHY_SHU1_PLL5 + SHU_GRP_DDRPHY_OFFSET * u1ShuLevel;
15600 u4PLL8_ADDR = DDRPHY_SHU1_PLL8 + SHU_GRP_DDRPHY_OFFSET * u1ShuLevel;
15601 u4CA_CMD6 = DDRPHY_SHU1_CA_CMD6 + SHU_GRP_DDRPHY_OFFSET * u1ShuLevel;
15602 u4SDM_PCW = u4IO32ReadFldAlign(u4PLL5_ADDR, SHU1_PLL5_RG_RPHYPLL_SDM_PCW);
15603 u4PREDIV = u4IO32ReadFldAlign(u4PLL8_ADDR, SHU1_PLL8_RG_RPHYPLL_PREDIV);
15604 u4POSDIV = u4IO32ReadFldAlign(u4PLL8_ADDR, SHU1_PLL8_RG_RPHYPLL_POSDIV);
15605 u4CKDIV4 = u4IO32ReadFldAlign(u4CA_CMD6, SHU1_CA_CMD6_RG_ARPI_MIDPI_CKDIV4_EN_CA);
15606 u4VCOFreq = ((52>>u4PREDIV)*(u4SDM_PCW>>8))>>u4POSDIV;
15607 u4DataRate = u4VCOFreq>>u4CKDIV4;
15608 u2real_freq = u4DataRate>>1;
15609
15610 u2real_period = (U16) (1000000/u2real_freq);
15611 //calculate delay cell time
15612
15613 u2gdelay_cell_ps = u2real_period*100 / ucg_num_dlycell_perT;
15614
15615 if (ucsearch_state==4)
15616 {
15617 mcSHOW_DBG_MSG(("\n\tMIOCK jitter meter\tch=%d\n\n"
15618 "1T = (%d-%d) = %d dly cells\n"
15619 "Clock freq = %d MHz, period = %d ps, 1 dly cell = %d/100 ps\n",
15620 p->channel,
15621 ucend_period, ucstart_period, ucg_num_dlycell_perT,
15622 u2real_freq, u2real_period, u2gdelay_cell_ps));
15623 }
15624 else
15625 {
15626 mcSHOW_DBG_MSG(("\n\tMIOCK jitter meter\tch=%d\n\n"
15627 "1T = (%d-%d)*2 = %d dly cells\n"
15628 "Clock freq = %d MHz, period = %d ps, 1 dly cell = %d/100 ps\n",
15629 p->channel,
15630 ucmiddle_period, ucstart_period, ucg_num_dlycell_perT,
15631 u2real_freq, u2real_period, u2gdelay_cell_ps));
15632 }
15633
15634 return DRAM_OK;
15635
15636// log example
15637/* dly: sample_cnt DQS0_cnt DQS1_cnt
15638 0 : 10962054, 0, 0
15639 1 : 10958229, 0, 0
15640 2 : 10961109, 0, 0
15641 3 : 10946916, 0, 0
15642 4 : 10955421, 0, 0
15643 5 : 10967274, 0, 0
15644 6 : 10893582, 0, 0
15645 7 : 10974762, 0, 0
15646 8 : 10990278, 0, 0
15647 9 : 10972026, 0, 0
15648 10 : 7421004, 0, 0
15649 11 : 10943883, 0, 0
15650 12 : 10984275, 0, 0
15651 13 : 10955268, 0, 0
15652 14 : 10960326, 0, 0
15653 15 : 10952451, 0, 0
15654 16 : 10956906, 0, 0
15655 17 : 10960803, 0, 0
15656 18 : 10944108, 0, 0
15657 19 : 10959939, 0, 0
15658 20 : 10959246, 0, 0
15659 21 : 11002212, 0, 0
15660 22 : 10919700, 0, 0
15661 23 : 10977489, 0, 0
15662 24 : 11009853, 0, 0
15663 25 : 10991133, 0, 0
15664 26 : 10990431, 0, 0
15665 27 : 10970703, 11161, 0
15666 28 : 10970775, 257118, 0
15667 29 : 10934442, 9450467, 0
15668 30 : 10970622, 10968475, 0
15669 31 : 10968831, 10968831, 0
15670 32 : 10956123, 10956123, 0
15671 33 : 10950273, 10950273, 0
15672 34 : 10975770, 10975770, 0
15673 35 : 10983024, 10983024, 0
15674 36 : 10981701, 10981701, 0
15675 37 : 10936782, 10936782, 0
15676 38 : 10889523, 10889523, 0
15677 39 : 10985913, 10985913, 55562
15678 40 : 10970235, 10970235, 272294
15679 41 : 10996056, 10996056, 9322868
15680 42 : 10972350, 10972350, 10969738
15681 43 : 10963917, 10963917, 10963917
15682 44 : 10967895, 10967895, 10967895
15683 45 : 10961739, 10961739, 10961739
15684 46 : 10937097, 10937097, 10937097
15685 47 : 10937952, 10937952, 10937952
15686 48 : 10926018, 10926018, 10926018
15687 49 : 10943793, 10943793, 10943793
15688 50 : 10954638, 10954638, 10954638
15689 51 : 10968048, 10968048, 10968048
15690 52 : 10944036, 10944036, 10944036
15691 53 : 11012112, 11012112, 11012112
15692 54 : 10969137, 10969137, 10969137
15693 55 : 10968516, 10968516, 10968516
15694 56 : 10952532, 10952532, 10952532
15695 57 : 10985832, 10985832, 10985832
15696 58 : 11002527, 11002527, 11002527
15697 59 : 10950660, 10873571, 10950660
15698 60 : 10949022, 10781797, 10949022
15699 61 : 10974366, 10700617, 10974366
15700 62 : 10972422, 1331974, 10972422
15701 63 : 10926567, 0, 10926567
15702 64 : 10961658, 0, 10961658
15703 65 : 10978893, 0, 10978893
15704 66 : 10962828, 0, 10962828
15705 67 : 10957599, 0, 10957599
15706 68 : 10969227, 0, 10969227
15707 69 : 10960722, 0, 10960722
15708 70 : 10970937, 0, 10963180
15709 71 : 10962054, 0, 10711639
15710 72 : 10954719, 0, 10612707
15711 73 : 10958778, 0, 479589
15712 74 : 10973898, 0, 0
15713 75 : 11004156, 0, 0
15714 76 : 10944261, 0, 0
15715 77 : 10955340, 0, 0
15716 78 : 10998153, 0, 0
15717 79 : 10998774, 0, 0
15718 80 : 10953234, 0, 0
15719 81 : 10960020, 0, 0
15720 82 : 10923831, 0, 0
15721 83 : 10951362, 0, 0
15722 84 : 10965249, 0, 0
15723 85 : 10949103, 0, 0
15724 86 : 10948707, 0, 0
15725 87 : 10941147, 0, 0
15726 88 : 10966572, 0, 0
15727 89 : 10971333, 0, 0
15728 90 : 10943721, 0, 0
15729 91 : 10949337, 0, 0
15730 92 : 10965942, 0, 0
15731 93 : 10970397, 0, 0
15732 94 : 10956429, 0, 0
15733 95 : 10939896, 0, 0
15734 96 : 10967112, 0, 0
15735 97 : 10951911, 0, 0
15736 98 : 10953702, 0, 0
15737 99 : 10971090, 0, 0
15738 100 : 10939590, 0, 0
15739 101 : 10993392, 0, 0
15740 102 : 10975932, 0, 0
15741 103 : 10949499, 40748, 0
15742 104 : 10962522, 258638, 0
15743 105 : 10951524, 275292, 0
15744 106 : 10982475, 417642, 0
15745 107 : 10966887, 10564347, 0
15746 ===============================================================================
15747 MIOCK jitter meter - channel=0
15748 ===============================================================================
15749 1T = (107-29) = 78 delay cells
15750 Clock frequency = 936 MHz, Clock period = 1068 ps, 1 delay cell = 13 ps
15751*/
15752}
15753#endif
15754
15755
15756
15757
15758#if ENABLE_DUTY_SCAN_V2
15759
15760#define DutyPrintAllLog 0
15761#define DutyPrintCalibrationLog 1
15762
15763#define DUTY_OFFSET_START -8
15764#define DUTY_OFFSET_END 8
15765
15766#define CLOCK_PI_START 0
15767#define CLOCK_PI_END 63
15768#define CLOCK_PI_STEP 2
15769
15770#define ClockDutyFailLowerBound 4500 // 45%
15771#define ClockDutyFailUpperBound 5500 // 55%
15772#define ClockDutyMiddleBound 5000 // 50%
15773
15774void DramcClockDutySetClkDelayCell(DRAMC_CTX_T *p, U8 u1RankIdx, S8 scDutyDelay, U8 use_rev_bit)
15775{
15776 U8 u1ShuffleIdx = 0;
15777 U32 save_offset;
15778 U8 ucDelay, ucDelayB;
15779 U8 ucRev_Bit0=0, ucRev_Bit1=0;
15780
15781// mcSHOW_DBG_MSG(("CH%d, Final CLK duty delay cell = %d\n", p->channel, scDutyDelay));
15782
15783 if (scDutyDelay<0)
15784 {
15785 ucDelay = -scDutyDelay;
15786 ucDelayB = 0;
15787
15788 if (use_rev_bit)
15789 {
15790 ucRev_Bit0 = 1;
15791 ucRev_Bit1 = 0;
15792 }
15793 }
15794 else if (scDutyDelay>0)
15795 {
15796 ucDelay = 0;
15797 ucDelayB= scDutyDelay;
15798
15799 if (use_rev_bit)
15800 {
15801 ucRev_Bit0 = 0;
15802 ucRev_Bit1 = 1;
15803 }
15804 }
15805 else
15806 {
15807 ucDelay = 0;
15808 ucDelayB= 0;
15809
15810 if (use_rev_bit)
15811 {
15812 ucRev_Bit0 = 0;
15813 ucRev_Bit1 = 0;
15814 }
15815 }
15816
15817#if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ
15818 for(u1ShuffleIdx = 0; u1ShuffleIdx<DRAM_DFS_SHUFFLE_MAX; u1ShuffleIdx++)
15819#endif
15820 {
15821 save_offset = u1ShuffleIdx * SHU_GRP_DDRPHY_OFFSET + u1RankIdx*0x100;
15822 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD1) + save_offset, P_Fld(ucDelay, SHU1_R0_CA_CMD1_RK0_TX_ARCLK_DLY) | P_Fld(ucDelay, SHU1_R0_CA_CMD1_RK0_TX_ARCLKB_DLY));
15823 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0) + save_offset, P_Fld(ucDelayB, SHU1_R0_CA_CMD0_RK0_TX_ARCLK_DLYB) | P_Fld(ucDelayB, SHU1_R0_CA_CMD0_RK0_TX_ARCLKB_DLYB));
15824
15825// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
15826 save_offset = u1ShuffleIdx * SHU_GRP_DDRPHY_OFFSET;
15827 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD3), P_Fld(ucRev_Bit0, SHU1_CA_CMD3_RG_TX_ARCMD_PU_BIT0) | P_Fld(ucRev_Bit1, SHU1_CA_CMD3_RG_TX_ARCMD_PU_BIT1));
15828 }
15829}
15830
15831void DQSDutyScan_SetDqsDelayCell(DRAMC_CTX_T *p, S8 *scDutyDelay, U8 use_rev_bit)
15832{
15833 U8 u1ShuffleIdx = 0, u1DQSIdx, u1RankIdx = 0;
15834 U32 save_offset;
15835 U8 u1Delay[2], u1DelayB[2];
15836 U8 ucRev_Bit0[2]={0,0}, ucRev_Bit1[2]={0,0};
15837
15838// mcSHOW_DBG_MSG(("CH%d, Final DQS0 duty delay cell = %d\n", p->channel, scDutyDelay[0]));
15839// mcSHOW_DBG_MSG(("CH%d, Final DQS1 duty delay cell = %d\n", p->channel, scDutyDelay[1]));
15840
15841 for(u1DQSIdx=0; u1DQSIdx<2; u1DQSIdx++)
15842 {
15843 if(scDutyDelay[u1DQSIdx] <0)
15844 {
15845 u1Delay[u1DQSIdx] = -(scDutyDelay[u1DQSIdx]);
15846 u1DelayB[u1DQSIdx] =0;
15847
15848 if (use_rev_bit)
15849 {
15850 ucRev_Bit0[u1DQSIdx] = 1;
15851 ucRev_Bit1[u1DQSIdx] = 0;
15852 }
15853 }
15854 else if(scDutyDelay[u1DQSIdx] >0)
15855 {
15856 u1Delay[u1DQSIdx] = 0;
15857 u1DelayB[u1DQSIdx] = scDutyDelay[u1DQSIdx];
15858
15859 if (use_rev_bit)
15860 {
15861 ucRev_Bit0[u1DQSIdx] = 0;
15862 ucRev_Bit1[u1DQSIdx] = 1;
15863 }
15864 }
15865 else
15866 {
15867 u1Delay[u1DQSIdx] = 0;
15868 u1DelayB[u1DQSIdx] =0;
15869
15870 if (use_rev_bit)
15871 {
15872 ucRev_Bit0[u1DQSIdx] = 0;
15873 ucRev_Bit1[u1DQSIdx] = 0;
15874 }
15875 }
15876 }
15877
15878#if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ
15879 for(u1ShuffleIdx = 0; u1ShuffleIdx<DRAM_DFS_SHUFFLE_MAX; u1ShuffleIdx++)
15880#endif
15881 {
15882 for(u1RankIdx = 0; u1RankIdx<RANK_MAX; u1RankIdx++)
15883 {
15884 for(u1DQSIdx = 0; u1DQSIdx<2; u1DQSIdx++)
15885 {
15886 save_offset = u1ShuffleIdx * SHU_GRP_DDRPHY_OFFSET + u1RankIdx*0x100 + u1DQSIdx*0x50;
15887 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ1) + save_offset, P_Fld(u1Delay[u1DQSIdx], SHU1_R0_B0_DQ1_RK0_TX_ARDQS0_DLY_B0) | P_Fld(u1Delay[u1DQSIdx], SHU1_R0_B0_DQ1_RK0_TX_ARDQS0B_DLY_B0));
15888 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ1) + save_offset, P_Fld(u1DelayB[u1DQSIdx], SHU1_R0_B0_DQ1_RK0_TX_ARDQS0_DLYB_B0) | P_Fld(u1DelayB[u1DQSIdx], SHU1_R0_B0_DQ1_RK0_TX_ARDQS0B_DLYB_B0));
15889
15890// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
15891 save_offset = u1ShuffleIdx * SHU_GRP_DDRPHY_OFFSET + u1DQSIdx*0x80;
15892 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1) + save_offset, P_Fld(ucRev_Bit0[u1DQSIdx], RG_ARDQ_REV_BIT_00_DQS_MCK4X_DLY_EN) | P_Fld(ucRev_Bit1[u1DQSIdx], RG_ARDQ_REV_BIT_01_DQS_MCK4XB_DLY_EN));
15893 }
15894 }
15895 }
15896}
15897
15898
15899void DQDQMDutyScan_SetDQDQMDelayCell(DRAMC_CTX_T *p, S8 *scDutyDelay, U8 use_rev_bit, U8 k_type)
15900{
15901 U8 u1ShuffleIdx = 0, u1DQSIdx;
15902 U32 save_offset;
15903 U8 u1Delay[2];
15904 U8 ucRev_Bit0[2], ucRev_Bit1[2];
15905
15906// mcSHOW_DBG_MSG(("CH%d, Final DQS0 duty delay cell = %d\n", p->channel, scDutyDelay[0]));
15907// mcSHOW_DBG_MSG(("CH%d, Final DQS1 duty delay cell = %d\n", p->channel, scDutyDelay[1]));
15908
15909 for(u1DQSIdx=0; u1DQSIdx<2; u1DQSIdx++)
15910 {
15911 if(scDutyDelay[u1DQSIdx] <0)
15912 {
15913 u1Delay[u1DQSIdx] = (-(scDutyDelay[u1DQSIdx])) | (1<<3); //sign bit
15914
15915 if (use_rev_bit)
15916 {
15917 ucRev_Bit0[u1DQSIdx] = 0;
15918 ucRev_Bit1[u1DQSIdx] = 1;
15919 }
15920 }
15921 else if(scDutyDelay[u1DQSIdx] >0)
15922 {
15923 u1Delay[u1DQSIdx] = scDutyDelay[u1DQSIdx];
15924
15925 if (use_rev_bit)
15926 {
15927 ucRev_Bit0[u1DQSIdx] = 1;
15928 ucRev_Bit1[u1DQSIdx] = 0;
15929 }
15930 }
15931 else
15932 {
15933 u1Delay[u1DQSIdx] = 0;
15934
15935 if (use_rev_bit)
15936 {
15937 ucRev_Bit0[u1DQSIdx] = 0;
15938 ucRev_Bit1[u1DQSIdx] = 0;
15939 }
15940 }
15941 }
15942
15943#if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ
15944 for(u1ShuffleIdx = 0; u1ShuffleIdx<DRAM_DFS_SHUFFLE_MAX; u1ShuffleIdx++)
15945#endif
15946 {
15947 for(u1DQSIdx = 0; u1DQSIdx<2; u1DQSIdx++)
15948 {
15949 save_offset = u1ShuffleIdx * SHU_GRP_DDRPHY_OFFSET + u1DQSIdx*DDRPHY_AO_B0_B1_OFFSET_0X80;
15950
15951 if (k_type == DutyScan_Calibration_K_DQM)
15952 {
15953 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ10) + save_offset, u1Delay[u1DQSIdx], B0_DQ10_RG_ARDQ_DUTYREV_B0_DQM_DUTY_DELAY);
15954
15955// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
15956// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ3) + save_offset, P_Fld(ucRev_Bit0[u1DQSIdx], SHU1_B0_DQ3_RG_TX_ARDQS0_PU_B0_BIT0)
15957// | P_Fld(ucRev_Bit1[u1DQSIdx], SHU1_B0_DQ3_RG_TX_ARDQS0_PU_B0_BIT1));
15958 }
15959
15960 if ((k_type == DutyScan_Calibration_K_DQ) || (k_type == DutyScan_Calibration_K_DQM)) //DQM is special case
15961 {
15962 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ10) + save_offset, u1Delay[u1DQSIdx], B0_DQ10_RG_ARDQ_DUTYREV_B0_DQ_DUTY_DELAY);
15963
15964// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
15965// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ3) + save_offset, P_Fld(ucRev_Bit0[u1DQSIdx], SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT0)
15966// | P_Fld(ucRev_Bit1[u1DQSIdx], SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT1));
15967 }
15968 }
15969 }
15970}
15971
15972
15973// offset is not related to DQ/DQM/DQS
15974// we have a circuit to measure duty, But this circuit is not very accurate
15975// so we need to K offset of this circuit first
15976// After we got this offset, then we can use it to measure duty
15977// this offset can measure DQ/DQS/DQM, and every byte has this circuit, too.
15978// B0/B1/CA all have one circuit.
15979// CA's circuit can measure CLK duty
15980// B0/B1's can measure DQ/DQM/DQS duty
15981S8 DutyScan_Offset_Convert(U8 val)
15982{
15983 U8 calibration_sequence[15]={0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
15984
15985 return ((S8)(calibration_sequence[val]>8 ? 0-(calibration_sequence[val]&0x7) : calibration_sequence[val]));
15986
15987}
15988void DutyScan_Offset_Calibration(DRAMC_CTX_T *p)
15989{
15990 U8 calibration_sequence[15]={0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7};
15991 U8 i, read_val_b0, read_val_b1, read_val_ca;
15992 U8 cal_i_b0=0xff, cal_i_b1=0xff, cal_i_ca=0xff;
15993
15994#if VENDER_JV_LOG
15995 vPrintCalibrationBasicInfo_ForJV(p);
15996#else
15997 vPrintCalibrationBasicInfo(p);
15998#endif
15999
16000#if DutyPrintCalibrationLog
16001 mcSHOW_DBG_MSG(("[Duty_Offset_Calibration]\n\n"));
16002#endif
16003
16004 //B0
16005 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ6), P_Fld(1, B0_DQ6_RG_RX_ARDQ_LPBK_EN_B0) | P_Fld(0, B0_DQ6_RG_RX_ARDQ_DDR4_SEL_B0) | P_Fld(1, B0_DQ6_RG_RX_ARDQ_DDR3_SEL_B0));
16006 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), P_Fld(1, RG_ARDQ_REV_BIT_20_DATA_SWAP_EN) | P_Fld(2, RG_ARDQ_REV_BIT_2221_DATA_SWAP));
16007// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ3), P_Fld(1, SHU1_B0_DQ3_DQ_REV_B0_BIT_06) | P_Fld(0, SHU1_B0_DQ3_DQ_REV_B0_BIT_05) | P_Fld(1, SHU1_B0_DQ3_DQ_REV_B0_BIT_04));
16008 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), P_Fld(0, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_BYPASS_B0) | P_Fld(0xB, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0));
16009 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), 1, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT1);
16010 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ0), 0, B0_DQ0_RG_RX_ARDQ2_OFFC_B0);
16011 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ5), P_Fld(1, B0_DQ5_RG_RX_ARDQ_VREF_EN_B0) | P_Fld(0x1, B0_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B0));
16012 mcDELAY_US(1);
16013 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), 1, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT2);
16014
16015 //B1
16016 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ6), P_Fld(1, B1_DQ6_RG_RX_ARDQ_LPBK_EN_B1) | P_Fld(0, B1_DQ6_RG_RX_ARDQ_DDR4_SEL_B1) | P_Fld(1, B1_DQ6_RG_RX_ARDQ_DDR3_SEL_B1));
16017 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), P_Fld(1, RG_ARDQ_REV_BIT_20_DATA_SWAP_EN) | P_Fld(2, RG_ARDQ_REV_BIT_2221_DATA_SWAP));
16018// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ3), P_Fld(1, SHU1_B1_DQ3_DQ_REV_B1_BIT_06) | P_Fld(0, SHU1_B1_DQ3_DQ_REV_B1_BIT_05) | P_Fld(1, SHU1_B1_DQ3_DQ_REV_B1_BIT_04));
16019 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), P_Fld(0, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_BYPASS_B1) | P_Fld(0xB, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1));
16020 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), 1, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT1);
16021 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ0), 0, B1_DQ0_RG_RX_ARDQ2_OFFC_B1);
16022 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ5), P_Fld(1, B1_DQ5_RG_RX_ARDQ_VREF_EN_B1) | P_Fld(0x1, B1_DQ5_RG_RX_ARDQ_EYE_VREF_EN_B1));
16023 mcDELAY_US(1);
16024 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), 1, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT2);
16025
16026 //CA
16027 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_CA_CMD6), P_Fld(1, CA_CMD6_RG_RX_ARCMD_LPBK_EN) | P_Fld(0, CA_CMD6_RG_RX_ARCMD_DDR4_SEL) | P_Fld(1, CA_CMD6_RG_RX_ARCMD_DDR3_SEL));
16028 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_DLL1), P_Fld(1, RG_ARCMD_REV_BIT_20_DATA_SWAP_EN) | P_Fld(2, RG_ARCMD_REV_BIT_2221_DATA_SWAP));
16029// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD3), P_Fld(1, SHU1_CA_CMD3_ARCMD_REV_BIT_06) | P_Fld(0, SHU1_CA_CMD3_ARCMD_REV_BIT_05) | P_Fld(1, SHU1_CA_CMD3_ARCMD_REV_BIT_04));
16030 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD5), P_Fld(0, SHU1_CA_CMD5_RG_RX_ARCMD_VREF_BYPASS) | P_Fld(0xB, SHU1_CA_CMD5_RG_RX_ARCMD_VREF_SEL));
16031 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), 1, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT1);
16032 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_CMD0), 0, CA_CMD0_RG_RX_ARCA2_OFFC);
16033 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_CA_CMD5), P_Fld(1, CA_CMD5_RG_RX_ARCMD_VREF_EN) | P_Fld(0x1, CA_CMD5_RG_RX_ARCMD_EYE_VREF_EN));
16034 mcDELAY_US(1);
16035 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), 1, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT2);
16036
16037 mcDELAY_US(1);
16038
16039 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), 1, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT0);
16040 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), 1, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT0);
16041 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), 1, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT0);
16042
16043#if DutyPrintCalibrationLog
16044 mcSHOW_DBG_MSG(("\tB0\tB1\tCA\n"));
16045 mcSHOW_DBG_MSG(("===========================\n"));
16046#endif
16047
16048 for(i=0; i<15; i++)
16049 {
16050 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ0), calibration_sequence[i], B0_DQ0_RG_RX_ARDQ2_OFFC_B0);
16051 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ0), calibration_sequence[i], B1_DQ0_RG_RX_ARDQ2_OFFC_B1);
16052 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_CMD0), calibration_sequence[i], CA_CMD0_RG_RX_ARCA2_OFFC);
16053
16054 mcDELAY_US(1);
16055
16056 read_val_b0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B0_BIT2);
16057 read_val_b1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B1_BIT2);
16058 read_val_ca = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_CMD_O1), MISC_AD_RX_CMD_O1_AD_RX_ARCA2_O1);
16059
16060#if DutyPrintCalibrationLog
16061 mcSHOW_DBG_MSG(("%d\t%d\t%d\t%d\n", DutyScan_Offset_Convert(i), read_val_b0, read_val_b1, read_val_ca));
16062#endif
16063
16064 if (read_val_b0 == 0 && cal_i_b0==0xff)
16065 {
16066 cal_i_b0 = i;
16067 }
16068
16069 if (read_val_b1 == 0 && cal_i_b1==0xff)
16070 {
16071 cal_i_b1 = i;
16072 }
16073
16074 if (read_val_ca == 0 && cal_i_ca==0xff)
16075 {
16076 cal_i_ca = i;
16077 }
16078 }
16079
16080 if (cal_i_b0==0 || cal_i_b1==0 || cal_i_ca==0)
16081 {
16082#if DutyPrintCalibrationLog
16083 mcSHOW_ERR_MSG(("offset calibration i=-7 and AD_RX_*RDQ_O1_B*<2>/AD_RX_*RCA2_O1 ==0 !!\n"));
16084#endif
16085#if __ETT__
16086 while(1);
16087#endif
16088 }
16089 else
16090 if ((read_val_b0==1 && cal_i_b0==0xff) || (read_val_b1==1 && cal_i_b1==0xff) || (read_val_ca==1 && cal_i_ca==0xff))
16091 {
16092#if DutyPrintCalibrationLog
16093 mcSHOW_ERR_MSG(("offset calibration i=7 and AD_RX_*RDQ_O1_B*<2>/AD_RX_*RCA2_O1 ==1 !!\n"));
16094#endif
16095#if __ETT__
16096 while(1);
16097#endif
16098
16099 }
16100 else
16101 {
16102#if DutyPrintCalibrationLog
16103 mcSHOW_DBG_MSG(("===========================\n"));
16104 mcSHOW_DBG_MSG(("\tB0:%d\tB1:%d\tCA:%d\n",DutyScan_Offset_Convert(cal_i_b0),DutyScan_Offset_Convert(cal_i_b1),DutyScan_Offset_Convert(cal_i_ca)));
16105#endif
16106 }
16107
16108 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), 0, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT0);
16109 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), 0, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT0);
16110 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), 0, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT0);
16111
16112 if (cal_i_b0!=0xff) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ0), calibration_sequence[cal_i_b0], B0_DQ0_RG_RX_ARDQ2_OFFC_B0);
16113 if (cal_i_b1!=0xff) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ0), calibration_sequence[cal_i_b1], B1_DQ0_RG_RX_ARDQ2_OFFC_B1);
16114 if (cal_i_ca!=0xff) vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_CMD0), calibration_sequence[cal_i_ca], CA_CMD0_RG_RX_ARCA2_OFFC);
16115
16116 return;
16117}
16118
16119#if defined(YH_SWEEP_IC)
16120typedef struct _YH_SWEEP_IC_T
16121{
16122 U32 maxduty;
16123 U32 minduty;
16124 U32 dutydiff;
16125 U32 avgduty;
16126} YH_SWEEP_IC_T;
16127
16128YH_SWEEP_IC_T gYH_Sweep_IC_test_result[4][CHANNEL_NUM][DQS_NUMBER];
16129
16130#define YH_SWEEP_IC_PASS_CRITERIO 1 // 0: FT 1: SLT
16131void YH_Sweep_IC_Print_Result(DRAMC_CTX_T *p)
16132{
16133 U8 u1ChannelIdx, u1ByteIdx, k_type;
16134 U8 u1ByteIdxNum;
16135
16136 // SLT:
16137 // CHB CLK duty max-min j5.3%: FAIL0
16138 // NDQS duty max-min j5.8%: FAIL1
16139 // NDQDQM maxduty j54.5% or min_duty<45.5% or max-min j5.8%: FAIL2
16140
16141 mcSHOW_ERR_MSG(("\n\n YH Sweep IC Print Result =========\n"));
16142
16143 for(k_type=0; k_type<4; k_type++)
16144 {
16145
16146 if (k_type == DutyScan_Calibration_K_CLK) u1ByteIdxNum = 1;
16147 else u1ByteIdxNum = 2;
16148
16149 for(u1ChannelIdx=0; u1ChannelIdx<CHANNEL_NUM; u1ChannelIdx++)
16150 for(u1ByteIdx=0; u1ByteIdx<u1ByteIdxNum; u1ByteIdx++)
16151 {
16152 if (k_type == DutyScan_Calibration_K_CLK && u1ChannelIdx == CHANNEL_B)
16153 {
16154 mcSHOW_ERR_MSG(("CH%d CLK max-min Duty %d%% : ",u1ChannelIdx, gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff));
16155#if YH_SWEEP_IC_PASS_CRITERIO
16156 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 530)
16157#else
16158 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 450)
16159#endif
16160 {
16161 mcSHOW_ERR_MSG(("FAIL0\n"));
16162 }
16163 else
16164 {
16165 mcSHOW_ERR_MSG(("PASS\n"));
16166 }
16167 }
16168 if (k_type == DutyScan_Calibration_K_DQS)
16169 {
16170 mcSHOW_ERR_MSG(("CH%d DQS Byte %d max-min Duty %d%% : ",u1ChannelIdx, u1ByteIdx, gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff));
16171#if YH_SWEEP_IC_PASS_CRITERIO
16172 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 580)
16173#else
16174 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 500)
16175#endif
16176 {
16177 mcSHOW_ERR_MSG(("FAIL1\n"));
16178 }
16179 else
16180 {
16181 mcSHOW_ERR_MSG(("PASS\n"));
16182 }
16183 }
16184 if (k_type == DutyScan_Calibration_K_DQ || k_type == DutyScan_Calibration_K_DQM)
16185 {
16186 mcSHOW_ERR_MSG(("CH%d %s Byte %d max Duty %d%%, min Duty %d%% : ",u1ChannelIdx, k_type == DutyScan_Calibration_K_DQ ? "DQ" : "DQM", u1ByteIdx, gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].maxduty, gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].minduty));
16187#if YH_SWEEP_IC_PASS_CRITERIO
16188 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].minduty < 4550 || gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].maxduty > 5450 || gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 580)
16189#else
16190 if (gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].minduty < 4600 || gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].maxduty > 5400 || gYH_Sweep_IC_test_result[k_type][u1ChannelIdx][u1ByteIdx].dutydiff > 500)
16191#endif
16192 {
16193 mcSHOW_ERR_MSG(("FAIL2\n"));
16194 }
16195 else
16196 {
16197 mcSHOW_ERR_MSG(("PASS\n"));
16198 }
16199 }
16200 }
16201 }
16202}
16203#endif
16204
16205S8 gcFinal_K_CLK_delay_cell[CHANNEL_NUM][DQS_NUMBER];
16206S8 gcFinal_K_DQS_delay_cell[CHANNEL_NUM][DQS_NUMBER];
16207#if APPLY_DQDQM_DUTY_CALIBRATION
16208S8 gcFinal_K_DQ_delay_cell[CHANNEL_NUM][DQS_NUMBER];
16209S8 gcFinal_K_DQM_delay_cell[CHANNEL_NUM][DQS_NUMBER];
16210#endif
16211DRAM_STATUS_T DutyScan_Calibration_Flow(DRAMC_CTX_T *p, U8 k_type, U8 use_rev_bit)
16212{
16213 S8 scinner_duty_ofst, scFinal_clk_delay_cell[DQS_NUMBER]={0,0};
16214 S8 scinner_duty_ofst_start = 0, scinner_duty_ofst_end = 0;
16215 S32 s4PICnt, s4PIBegin, s4PIEnd, s4PICnt_mod64;
16216 S8 i, swap_idx, ucdqs_i, ucdqs_i_count=2;
16217 U8 ucDelay, ucDelayB;
16218 U8 ucRev_Bit0=0, ucRev_Bit1=0;
16219 U8 ucDelayDQDQM, ucRev_Bit0_DQDQM=0, ucRev_Bit1_DQDQM=0;
16220 U32 u4DutyDiff, u4DutyDiff_Limit=900;
16221
16222 U8 vref_sel_value[2], cal_out_value;
16223 S32 duty_value[2];
16224 S32 final_duty;
16225
16226 U32 ucperiod_duty_max=0, ucperiod_duty_min=0xffffffff, ucperiod_duty_max_clk_dly=0, ucperiod_duty_min_clk_dly=0;
16227 U32 ucperiod_duty_averige=0, ucFinal_period_duty_averige[DQS_NUMBER]={0,0}, ucmost_approach_50_percent=0xffffffff;
16228 U32 ucFinal_period_duty_max[DQS_NUMBER] = {0,0}, ucFinal_period_duty_min[DQS_NUMBER] = {0,0};
16229 U32 ucFinal_duty_max_clk_dly[DQS_NUMBER]={0},ucFinal_duty_min_clk_dly[DQS_NUMBER]={0};
16230 U8 early_break_count=0;
16231 U8 str_clk_duty[]="CLK", str_dqs_duty[]="DQS", str_dq_duty[]="DQ", str_dqm_duty[]="DQM";
16232 U8 *str_who_am_I=str_clk_duty;
16233
16234 mcSHOW_ERR_MSG(("\n[DutyScan_Calibration_Flow] %s Calibration\n", use_rev_bit==0 ? "First" : "Second"));
16235 mcSHOW_ERR_MSG(("\n[DutyScan_Calibration_Flow] k_type=%d, use_rev_bit=%d\n", k_type, use_rev_bit));
16236 /*TINFO="\n[DutyScan_Calibration_Flow] k_type=%d\n", k_type */
16237
16238
16239 if (k_type == DutyScan_Calibration_K_CLK)
16240 {
16241#if 0
16242 // DQS duty test 3
16243 //mcSHOW_ERR_MSG(("\n[*PHDET_EN*=0]\n"));
16244 mcSHOW_ERR_MSG(("\n[*PI*RESETB*=0 *PHDET_EN*=0 *PI_RESETB*=1]\n"));
16245 /*TINFO="\n[*PI*RESETB*=0 *PHDET_EN*=0 *PI_RESETB*=1]\n" */
16246 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_DLL_ARPI0), 0x0, CA_DLL_ARPI0_RG_ARPI_RESETB_CA);
16247 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_DLL_ARPI2), 0x0, CA_DLL_ARPI2_RG_ARDLL_PHDET_EN_CA);
16248 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_DLL_ARPI0), 0x1, CA_DLL_ARPI0_RG_ARPI_RESETB_CA);
16249#else
16250#if DutyPrintCalibrationLog
16251 mcSHOW_ERR_MSG(("\n[ *PHDET_EN*=0 \n"));
16252#endif
16253 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_DLL_ARPI2), 0x0, CA_DLL_ARPI2_RG_ARDLL_PHDET_EN_CA);
16254#endif
16255 }
16256 else
16257 {
16258 // DQS duty test 3
16259 //mcSHOW_ERR_MSG(("\n[*PHDET_EN*=0]\n"));
16260#if DutyPrintCalibrationLog
16261 mcSHOW_ERR_MSG(("[*PI*RESETB*=0 *PHDET_EN*=0 *PI_RESETB*=1]\n"));
16262#endif
16263 /*TINFO="[*PI*RESETB*=0 *PHDET_EN*=0 *PI_RESETB*=1]\n" */
16264 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DLL_ARPI0), 0x0, B0_DLL_ARPI0_RG_ARPI_RESETB_B0);
16265 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DLL_ARPI0), 0x0, B1_DLL_ARPI0_RG_ARPI_RESETB_B1);
16266
16267 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DLL_ARPI2), 0x0, B0_DLL_ARPI2_RG_ARDLL_PHDET_EN_B0);
16268 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DLL_ARPI2), 0x0, B1_DLL_ARPI2_RG_ARDLL_PHDET_EN_B1);
16269
16270 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DLL_ARPI0), 0x1, B0_DLL_ARPI0_RG_ARPI_RESETB_B0);
16271 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DLL_ARPI0), 0x1, B1_DLL_ARPI0_RG_ARPI_RESETB_B1);
16272 }
16273
16274 //CLK Source Select (DQ/DQM/DQS/CLK)
16275 if (k_type == DutyScan_Calibration_K_DQ) // K DQ
16276 {
16277 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ8), 0, B0_DQ8_RG_TX_ARDQ_CAP_DET_B0);
16278 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), 0, RG_ARDQ_REV_BIT_06_MCK4X_SEL_DQ1);
16279
16280 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ8), 0, B1_DQ8_RG_TX_ARDQ_CAP_DET_B1);
16281 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), 0, RG_ARDQ_REV_BIT_06_MCK4X_SEL_DQ1);
16282
16283 ucdqs_i_count = 2;
16284 str_who_am_I = (U8*)str_dq_duty;
16285
16286#if APPLY_DQDQM_DUTY_CALIBRATION
16287 scinner_duty_ofst_start = -7;
16288 scinner_duty_ofst_end = 7;
16289#else
16290 scinner_duty_ofst_start = 0;
16291 scinner_duty_ofst_end = 0;
16292#endif
16293
16294#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16295 p->pSavetimeData->u1dq_use_rev_bit = use_rev_bit;
16296#endif
16297 }
16298 else if (k_type == DutyScan_Calibration_K_DQM) // K DQM
16299 {
16300 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ8), 0, B0_DQ8_RG_TX_ARDQ_CAP_DET_B0);
16301 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), 1, RG_ARDQ_REV_BIT_06_MCK4X_SEL_DQ1);
16302
16303 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ8), 0, B1_DQ8_RG_TX_ARDQ_CAP_DET_B1);
16304 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), 1, RG_ARDQ_REV_BIT_06_MCK4X_SEL_DQ1);
16305
16306 ucdqs_i_count = 2;
16307 str_who_am_I = (U8*)str_dqm_duty;
16308
16309#if APPLY_DQDQM_DUTY_CALIBRATION
16310 scinner_duty_ofst_start = -7;
16311 scinner_duty_ofst_end = 7;
16312#else
16313 scinner_duty_ofst_start = 0;
16314 scinner_duty_ofst_end = 0;
16315#endif
16316
16317#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16318 p->pSavetimeData->u1dqm_use_rev_bit = use_rev_bit;
16319#endif
16320 }
16321 else if (k_type == DutyScan_Calibration_K_DQS) // K DQS
16322 {
16323 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ8), 1, B0_DQ8_RG_TX_ARDQ_CAP_DET_B0);
16324
16325 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ8), 1, B1_DQ8_RG_TX_ARDQ_CAP_DET_B1);
16326
16327 ucdqs_i_count = 2;
16328 str_who_am_I = (U8*)str_dqs_duty;
16329
16330 scinner_duty_ofst_start = DUTY_OFFSET_START;
16331 scinner_duty_ofst_end = DUTY_OFFSET_END;
16332
16333#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16334 p->pSavetimeData->u1dqs_use_rev_bit = use_rev_bit;
16335#endif
16336 }
16337 else if (k_type == DutyScan_Calibration_K_CLK) // K CLK
16338 {
16339 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_CA_CMD9), 1, CA_CMD9_RG_TX_ARCMD_CAP_DET);
16340
16341 ucdqs_i_count = 1;
16342 str_who_am_I = (U8*)str_clk_duty;
16343
16344 scinner_duty_ofst_start = DUTY_OFFSET_START;
16345 scinner_duty_ofst_end = DUTY_OFFSET_END;
16346
16347#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16348 p->pSavetimeData->u1clk_use_rev_bit = use_rev_bit;
16349#endif
16350 }
16351
16352#if defined(YH_SWEEP_IC) || FT_DSIM_USED
16353 scinner_duty_ofst_start=0;
16354 scinner_duty_ofst_end=0;
16355#endif
16356
16357#if (fcFOR_CHIP_ID == fcLaurel)
16358 if (k_type == DutyScan_Calibration_K_CLK)
16359 {
16360 u4DutyDiff_Limit = 530;
16361 }
16362 else
16363 {
16364 u4DutyDiff_Limit = 580;
16365 }
16366#endif
16367
16368#if (fcFOR_CHIP_ID == fcLaurel)
16369#if !defined(YH_SWEEP_IC)
16370 if (k_type == DutyScan_Calibration_K_CLK && p->channel == CHANNEL_A)
16371 {
16372 s4PIBegin = 0;
16373 s4PIEnd = 0;
16374 }
16375 else
16376#endif
16377#endif
16378 {
16379 s4PIBegin = CLOCK_PI_START;
16380 s4PIEnd = CLOCK_PI_END;
16381 }
16382
16383 for(ucdqs_i=0; ucdqs_i<ucdqs_i_count; ucdqs_i++)
16384 {
16385#if DutyPrintCalibrationLog
16386 if (k_type == DutyScan_Calibration_K_CLK)
16387 {
16388 mcSHOW_ERR_MSG(("\n[CLK Duty scan]\n"));
16389 /*TINFO="\n[CLK Duty scan]\n"*/
16390 }
16391 else
16392 {
16393 mcSHOW_ERR_MSG(("\n[%s B%d Duty scan]\n", str_who_am_I, ucdqs_i));
16394 /*TINFO="\n[%s B%d Duty scan]\n", str_who_am_I, ucdqs_i */
16395 }
16396#endif
16397
16398 ucmost_approach_50_percent=0xffffffff;
16399 early_break_count=0;
16400
16401 for(scinner_duty_ofst=scinner_duty_ofst_start; scinner_duty_ofst<=scinner_duty_ofst_end; scinner_duty_ofst++)
16402 {
16403 ucperiod_duty_max = 0;
16404 ucperiod_duty_min = 100000;
16405
16406 if (scinner_duty_ofst<0)
16407 {
16408 ucDelay = -scinner_duty_ofst;
16409 ucDelayB = 0;
16410
16411 if (use_rev_bit)
16412 {
16413 ucRev_Bit0 = 1;
16414 ucRev_Bit1 = 0;
16415 }
16416
16417 ucDelayDQDQM = (-scinner_duty_ofst) | (1<<3); //sign bit
16418 ucRev_Bit0_DQDQM = 0;
16419 ucRev_Bit1_DQDQM = 1;
16420 }
16421 else if (scinner_duty_ofst>0)
16422 {
16423 ucDelay = 0;
16424 ucDelayB= scinner_duty_ofst;
16425
16426 if (use_rev_bit)
16427 {
16428 ucRev_Bit0 = 0;
16429 ucRev_Bit1 = 1;
16430 }
16431
16432 ucDelayDQDQM = scinner_duty_ofst;
16433 ucRev_Bit0_DQDQM = 1;
16434 ucRev_Bit1_DQDQM = 0;
16435 }
16436 else
16437 {
16438 ucDelay = 0;
16439 ucDelayB= 0;
16440
16441 if (use_rev_bit)
16442 {
16443 ucRev_Bit0 = 0;
16444 ucRev_Bit1 = 0;
16445 }
16446
16447 ucDelayDQDQM = 0;
16448 ucRev_Bit0_DQDQM = 0;
16449 ucRev_Bit1_DQDQM = 0;
16450 }
16451
16452 if (k_type == DutyScan_Calibration_K_DQS)
16453 {
16454 if (ucdqs_i==0)
16455 {
16456 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ1), P_Fld(ucDelay, SHU1_R0_B0_DQ1_RK0_TX_ARDQS0_DLY_B0)
16457 | P_Fld(ucDelay, SHU1_R0_B0_DQ1_RK0_TX_ARDQS0B_DLY_B0)
16458 | P_Fld(ucDelayB, SHU1_R0_B0_DQ1_RK0_TX_ARDQS0_DLYB_B0)
16459 | P_Fld(ucDelayB, SHU1_R0_B0_DQ1_RK0_TX_ARDQS0B_DLYB_B0));
16460
16461// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
16462 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), P_Fld(ucRev_Bit0, RG_ARDQ_REV_BIT_00_DQS_MCK4X_DLY_EN)
16463 | P_Fld(ucRev_Bit1, RG_ARDQ_REV_BIT_01_DQS_MCK4XB_DLY_EN));
16464
16465 }
16466 else
16467 {
16468 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ1), P_Fld(ucDelay, SHU1_R0_B1_DQ1_RK0_TX_ARDQS0_DLY_B1)
16469 | P_Fld(ucDelay, SHU1_R0_B1_DQ1_RK0_TX_ARDQS0B_DLY_B1)
16470 | P_Fld(ucDelayB, SHU1_R0_B1_DQ1_RK0_TX_ARDQS0_DLYB_B1)
16471 | P_Fld(ucDelayB, SHU1_R0_B1_DQ1_RK0_TX_ARDQS0B_DLYB_B1));
16472
16473// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
16474 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), P_Fld(ucRev_Bit0, RG_ARDQ_REV_BIT_00_DQS_MCK4X_DLY_EN)
16475 | P_Fld(ucRev_Bit1, RG_ARDQ_REV_BIT_01_DQS_MCK4XB_DLY_EN));
16476 }
16477
16478 }
16479
16480 if (k_type == DutyScan_Calibration_K_CLK)
16481 {
16482 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD1), P_Fld(ucDelay, SHU1_R0_CA_CMD1_RK0_TX_ARCLK_DLY)
16483 | P_Fld(ucDelay, SHU1_R0_CA_CMD1_RK0_TX_ARCLKB_DLY));
16484 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD0), P_Fld(ucDelayB, SHU1_R0_CA_CMD0_RK0_TX_ARCLK_DLYB)
16485 | P_Fld(ucDelayB, SHU1_R0_CA_CMD0_RK0_TX_ARCLKB_DLYB));
16486
16487// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
16488 vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD3), P_Fld(ucRev_Bit0, SHU1_CA_CMD3_RG_TX_ARCMD_PU_BIT0)
16489 | P_Fld(ucRev_Bit1, SHU1_CA_CMD3_RG_TX_ARCMD_PU_BIT1));
16490 }
16491
16492#if APPLY_DQDQM_DUTY_CALIBRATION
16493 if (k_type == DutyScan_Calibration_K_DQ || k_type == DutyScan_Calibration_K_DQM)
16494 {
16495 if (ucdqs_i==0)
16496 {
16497 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B0_DQ10), ucDelayDQDQM, B0_DQ10_RG_ARDQ_DUTYREV_B0_DQ_DUTY_DELAY);
16498
16499// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
16500// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B0_DQ3), P_Fld(ucRev_Bit0_DQDQM, SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT0)
16501// | P_Fld(ucRev_Bit1_DQDQM, SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT1));
16502 }
16503 else
16504 {
16505 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_B1_DQ10), ucDelayDQDQM, B0_DQ10_RG_ARDQ_DUTYREV_B0_DQ_DUTY_DELAY);
16506
16507// Lau_rel like Mer_lot, no need to set this to big scale mode, just use small scale mode
16508// vIO32WriteFldMulti(DRAMC_REG_ADDR(DDRPHY_B1_DQ3), P_Fld(ucRev_Bit0_DQDQM, SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT0)
16509// | P_Fld(ucRev_Bit1_DQDQM, SHU1_B0_DQ3_RG_TX_ARDQS0_PU_PRE_B0_BIT1));
16510 }
16511 }
16512#endif
16513
16514 for(s4PICnt=s4PIBegin; s4PICnt<=s4PIEnd; s4PICnt+=CLOCK_PI_STEP)
16515 {
16516 s4PICnt_mod64 = (s4PICnt+64)&0x3f;//s4PICnt_mod64 = (s4PICnt+64)%64;
16517#if DutyPrintAllLog
16518 //if(scinner_duty_ofst!=DUTY_OFFSET_START)
16519 mcSHOW_ERR_MSG(("PI= %d\n", s4PICnt_mod64));
16520#endif
16521
16522 if (k_type == DutyScan_Calibration_K_DQS)
16523 {
16524 if (ucdqs_i==0)
16525 {
16526 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), s4PICnt_mod64, SHU1_R0_B0_DQ7_RK0_ARPI_PBYTE_B0);
16527 }
16528 else
16529 {
16530 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), s4PICnt_mod64, SHU1_R0_B1_DQ7_RK0_ARPI_PBYTE_B1);
16531 }
16532 }
16533 else
16534 if (k_type == DutyScan_Calibration_K_CLK)
16535 {
16536 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_CA_CMD9), s4PICnt_mod64, SHU1_R0_CA_CMD9_RG_RK0_ARPI_CLK);
16537 }
16538 else
16539 if (k_type == DutyScan_Calibration_K_DQ)
16540 {
16541 if (ucdqs_i==0)
16542 {
16543 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), s4PICnt_mod64, SHU1_R0_B0_DQ7_RK0_ARPI_DQ_B0);
16544 }
16545 else
16546 {
16547 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), s4PICnt_mod64, SHU1_R0_B1_DQ7_RK0_ARPI_DQ_B1);
16548 }
16549 }
16550 else
16551 if (k_type == DutyScan_Calibration_K_DQM)
16552 {
16553 if (ucdqs_i==0)
16554 {
16555 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B0_DQ7), s4PICnt_mod64, SHU1_R0_B0_DQ7_RK0_ARPI_DQM_B0);
16556 }
16557 else
16558 {
16559 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_R0_B1_DQ7), s4PICnt_mod64, SHU1_R0_B1_DQ7_RK0_ARPI_DQM_B1);
16560 }
16561 }
16562
16563 for(swap_idx=0; swap_idx<2; swap_idx++)
16564 {
16565 if (k_type == DutyScan_Calibration_K_CLK)
16566 {
16567 if (swap_idx==0)
16568 {
16569 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_DLL1), 2, RG_ARCMD_REV_BIT_2221_DATA_SWAP);
16570 }
16571 else
16572 {
16573 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_DLL1), 3, RG_ARCMD_REV_BIT_2221_DATA_SWAP);
16574 }
16575
16576 vref_sel_value[swap_idx]= 0;
16577 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD5), vref_sel_value[swap_idx]>>1, SHU1_CA_CMD5_RG_RX_ARCMD_VREF_SEL);
16578 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT1);
16579 }
16580 else
16581 {
16582 if (ucdqs_i==0)
16583 {
16584 if (swap_idx==0)
16585 {
16586 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), 2, RG_ARDQ_REV_BIT_2221_DATA_SWAP);
16587 }
16588 else
16589 {
16590 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DLL1), 3, RG_ARDQ_REV_BIT_2221_DATA_SWAP);
16591 }
16592
16593 vref_sel_value[swap_idx]= 0;
16594 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), vref_sel_value[swap_idx]>>1, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0);
16595 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT1);
16596 }
16597 else
16598 {
16599 if (swap_idx==0)
16600 {
16601 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), 2, RG_ARDQ_REV_BIT_2221_DATA_SWAP);
16602 }
16603 else
16604 {
16605 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DLL1), 3, RG_ARDQ_REV_BIT_2221_DATA_SWAP);
16606 }
16607
16608 vref_sel_value[swap_idx]= 0;
16609 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), vref_sel_value[swap_idx]>>1, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1);
16610 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT1);
16611 }
16612 }
16613
16614 for(i=5; i>=0; i--)
16615 {
16616 if (k_type == DutyScan_Calibration_K_CLK)
16617 {
16618 vref_sel_value[swap_idx] |= (1<<i);
16619 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD5), vref_sel_value[swap_idx]>>1, SHU1_CA_CMD5_RG_RX_ARCMD_VREF_SEL);
16620 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_CA_CMD0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_CA_CMD0_RG_TX_ARCLK_DRVP_PRE_BIT1);
16621
16622 mcDELAY_US(1);
16623
16624 cal_out_value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_CMD_O1), MISC_AD_RX_CMD_O1_AD_RX_ARCA2_O1);
16625
16626 if (cal_out_value == 0)
16627 {
16628 vref_sel_value[swap_idx] &= ~(1<<i);
16629 }
16630 }
16631 else
16632 {
16633 if (ucdqs_i==0)
16634 {
16635 vref_sel_value[swap_idx] |= (1<<i);
16636 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ5), vref_sel_value[swap_idx]>>1, SHU1_B0_DQ5_RG_RX_ARDQ_VREF_SEL_B0);
16637 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B0_DQ0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_B0_DQ0_RG_TX_ARDQS0_DRVP_PRE_B0_BIT1);
16638
16639 mcDELAY_US(1);
16640
16641 cal_out_value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B0_BIT2);
16642 }
16643 else
16644 {
16645 vref_sel_value[swap_idx] |= (1<<i);
16646 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ5), vref_sel_value[swap_idx]>>1, SHU1_B1_DQ5_RG_RX_ARDQ_VREF_SEL_B1);
16647 vIO32WriteFldAlign(DRAMC_REG_ADDR(DDRPHY_SHU1_B1_DQ0), (vref_sel_value[swap_idx]&1)==1?0:1, SHU1_B1_DQ0_RG_TX_ARDQS0_DRVP_PRE_B1_BIT1);
16648
16649 mcDELAY_US(1);
16650
16651 cal_out_value = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DDRPHY_MISC_AD_RX_DQ_O1), MISC_AD_RX_DQ_O1_AD_RX_ARDQ_O1_B1_BIT2);
16652 }
16653
16654#if DutyPrintAllLog
16655 //mcSHOW_DBG_MSG(("Fra i=%d vref_sel_value[swap_idx]=%x, cal_out=%d\n",i, vref_sel_value[swap_idx], cal_out_value));
16656#endif
16657
16658 if (cal_out_value == 0)
16659 {
16660 vref_sel_value[swap_idx] &= ~(1<<i);
16661 }
16662 }
16663 }
16664 }
16665
16666
16667 for(swap_idx=0; swap_idx<2; swap_idx++)
16668 {
16669 if (vref_sel_value[swap_idx]<=31)
16670 {
16671 duty_value[swap_idx] = (vref_sel_value[swap_idx]-23)*69+5050;
16672 }
16673 else
16674 {
16675 duty_value[swap_idx] = (vref_sel_value[swap_idx]-32)*55+5600;
16676 }
16677 }
16678
16679#if DutyPrintAllLog
16680 mcSHOW_ERR_MSG(("\t[%d][%d] B%d : Vref_Sel=0x%x, Swap Vref_Sel=0x%x\n", scinner_duty_ofst, s4PICnt, ucdqs_i, vref_sel_value[0], vref_sel_value[1]));
16681 mcSHOW_ERR_MSG(("\t[%d][%d] B%d : duty_value=%d, Swap duty_value=%d\n", scinner_duty_ofst, s4PICnt, ucdqs_i, duty_value[0], duty_value[1]));
16682#endif
16683
16684 final_duty = 5000+((duty_value[0]-duty_value[1])/2);
16685
16686 if (final_duty > (S32) ucperiod_duty_max)
16687 {
16688 ucperiod_duty_max = final_duty;
16689 ucperiod_duty_max_clk_dly = s4PICnt;
16690 }
16691 if (final_duty < (S32) ucperiod_duty_min)
16692 {
16693 ucperiod_duty_min = final_duty;
16694 ucperiod_duty_min_clk_dly = s4PICnt;
16695 }
16696
16697#if DutyPrintAllLog
16698 mcSHOW_ERR_MSG(("\t[%d][%d] B%d : Final_Duty=%d\n", scinner_duty_ofst, s4PICnt, ucdqs_i, final_duty));
16699#endif
16700 }
16701
16702
16703
16704 ucperiod_duty_averige = (ucperiod_duty_max + ucperiod_duty_min)>>1;
16705
16706#if DutyPrintCalibrationLog
16707 if (k_type==DutyScan_Calibration_K_CLK)
16708 {
16709 mcSHOW_ERR_MSG(("[%d] CLK\n",scinner_duty_ofst));
16710 /*TINFO="[%d] CLK\n",scinner_duty_ofst */
16711 }
16712 else
16713 {
16714 mcSHOW_ERR_MSG(("[%d] %s%d\n",scinner_duty_ofst, str_who_am_I, ucdqs_i));
16715 /*TINFO="[%d] %s%d\n",scinner_duty_ofst, str_who_am_I, ucdqs_i */
16716 }
16717#endif
16718
16719#if DutyPrintCalibrationLog
16720 mcSHOW_ERR_MSG(("\tMAX Duty = %d%%(X100), CLK PI=%d\n",ucperiod_duty_max, ucperiod_duty_max_clk_dly));
16721 /*TINFO="\tMAX Duty = %d%%(X100), CLK PI=%d\n",ucperiod_duty_max, ucperiod_duty_max_clk_dly */
16722 mcSHOW_ERR_MSG(("\tMIN Duty = %d%%(X100), CLK PI=%d\n",ucperiod_duty_min, ucperiod_duty_min_clk_dly));
16723 /*TINFO="\tMIN Duty = %d%%(X100), CLK PI=%d\n",ucperiod_duty_min, ucperiod_duty_min_clk_dly */
16724 mcSHOW_ERR_MSG(("\tAVG Duty = %d%%(X100)\n", ucperiod_duty_averige));
16725 /*TINFO="\tAVG Duty = %d%%(X100)\n", ucperiod_duty_averige */
16726#endif
16727
16728 if (ucperiod_duty_averige >= ClockDutyMiddleBound)
16729 {
16730 if ((scinner_duty_ofst<=0 && ((ucperiod_duty_averige-ClockDutyMiddleBound+(ucperiod_duty_max-ucperiod_duty_min)/2) <= ucmost_approach_50_percent)) ||
16731 (scinner_duty_ofst>0 && ((ucperiod_duty_averige-ClockDutyMiddleBound+(ucperiod_duty_max-ucperiod_duty_min)/2) < ucmost_approach_50_percent)))
16732 {
16733 ucmost_approach_50_percent = ucperiod_duty_averige-ClockDutyMiddleBound+(ucperiod_duty_max-ucperiod_duty_min)/2;
16734 scFinal_clk_delay_cell[ucdqs_i] = scinner_duty_ofst;
16735 ucFinal_period_duty_averige[ucdqs_i] = ucperiod_duty_averige;
16736 ucFinal_period_duty_max[ucdqs_i] = ucperiod_duty_max;
16737 ucFinal_period_duty_min[ucdqs_i] = ucperiod_duty_min;
16738 ucFinal_duty_max_clk_dly[ucdqs_i] = ucperiod_duty_max_clk_dly;
16739 ucFinal_duty_min_clk_dly[ucdqs_i] = ucperiod_duty_min_clk_dly;
16740#if DutyPrintCalibrationLog
16741 mcSHOW_ERR_MSG(("\t!!! ucmost_approach_50_percent = %d%%(X100) !!!\n",ucmost_approach_50_percent));
16742 /*TINFO="!!! ucmost_approach_50_percent = %d%%(X100) !!!\n",ucmost_approach_50_percent */
16743#endif
16744 early_break_count = 0;
16745 }
16746 else
16747 {
16748 if (scinner_duty_ofst>0) early_break_count ++;
16749#if DutyPrintAllLog==0
16750 if (early_break_count>=2) break; //early break;
16751#endif
16752 }
16753 }
16754 else
16755 {
16756 if ((scinner_duty_ofst<=0 && ((ClockDutyMiddleBound-ucperiod_duty_averige+(ucperiod_duty_max-ucperiod_duty_min)/2) <= ucmost_approach_50_percent)) ||
16757 (scinner_duty_ofst>0 && ((ClockDutyMiddleBound-ucperiod_duty_averige+(ucperiod_duty_max-ucperiod_duty_min)/2) < ucmost_approach_50_percent)))
16758 {
16759 ucmost_approach_50_percent = ClockDutyMiddleBound-ucperiod_duty_averige+(ucperiod_duty_max-ucperiod_duty_min)/2;
16760 scFinal_clk_delay_cell[ucdqs_i] = scinner_duty_ofst;
16761 ucFinal_period_duty_averige[ucdqs_i] = ucperiod_duty_averige;
16762 ucFinal_period_duty_max[ucdqs_i] = ucperiod_duty_max;
16763 ucFinal_period_duty_min[ucdqs_i] = ucperiod_duty_min;
16764 ucFinal_duty_max_clk_dly[ucdqs_i] = ucperiod_duty_max_clk_dly;
16765 ucFinal_duty_min_clk_dly[ucdqs_i] = ucperiod_duty_min_clk_dly;
16766#if DutyPrintCalibrationLog
16767 mcSHOW_ERR_MSG(("\t!!! ucmost_approach_50_percent = %d%%(X100) !!!\n",ucmost_approach_50_percent));
16768 /*TINFO="!!! ucmost_approach_50_percent = %d%%(X100) !!!\n",ucmost_approach_50_percent */
16769#endif
16770 early_break_count = 0;
16771 }
16772 else
16773 {
16774 if (scinner_duty_ofst>0) early_break_count ++;
16775#if DutyPrintAllLog==0
16776 if (early_break_count>=2) break; //early break;
16777#endif
16778 }
16779 }
16780
16781#if DutyPrintCalibrationLog
16782 mcSHOW_ERR_MSG(("\n"));
16783 /*TINFO="\n" */
16784#endif
16785 }
16786 }
16787
16788 for(ucdqs_i=0; ucdqs_i<ucdqs_i_count; ucdqs_i++)
16789 {
16790 //for SLT, use ERR_MSG to force print log
16791 if (k_type == DutyScan_Calibration_K_CLK)
16792 {
16793 mcSHOW_ERR_MSG(("\n==%s ==\n", str_who_am_I, ucdqs_i));
16794 /*TINFO="\n==%s ==\n", str_who_am_I */
16795 }
16796 else
16797 {
16798 mcSHOW_ERR_MSG(("\n==%s %d ==\n", str_who_am_I, ucdqs_i));
16799 /*TINFO="\n==%s %d ==\n", str_who_am_I, ucdqs_i */
16800 }
16801 mcSHOW_ERR_MSG(("Final %s duty delay cell = %d\n", str_who_am_I, scFinal_clk_delay_cell[ucdqs_i]));
16802 /*TINFO="Final %s duty delay cell = %d\n", str_who_am_I, scFinal_clk_delay_cell[ucdqs_i] */
16803 mcSHOW_ERR_MSG(("[%d] MAX Duty = %d%%(X100), DQS PI = %d\n",scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_max[ucdqs_i], ucFinal_duty_max_clk_dly[ucdqs_i]));
16804 /*TINFO="[%d] MAX Duty = %d%%(X100), DQS PI = %d\n",scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_max[ucdqs_i], ucFinal_duty_max_clk_dly[ucdqs_i] */
16805 mcSHOW_ERR_MSG(("[%d] MIN Duty = %d%%(X100), DQS PI = %d\n",scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_min[ucdqs_i], ucFinal_duty_min_clk_dly[ucdqs_i]));
16806 /*TINFO="[%d] MIN Duty = %d%%(X100), DQS PI = %d\n",scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_min[ucdqs_i], ucFinal_duty_min_clk_dly[ucdqs_i] */
16807 mcSHOW_ERR_MSG(("[%d] AVG Duty = %d%%(X100)\n", scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_averige[ucdqs_i]));
16808 /*TINFO="[%d] AVG Duty = %d%%(X100)\n", scFinal_clk_delay_cell[ucdqs_i], ucFinal_period_duty_averige[ucdqs_i] */
16809 }
16810
16811#if FT_DSIM_USED
16812 FT_Duty_Compare_PassFail(p->channel, k_type, ucFinal_period_duty_max[0] , ucFinal_period_duty_min[0],ucFinal_period_duty_max[1] , ucFinal_period_duty_min[1]);
16813#else
16814 for(ucdqs_i=0; ucdqs_i<ucdqs_i_count; ucdqs_i++)
16815 {
16816 u4DutyDiff = ucFinal_period_duty_max[ucdqs_i] - ucFinal_period_duty_min[ucdqs_i];
16817
16818#if DQS_DUTY_SLT_CONDITION_TEST
16819 if (k_type == DutyScan_Calibration_K_CLK || (k_type == DutyScan_Calibration_K_DQS))
16820 {
16821 u4DQSDutyDiff_Rec[p->channel][ucdqs_i][u1GlobalTestCnt]=u4DutyDiff;
16822
16823 u4DQSDutyDutyDly[p->channel][ucdqs_i] = scFinal_clk_delay_cell[ucdqs_i];
16824
16825 if(u4DutyDiff > u4DQSDutyDiff_Max[p->channel][ucdqs_i])
16826 u4DQSDutyDiff_Max[p->channel][ucdqs_i] = u4DutyDiff;
16827
16828 if(u4DutyDiff < u4DQSDutyDiff_Min[p->channel][ucdqs_i])
16829 u4DQSDutyDiff_Min[p->channel][ucdqs_i] = u4DutyDiff;
16830
16831 u4DQSDutyDiff_Avrg[p->channel][ucdqs_i] += u4DutyDiff;
16832 }
16833#endif
16834
16835#if defined(YH_SWEEP_IC)
16836 gYH_Sweep_IC_test_result[k_type][p->channel][ucdqs_i].maxduty = ucFinal_period_duty_max[ucdqs_i];
16837 gYH_Sweep_IC_test_result[k_type][p->channel][ucdqs_i].minduty = ucFinal_period_duty_min[ucdqs_i];
16838 gYH_Sweep_IC_test_result[k_type][p->channel][ucdqs_i].dutydiff = u4DutyDiff;
16839 gYH_Sweep_IC_test_result[k_type][p->channel][ucdqs_i].avgduty = ucFinal_period_duty_averige[ucdqs_i];
16840#else
16841 if ((((k_type == DutyScan_Calibration_K_CLK) || (k_type == DutyScan_Calibration_K_DQS)) && (u4DutyDiff < u4DutyDiff_Limit)) ||
16842#if APPLY_DQDQM_DUTY_CALIBRATION
16843 (((k_type == DutyScan_Calibration_K_DQ) || (k_type == DutyScan_Calibration_K_DQM)) && (u4DutyDiff < u4DutyDiff_Limit)))
16844#else
16845 (((k_type == DutyScan_Calibration_K_DQ) || (k_type == DutyScan_Calibration_K_DQM)) && ((u4DutyDiff < u4DutyDiff_Limit) && (ucFinal_period_duty_averige[ucdqs_i] >= 4550 && ucFinal_period_duty_averige[ucdqs_i] <= 5450))))
16846#endif
16847 {
16848 if (k_type == DutyScan_Calibration_K_CLK)
16849 {
16850 mcSHOW_ERR_MSG(("\nCH%d %s Duty spec in!! Max-Min= %d%%\n",p->channel, str_who_am_I, u4DutyDiff));
16851 /*TINFO="\nCH%d %s Duty spec in!! Max-Min= %d%%\n",p->channel, str_who_am_I, u4DutyDiff */
16852 }
16853 else
16854 {
16855 mcSHOW_ERR_MSG(("\nCH%d %s %d Duty spec in!! Max-Min= %d%%\n",p->channel, str_who_am_I, ucdqs_i, u4DutyDiff));
16856 /*TINFO="\nCH%d %s %d Duty spec in!! Max-Min= %d%%\n",p->channel, str_who_am_I, ucdqs_i, u4DutyDiff */
16857 }
16858 }
16859 else
16860 {
16861 if (k_type == DutyScan_Calibration_K_CLK)
16862 {
16863 mcSHOW_ERR_MSG(("\n\t\t\t\t\t\tCH%d %s Duty spec \033[1;32mout\033[m!! Max-Min= \033[1;32m%d%% >%d%%\033[m\n", p->channel, str_who_am_I, u4DutyDiff, u4DutyDiff_Limit));
16864 /*TINFO="\nCH%d %s Duty spec out!! Max-Min= %d%% >8%%\n", p->channel, str_who_am_I, u4DutyDiff */
16865 }
16866 else
16867 {
16868 mcSHOW_ERR_MSG(("\n\t\t\t\t\t\tCH%d %s %d Duty spec \033[1;32mout\033[m!! Max-Min= \033[1;32m%d%% >%d%%\033[m\n", p->channel, str_who_am_I, ucdqs_i, u4DutyDiff, u4DutyDiff_Limit));
16869 /*TINFO="\nCH%d %s %d Duty spec out!! Max-Min= %d%% >8%%\n", p->channel, str_who_am_I, ucdqs_i, u4DutyDiff */
16870 }
16871
16872 #if defined(SLT)
16873 while(1); //stop here
16874 #endif
16875
16876 #if __ETT__
16877
16878 #if DQS_DUTY_SLT_CONDITION_TEST
16879 retStatus = DRAM_FAIL;
16880 #else
16881 while(1); //stop here
16882 #endif
16883
16884 #endif
16885 }
16886#endif
16887 }
16888
16889#endif
16890
16891 if (k_type == DutyScan_Calibration_K_DQS)
16892 {
16893#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16894 if(p->femmc_Ready==0)
16895 {
16896 p->pSavetimeData->s1DQSDuty_clk_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16897 p->pSavetimeData->s1DQSDuty_clk_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16898 }
16899#endif
16900
16901 // backup final values
16902 gcFinal_K_DQS_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16903 gcFinal_K_DQS_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16904
16905 DQSDutyScan_SetDqsDelayCell(p, scFinal_clk_delay_cell, use_rev_bit);
16906
16907#ifdef FOR_HQA_TEST_USED
16908 gFinalDQSDuty[p->channel][0] = scFinal_clk_delay_cell[0];
16909 gFinalDQSDuty[p->channel][1] = scFinal_clk_delay_cell[1];
16910 gFinalDQSDutyMinMax[p->channel][0][0] = ucFinal_period_duty_min[0];
16911 gFinalDQSDutyMinMax[p->channel][0][1] = ucFinal_period_duty_max[0];
16912 gFinalDQSDutyMinMax[p->channel][1][0] = ucFinal_period_duty_min[1];
16913 gFinalDQSDutyMinMax[p->channel][1][1] = ucFinal_period_duty_max[1];
16914#endif
16915 }
16916
16917 if (k_type == DutyScan_Calibration_K_CLK)
16918 {
16919 DramcClockDutySetClkDelayCell(p, RANK_0, scFinal_clk_delay_cell[0], use_rev_bit);
16920 DramcClockDutySetClkDelayCell(p, RANK_1, scFinal_clk_delay_cell[0], use_rev_bit);
16921
16922#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16923 if(p->femmc_Ready==0)
16924 {
16925 p->pSavetimeData->s1ClockDuty_clk_delay_cell[p->channel][RANK_0] = scFinal_clk_delay_cell[0];
16926 p->pSavetimeData->s1ClockDuty_clk_delay_cell[p->channel][RANK_1] = scFinal_clk_delay_cell[0];
16927 }
16928#endif
16929
16930 // backup final values
16931 gcFinal_K_CLK_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16932 gcFinal_K_CLK_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16933
16934#ifdef FOR_HQA_TEST_USED
16935 gFinalClkDuty[p->channel] = scFinal_clk_delay_cell[0];
16936 gFinalClkDutyMinMax[p->channel][0] = ucFinal_period_duty_min[0];
16937 gFinalClkDutyMinMax[p->channel][1] = ucFinal_period_duty_max[0];
16938#endif
16939 }
16940
16941#if APPLY_DQDQM_DUTY_CALIBRATION
16942 if (k_type == DutyScan_Calibration_K_DQ)
16943 {
16944#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16945 if(p->femmc_Ready==0)
16946 {
16947 p->pSavetimeData->s1DQDuty_clk_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16948 p->pSavetimeData->s1DQDuty_clk_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16949 }
16950#endif
16951
16952 // backup final values
16953 gcFinal_K_DQ_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16954 gcFinal_K_DQ_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16955
16956 DQDQMDutyScan_SetDQDQMDelayCell(p, scFinal_clk_delay_cell, use_rev_bit, DutyScan_Calibration_K_DQ);
16957 }
16958
16959 if (k_type == DutyScan_Calibration_K_DQM)
16960 {
16961#if SUPPORT_SAVE_TIME_FOR_CALIBRATION
16962 if(p->femmc_Ready==0)
16963 {
16964 p->pSavetimeData->s1DQMDuty_clk_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16965 p->pSavetimeData->s1DQMDuty_clk_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16966 }
16967#endif
16968
16969 // backup final values
16970 gcFinal_K_DQM_delay_cell[p->channel][0] = scFinal_clk_delay_cell[0];
16971 gcFinal_K_DQM_delay_cell[p->channel][1] = scFinal_clk_delay_cell[1];
16972
16973 DQDQMDutyScan_SetDQDQMDelayCell(p, scFinal_clk_delay_cell, use_rev_bit, DutyScan_Calibration_K_DQM);
16974 }
16975#endif
16976
16977 DramPhyReset(p);
16978
16979 mcSHOW_ERR_MSG(("[DutyScan_Calibration_Flow] ====Done====\n"));
16980 /*TINFO="[DutyScan_Calibration_Flow] ====Done====\n" */
16981
16982 return DRAM_OK;
16983}
16984
16985void DramcNewDutyCalibration(DRAMC_CTX_T *p)
16986{
16987 U8 u1backup_channel;
16988
16989#if(DQS_DUTY_SLT_CONDITION_TEST)
16990 U16 u2TestCnt, u2FailCnt=0, u2TestCntTotal =20; //fra 400;
16991 U8 u1ByteIdx, u1PI_FB;
16992 U32 u4Variance;
16993#endif
16994 U8 use_rev_bit=0;
16995
16996 DRAM_STATUS_T u2FailStatusByCh[CHANNEL_NUM]={DRAM_OK,DRAM_OK};
16997
16998 //backup register value
16999#if FT_DSIM_USED==0
17000 U32 u4RegBackupAddress[] =
17001 {
17002 (DDRPHY_B0_DQ6),
17003 (DDRPHY_SHU1_B0_DLL1),
17004 (DDRPHY_SHU1_B0_DQ5),
17005 (DDRPHY_SHU1_B0_DQ0),
17006 (DDRPHY_B0_DQ0),
17007 (DDRPHY_B0_DQ5),
17008 (DDRPHY_B0_DQ8),
17009 (DDRPHY_SHU1_R0_B0_DQ7),
17010 (DDRPHY_B0_DLL_ARPI0),
17011 (DDRPHY_B0_DLL_ARPI2),
17012
17013 (DDRPHY_B1_DQ6),
17014 (DDRPHY_SHU1_B1_DLL1),
17015 (DDRPHY_SHU1_B1_DQ5),
17016 (DDRPHY_SHU1_B1_DQ0),
17017 (DDRPHY_B1_DQ0),
17018 (DDRPHY_B1_DQ5),
17019 (DDRPHY_B1_DQ8),
17020 (DDRPHY_SHU1_R0_B1_DQ7),
17021 (DDRPHY_B1_DLL_ARPI0),
17022 (DDRPHY_B1_DLL_ARPI2),
17023
17024
17025 (DDRPHY_CA_CMD6),
17026 (DDRPHY_SHU1_CA_DLL1),
17027 (DDRPHY_SHU1_CA_CMD5),
17028 (DDRPHY_SHU1_CA_CMD0),
17029 (DDRPHY_CA_CMD0),
17030 (DDRPHY_CA_CMD5),
17031 (DDRPHY_CA_CMD9),
17032// (DDRPHY_SHU1_CA_CMD3),
17033 (DDRPHY_SHU1_R0_CA_CMD9),
17034 (DDRPHY_CA_DLL_ARPI0),
17035 (DDRPHY_CA_DLL_ARPI2),
17036
17037
17038
17039 (DDRPHY_B0_DQ6 + SHIFT_TO_CHB_ADDR),
17040 (DDRPHY_SHU1_B0_DLL1 + SHIFT_TO_CHB_ADDR),
17041 (DDRPHY_SHU1_B0_DQ5 + SHIFT_TO_CHB_ADDR),
17042 (DDRPHY_SHU1_B0_DQ0 + SHIFT_TO_CHB_ADDR),
17043 (DDRPHY_B0_DQ0 + SHIFT_TO_CHB_ADDR),
17044 (DDRPHY_B0_DQ5 + SHIFT_TO_CHB_ADDR),
17045 (DDRPHY_B0_DQ8 + SHIFT_TO_CHB_ADDR),
17046 (DDRPHY_SHU1_R0_B0_DQ7 + SHIFT_TO_CHB_ADDR),
17047 (DDRPHY_B0_DLL_ARPI0 + SHIFT_TO_CHB_ADDR),
17048 (DDRPHY_B0_DLL_ARPI2 + SHIFT_TO_CHB_ADDR),
17049
17050 (DDRPHY_B1_DQ6 + SHIFT_TO_CHB_ADDR),
17051 (DDRPHY_SHU1_B1_DLL1 + SHIFT_TO_CHB_ADDR),
17052 (DDRPHY_SHU1_B1_DQ5 + SHIFT_TO_CHB_ADDR),
17053 (DDRPHY_SHU1_B1_DQ0 + SHIFT_TO_CHB_ADDR),
17054 (DDRPHY_B1_DQ0 + SHIFT_TO_CHB_ADDR),
17055 (DDRPHY_B1_DQ5 + SHIFT_TO_CHB_ADDR),
17056 (DDRPHY_B1_DQ8 + SHIFT_TO_CHB_ADDR),
17057 (DDRPHY_SHU1_R0_B1_DQ7 + SHIFT_TO_CHB_ADDR),
17058 (DDRPHY_B1_DLL_ARPI0 + SHIFT_TO_CHB_ADDR),
17059 (DDRPHY_B1_DLL_ARPI2 + SHIFT_TO_CHB_ADDR),
17060
17061
17062 (DDRPHY_CA_CMD6 + SHIFT_TO_CHB_ADDR),
17063 (DDRPHY_SHU1_CA_DLL1 + SHIFT_TO_CHB_ADDR),
17064 (DDRPHY_SHU1_CA_CMD5 + SHIFT_TO_CHB_ADDR),
17065 (DDRPHY_SHU1_CA_CMD0 + SHIFT_TO_CHB_ADDR),
17066 (DDRPHY_CA_CMD0 + SHIFT_TO_CHB_ADDR),
17067 (DDRPHY_CA_CMD5 + SHIFT_TO_CHB_ADDR),
17068 (DDRPHY_CA_CMD9 + SHIFT_TO_CHB_ADDR),
17069// (DDRPHY_SHU1_CA_CMD3 + SHIFT_TO_CHB_ADDR),
17070 (DDRPHY_SHU1_R0_CA_CMD9 + SHIFT_TO_CHB_ADDR),
17071 (DDRPHY_CA_DLL_ARPI0 + SHIFT_TO_CHB_ADDR),
17072 (DDRPHY_CA_DLL_ARPI2 + SHIFT_TO_CHB_ADDR)
17073 };
17074#endif
17075
17076#if !FT_DSIM_USED
17077#if DUTY_SCAN_V2_ONLY_K_HIGHEST_FREQ
17078 if((p->frequency == u2DFSGetHighestFreq(p)) && (Get_PRE_MIOCK_JMETER_HQA_USED_flag()==0))
17079#else
17080 if(Get_PRE_MIOCK_JMETER_HQA_USED_flag()==0)
17081#endif
17082#endif
17083 {
17084 if(u1IsLP4Family(p->dram_type))
17085 {
17086 U8 u1ChannelIdx;
17087 u1backup_channel = vGetPHY2ChannelMapping(p);
17088
17089 #if SUPPORT_SAVE_TIME_FOR_CALIBRATION
17090 if(p->femmc_Ready==1)
17091 {
17092 for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<p->support_channel_num; u1ChannelIdx++)
17093 {
17094 vSetPHY2ChannelMapping(p, u1ChannelSet[u1ChannelIdx]);
17095 DramcClockDutySetClkDelayCell(p, RANK_0, p->pSavetimeData->s1ClockDuty_clk_delay_cell[p->channel][RANK_0], p->pSavetimeData->u1clk_use_rev_bit);
17096 DramcClockDutySetClkDelayCell(p, RANK_1, p->pSavetimeData->s1ClockDuty_clk_delay_cell[p->channel][RANK_1], p->pSavetimeData->u1clk_use_rev_bit);
17097 DQSDutyScan_SetDqsDelayCell(p, p->pSavetimeData->s1DQSDuty_clk_delay_cell[p->channel], p->pSavetimeData->u1dqs_use_rev_bit);
17098 #if APPLY_DQDQM_DUTY_CALIBRATION
17099 DQDQMDutyScan_SetDQDQMDelayCell(p, p->pSavetimeData->s1DQMDuty_clk_delay_cell[p->channel], p->pSavetimeData->u1dqm_use_rev_bit, DutyScan_Calibration_K_DQM);
17100 DQDQMDutyScan_SetDQDQMDelayCell(p, p->pSavetimeData->s1DQDuty_clk_delay_cell[p->channel], p->pSavetimeData->u1dq_use_rev_bit, DutyScan_Calibration_K_DQ);
17101 #endif
17102 }
17103 vSetPHY2ChannelMapping(p, u1backup_channel);
17104 return;
17105 }
17106 else
17107 #endif
17108 {
17109 //Clk free run
17110 EnableDramcPhyDCM(p, 0);
17111
17112 for(u1ChannelIdx=CHANNEL_A; u1ChannelIdx<p->support_channel_num; u1ChannelIdx++)
17113 {
17114 vSetPHY2ChannelMapping(p, u1ChannelSet[u1ChannelIdx]);
17115
17116 //Fix rank to rank0
17117 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANK);
17118 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 1, RKCFG_TXRANKFIX);
17119
17120 //backup register value
17121 #if FT_DSIM_USED==0
17122 DramcBackupRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
17123 #endif
17124
17125 DutyScan_Offset_Calibration(p);
17126
17127 #if defined(YH_SWEEP_IC)
17128 if (p->channel == CHANNEL_B)
17129 {
17130 u2FailStatusByCh[u1ChannelSet[u1ChannelIdx]]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_CLK, 0);
17131
17132 if (gcFinal_K_CLK_delay_cell[p->channel][0] == 8 || gcFinal_K_CLK_delay_cell[p->channel][0] == -8)
17133 {
17134 u2FailStatusByCh[u1ChannelIdx]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_CLK, 1);
17135 }
17136 }
17137 #else
17138 u2FailStatusByCh[u1ChannelSet[u1ChannelIdx]]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_CLK, 0);
17139
17140 if (gcFinal_K_CLK_delay_cell[p->channel][0] == 8 || gcFinal_K_CLK_delay_cell[p->channel][0] == -8)
17141 {
17142 u2FailStatusByCh[u1ChannelIdx]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_CLK, 1);
17143 }
17144 #endif
17145
17146 u2FailStatusByCh[u1ChannelSet[u1ChannelIdx]]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_DQS, 0);
17147 use_rev_bit=0;
17148
17149 if (gcFinal_K_DQS_delay_cell[p->channel][0] == 8 || gcFinal_K_DQS_delay_cell[p->channel][0] == -8 || gcFinal_K_DQS_delay_cell[p->channel][1] == 8 || gcFinal_K_DQS_delay_cell[p->channel][1] == -8)
17150 {
17151 u2FailStatusByCh[u1ChannelIdx]= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_DQS, 1);
17152 use_rev_bit=1;
17153 }
17154
17155 #if defined(APPLY_DQDQM_DUTY_CALIBRATION)
17156 u2FailStatusByCh[u1ChannelSet[u1ChannelIdx]]|= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_DQM, 0);
17157
17158 u2FailStatusByCh[u1ChannelSet[u1ChannelIdx]]|= DutyScan_Calibration_Flow(p, DutyScan_Calibration_K_DQ, 0);
17159 #endif
17160 #if FT_DSIM_USED==0
17161 //restore to orignal value
17162 DramcRestoreRegisters(p, u4RegBackupAddress, sizeof(u4RegBackupAddress)/sizeof(U32));
17163 #endif
17164
17165 //Set K DQS MCK4X_DLY_EN and MCK4XB_DLY_EN again, this is especially for K DQS because other bit fields need to be restored.
17166 DQSDutyScan_SetDqsDelayCell(p, gcFinal_K_DQS_delay_cell[p->channel], use_rev_bit);
17167
17168 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANK);
17169 vIO32WriteFldAlign(DRAMC_REG_ADDR(DRAMC_REG_RKCFG), 0, RKCFG_TXRANKFIX);
17170 }
17171 }
17172
17173 vSetPHY2ChannelMapping(p, u1backup_channel);
17174 }
17175
17176#if !FT_DSIM_USED
17177#if defined(YH_SWEEP_IC)
17178 YH_Sweep_IC_Print_Result(p);
17179 while(1); //stop here
17180#endif
17181#endif
17182 }
17183}
17184#endif
17185
17186
17187#ifdef ENABLE_MIOCK_JMETER
17188/* "picoseconds per delay cell" depends on Vcore only (frequency doesn't matter)
17189 * 1. Retrieve current freq's vcore voltage using pmic API
17190 * 2. Perform delay cell time calculation (Bypass if shuffle vcore value is the same as before)
17191 */
17192static void GetVcoreDelayCellTime(DRAMC_CTX_T *p, U8 shuffleIdx)
17193{
17194 U32 channel_i;
17195
17196#if __ETT__
17197 static U32 u4previousVcore = 0;
17198
17199#if (FOR_DV_SIMULATION_USED==0 && SW_CHANGE_FOR_SIMULATION==0)
17200 u4gVcore[shuffleIdx] = pmic_vcore_voltage_read();
17201#endif
17202
17203 /* delay cell calculation is skipped if vcore is same as previous shuffle's */
17204 if (u4gVcore[shuffleIdx] != u4previousVcore)
17205 {
17206 u4previousVcore = u4gVcore[shuffleIdx];
17207 DramcMiockJmeter(p);
17208 }
17209#else
17210 DramcMiockJmeter(p);
17211#endif
17212
17213 for(channel_i=CHANNEL_A; channel_i < p->support_channel_num; channel_i++)
17214 {
17215 ucg_num_dlycell_perT_all[shuffleIdx][u1ChannelSet[channel_i]] = ucg_num_dlycell_perT;
17216 u2gdelay_cell_ps_all[shuffleIdx][u1ChannelSet[channel_i]] = u2gdelay_cell_ps;
17217 }
17218#if __ETT__
17219 mcSHOW_DBG_MSG(("Freq=%d, CH_%d, VCORE=%d, cell=%d\n", p->frequency, p->channel, u4gVcore[shuffleIdx], u2gdelay_cell_ps_all[shuffleIdx][p->channel]));
17220#endif
17221
17222 return;
17223}
17224
17225
17226void DramcMiockJmeterHQA(DRAMC_CTX_T *p)
17227{
17228 //do MiockJitterMeter@DDR2667
17229 U8 shuffleIdx;
17230
17231 mcSHOW_DBG_MSG(("[MiockJmeterHQA]\n"));
17232
17233 shuffleIdx = get_shuffleIndex_by_Freq(p);
17234
17235 if (u1IsLP4Family(p->dram_type))
17236 {
17237 //if(p->channel == CHANNEL_A)
17238 {
17239 GetVcoreDelayCellTime(p, shuffleIdx);
17240 }
17241
17242 if((p->support_channel_num != CHANNEL_SINGLE) || (u1ChannelSet[0] == CHANNEL_A))
17243 u2gdelay_cell_ps_all[shuffleIdx][CHANNEL_B] = u2gdelay_cell_ps_all[shuffleIdx][CHANNEL_A];
17244 }
17245#if ENABLE_LP3_SW
17246 else
17247 {
17248 GetVcoreDelayCellTime(p, shuffleIdx);
17249 }
17250#endif /* ENABLE_LP3_SW */
17251
17252#ifdef FOR_HQA_TEST_USED
17253 if (ucg_num_dlycell_perT_all[shuffleIdx][p->channel] == 0) GetVcoreDelayCellTimeFromTable(p); //lookup table
17254#endif
17255
17256 /* Use highest freq's delay cell time measurement results as reference */
17257 p->ucnum_dlycell_perT = ucg_num_dlycell_perT_all[shuffleIdx][p->channel];
17258 p->u2DelayCellTimex100 = u2gdelay_cell_ps_all[shuffleIdx][p->channel];
17259 mcSHOW_DBG_MSG3(("DelayCellTimex100 CH_%d, (VCORE=%d, cell=%d)\n",p->channel, u4gVcore[shuffleIdx], p->u2DelayCellTimex100));
17260}
17261#endif //#ifdef ENABLE_MIOCK_JMETER
17262
17263void DramcWriteDBIOnOff(DRAMC_CTX_T *p, U8 onoff)
17264{
17265 // DRAMC Write-DBI On/Off
17266 if(u1IsLP4Family(p->dram_type))
17267 {
17268 vIO32WriteFldAlign_All(DRAMC_REG_SHU1_WODT, onoff, SHU1_WODT_DBIWR);
17269 mcSHOW_DBG_MSG(("DramC Write-DBI %s\n", ((onoff == DBI_ON) ? "on" : "off")));
17270 }
17271}
17272
17273void DramcReadDBIOnOff(DRAMC_CTX_T *p, U8 onoff)
17274{
17275 // DRAMC Read-DBI On/Off
17276 if(u1IsLP4Family(p->dram_type))
17277 {
17278 vIO32WriteFldAlign_All(DDRPHY_SHU1_B0_DQ7, onoff, SHU1_B0_DQ7_R_DMDQMDBI_SHU_B0);
17279 vIO32WriteFldAlign_All(DDRPHY_SHU1_B1_DQ7, onoff, SHU1_B1_DQ7_R_DMDQMDBI_SHU_B1);
17280 mcSHOW_DBG_MSG(("DramC Read-DBI %s\n", ((onoff == DBI_ON) ? "on" : "off")));
17281 }
17282}
17283#if ENABLE_READ_DBI
17284void SetDramModeRegForReadDBIOnOff(DRAMC_CTX_T *p, U8 onoff)
17285{
17286 if(u1IsLP4Family(p->dram_type))
17287 {
17288#if MRW_CHECK_ONLY
17289 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
17290#endif
17291 //mcSHOW_DBG_MSG(("--Fsp%d --\n", p->dram_fsp));
17292
17293 //DRAM MR3[6] read-DBI On/Off
17294 u1MR03Value[p->dram_fsp] = ((u1MR03Value[p->dram_fsp] & 0xbf) | (onoff<<6));
17295 DramcModeRegWriteByRank(p, p->rank, 3, u1MR03Value[p->dram_fsp]);
17296 }
17297}
17298#endif
17299
17300#if ENABLE_WRITE_DBI || TX_K_DQM_WITH_WDBI
17301void DramcWriteMinus1MCKForWriteDBI(DRAMC_CTX_T *p, S8 iShiftUI)
17302{
17303 //U8 ucdq_ui_large_dqs0, ucdq_ui_large_dqs1;
17304 //U8 ucdq_final_dqm_ui_large_dqs0, ucdq_final_dqm_ui_large_dqs1;
17305 REG_TRANSFER_T TransferReg[2];
17306
17307 if((u1IsLP4Family(p->dram_type))&&(p->DBI_W_onoff[p->dram_fsp]))
17308 {
17309 //ucdq_ui_large_dqs0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ0);
17310 //ucdq_ui_large_dqs1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ1);
17311 //mcSHOW_DBG_MSG(("Before -1MCK, ucdq_final_ui_large_dqs0 = %d, ucdq_final_ui_large_dqs1 = %d\n", ucdq_ui_large_dqs0, ucdq_ui_large_dqs1));
17312 // DQ0
17313 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
17314 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ0;
17315 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
17316 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ0;
17317 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
17318
17319 // DQ1
17320 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ2;
17321 TransferReg[0].u4Fld =SHURK0_SELPH_DQ2_DLY_DQ1;
17322 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ0;
17323 TransferReg[1].u4Fld =SHURK0_SELPH_DQ0_TXDLY_DQ1;
17324 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
17325
17326 //ucdq_ui_large_dqs0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ0);
17327 //ucdq_ui_large_dqs1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ0), SHURK0_SELPH_DQ0_TXDLY_DQ1);
17328 //mcSHOW_DBG_MSG(("After -1MCK, ucdq_final_ui_large_dqs0 = %d, ucdq_final_ui_large_dqs1 = %d\n", ucdq_ui_large_dqs0, ucdq_ui_large_dqs1));
17329
17330
17331 //ucdq_final_dqm_ui_large_dqs0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM0);
17332 //ucdq_final_dqm_ui_large_dqs1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM1);
17333 //mcSHOW_DBG_MSG(("Before -1MCK, ucdq_final_dqm_ui_large_dqs0 = %d, ucdq_final_dqm_ui_large_dqs1 = %d\n", ucdq_final_dqm_ui_large_dqs0, ucdq_final_dqm_ui_large_dqs1));
17334 // DQM0
17335 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
17336 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM0;
17337 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
17338 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM0;
17339 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
17340
17341 // DQM1
17342 TransferReg[0].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ3;
17343 TransferReg[0].u4Fld =SHURK0_SELPH_DQ3_DLY_DQM1;
17344 TransferReg[1].u4Addr = DRAMC_REG_SHURK0_SELPH_DQ1;
17345 TransferReg[1].u4Fld =SHURK0_SELPH_DQ1_TXDLY_DQM1;
17346 ExecuteMoveDramCDelay(p, TransferReg, iShiftUI);
17347 //ucdq_final_dqm_ui_large_dqs0 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM0);
17348 //ucdq_final_dqm_ui_large_dqs1 = u4IO32ReadFldAlign(DRAMC_REG_ADDR(DRAMC_REG_SHURK0_SELPH_DQ1), SHURK0_SELPH_DQ1_TXDLY_DQM1);
17349 //mcSHOW_DBG_MSG(("After -1MCK, ucdq_final_dqm_ui_large_dqs0 = %d, ucdq_final_dqm_ui_large_dqs1 = %d\n", ucdq_final_dqm_ui_large_dqs0, ucdq_final_dqm_ui_large_dqs1));
17350 }
17351}
17352
17353void SetDramModeRegForWriteDBIOnOff(DRAMC_CTX_T *p, U8 onoff)
17354{
17355 if(u1IsLP4Family(p->dram_type))
17356 {
17357#if MRW_CHECK_ONLY
17358 mcSHOW_MRW_MSG(("\n==[MR Dump] %s==\n", __func__));
17359#endif
17360 //DRAM MR3[7] write-DBI On/Off
17361 u1MR03Value[p->dram_fsp] = ((u1MR03Value[p->dram_fsp] & 0x7F) | (onoff<<7));
17362 DramcModeRegWriteByRank(p, p->rank, 3, u1MR03Value[p->dram_fsp]);
17363 }
17364}
17365#endif
17366
17367#if (SW_CHANGE_FOR_SIMULATION || FOR_DV_SIMULATION_USED)
17368void vMR2InitForSimulationTest(DRAMC_CTX_T *p)
17369{
17370 if(u1IsLP4Family(p->dram_type))
17371 {
17372 // Dram Init will set MR2's value
17373 #if 0
17374 if(p->frequency >HIGH_FREQ)
17375 {
17376 u1MR02Value[p->dram_fsp] = 0x3f;
17377 }
17378 else if(p->frequency <=DUAL_FREQ_LOW_LP4)
17379 {
17380 u1MR02Value[p->dram_fsp] = 0x1b;
17381 }
17382 else
17383 {
17384 u1MR02Value[p->dram_fsp] = 0x2d;
17385 }
17386 #endif
17387 }
17388 #if ENABLE_LP3_SW
17389 else
17390 {
17391 #if SUPPORT_LP3_800
17392 if(p->frequency<=400)
17393 {
17394 u1MR02Value[p->dram_fsp] = 0x18;
17395 }
17396 else
17397 #endif
17398 if(p->frequency==533)
17399 {
17400 u1MR02Value[p->dram_fsp] = 0x16;
17401 }
17402 else if(p->frequency == 635)
17403 {
17404 u1MR02Value[p->dram_fsp] = 0x18;
17405 }
17406 else if(p->frequency == 800)
17407 {
17408 u1MR02Value[p->dram_fsp] = 0x1a;
17409 }
17410 else
17411 {
17412 u1MR02Value[p->dram_fsp] = 0x1c;
17413 }
17414 }
17415 #endif
17416}
17417#endif
17418
17419#if ENABLE_WRITE_DBI_Protect
17420void ApplyWriteDBIProtect(DRAMC_CTX_T *p, U8 onoff)
17421{
17422 U8 *uiLPDDR_O1_Mapping;
17423 U16 Temp_PinMux_MaskWrite_WriteDBIOn=0;
17424 U8 B0_PinMux_MaskWrite_WriteDBIOn=0, B1_PinMux_MaskWrite_WriteDBIOn=0;
17425 int DQ_index;
17426
17427 if(u1IsLP4Family(p->dram_type))
17428 {
17429 uiLPDDR_O1_Mapping = (U8 *)uiLPDDR4_O1_Mapping_POP[p->channel];
17430
17431 // Write DMI/DBI Protect Function
17432 // Byte0 can not have bit swap between Group1(DQ0/1) and Group2(DQ02~DQ07).
17433 // Byte1 can not have bit swap between Group1(DQ8/9) and Group2(DQ10~DQ15).
17434 // DBIWR_IMP_EN=1 and DBIWR_PINMUX_EN=1
17435 // set DBIWR_OPTB0[7:0] meet with Byte0 pin MUX table.
17436 // set DBIWR_OPTB1[7:0] meet with Byte1 pin MUX table.
17437
17438 for(DQ_index=0; DQ_index<16; DQ_index++)
17439 {
17440 Temp_PinMux_MaskWrite_WriteDBIOn |= ((0x7C7C >> uiLPDDR_O1_Mapping[DQ_index]) & 0x1) << DQ_index;
17441 }
17442 B1_PinMux_MaskWrite_WriteDBIOn = (U8)(Temp_PinMux_MaskWrite_WriteDBIOn>>8) & 0xff;
17443 B0_PinMux_MaskWrite_WriteDBIOn = (U8) Temp_PinMux_MaskWrite_WriteDBIOn & 0xff;
17444
17445 vIO32WriteFldMulti_All(DRAMC_REG_ARBCTL, P_Fld(B1_PinMux_MaskWrite_WriteDBIOn, ARBCTL_DBIWR_OPT_B1)
17446 | P_Fld(B0_PinMux_MaskWrite_WriteDBIOn, ARBCTL_DBIWR_OPT_B0)
17447 | P_Fld(onoff, ARBCTL_DBIWR_PINMUX_EN)
17448 | P_Fld(onoff, ARBCTL_DBIWR_IMP_EN));
17449 }
17450}
17451#endif
17452
17453#if ENABLE_WRITE_DBI
17454void ApplyWriteDBIPowerImprove(DRAMC_CTX_T *p, U8 onoff)
17455{
17456 // set DBIWR_IMP_EN = 1
17457 // DBIWR_OPTB0[1:0]=0, DBIWR_OPT_B0[7]=0
17458 // DBIWR_OPTB1[1:0]=0, DBIWR_OPT_B1[7]=0
17459 if(u1IsLP4Family(p->dram_type))
17460 {
17461 vIO32WriteFldMulti_All(DRAMC_REG_ARBCTL, P_Fld(0, ARBCTL_DBIWR_OPT_bit15)
17462 | P_Fld(0, ARBCTL_DBIWR_OPT_bit9_8)
17463 | P_Fld(0, ARBCTL_DBIWR_OPT_bit7)
17464 | P_Fld(0, ARBCTL_DBIWR_OPT_bit1_0)
17465 | P_Fld(onoff, ARBCTL_DBIWR_IMP_EN));
17466 }
17467}
17468#endif
17469
17470#if SW_CHANGE_FOR_SIMULATION
17471void main(void)
17472{
17473
17474 DRAMC_CTX_T DramConfig;
17475 DramConfig.channel = CHANNEL_A;
17476 DramConfig.support_rank_num = RANK_DUAL;
17477 // DramRank
17478 DramConfig.rank = RANK_0;
17479 // DRAM type
17480 DramConfig.dram_type = TYPE_LPDDR4X;
17481 // DRAM Fast switch point type, only for LP4, useless in LP3
17482 DramConfig.dram_fsp = FSP_0;
17483 // DRAM CBT mode, only for LP4, useless in LP3
17484 DramConfig.dram_cbt_mode[RANK_0] = CBT_NORMAL_MODE;
17485 DramConfig.dram_cbt_mode[RANK_1] = CBT_NORMAL_MODE;
17486 // IC and DRAM read DBI
17487 DramConfig.DBI_R_onoff[FSP_0] = DBI_OFF; // only for LP4, uesless in LP3
17488 #if ENABLE_READ_DBI
17489 DramConfig.DBI_R_onoff[FSP_1] = DBI_ON; // only for LP4, uesless in LP3
17490 #else
17491 DramConfig.DBI_R_onoff[FSP_1] = DBI_OFF; // only for LP4, uesless in LP3
17492 #endif
17493 // IC and DRAM write DBI
17494 DramConfig.DBI_W_onoff[FSP_0] = DBI_OFF; // only for LP4, uesless in LP3
17495 #if ENABLE_WRITE_DBI
17496 DramConfig.DBI_W_onoff[FSP_1] = DBI_ON; // only for LP4, uesless in LP3
17497 #else
17498 DramConfig.DBI_W_onoff[FSP_1] = DBI_OFF; // only for LP4, uesless in LP3
17499 #endif
17500 // bus width
17501 DramConfig.data_width = DATA_WIDTH_32BIT;
17502 // DRAMC internal test engine-2 parameters in calibration
17503 DramConfig.test2_1 = DEFAULT_TEST2_1_CAL;
17504 DramConfig.test2_2 = DEFAULT_TEST2_2_CAL;
17505 // DRAMC test pattern in calibration
17506 DramConfig.test_pattern = TEST_XTALK_PATTERN;
17507 // DRAMC operation clock frequency in MHz
17508 DramConfig.frequency = 800;
17509
17510 DramConfig.enable_rx_scan_vref =DISABLE_VREF_SCAN;
17511 DramConfig.enable_tx_scan_vref =DISABLE_VREF_SCAN;
17512 //DramConfig.dynamicODT = DISABLE;
17513
17514 MPLLInit();
17515
17516 Global_Option_Init(&DramConfig);
17517 Global_Option_Init2(&DramConfig);
17518
17519 // DramC & PHY init for all channels
17520 DDRPhyFreqSel(&DramConfig, LP4_DDR1600);
17521
17522
17523#if WRITE_LEVELING_MOVE_DQS_INSTEAD_OF_CLK
17524 memset(DramConfig.arfgWriteLevelingInitShif, FALSE, sizeof(DramConfig.arfgWriteLevelingInitShif));
17525 //>fgWriteLevelingInitShif= FALSE;
17526#endif
17527#if TX_PERBIT_INIT_FLOW_CONTROL
17528 memset(DramConfig.fgTXPerbifInit, FALSE, sizeof(DramConfig.fgTXPerbifInit));
17529#endif
17530
17531 DramcInit(&DramConfig);
17532
17533 vApplyConfigBeforeCalibration(&DramConfig);
17534 vMR2InitForSimulationTest(&DramConfig);
17535
17536 vSetPHY2ChannelMapping(&DramConfig, DramConfig.channel);
17537
17538 #if SIMULATION_SW_IMPED
17539 if (u1IsLP4Family(DramConfig.dram_type))
17540 {
17541 DramcSwImpedanceCal(&DramConfig,1, 1); //within term
17542 DramcSwImpedanceCal(&DramConfig,1, 0); //without term
17543 }
17544#if ENABLE_LP3_SW
17545 else
17546 {
17547 DramcSwImpedanceCal(&DramConfig,1, 1); //within term
17548 }
17549#endif /* ENABLE_LP3_SW */
17550 #endif
17551
17552
17553#if SIMULATION_LP4_ZQ
17554 if (DramConfig.dram_type == TYPE_LPDDR4 || DramConfig.dram_type == TYPE_LPDDR4X || DramConfig.dram_type == TYPE_LPDDR4P)
17555 {
17556 DramcZQCalibration(&DramConfig);
17557 }
17558#endif
17559
17560 if (u1IsLP4Family(DramConfig.dram_type))
17561 {
17562 #if SIMUILATION_LP4_CBT
17563 CmdBusTrainingLP4(&DramConfig);
17564 #endif
17565 }
17566#if ENABLE_LP3_SW
17567 else
17568 {
17569 #if SIMULATION_LP3_CA_TRAINING
17570 vSetRank(DramConfig, RANK_0);
17571 CATrainingLP3(&DramConfig);
17572 #endif
17573 }
17574#endif /* ENABLE_LP3_SW */
17575
17576#if SIMULATION_WRITE_LEVELING
17577 DramcWriteLeveling(&DramConfig);
17578#endif
17579
17580 #if SIMULATION_GATING
17581 // Gating calibration of single rank
17582 DramcRxdqsGatingCal(&DramConfig);
17583
17584 // Gating calibration of both rank
17585 //DualRankDramcRxdqsGatingCal(&DramConfig);
17586 #endif
17587
17588#if SIMUILATION_LP4_RDDQC
17589 DramcRxWindowPerbitCal(&DramConfig, 0);
17590#endif
17591
17592 #if SIMULATION_DATLAT
17593 // RX Datlat calibration of single rank
17594 DramcRxdatlatCal(&DramConfig);
17595
17596 // RX Datlat calibration of two rank
17597 //DramcDualRankRxdatlatCal(&DramConfig);
17598 #endif
17599
17600 #if SIMULATION_RX_PERBIT
17601 DramcRxWindowPerbitCal(&DramConfig, 1);
17602 #endif
17603
17604 #if SIMULATION_TX_PERBIT
17605 DramcTxWindowPerbitCal(&DramConfig, TX_DQ_DQS_MOVE_DQ_DQM);
17606 DramcTxWindowPerbitCal(&DramConfig, TX_DQ_DQS_MOVE_DQ_ONLY);
17607 #endif
17608
17609 #if ENABLE_READ_DBI
17610 //Read DBI ON
17611 SetDramModeRegForReadDBIOnOff(&DramConfig, DramConfig.DBI_R_onoff[DramConfig.dram_fsp]);
17612 #endif
17613
17614 #if ENABLE_WRITE_DBI
17615 //Write DBI ON
17616 DramcWriteMinus1MCKForWriteDBI(&DramConfig, -8); //Tx DQ/DQM -1 MCK for write DBI ON
17617 SetDramModeRegForWriteDBIOnOff(&DramConfig, DramConfig.DBI_W_onoff[DramConfig.dram_fsp]);
17618 #endif
17619
17620 #if ENABLE_READ_DBI
17621 DramcReadDBIOnOff(&DramConfig, DramConfig.DBI_R_onoff[DramConfig.dram_fsp]);
17622 #endif
17623
17624 #if ENABLE_WRITE_DBI
17625 DramcWriteDBIOnOff(&DramConfig, DramConfig.DBI_W_onoff[DramConfig.dram_fsp]);
17626 #endif
17627}
17628#endif //SW_CHANGE_FOR_SIMULATION
17629