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