xref: /OK3568_Linux_fs/u-boot/drivers/ddr/marvell/a38x/ddr3_training_pbs.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) Marvell International Ltd. and its affiliates
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <spl.h>
9*4882a593Smuzhiyun #include <asm/io.h>
10*4882a593Smuzhiyun #include <asm/arch/cpu.h>
11*4882a593Smuzhiyun #include <asm/arch/soc.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "ddr3_init.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun #define TYPICAL_PBS_VALUE	12
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun u32 nominal_adll[MAX_INTERFACE_NUM * MAX_BUS_NUM];
18*4882a593Smuzhiyun enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
19*4882a593Smuzhiyun u8 result_mat[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
20*4882a593Smuzhiyun u8 result_mat_rx_dqs[MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_CS_NUM];
21*4882a593Smuzhiyun /* 4-EEWA, 3-EWA, 2-SWA, 1-Fail, 0-Pass */
22*4882a593Smuzhiyun u8 result_all_bit[MAX_BUS_NUM * BUS_WIDTH_IN_BITS * MAX_INTERFACE_NUM];
23*4882a593Smuzhiyun u8 max_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
24*4882a593Smuzhiyun u8 min_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
25*4882a593Smuzhiyun u8 max_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
26*4882a593Smuzhiyun u8 min_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
27*4882a593Smuzhiyun u32 pbsdelay_per_pup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
28*4882a593Smuzhiyun u8 adll_shift_lock[MAX_INTERFACE_NUM][MAX_BUS_NUM];
29*4882a593Smuzhiyun u8 adll_shift_val[MAX_INTERFACE_NUM][MAX_BUS_NUM];
30*4882a593Smuzhiyun enum hws_pattern pbs_pattern = PATTERN_VREF;
31*4882a593Smuzhiyun static u8 pup_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun /*
34*4882a593Smuzhiyun  * Name:     ddr3_tip_pbs
35*4882a593Smuzhiyun  * Desc:     PBS
36*4882a593Smuzhiyun  * Args:     TBD
37*4882a593Smuzhiyun  * Notes:
38*4882a593Smuzhiyun  * Returns:  OK if success, other error code if fail.
39*4882a593Smuzhiyun  */
ddr3_tip_pbs(u32 dev_num,enum pbs_dir pbs_mode)40*4882a593Smuzhiyun int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	u32 res0[MAX_INTERFACE_NUM];
43*4882a593Smuzhiyun 	int adll_tap = MEGA / freq_val[medium_freq] / 64;
44*4882a593Smuzhiyun 	int pad_num = 0;
45*4882a593Smuzhiyun 	enum hws_search_dir search_dir =
46*4882a593Smuzhiyun 		(pbs_mode == PBS_RX_MODE) ? HWS_HIGH2LOW : HWS_LOW2HIGH;
47*4882a593Smuzhiyun 	enum hws_dir dir = (pbs_mode == PBS_RX_MODE) ? OPER_READ : OPER_WRITE;
48*4882a593Smuzhiyun 	int iterations = (pbs_mode == PBS_RX_MODE) ? 31 : 63;
49*4882a593Smuzhiyun 	u32 res_valid_mask = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
50*4882a593Smuzhiyun 	int init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
51*4882a593Smuzhiyun 	enum hws_edge_compare search_edge = EDGE_FP;
52*4882a593Smuzhiyun 	u32 pup = 0, bit = 0, if_id = 0, all_lock = 0, cs_num = 0;
53*4882a593Smuzhiyun 	int reg_addr = 0;
54*4882a593Smuzhiyun 	u32 validation_val = 0;
55*4882a593Smuzhiyun 	u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
56*4882a593Smuzhiyun 	u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
57*4882a593Smuzhiyun 	u8 temp = 0;
58*4882a593Smuzhiyun 	struct hws_topology_map *tm = ddr3_get_topology_map();
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	/* save current cs enable reg val */
61*4882a593Smuzhiyun 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
62*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 		/* save current cs enable reg val */
65*4882a593Smuzhiyun 		CHECK_STATUS(ddr3_tip_if_read
66*4882a593Smuzhiyun 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
67*4882a593Smuzhiyun 			      CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 		/* enable single cs */
70*4882a593Smuzhiyun 		CHECK_STATUS(ddr3_tip_if_write
71*4882a593Smuzhiyun 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
72*4882a593Smuzhiyun 			      CS_ENABLE_REG, (1 << 3), (1 << 3)));
73*4882a593Smuzhiyun 	}
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	reg_addr = (pbs_mode == PBS_RX_MODE) ?
76*4882a593Smuzhiyun 		(READ_CENTRALIZATION_PHY_REG +
77*4882a593Smuzhiyun 		 (effective_cs * CS_REGISTER_ADDR_OFFSET)) :
78*4882a593Smuzhiyun 		(WRITE_CENTRALIZATION_PHY_REG +
79*4882a593Smuzhiyun 		 (effective_cs * CS_REGISTER_ADDR_OFFSET));
80*4882a593Smuzhiyun 	read_adll_value(nominal_adll, reg_addr, MASK_ALL_BITS);
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun 	/* stage 1 shift ADLL */
83*4882a593Smuzhiyun 	ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
84*4882a593Smuzhiyun 			     PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
85*4882a593Smuzhiyun 			     PARAM_NOT_CARE, RESULT_PER_BIT,
86*4882a593Smuzhiyun 			     HWS_CONTROL_ELEMENT_ADLL, search_dir, dir,
87*4882a593Smuzhiyun 			     tm->if_act_mask, init_val, iterations,
88*4882a593Smuzhiyun 			     pbs_pattern, search_edge, CS_SINGLE, cs_num,
89*4882a593Smuzhiyun 			     train_status);
90*4882a593Smuzhiyun 	validation_val = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0;
91*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
92*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
93*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
94*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
95*4882a593Smuzhiyun 			min_adll_per_pup[if_id][pup] =
96*4882a593Smuzhiyun 				(pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
97*4882a593Smuzhiyun 			pup_state[if_id][pup] = 0x3;
98*4882a593Smuzhiyun 			adll_shift_lock[if_id][pup] = 1;
99*4882a593Smuzhiyun 			max_adll_per_pup[if_id][pup] = 0x0;
100*4882a593Smuzhiyun 		}
101*4882a593Smuzhiyun 	}
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	/* EBA */
104*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
105*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
106*4882a593Smuzhiyun 		for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
107*4882a593Smuzhiyun 			CHECK_STATUS(ddr3_tip_if_read
108*4882a593Smuzhiyun 				     (dev_num, ACCESS_TYPE_MULTICAST,
109*4882a593Smuzhiyun 				      PARAM_NOT_CARE,
110*4882a593Smuzhiyun 				      mask_results_dq_reg_map[
111*4882a593Smuzhiyun 					      bit + pup * BUS_WIDTH_IN_BITS],
112*4882a593Smuzhiyun 				      res0, MASK_ALL_BITS));
113*4882a593Smuzhiyun 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
114*4882a593Smuzhiyun 			     if_id++) {
115*4882a593Smuzhiyun 				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
116*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
117*4882a593Smuzhiyun 						 ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
118*4882a593Smuzhiyun 						  if_id, bit, pup,
119*4882a593Smuzhiyun 						  res0[if_id]));
120*4882a593Smuzhiyun 				if (pup_state[if_id][pup] != 3)
121*4882a593Smuzhiyun 					continue;
122*4882a593Smuzhiyun 				/* if not EBA state than move to next pup */
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 				if ((res0[if_id] & 0x2000000) == 0) {
125*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
126*4882a593Smuzhiyun 							 ("-- Fail Training IP\n"));
127*4882a593Smuzhiyun 					/* training machine failed */
128*4882a593Smuzhiyun 					pup_state[if_id][pup] = 1;
129*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 0;
130*4882a593Smuzhiyun 					continue;
131*4882a593Smuzhiyun 				}
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 				else if ((res0[if_id] & res_valid_mask) ==
134*4882a593Smuzhiyun 					 validation_val) {
135*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
136*4882a593Smuzhiyun 							 ("-- FAIL EBA %d %d %d %d\n",
137*4882a593Smuzhiyun 							  if_id, bit, pup,
138*4882a593Smuzhiyun 							  res0[if_id]));
139*4882a593Smuzhiyun 					pup_state[if_id][pup] = 4;
140*4882a593Smuzhiyun 					/* this pup move to EEBA */
141*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 0;
142*4882a593Smuzhiyun 					continue;
143*4882a593Smuzhiyun 				} else {
144*4882a593Smuzhiyun 					/*
145*4882a593Smuzhiyun 					 * The search ended in Pass we need
146*4882a593Smuzhiyun 					 * Fail
147*4882a593Smuzhiyun 					 */
148*4882a593Smuzhiyun 					res0[if_id] =
149*4882a593Smuzhiyun 						(pbs_mode == PBS_RX_MODE) ?
150*4882a593Smuzhiyun 						((res0[if_id] &
151*4882a593Smuzhiyun 						  res_valid_mask) + 1) :
152*4882a593Smuzhiyun 						((res0[if_id] &
153*4882a593Smuzhiyun 						  res_valid_mask) - 1);
154*4882a593Smuzhiyun 					max_adll_per_pup[if_id][pup] =
155*4882a593Smuzhiyun 						(max_adll_per_pup[if_id][pup] <
156*4882a593Smuzhiyun 						 res0[if_id]) ?
157*4882a593Smuzhiyun 						(u8)res0[if_id] :
158*4882a593Smuzhiyun 						max_adll_per_pup[if_id][pup];
159*4882a593Smuzhiyun 					min_adll_per_pup[if_id][pup] =
160*4882a593Smuzhiyun 						(res0[if_id] >
161*4882a593Smuzhiyun 						 min_adll_per_pup[if_id][pup]) ?
162*4882a593Smuzhiyun 						min_adll_per_pup[if_id][pup] :
163*4882a593Smuzhiyun 						(u8)
164*4882a593Smuzhiyun 						res0[if_id];
165*4882a593Smuzhiyun 					/*
166*4882a593Smuzhiyun 					 * vs the Rx we are searching for the
167*4882a593Smuzhiyun 					 * smallest value of DQ shift so all
168*4882a593Smuzhiyun 					 * Bus would fail
169*4882a593Smuzhiyun 					 */
170*4882a593Smuzhiyun 					adll_shift_val[if_id][pup] =
171*4882a593Smuzhiyun 						(pbs_mode == PBS_RX_MODE) ?
172*4882a593Smuzhiyun 						max_adll_per_pup[if_id][pup] :
173*4882a593Smuzhiyun 						min_adll_per_pup[if_id][pup];
174*4882a593Smuzhiyun 				}
175*4882a593Smuzhiyun 			}
176*4882a593Smuzhiyun 		}
177*4882a593Smuzhiyun 	}
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	/* EEBA */
180*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
181*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
182*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
183*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 			if (pup_state[if_id][pup] != 4)
186*4882a593Smuzhiyun 				continue;
187*4882a593Smuzhiyun 			/*
188*4882a593Smuzhiyun 			 * if pup state different from EEBA than move to
189*4882a593Smuzhiyun 			 * next pup
190*4882a593Smuzhiyun 			 */
191*4882a593Smuzhiyun 			reg_addr = (pbs_mode == PBS_RX_MODE) ?
192*4882a593Smuzhiyun 				(0x54 + effective_cs * 0x10) :
193*4882a593Smuzhiyun 				(0x14 + effective_cs * 0x10);
194*4882a593Smuzhiyun 			CHECK_STATUS(ddr3_tip_bus_write
195*4882a593Smuzhiyun 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
196*4882a593Smuzhiyun 				      ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
197*4882a593Smuzhiyun 				      reg_addr, 0x1f));
198*4882a593Smuzhiyun 			reg_addr = (pbs_mode == PBS_RX_MODE) ?
199*4882a593Smuzhiyun 				(0x55 + effective_cs * 0x10) :
200*4882a593Smuzhiyun 				(0x15 + effective_cs * 0x10);
201*4882a593Smuzhiyun 			CHECK_STATUS(ddr3_tip_bus_write
202*4882a593Smuzhiyun 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
203*4882a593Smuzhiyun 				      ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
204*4882a593Smuzhiyun 				      reg_addr, 0x1f));
205*4882a593Smuzhiyun 			/* initialize the Edge2 Max. */
206*4882a593Smuzhiyun 			adll_shift_val[if_id][pup] = 0;
207*4882a593Smuzhiyun 			min_adll_per_pup[if_id][pup] =
208*4882a593Smuzhiyun 				(pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
209*4882a593Smuzhiyun 			max_adll_per_pup[if_id][pup] = 0x0;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun 			ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
212*4882a593Smuzhiyun 					     PARAM_NOT_CARE,
213*4882a593Smuzhiyun 					     ACCESS_TYPE_MULTICAST,
214*4882a593Smuzhiyun 					     PARAM_NOT_CARE, RESULT_PER_BIT,
215*4882a593Smuzhiyun 					     HWS_CONTROL_ELEMENT_ADLL,
216*4882a593Smuzhiyun 					     search_dir, dir,
217*4882a593Smuzhiyun 					     tm->if_act_mask, init_val,
218*4882a593Smuzhiyun 					     iterations, pbs_pattern,
219*4882a593Smuzhiyun 					     search_edge, CS_SINGLE, cs_num,
220*4882a593Smuzhiyun 					     train_status);
221*4882a593Smuzhiyun 			DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
222*4882a593Smuzhiyun 					 ("ADLL shift results:\n"));
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 			for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
225*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_if_read
226*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_MULTICAST,
227*4882a593Smuzhiyun 					      PARAM_NOT_CARE,
228*4882a593Smuzhiyun 					      mask_results_dq_reg_map[
229*4882a593Smuzhiyun 						      bit + pup *
230*4882a593Smuzhiyun 						      BUS_WIDTH_IN_BITS],
231*4882a593Smuzhiyun 					      res0, MASK_ALL_BITS));
232*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
233*4882a593Smuzhiyun 						 ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
234*4882a593Smuzhiyun 						  if_id, bit, pup,
235*4882a593Smuzhiyun 						  res0[if_id]));
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 				if ((res0[if_id] & 0x2000000) == 0) {
238*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
239*4882a593Smuzhiyun 							 (" -- EEBA Fail\n"));
240*4882a593Smuzhiyun 					bit = BUS_WIDTH_IN_BITS;
241*4882a593Smuzhiyun 					/* exit bit loop */
242*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
243*4882a593Smuzhiyun 							 ("-- EEBA Fail Training IP\n"));
244*4882a593Smuzhiyun 					/*
245*4882a593Smuzhiyun 					 * training machine failed but pass
246*4882a593Smuzhiyun 					 * before in the EBA so maybe the DQS
247*4882a593Smuzhiyun 					 * shift change env.
248*4882a593Smuzhiyun 					 */
249*4882a593Smuzhiyun 					pup_state[if_id][pup] = 2;
250*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 0;
251*4882a593Smuzhiyun 					reg_addr = (pbs_mode == PBS_RX_MODE) ?
252*4882a593Smuzhiyun 						(0x54 + effective_cs * 0x10) :
253*4882a593Smuzhiyun 						(0x14 + effective_cs * 0x10);
254*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_bus_write
255*4882a593Smuzhiyun 						     (dev_num,
256*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST,
257*4882a593Smuzhiyun 						      if_id,
258*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST, pup,
259*4882a593Smuzhiyun 						      DDR_PHY_DATA, reg_addr,
260*4882a593Smuzhiyun 						      0x0));
261*4882a593Smuzhiyun 					reg_addr = (pbs_mode == PBS_RX_MODE) ?
262*4882a593Smuzhiyun 						(0x55 + effective_cs * 0x10) :
263*4882a593Smuzhiyun 						(0x15 + effective_cs * 0x10);
264*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_bus_write
265*4882a593Smuzhiyun 						     (dev_num,
266*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST,
267*4882a593Smuzhiyun 						      if_id,
268*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST, pup,
269*4882a593Smuzhiyun 						      DDR_PHY_DATA, reg_addr,
270*4882a593Smuzhiyun 						      0x0));
271*4882a593Smuzhiyun 					continue;
272*4882a593Smuzhiyun 				} else if ((res0[if_id] & res_valid_mask) ==
273*4882a593Smuzhiyun 					   validation_val) {
274*4882a593Smuzhiyun 					/* exit bit loop */
275*4882a593Smuzhiyun 					bit = BUS_WIDTH_IN_BITS;
276*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
277*4882a593Smuzhiyun 							 ("-- FAIL EEBA\n"));
278*4882a593Smuzhiyun 					/* this pup move to SBA */
279*4882a593Smuzhiyun 					pup_state[if_id][pup] = 2;
280*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 0;
281*4882a593Smuzhiyun 					reg_addr = (pbs_mode == PBS_RX_MODE) ?
282*4882a593Smuzhiyun 						(0x54 + effective_cs * 0x10) :
283*4882a593Smuzhiyun 						(0x14 + effective_cs * 0x10);
284*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_bus_write
285*4882a593Smuzhiyun 						     (dev_num,
286*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST,
287*4882a593Smuzhiyun 						      if_id,
288*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST, pup,
289*4882a593Smuzhiyun 						      DDR_PHY_DATA, reg_addr,
290*4882a593Smuzhiyun 						      0x0));
291*4882a593Smuzhiyun 					reg_addr = (pbs_mode == PBS_RX_MODE) ?
292*4882a593Smuzhiyun 						(0x55 + effective_cs * 0x10) :
293*4882a593Smuzhiyun 						(0x15 + effective_cs * 0x10);
294*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_bus_write
295*4882a593Smuzhiyun 						     (dev_num,
296*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST,
297*4882a593Smuzhiyun 						      if_id,
298*4882a593Smuzhiyun 						      ACCESS_TYPE_UNICAST, pup,
299*4882a593Smuzhiyun 						      DDR_PHY_DATA, reg_addr,
300*4882a593Smuzhiyun 						      0x0));
301*4882a593Smuzhiyun 					continue;
302*4882a593Smuzhiyun 				} else {
303*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 1;
304*4882a593Smuzhiyun 					/*
305*4882a593Smuzhiyun 					 * The search ended in Pass we need
306*4882a593Smuzhiyun 					 * Fail
307*4882a593Smuzhiyun 					 */
308*4882a593Smuzhiyun 					res0[if_id] =
309*4882a593Smuzhiyun 						(pbs_mode == PBS_RX_MODE) ?
310*4882a593Smuzhiyun 						((res0[if_id] &
311*4882a593Smuzhiyun 						  res_valid_mask) + 1) :
312*4882a593Smuzhiyun 						((res0[if_id] &
313*4882a593Smuzhiyun 						  res_valid_mask) - 1);
314*4882a593Smuzhiyun 					max_adll_per_pup[if_id][pup] =
315*4882a593Smuzhiyun 						(max_adll_per_pup[if_id][pup] <
316*4882a593Smuzhiyun 						 res0[if_id]) ?
317*4882a593Smuzhiyun 						(u8)res0[if_id] :
318*4882a593Smuzhiyun 						max_adll_per_pup[if_id][pup];
319*4882a593Smuzhiyun 					min_adll_per_pup[if_id][pup] =
320*4882a593Smuzhiyun 						(res0[if_id] >
321*4882a593Smuzhiyun 						 min_adll_per_pup[if_id][pup]) ?
322*4882a593Smuzhiyun 						min_adll_per_pup[if_id][pup] :
323*4882a593Smuzhiyun 						(u8)res0[if_id];
324*4882a593Smuzhiyun 					/*
325*4882a593Smuzhiyun 					 * vs the Rx we are searching for the
326*4882a593Smuzhiyun 					 * smallest value of DQ shift so all Bus
327*4882a593Smuzhiyun 					 * would fail
328*4882a593Smuzhiyun 					 */
329*4882a593Smuzhiyun 					adll_shift_val[if_id][pup] =
330*4882a593Smuzhiyun 						(pbs_mode == PBS_RX_MODE) ?
331*4882a593Smuzhiyun 						max_adll_per_pup[if_id][pup] :
332*4882a593Smuzhiyun 						min_adll_per_pup[if_id][pup];
333*4882a593Smuzhiyun 				}
334*4882a593Smuzhiyun 			}
335*4882a593Smuzhiyun 		}
336*4882a593Smuzhiyun 	}
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	/* Print Stage result */
339*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
340*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
341*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
342*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
343*4882a593Smuzhiyun 			DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
344*4882a593Smuzhiyun 					 ("FP I/F %d, ADLL Shift for EBA: pup[%d] Lock status = %d Lock Val = %d,%d\n",
345*4882a593Smuzhiyun 					  if_id, pup,
346*4882a593Smuzhiyun 					  adll_shift_lock[if_id][pup],
347*4882a593Smuzhiyun 					  max_adll_per_pup[if_id][pup],
348*4882a593Smuzhiyun 					  min_adll_per_pup[if_id][pup]));
349*4882a593Smuzhiyun 		}
350*4882a593Smuzhiyun 	}
351*4882a593Smuzhiyun 	DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
352*4882a593Smuzhiyun 			 ("Update ADLL Shift of all pups:\n"));
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
355*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
356*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
357*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
358*4882a593Smuzhiyun 			if (adll_shift_lock[if_id][pup] != 1)
359*4882a593Smuzhiyun 				continue;
360*4882a593Smuzhiyun 			/* if pup not locked continue to next pup */
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 			reg_addr = (pbs_mode == PBS_RX_MODE) ?
363*4882a593Smuzhiyun 				(0x3 + effective_cs * 4) :
364*4882a593Smuzhiyun 				(0x1 + effective_cs * 4);
365*4882a593Smuzhiyun 			CHECK_STATUS(ddr3_tip_bus_write
366*4882a593Smuzhiyun 				     (dev_num, ACCESS_TYPE_UNICAST, if_id,
367*4882a593Smuzhiyun 				      ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
368*4882a593Smuzhiyun 				      reg_addr, adll_shift_val[if_id][pup]));
369*4882a593Smuzhiyun 			DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
370*4882a593Smuzhiyun 					 ("FP I/F %d, Pup[%d] = %d\n", if_id,
371*4882a593Smuzhiyun 					  pup, adll_shift_val[if_id][pup]));
372*4882a593Smuzhiyun 		}
373*4882a593Smuzhiyun 	}
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	/* PBS EEBA&EBA */
376*4882a593Smuzhiyun 	/* Start the Per Bit Skew search */
377*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
378*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
379*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
380*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
381*4882a593Smuzhiyun 			max_pbs_per_pup[if_id][pup] = 0x0;
382*4882a593Smuzhiyun 			min_pbs_per_pup[if_id][pup] = 0x1f;
383*4882a593Smuzhiyun 			for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
384*4882a593Smuzhiyun 				/* reset result for PBS */
385*4882a593Smuzhiyun 				result_all_bit[bit + pup * BUS_WIDTH_IN_BITS +
386*4882a593Smuzhiyun 					       if_id * MAX_BUS_NUM *
387*4882a593Smuzhiyun 					       BUS_WIDTH_IN_BITS] = 0;
388*4882a593Smuzhiyun 			}
389*4882a593Smuzhiyun 		}
390*4882a593Smuzhiyun 	}
391*4882a593Smuzhiyun 
392*4882a593Smuzhiyun 	iterations = 31;
393*4882a593Smuzhiyun 	search_dir = HWS_LOW2HIGH;
394*4882a593Smuzhiyun 	/* !!!!! ran sh (search_dir == HWS_LOW2HIGH)?0:iterations; */
395*4882a593Smuzhiyun 	init_val = 0;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
398*4882a593Smuzhiyun 			     ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
399*4882a593Smuzhiyun 			     RESULT_PER_BIT, HWS_CONTROL_ELEMENT_DQ_SKEW,
400*4882a593Smuzhiyun 			     search_dir, dir, tm->if_act_mask, init_val,
401*4882a593Smuzhiyun 			     iterations, pbs_pattern, search_edge,
402*4882a593Smuzhiyun 			     CS_SINGLE, cs_num, train_status);
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
405*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
406*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
407*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
408*4882a593Smuzhiyun 			if (adll_shift_lock[if_id][pup] != 1) {
409*4882a593Smuzhiyun 				/* if pup not lock continue to next pup */
410*4882a593Smuzhiyun 				continue;
411*4882a593Smuzhiyun 			}
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 			for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
414*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_if_read
415*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_MULTICAST,
416*4882a593Smuzhiyun 					      PARAM_NOT_CARE,
417*4882a593Smuzhiyun 					      mask_results_dq_reg_map[
418*4882a593Smuzhiyun 						      bit +
419*4882a593Smuzhiyun 						      pup * BUS_WIDTH_IN_BITS],
420*4882a593Smuzhiyun 					      res0, MASK_ALL_BITS));
421*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
422*4882a593Smuzhiyun 						 ("Per Bit Skew search, FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
423*4882a593Smuzhiyun 						  if_id, bit, pup,
424*4882a593Smuzhiyun 						  res0[if_id]));
425*4882a593Smuzhiyun 				if ((res0[if_id] & 0x2000000) == 0) {
426*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
427*4882a593Smuzhiyun 							 ("--EBA PBS Fail - Training IP machine\n"));
428*4882a593Smuzhiyun 					/* exit the bit loop */
429*4882a593Smuzhiyun 					bit = BUS_WIDTH_IN_BITS;
430*4882a593Smuzhiyun 					/*
431*4882a593Smuzhiyun 					 * ADLL is no long in lock need new
432*4882a593Smuzhiyun 					 * search
433*4882a593Smuzhiyun 					 */
434*4882a593Smuzhiyun 					adll_shift_lock[if_id][pup] = 0;
435*4882a593Smuzhiyun 					/* Move to SBA */
436*4882a593Smuzhiyun 					pup_state[if_id][pup] = 2;
437*4882a593Smuzhiyun 					max_pbs_per_pup[if_id][pup] = 0x0;
438*4882a593Smuzhiyun 					min_pbs_per_pup[if_id][pup] = 0x1f;
439*4882a593Smuzhiyun 					continue;
440*4882a593Smuzhiyun 				} else {
441*4882a593Smuzhiyun 					temp = (u8)(res0[if_id] &
442*4882a593Smuzhiyun 						    res_valid_mask);
443*4882a593Smuzhiyun 					max_pbs_per_pup[if_id][pup] =
444*4882a593Smuzhiyun 						(temp >
445*4882a593Smuzhiyun 						 max_pbs_per_pup[if_id][pup]) ?
446*4882a593Smuzhiyun 						temp :
447*4882a593Smuzhiyun 						max_pbs_per_pup[if_id][pup];
448*4882a593Smuzhiyun 					min_pbs_per_pup[if_id][pup] =
449*4882a593Smuzhiyun 						(temp <
450*4882a593Smuzhiyun 						 min_pbs_per_pup[if_id][pup]) ?
451*4882a593Smuzhiyun 						temp :
452*4882a593Smuzhiyun 						min_pbs_per_pup[if_id][pup];
453*4882a593Smuzhiyun 					result_all_bit[bit +
454*4882a593Smuzhiyun 						       pup * BUS_WIDTH_IN_BITS +
455*4882a593Smuzhiyun 						       if_id * MAX_BUS_NUM *
456*4882a593Smuzhiyun 						       BUS_WIDTH_IN_BITS] =
457*4882a593Smuzhiyun 						temp;
458*4882a593Smuzhiyun 				}
459*4882a593Smuzhiyun 			}
460*4882a593Smuzhiyun 		}
461*4882a593Smuzhiyun 	}
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	/* Check all Pup lock */
464*4882a593Smuzhiyun 	all_lock = 1;
465*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
466*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
467*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
468*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
469*4882a593Smuzhiyun 			all_lock = all_lock * adll_shift_lock[if_id][pup];
470*4882a593Smuzhiyun 		}
471*4882a593Smuzhiyun 	}
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	/* Only if not all Pups Lock */
474*4882a593Smuzhiyun 	if (all_lock == 0) {
475*4882a593Smuzhiyun 		DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
476*4882a593Smuzhiyun 				 ("##########ADLL shift for SBA###########\n"));
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun 		/* ADLL shift for SBA */
479*4882a593Smuzhiyun 		search_dir = (pbs_mode == PBS_RX_MODE) ? HWS_LOW2HIGH :
480*4882a593Smuzhiyun 			HWS_HIGH2LOW;
481*4882a593Smuzhiyun 		init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
482*4882a593Smuzhiyun 		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
483*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
484*4882a593Smuzhiyun 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
485*4882a593Smuzhiyun 			     if_id++) {
486*4882a593Smuzhiyun 				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
487*4882a593Smuzhiyun 				if (adll_shift_lock[if_id][pup] == 1) {
488*4882a593Smuzhiyun 					/*if pup lock continue to next pup */
489*4882a593Smuzhiyun 					continue;
490*4882a593Smuzhiyun 				}
491*4882a593Smuzhiyun 				/*init the var altogth init before */
492*4882a593Smuzhiyun 				adll_shift_lock[if_id][pup] = 0;
493*4882a593Smuzhiyun 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
494*4882a593Smuzhiyun 					(0x54 + effective_cs * 0x10) :
495*4882a593Smuzhiyun 					(0x14 + effective_cs * 0x10);
496*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
497*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
498*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
499*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr, 0));
500*4882a593Smuzhiyun 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
501*4882a593Smuzhiyun 					(0x55 + effective_cs * 0x10) :
502*4882a593Smuzhiyun 					(0x15 + effective_cs * 0x10);
503*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
504*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
505*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
506*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr, 0));
507*4882a593Smuzhiyun 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
508*4882a593Smuzhiyun 					(0x5f + effective_cs * 0x10) :
509*4882a593Smuzhiyun 					(0x1f + effective_cs * 0x10);
510*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
511*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
512*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
513*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr, 0));
514*4882a593Smuzhiyun 				/* initilaze the Edge2 Max. */
515*4882a593Smuzhiyun 				adll_shift_val[if_id][pup] = 0;
516*4882a593Smuzhiyun 				min_adll_per_pup[if_id][pup] = 0x1f;
517*4882a593Smuzhiyun 				max_adll_per_pup[if_id][pup] = 0x0;
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 				ddr3_tip_ip_training(dev_num,
520*4882a593Smuzhiyun 						     ACCESS_TYPE_MULTICAST,
521*4882a593Smuzhiyun 						     PARAM_NOT_CARE,
522*4882a593Smuzhiyun 						     ACCESS_TYPE_MULTICAST,
523*4882a593Smuzhiyun 						     PARAM_NOT_CARE,
524*4882a593Smuzhiyun 						     RESULT_PER_BIT,
525*4882a593Smuzhiyun 						     HWS_CONTROL_ELEMENT_ADLL,
526*4882a593Smuzhiyun 						     search_dir, dir,
527*4882a593Smuzhiyun 						     tm->if_act_mask,
528*4882a593Smuzhiyun 						     init_val, iterations,
529*4882a593Smuzhiyun 						     pbs_pattern,
530*4882a593Smuzhiyun 						     search_edge, CS_SINGLE,
531*4882a593Smuzhiyun 						     cs_num, train_status);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 				for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
534*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_if_read
535*4882a593Smuzhiyun 						     (dev_num,
536*4882a593Smuzhiyun 						      ACCESS_TYPE_MULTICAST,
537*4882a593Smuzhiyun 						      PARAM_NOT_CARE,
538*4882a593Smuzhiyun 						      mask_results_dq_reg_map
539*4882a593Smuzhiyun 						      [bit +
540*4882a593Smuzhiyun 						       pup *
541*4882a593Smuzhiyun 						       BUS_WIDTH_IN_BITS],
542*4882a593Smuzhiyun 						      res0, MASK_ALL_BITS));
543*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(
544*4882a593Smuzhiyun 						DEBUG_LEVEL_INFO,
545*4882a593Smuzhiyun 						("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
546*4882a593Smuzhiyun 						 if_id, bit, pup, res0[if_id]));
547*4882a593Smuzhiyun 					if ((res0[if_id] & 0x2000000) == 0) {
548*4882a593Smuzhiyun 						/* exit the bit loop */
549*4882a593Smuzhiyun 						bit = BUS_WIDTH_IN_BITS;
550*4882a593Smuzhiyun 						/* Fail SBA --> Fail PBS */
551*4882a593Smuzhiyun 						pup_state[if_id][pup] = 1;
552*4882a593Smuzhiyun 						DEBUG_PBS_ENGINE
553*4882a593Smuzhiyun 							(DEBUG_LEVEL_INFO,
554*4882a593Smuzhiyun 							 (" SBA Fail\n"));
555*4882a593Smuzhiyun 						continue;
556*4882a593Smuzhiyun 					} else {
557*4882a593Smuzhiyun 						/*
558*4882a593Smuzhiyun 						 * - increment to get all
559*4882a593Smuzhiyun 						 * 8 bit lock.
560*4882a593Smuzhiyun 						 */
561*4882a593Smuzhiyun 						adll_shift_lock[if_id][pup]++;
562*4882a593Smuzhiyun 						/*
563*4882a593Smuzhiyun 						 * The search ended in Pass
564*4882a593Smuzhiyun 						 * we need Fail
565*4882a593Smuzhiyun 						 */
566*4882a593Smuzhiyun 						res0[if_id] =
567*4882a593Smuzhiyun 							(pbs_mode == PBS_RX_MODE) ?
568*4882a593Smuzhiyun 							((res0[if_id] & res_valid_mask) + 1) :
569*4882a593Smuzhiyun 							((res0[if_id] & res_valid_mask) - 1);
570*4882a593Smuzhiyun 						max_adll_per_pup[if_id][pup] =
571*4882a593Smuzhiyun 							(max_adll_per_pup[if_id]
572*4882a593Smuzhiyun 							 [pup] < res0[if_id]) ?
573*4882a593Smuzhiyun 							(u8)res0[if_id] :
574*4882a593Smuzhiyun 							max_adll_per_pup[if_id][pup];
575*4882a593Smuzhiyun 						min_adll_per_pup[if_id][pup] =
576*4882a593Smuzhiyun 							(res0[if_id] >
577*4882a593Smuzhiyun 							 min_adll_per_pup[if_id]
578*4882a593Smuzhiyun 							 [pup]) ?
579*4882a593Smuzhiyun 							min_adll_per_pup[if_id][pup] :
580*4882a593Smuzhiyun 							(u8)res0[if_id];
581*4882a593Smuzhiyun 						/*
582*4882a593Smuzhiyun 						 * vs the Rx we are searching for
583*4882a593Smuzhiyun 						 * the smallest value of DQ shift
584*4882a593Smuzhiyun 						 * so all Bus would fail
585*4882a593Smuzhiyun 						 */
586*4882a593Smuzhiyun 						adll_shift_val[if_id][pup] =
587*4882a593Smuzhiyun 							(pbs_mode == PBS_RX_MODE) ?
588*4882a593Smuzhiyun 							max_adll_per_pup[if_id][pup] :
589*4882a593Smuzhiyun 							min_adll_per_pup[if_id][pup];
590*4882a593Smuzhiyun 					}
591*4882a593Smuzhiyun 				}
592*4882a593Smuzhiyun 				/* 1 is lock */
593*4882a593Smuzhiyun 				adll_shift_lock[if_id][pup] =
594*4882a593Smuzhiyun 					(adll_shift_lock[if_id][pup] == 8) ?
595*4882a593Smuzhiyun 					1 : 0;
596*4882a593Smuzhiyun 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
597*4882a593Smuzhiyun 					(0x3 + effective_cs * 4) :
598*4882a593Smuzhiyun 					(0x1 + effective_cs * 4);
599*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
600*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
601*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
602*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr,
603*4882a593Smuzhiyun 					      adll_shift_val[if_id][pup]));
604*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(
605*4882a593Smuzhiyun 					DEBUG_LEVEL_INFO,
606*4882a593Smuzhiyun 					("adll_shift_lock[%x][%x] = %x\n",
607*4882a593Smuzhiyun 					 if_id, pup,
608*4882a593Smuzhiyun 					 adll_shift_lock[if_id][pup]));
609*4882a593Smuzhiyun 			}
610*4882a593Smuzhiyun 		}
611*4882a593Smuzhiyun 
612*4882a593Smuzhiyun 		/* End ADLL Shift for SBA */
613*4882a593Smuzhiyun 		/* Start the Per Bit Skew search */
614*4882a593Smuzhiyun 		/* The ADLL shift finished with a Pass */
615*4882a593Smuzhiyun 		search_edge = (pbs_mode == PBS_RX_MODE) ? EDGE_PF : EDGE_FP;
616*4882a593Smuzhiyun 		search_dir = (pbs_mode == PBS_RX_MODE) ?
617*4882a593Smuzhiyun 			HWS_LOW2HIGH : HWS_HIGH2LOW;
618*4882a593Smuzhiyun 		iterations = 0x1f;
619*4882a593Smuzhiyun 		/* - The initial value is different in Rx and Tx mode */
620*4882a593Smuzhiyun 		init_val = (pbs_mode == PBS_RX_MODE) ? 0 : iterations;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 		ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
623*4882a593Smuzhiyun 				     PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
624*4882a593Smuzhiyun 				     PARAM_NOT_CARE, RESULT_PER_BIT,
625*4882a593Smuzhiyun 				     HWS_CONTROL_ELEMENT_DQ_SKEW,
626*4882a593Smuzhiyun 				     search_dir, dir, tm->if_act_mask,
627*4882a593Smuzhiyun 				     init_val, iterations, pbs_pattern,
628*4882a593Smuzhiyun 				     search_edge, CS_SINGLE, cs_num,
629*4882a593Smuzhiyun 				     train_status);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
632*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
633*4882a593Smuzhiyun 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
634*4882a593Smuzhiyun 			     if_id++) {
635*4882a593Smuzhiyun 				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
636*4882a593Smuzhiyun 				for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
637*4882a593Smuzhiyun 					CHECK_STATUS(ddr3_tip_if_read
638*4882a593Smuzhiyun 						     (dev_num,
639*4882a593Smuzhiyun 						      ACCESS_TYPE_MULTICAST,
640*4882a593Smuzhiyun 						      PARAM_NOT_CARE,
641*4882a593Smuzhiyun 						      mask_results_dq_reg_map
642*4882a593Smuzhiyun 						      [bit +
643*4882a593Smuzhiyun 						       pup *
644*4882a593Smuzhiyun 						       BUS_WIDTH_IN_BITS],
645*4882a593Smuzhiyun 						      res0, MASK_ALL_BITS));
646*4882a593Smuzhiyun 					if (pup_state[if_id][pup] != 2) {
647*4882a593Smuzhiyun 						/*
648*4882a593Smuzhiyun 						 * if pup is not SBA continue
649*4882a593Smuzhiyun 						 * to next pup
650*4882a593Smuzhiyun 						 */
651*4882a593Smuzhiyun 						bit = BUS_WIDTH_IN_BITS;
652*4882a593Smuzhiyun 						continue;
653*4882a593Smuzhiyun 					}
654*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(
655*4882a593Smuzhiyun 						DEBUG_LEVEL_INFO,
656*4882a593Smuzhiyun 						("Per Bit Skew search, PF I/F %d, bit:%d, pup:%d res0 0x%x\n",
657*4882a593Smuzhiyun 						 if_id, bit, pup, res0[if_id]));
658*4882a593Smuzhiyun 					if ((res0[if_id] & 0x2000000) == 0) {
659*4882a593Smuzhiyun 						DEBUG_PBS_ENGINE
660*4882a593Smuzhiyun 							(DEBUG_LEVEL_INFO,
661*4882a593Smuzhiyun 							 ("SBA Fail\n"));
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 						max_pbs_per_pup[if_id][pup] =
664*4882a593Smuzhiyun 							0x1f;
665*4882a593Smuzhiyun 						result_all_bit[
666*4882a593Smuzhiyun 							bit + pup *
667*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS +
668*4882a593Smuzhiyun 							if_id * MAX_BUS_NUM *
669*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS] =
670*4882a593Smuzhiyun 							0x1f;
671*4882a593Smuzhiyun 					} else {
672*4882a593Smuzhiyun 						temp = (u8)(res0[if_id] &
673*4882a593Smuzhiyun 							    res_valid_mask);
674*4882a593Smuzhiyun 						max_pbs_per_pup[if_id][pup] =
675*4882a593Smuzhiyun 							(temp >
676*4882a593Smuzhiyun 							 max_pbs_per_pup[if_id]
677*4882a593Smuzhiyun 							 [pup]) ? temp :
678*4882a593Smuzhiyun 							max_pbs_per_pup
679*4882a593Smuzhiyun 							[if_id][pup];
680*4882a593Smuzhiyun 						min_pbs_per_pup[if_id][pup] =
681*4882a593Smuzhiyun 							(temp <
682*4882a593Smuzhiyun 							 min_pbs_per_pup[if_id]
683*4882a593Smuzhiyun 							 [pup]) ? temp :
684*4882a593Smuzhiyun 							min_pbs_per_pup
685*4882a593Smuzhiyun 							[if_id][pup];
686*4882a593Smuzhiyun 						result_all_bit[
687*4882a593Smuzhiyun 							bit + pup *
688*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS +
689*4882a593Smuzhiyun 							if_id * MAX_BUS_NUM *
690*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS] =
691*4882a593Smuzhiyun 							temp;
692*4882a593Smuzhiyun 						adll_shift_lock[if_id][pup] = 1;
693*4882a593Smuzhiyun 					}
694*4882a593Smuzhiyun 				}
695*4882a593Smuzhiyun 			}
696*4882a593Smuzhiyun 		}
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 		/* Check all Pup state */
699*4882a593Smuzhiyun 		all_lock = 1;
700*4882a593Smuzhiyun 		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
701*4882a593Smuzhiyun 			/*
702*4882a593Smuzhiyun 			 * DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
703*4882a593Smuzhiyun 			 * ("pup_state[%d][%d] = %d\n",if_id,pup,pup_state
704*4882a593Smuzhiyun 			 * [if_id][pup]));
705*4882a593Smuzhiyun 			*/
706*4882a593Smuzhiyun 		}
707*4882a593Smuzhiyun 	}
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	/* END OF SBA */
710*4882a593Smuzhiyun 	/* Norm */
711*4882a593Smuzhiyun 	for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
712*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->bus_act_mask, pup);
713*4882a593Smuzhiyun 		for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
714*4882a593Smuzhiyun 			for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
715*4882a593Smuzhiyun 			     if_id++) {
716*4882a593Smuzhiyun 				VALIDATE_ACTIVE(tm->if_act_mask, if_id);
717*4882a593Smuzhiyun 				/* if pup not lock continue to next pup */
718*4882a593Smuzhiyun 				if (adll_shift_lock[if_id][pup] != 1) {
719*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(
720*4882a593Smuzhiyun 						DEBUG_LEVEL_ERROR,
721*4882a593Smuzhiyun 						("PBS failed for IF #%d\n",
722*4882a593Smuzhiyun 						 if_id));
723*4882a593Smuzhiyun 					training_result[training_stage][if_id]
724*4882a593Smuzhiyun 						= TEST_FAILED;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 					result_mat[if_id][pup][bit] = 0;
727*4882a593Smuzhiyun 					max_pbs_per_pup[if_id][pup] = 0;
728*4882a593Smuzhiyun 					min_pbs_per_pup[if_id][pup] = 0;
729*4882a593Smuzhiyun 				} else {
730*4882a593Smuzhiyun 					training_result[
731*4882a593Smuzhiyun 						training_stage][if_id] =
732*4882a593Smuzhiyun 						(training_result[training_stage]
733*4882a593Smuzhiyun 						 [if_id] == TEST_FAILED) ?
734*4882a593Smuzhiyun 						TEST_FAILED : TEST_SUCCESS;
735*4882a593Smuzhiyun 					result_mat[if_id][pup][bit] =
736*4882a593Smuzhiyun 						result_all_bit[
737*4882a593Smuzhiyun 							bit + pup *
738*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS +
739*4882a593Smuzhiyun 							if_id * MAX_BUS_NUM *
740*4882a593Smuzhiyun 							BUS_WIDTH_IN_BITS] -
741*4882a593Smuzhiyun 						min_pbs_per_pup[if_id][pup];
742*4882a593Smuzhiyun 				}
743*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(
744*4882a593Smuzhiyun 					DEBUG_LEVEL_INFO,
745*4882a593Smuzhiyun 					("The abs min_pbs[%d][%d] = %d\n",
746*4882a593Smuzhiyun 					 if_id, pup,
747*4882a593Smuzhiyun 					 min_pbs_per_pup[if_id][pup]));
748*4882a593Smuzhiyun 			}
749*4882a593Smuzhiyun 		}
750*4882a593Smuzhiyun 	}
751*4882a593Smuzhiyun 
752*4882a593Smuzhiyun 	/* Clean all results */
753*4882a593Smuzhiyun 	ddr3_tip_clean_pbs_result(dev_num, pbs_mode);
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 	/* DQ PBS register update with the final result */
756*4882a593Smuzhiyun 	for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
757*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
758*4882a593Smuzhiyun 		for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
759*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->bus_act_mask, pup);
760*4882a593Smuzhiyun 
761*4882a593Smuzhiyun 			DEBUG_PBS_ENGINE(
762*4882a593Smuzhiyun 				DEBUG_LEVEL_INFO,
763*4882a593Smuzhiyun 				("Final Results: if_id %d, pup %d, Pup State: %d\n",
764*4882a593Smuzhiyun 				 if_id, pup, pup_state[if_id][pup]));
765*4882a593Smuzhiyun 			for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
766*4882a593Smuzhiyun 				if (dq_map_table == NULL) {
767*4882a593Smuzhiyun 					DEBUG_PBS_ENGINE(
768*4882a593Smuzhiyun 						DEBUG_LEVEL_ERROR,
769*4882a593Smuzhiyun 						("dq_map_table not initialized\n"));
770*4882a593Smuzhiyun 					return MV_FAIL;
771*4882a593Smuzhiyun 				}
772*4882a593Smuzhiyun 				pad_num = dq_map_table[
773*4882a593Smuzhiyun 					bit + pup * BUS_WIDTH_IN_BITS +
774*4882a593Smuzhiyun 					if_id * BUS_WIDTH_IN_BITS *
775*4882a593Smuzhiyun 					tm->num_of_bus_per_interface];
776*4882a593Smuzhiyun 				DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
777*4882a593Smuzhiyun 						 ("result_mat: %d ",
778*4882a593Smuzhiyun 						  result_mat[if_id][pup]
779*4882a593Smuzhiyun 						  [bit]));
780*4882a593Smuzhiyun 				reg_addr = (pbs_mode == PBS_RX_MODE) ?
781*4882a593Smuzhiyun 					(PBS_RX_PHY_REG + effective_cs * 0x10) :
782*4882a593Smuzhiyun 					(PBS_TX_PHY_REG + effective_cs * 0x10);
783*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
784*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
785*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
786*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr + pad_num,
787*4882a593Smuzhiyun 					      result_mat[if_id][pup][bit]));
788*4882a593Smuzhiyun 			}
789*4882a593Smuzhiyun 			pbsdelay_per_pup[pbs_mode][if_id][pup] =
790*4882a593Smuzhiyun 				(max_pbs_per_pup[if_id][pup] ==
791*4882a593Smuzhiyun 				 min_pbs_per_pup[if_id][pup]) ?
792*4882a593Smuzhiyun 				TYPICAL_PBS_VALUE :
793*4882a593Smuzhiyun 				((max_adll_per_pup[if_id][pup] -
794*4882a593Smuzhiyun 				  min_adll_per_pup[if_id][pup]) * adll_tap /
795*4882a593Smuzhiyun 				 (max_pbs_per_pup[if_id][pup] -
796*4882a593Smuzhiyun 				  min_pbs_per_pup[if_id][pup]));
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun 			/* RX results ready, write RX also */
799*4882a593Smuzhiyun 			if (pbs_mode == PBS_TX_MODE) {
800*4882a593Smuzhiyun 				/* Write TX results */
801*4882a593Smuzhiyun 				reg_addr = (0x14 + effective_cs * 0x10);
802*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
803*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
804*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
805*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr,
806*4882a593Smuzhiyun 					      (max_pbs_per_pup[if_id][pup] -
807*4882a593Smuzhiyun 					       min_pbs_per_pup[if_id][pup]) /
808*4882a593Smuzhiyun 					      2));
809*4882a593Smuzhiyun 				reg_addr = (0x15 + effective_cs * 0x10);
810*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
811*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
812*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
813*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr,
814*4882a593Smuzhiyun 					      (max_pbs_per_pup[if_id][pup] -
815*4882a593Smuzhiyun 					       min_pbs_per_pup[if_id][pup]) /
816*4882a593Smuzhiyun 					      2));
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 				/* Write previously stored RX results */
819*4882a593Smuzhiyun 				reg_addr = (0x54 + effective_cs * 0x10);
820*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
821*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
822*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
823*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr,
824*4882a593Smuzhiyun 					      result_mat_rx_dqs[if_id][pup]
825*4882a593Smuzhiyun 					      [effective_cs]));
826*4882a593Smuzhiyun 				reg_addr = (0x55 + effective_cs * 0x10);
827*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
828*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
829*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
830*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr,
831*4882a593Smuzhiyun 					      result_mat_rx_dqs[if_id][pup]
832*4882a593Smuzhiyun 					      [effective_cs]));
833*4882a593Smuzhiyun 			} else {
834*4882a593Smuzhiyun 				/*
835*4882a593Smuzhiyun 				 * RX results may affect RL results correctess,
836*4882a593Smuzhiyun 				 * so just store the results that will written
837*4882a593Smuzhiyun 				 * in TX stage
838*4882a593Smuzhiyun 				 */
839*4882a593Smuzhiyun 				result_mat_rx_dqs[if_id][pup][effective_cs] =
840*4882a593Smuzhiyun 					(max_pbs_per_pup[if_id][pup] -
841*4882a593Smuzhiyun 					 min_pbs_per_pup[if_id][pup]) / 2;
842*4882a593Smuzhiyun 			}
843*4882a593Smuzhiyun 			DEBUG_PBS_ENGINE(
844*4882a593Smuzhiyun 				DEBUG_LEVEL_INFO,
845*4882a593Smuzhiyun 				(", PBS tap=%d [psec] ==> skew observed = %d\n",
846*4882a593Smuzhiyun 				 pbsdelay_per_pup[pbs_mode][if_id][pup],
847*4882a593Smuzhiyun 				 ((max_pbs_per_pup[if_id][pup] -
848*4882a593Smuzhiyun 				   min_pbs_per_pup[if_id][pup]) *
849*4882a593Smuzhiyun 				  pbsdelay_per_pup[pbs_mode][if_id][pup])));
850*4882a593Smuzhiyun 		}
851*4882a593Smuzhiyun 	}
852*4882a593Smuzhiyun 
853*4882a593Smuzhiyun 	/* Write back to the phy the default values */
854*4882a593Smuzhiyun 	reg_addr = (pbs_mode == PBS_RX_MODE) ?
855*4882a593Smuzhiyun 		(READ_CENTRALIZATION_PHY_REG + effective_cs * 4) :
856*4882a593Smuzhiyun 		(WRITE_CENTRALIZATION_PHY_REG + effective_cs * 4);
857*4882a593Smuzhiyun 	write_adll_value(nominal_adll, reg_addr);
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
860*4882a593Smuzhiyun 		reg_addr = (pbs_mode == PBS_RX_MODE) ?
861*4882a593Smuzhiyun 			(0x5a + effective_cs * 0x10) :
862*4882a593Smuzhiyun 			(0x1a + effective_cs * 0x10);
863*4882a593Smuzhiyun 		CHECK_STATUS(ddr3_tip_bus_write
864*4882a593Smuzhiyun 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
865*4882a593Smuzhiyun 			      ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, reg_addr,
866*4882a593Smuzhiyun 			      0));
867*4882a593Smuzhiyun 
868*4882a593Smuzhiyun 		/* restore cs enable value */
869*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
870*4882a593Smuzhiyun 		CHECK_STATUS(ddr3_tip_if_write
871*4882a593Smuzhiyun 			     (dev_num, ACCESS_TYPE_UNICAST, if_id,
872*4882a593Smuzhiyun 			      CS_ENABLE_REG, cs_enable_reg_val[if_id],
873*4882a593Smuzhiyun 			      MASK_ALL_BITS));
874*4882a593Smuzhiyun 	}
875*4882a593Smuzhiyun 
876*4882a593Smuzhiyun 	/* exit test mode */
877*4882a593Smuzhiyun 	CHECK_STATUS(ddr3_tip_if_write
878*4882a593Smuzhiyun 		     (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
879*4882a593Smuzhiyun 		      ODPG_WRITE_READ_MODE_ENABLE_REG, 0xffff, MASK_ALL_BITS));
880*4882a593Smuzhiyun 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
881*4882a593Smuzhiyun 		/*
882*4882a593Smuzhiyun 		 * meaning that there is no VW exist at all (No lock at
883*4882a593Smuzhiyun 		 * the EBA ADLL shift at EBS)
884*4882a593Smuzhiyun 		 */
885*4882a593Smuzhiyun 		if (pup_state[if_id][pup] == 1)
886*4882a593Smuzhiyun 			return MV_FAIL;
887*4882a593Smuzhiyun 	}
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	return MV_OK;
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun /*
893*4882a593Smuzhiyun  * Name:     ddr3_tip_pbs_rx.
894*4882a593Smuzhiyun  * Desc:     PBS TX
895*4882a593Smuzhiyun  * Args:     TBD
896*4882a593Smuzhiyun  * Notes:
897*4882a593Smuzhiyun  * Returns:  OK if success, other error code if fail.
898*4882a593Smuzhiyun  */
ddr3_tip_pbs_rx(u32 uidev_num)899*4882a593Smuzhiyun int ddr3_tip_pbs_rx(u32 uidev_num)
900*4882a593Smuzhiyun {
901*4882a593Smuzhiyun 	return ddr3_tip_pbs(uidev_num, PBS_RX_MODE);
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun 
904*4882a593Smuzhiyun /*
905*4882a593Smuzhiyun  * Name:     ddr3_tip_pbs_tx.
906*4882a593Smuzhiyun  * Desc:     PBS TX
907*4882a593Smuzhiyun  * Args:     TBD
908*4882a593Smuzhiyun  * Notes:
909*4882a593Smuzhiyun  * Returns:  OK if success, other error code if fail.
910*4882a593Smuzhiyun  */
ddr3_tip_pbs_tx(u32 uidev_num)911*4882a593Smuzhiyun int ddr3_tip_pbs_tx(u32 uidev_num)
912*4882a593Smuzhiyun {
913*4882a593Smuzhiyun 	return ddr3_tip_pbs(uidev_num, PBS_TX_MODE);
914*4882a593Smuzhiyun }
915*4882a593Smuzhiyun 
916*4882a593Smuzhiyun #ifndef EXCLUDE_SWITCH_DEBUG
917*4882a593Smuzhiyun /*
918*4882a593Smuzhiyun  * Print PBS Result
919*4882a593Smuzhiyun  */
ddr3_tip_print_all_pbs_result(u32 dev_num)920*4882a593Smuzhiyun int ddr3_tip_print_all_pbs_result(u32 dev_num)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun 	u32 curr_cs;
923*4882a593Smuzhiyun 	u32 max_cs = hws_ddr3_tip_max_cs_get();
924*4882a593Smuzhiyun 
925*4882a593Smuzhiyun 	for (curr_cs = 0; curr_cs < max_cs; curr_cs++) {
926*4882a593Smuzhiyun 		ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_RX_MODE);
927*4882a593Smuzhiyun 		ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_TX_MODE);
928*4882a593Smuzhiyun 	}
929*4882a593Smuzhiyun 
930*4882a593Smuzhiyun 	return MV_OK;
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun 
933*4882a593Smuzhiyun /*
934*4882a593Smuzhiyun  * Print PBS Result
935*4882a593Smuzhiyun  */
ddr3_tip_print_pbs_result(u32 dev_num,u32 cs_num,enum pbs_dir pbs_mode)936*4882a593Smuzhiyun int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode)
937*4882a593Smuzhiyun {
938*4882a593Smuzhiyun 	u32 data_value = 0, bit = 0, if_id = 0, pup = 0;
939*4882a593Smuzhiyun 	u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
940*4882a593Smuzhiyun 		(PBS_RX_PHY_REG + cs_num * 0x10) :
941*4882a593Smuzhiyun 		(PBS_TX_PHY_REG + cs_num * 0x10);
942*4882a593Smuzhiyun 	struct hws_topology_map *tm = ddr3_get_topology_map();
943*4882a593Smuzhiyun 
944*4882a593Smuzhiyun 	printf("CS%d, %s ,PBS\n", cs_num,
945*4882a593Smuzhiyun 	       (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
946*4882a593Smuzhiyun 
947*4882a593Smuzhiyun 	for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
948*4882a593Smuzhiyun 		printf("%s, DQ", (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
949*4882a593Smuzhiyun 		for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
950*4882a593Smuzhiyun 			VALIDATE_ACTIVE(tm->if_act_mask, if_id);
951*4882a593Smuzhiyun 			printf("%d ,PBS,,, ", bit);
952*4882a593Smuzhiyun 			for (pup = 0; pup <= tm->num_of_bus_per_interface;
953*4882a593Smuzhiyun 			     pup++) {
954*4882a593Smuzhiyun 				VALIDATE_ACTIVE(tm->bus_act_mask, pup);
955*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_read
956*4882a593Smuzhiyun 					     (dev_num, if_id,
957*4882a593Smuzhiyun 					      ACCESS_TYPE_UNICAST, pup,
958*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr + bit,
959*4882a593Smuzhiyun 					      &data_value));
960*4882a593Smuzhiyun 				printf("%d , ", data_value);
961*4882a593Smuzhiyun 			}
962*4882a593Smuzhiyun 		}
963*4882a593Smuzhiyun 		printf("\n");
964*4882a593Smuzhiyun 	}
965*4882a593Smuzhiyun 	printf("\n");
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 	return MV_OK;
968*4882a593Smuzhiyun }
969*4882a593Smuzhiyun #endif
970*4882a593Smuzhiyun 
971*4882a593Smuzhiyun /*
972*4882a593Smuzhiyun  * Fixup PBS Result
973*4882a593Smuzhiyun  */
ddr3_tip_clean_pbs_result(u32 dev_num,enum pbs_dir pbs_mode)974*4882a593Smuzhiyun int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode)
975*4882a593Smuzhiyun {
976*4882a593Smuzhiyun 	u32 if_id, pup, bit;
977*4882a593Smuzhiyun 	u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
978*4882a593Smuzhiyun 		(PBS_RX_PHY_REG + effective_cs * 0x10) :
979*4882a593Smuzhiyun 		(PBS_TX_PHY_REG + effective_cs * 0x10);
980*4882a593Smuzhiyun 	struct hws_topology_map *tm = ddr3_get_topology_map();
981*4882a593Smuzhiyun 
982*4882a593Smuzhiyun 	for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
983*4882a593Smuzhiyun 		VALIDATE_ACTIVE(tm->if_act_mask, if_id);
984*4882a593Smuzhiyun 		for (pup = 0; pup <= tm->num_of_bus_per_interface; pup++) {
985*4882a593Smuzhiyun 			for (bit = 0; bit <= BUS_WIDTH_IN_BITS + 3; bit++) {
986*4882a593Smuzhiyun 				CHECK_STATUS(ddr3_tip_bus_write
987*4882a593Smuzhiyun 					     (dev_num, ACCESS_TYPE_UNICAST,
988*4882a593Smuzhiyun 					      if_id, ACCESS_TYPE_UNICAST, pup,
989*4882a593Smuzhiyun 					      DDR_PHY_DATA, reg_addr + bit, 0));
990*4882a593Smuzhiyun 			}
991*4882a593Smuzhiyun 		}
992*4882a593Smuzhiyun 	}
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	return MV_OK;
995*4882a593Smuzhiyun }
996