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