1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) Marvell International Ltd. and its affiliates
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <spl.h>
9*4882a593Smuzhiyun #include <asm/io.h>
10*4882a593Smuzhiyun #include <asm/arch/cpu.h>
11*4882a593Smuzhiyun #include <asm/arch/soc.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include "ddr3_init.h"
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /* Design Guidelines parameters */
16*4882a593Smuzhiyun u32 g_zpri_data = 123; /* controller data - P drive strength */
17*4882a593Smuzhiyun u32 g_znri_data = 123; /* controller data - N drive strength */
18*4882a593Smuzhiyun u32 g_zpri_ctrl = 74; /* controller C/A - P drive strength */
19*4882a593Smuzhiyun u32 g_znri_ctrl = 74; /* controller C/A - N drive strength */
20*4882a593Smuzhiyun u32 g_zpodt_data = 45; /* controller data - P ODT */
21*4882a593Smuzhiyun u32 g_znodt_data = 45; /* controller data - N ODT */
22*4882a593Smuzhiyun u32 g_zpodt_ctrl = 45; /* controller data - P ODT */
23*4882a593Smuzhiyun u32 g_znodt_ctrl = 45; /* controller data - N ODT */
24*4882a593Smuzhiyun u32 g_odt_config = 0x120012;
25*4882a593Smuzhiyun u32 g_rtt_nom = 0x44;
26*4882a593Smuzhiyun u32 g_dic = 0x2;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #ifdef STATIC_ALGO_SUPPORT
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define PARAM_NOT_CARE 0
31*4882a593Smuzhiyun #define MAX_STATIC_SEQ 48
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun u32 silicon_delay[HWS_MAX_DEVICE_NUM];
34*4882a593Smuzhiyun struct hws_tip_static_config_info static_config[HWS_MAX_DEVICE_NUM];
35*4882a593Smuzhiyun static reg_data *static_init_controller_config[HWS_MAX_DEVICE_NUM];
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* debug delay in write leveling */
38*4882a593Smuzhiyun int wl_debug_delay = 0;
39*4882a593Smuzhiyun /* pup register #3 for functional board */
40*4882a593Smuzhiyun int function_reg_value = 8;
41*4882a593Smuzhiyun u32 silicon;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun u32 read_ready_delay_phase_offset[] = { 4, 4, 4, 4, 6, 6, 6, 6 };
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun static struct cs_element chip_select_map[] = {
46*4882a593Smuzhiyun /* CS Value (single only) Num_CS */
47*4882a593Smuzhiyun {0, 0},
48*4882a593Smuzhiyun {0, 1},
49*4882a593Smuzhiyun {1, 1},
50*4882a593Smuzhiyun {0, 2},
51*4882a593Smuzhiyun {2, 1},
52*4882a593Smuzhiyun {0, 2},
53*4882a593Smuzhiyun {0, 2},
54*4882a593Smuzhiyun {0, 3},
55*4882a593Smuzhiyun {3, 1},
56*4882a593Smuzhiyun {0, 2},
57*4882a593Smuzhiyun {0, 2},
58*4882a593Smuzhiyun {0, 3},
59*4882a593Smuzhiyun {0, 2},
60*4882a593Smuzhiyun {0, 3},
61*4882a593Smuzhiyun {0, 3},
62*4882a593Smuzhiyun {0, 4}
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * Register static init controller DB
67*4882a593Smuzhiyun */
ddr3_tip_init_specific_reg_config(u32 dev_num,reg_data * reg_config_arr)68*4882a593Smuzhiyun int ddr3_tip_init_specific_reg_config(u32 dev_num, reg_data *reg_config_arr)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun static_init_controller_config[dev_num] = reg_config_arr;
71*4882a593Smuzhiyun return MV_OK;
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun /*
75*4882a593Smuzhiyun * Register static info DB
76*4882a593Smuzhiyun */
ddr3_tip_init_static_config_db(u32 dev_num,struct hws_tip_static_config_info * static_config_info)77*4882a593Smuzhiyun int ddr3_tip_init_static_config_db(
78*4882a593Smuzhiyun u32 dev_num, struct hws_tip_static_config_info *static_config_info)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun static_config[dev_num].board_trace_arr =
81*4882a593Smuzhiyun static_config_info->board_trace_arr;
82*4882a593Smuzhiyun static_config[dev_num].package_trace_arr =
83*4882a593Smuzhiyun static_config_info->package_trace_arr;
84*4882a593Smuzhiyun silicon_delay[dev_num] = static_config_info->silicon_delay;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun return MV_OK;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*
90*4882a593Smuzhiyun * Static round trip flow - Calculates the total round trip delay.
91*4882a593Smuzhiyun */
ddr3_tip_static_round_trip_arr_build(u32 dev_num,struct trip_delay_element * table_ptr,int is_wl,u32 * round_trip_delay_arr)92*4882a593Smuzhiyun int ddr3_tip_static_round_trip_arr_build(u32 dev_num,
93*4882a593Smuzhiyun struct trip_delay_element *table_ptr,
94*4882a593Smuzhiyun int is_wl, u32 *round_trip_delay_arr)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun u32 bus_index, global_bus;
97*4882a593Smuzhiyun u32 if_id;
98*4882a593Smuzhiyun u32 bus_per_interface;
99*4882a593Smuzhiyun int sign;
100*4882a593Smuzhiyun u32 temp;
101*4882a593Smuzhiyun u32 board_trace;
102*4882a593Smuzhiyun struct trip_delay_element *pkg_delay_ptr;
103*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /*
106*4882a593Smuzhiyun * In WL we calc the diff between Clock to DQs in RL we sum the round
107*4882a593Smuzhiyun * trip of Clock and DQs
108*4882a593Smuzhiyun */
109*4882a593Smuzhiyun sign = (is_wl) ? -1 : 1;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
114*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->if_act_mask, if_id);
115*4882a593Smuzhiyun for (bus_index = 0; bus_index < bus_per_interface;
116*4882a593Smuzhiyun bus_index++) {
117*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
118*4882a593Smuzhiyun global_bus = (if_id * bus_per_interface) + bus_index;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* calculate total trip delay (package and board) */
121*4882a593Smuzhiyun board_trace = (table_ptr[global_bus].dqs_delay * sign) +
122*4882a593Smuzhiyun table_ptr[global_bus].ck_delay;
123*4882a593Smuzhiyun temp = (board_trace * 163) / 1000;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* Convert the length to delay in psec units */
126*4882a593Smuzhiyun pkg_delay_ptr =
127*4882a593Smuzhiyun static_config[dev_num].package_trace_arr;
128*4882a593Smuzhiyun round_trip_delay_arr[global_bus] = temp +
129*4882a593Smuzhiyun (int)(pkg_delay_ptr[global_bus].dqs_delay *
130*4882a593Smuzhiyun sign) +
131*4882a593Smuzhiyun (int)pkg_delay_ptr[global_bus].ck_delay +
132*4882a593Smuzhiyun (int)((is_wl == 1) ? wl_debug_delay :
133*4882a593Smuzhiyun (int)silicon_delay[dev_num]);
134*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
135*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
136*4882a593Smuzhiyun ("Round Trip Build round_trip_delay_arr[0x%x]: 0x%x temp 0x%x\n",
137*4882a593Smuzhiyun global_bus, round_trip_delay_arr[global_bus],
138*4882a593Smuzhiyun temp));
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun return MV_OK;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /*
146*4882a593Smuzhiyun * Write leveling for static flow - calculating the round trip delay of the
147*4882a593Smuzhiyun * DQS signal.
148*4882a593Smuzhiyun */
ddr3_tip_write_leveling_static_config(u32 dev_num,u32 if_id,enum hws_ddr_freq frequency,u32 * round_trip_delay_arr)149*4882a593Smuzhiyun int ddr3_tip_write_leveling_static_config(u32 dev_num, u32 if_id,
150*4882a593Smuzhiyun enum hws_ddr_freq frequency,
151*4882a593Smuzhiyun u32 *round_trip_delay_arr)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun u32 bus_index; /* index to the bus loop */
154*4882a593Smuzhiyun u32 bus_start_index;
155*4882a593Smuzhiyun u32 bus_per_interface;
156*4882a593Smuzhiyun u32 phase = 0;
157*4882a593Smuzhiyun u32 adll = 0, adll_cen, adll_inv, adll_final;
158*4882a593Smuzhiyun u32 adll_period = MEGA / freq_val[frequency] / 64;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
161*4882a593Smuzhiyun ("ddr3_tip_write_leveling_static_config\n"));
162*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
163*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
164*4882a593Smuzhiyun ("dev_num 0x%x IF 0x%x freq %d (adll_period 0x%x)\n",
165*4882a593Smuzhiyun dev_num, if_id, frequency, adll_period));
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
168*4882a593Smuzhiyun bus_start_index = if_id * bus_per_interface;
169*4882a593Smuzhiyun for (bus_index = bus_start_index;
170*4882a593Smuzhiyun bus_index < (bus_start_index + bus_per_interface); bus_index++) {
171*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
172*4882a593Smuzhiyun phase = round_trip_delay_arr[bus_index] / (32 * adll_period);
173*4882a593Smuzhiyun adll = (round_trip_delay_arr[bus_index] -
174*4882a593Smuzhiyun (phase * 32 * adll_period)) / adll_period;
175*4882a593Smuzhiyun adll = (adll > 31) ? 31 : adll;
176*4882a593Smuzhiyun adll_cen = 16 + adll;
177*4882a593Smuzhiyun adll_inv = adll_cen / 32;
178*4882a593Smuzhiyun adll_final = adll_cen - (adll_inv * 32);
179*4882a593Smuzhiyun adll_final = (adll_final > 31) ? 31 : adll_final;
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
182*4882a593Smuzhiyun ("\t%d - phase 0x%x adll 0x%x\n",
183*4882a593Smuzhiyun bus_index, phase, adll));
184*4882a593Smuzhiyun /*
185*4882a593Smuzhiyun * Writing to all 4 phy of Interface number,
186*4882a593Smuzhiyun * bit 0 \96 4 \96 ADLL, bit 6-8 phase
187*4882a593Smuzhiyun */
188*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
189*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
190*4882a593Smuzhiyun (bus_index % 4), DDR_PHY_DATA,
191*4882a593Smuzhiyun PHY_WRITE_DELAY(cs),
192*4882a593Smuzhiyun ((phase << 6) + (adll & 0x1f)), 0x1df));
193*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
194*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
195*4882a593Smuzhiyun ACCESS_TYPE_UNICAST, (bus_index % 4),
196*4882a593Smuzhiyun DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG,
197*4882a593Smuzhiyun ((adll_inv & 0x1) << 5) + adll_final));
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun return MV_OK;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun /*
204*4882a593Smuzhiyun * Read leveling for static flow
205*4882a593Smuzhiyun */
ddr3_tip_read_leveling_static_config(u32 dev_num,u32 if_id,enum hws_ddr_freq frequency,u32 * total_round_trip_delay_arr)206*4882a593Smuzhiyun int ddr3_tip_read_leveling_static_config(u32 dev_num,
207*4882a593Smuzhiyun u32 if_id,
208*4882a593Smuzhiyun enum hws_ddr_freq frequency,
209*4882a593Smuzhiyun u32 *total_round_trip_delay_arr)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun u32 cs, data0, data1, data3 = 0;
212*4882a593Smuzhiyun u32 bus_index; /* index to the bus loop */
213*4882a593Smuzhiyun u32 bus_start_index;
214*4882a593Smuzhiyun u32 phase0, phase1, max_phase;
215*4882a593Smuzhiyun u32 adll0, adll1;
216*4882a593Smuzhiyun u32 cl_value;
217*4882a593Smuzhiyun u32 min_delay;
218*4882a593Smuzhiyun u32 sdr_period = MEGA / freq_val[frequency];
219*4882a593Smuzhiyun u32 ddr_period = MEGA / freq_val[frequency] / 2;
220*4882a593Smuzhiyun u32 adll_period = MEGA / freq_val[frequency] / 64;
221*4882a593Smuzhiyun enum hws_speed_bin speed_bin_index;
222*4882a593Smuzhiyun u32 rd_sample_dly[MAX_CS_NUM] = { 0 };
223*4882a593Smuzhiyun u32 rd_ready_del[MAX_CS_NUM] = { 0 };
224*4882a593Smuzhiyun u32 bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
225*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
228*4882a593Smuzhiyun ("ddr3_tip_read_leveling_static_config\n"));
229*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
230*4882a593Smuzhiyun ("dev_num 0x%x ifc 0x%x freq %d\n", dev_num,
231*4882a593Smuzhiyun if_id, frequency));
232*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
233*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
234*4882a593Smuzhiyun ("Sdr_period 0x%x Ddr_period 0x%x adll_period 0x%x\n",
235*4882a593Smuzhiyun sdr_period, ddr_period, adll_period));
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun if (tm->interface_params[first_active_if].memory_freq ==
238*4882a593Smuzhiyun frequency) {
239*4882a593Smuzhiyun cl_value = tm->interface_params[first_active_if].cas_l;
240*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
241*4882a593Smuzhiyun ("cl_value 0x%x\n", cl_value));
242*4882a593Smuzhiyun } else {
243*4882a593Smuzhiyun speed_bin_index = tm->interface_params[if_id].speed_bin_index;
244*4882a593Smuzhiyun cl_value = cas_latency_table[speed_bin_index].cl_val[frequency];
245*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
246*4882a593Smuzhiyun ("cl_value 0x%x speed_bin_index %d\n",
247*4882a593Smuzhiyun cl_value, speed_bin_index));
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun bus_start_index = if_id * bus_per_interface;
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun for (bus_index = bus_start_index;
253*4882a593Smuzhiyun bus_index < (bus_start_index + bus_per_interface);
254*4882a593Smuzhiyun bus_index += 2) {
255*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
256*4882a593Smuzhiyun cs = chip_select_map[
257*4882a593Smuzhiyun tm->interface_params[if_id].as_bus_params[
258*4882a593Smuzhiyun (bus_index % 4)].cs_bitmask].cs_num;
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* read sample delay calculation */
261*4882a593Smuzhiyun min_delay = (total_round_trip_delay_arr[bus_index] <
262*4882a593Smuzhiyun total_round_trip_delay_arr[bus_index + 1]) ?
263*4882a593Smuzhiyun total_round_trip_delay_arr[bus_index] :
264*4882a593Smuzhiyun total_round_trip_delay_arr[bus_index + 1];
265*4882a593Smuzhiyun /* round down */
266*4882a593Smuzhiyun rd_sample_dly[cs] = 2 * (min_delay / (sdr_period * 2));
267*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
268*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
269*4882a593Smuzhiyun ("\t%d - min_delay 0x%x cs 0x%x rd_sample_dly[cs] 0x%x\n",
270*4882a593Smuzhiyun bus_index, min_delay, cs, rd_sample_dly[cs]));
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /* phase calculation */
273*4882a593Smuzhiyun phase0 = (total_round_trip_delay_arr[bus_index] -
274*4882a593Smuzhiyun (sdr_period * rd_sample_dly[cs])) / (ddr_period);
275*4882a593Smuzhiyun phase1 = (total_round_trip_delay_arr[bus_index + 1] -
276*4882a593Smuzhiyun (sdr_period * rd_sample_dly[cs])) / (ddr_period);
277*4882a593Smuzhiyun max_phase = (phase0 > phase1) ? phase0 : phase1;
278*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
279*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
280*4882a593Smuzhiyun ("\tphase0 0x%x phase1 0x%x max_phase 0x%x\n",
281*4882a593Smuzhiyun phase0, phase1, max_phase));
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun /* ADLL calculation */
284*4882a593Smuzhiyun adll0 = (u32)((total_round_trip_delay_arr[bus_index] -
285*4882a593Smuzhiyun (sdr_period * rd_sample_dly[cs]) -
286*4882a593Smuzhiyun (ddr_period * phase0)) / adll_period);
287*4882a593Smuzhiyun adll0 = (adll0 > 31) ? 31 : adll0;
288*4882a593Smuzhiyun adll1 = (u32)((total_round_trip_delay_arr[bus_index + 1] -
289*4882a593Smuzhiyun (sdr_period * rd_sample_dly[cs]) -
290*4882a593Smuzhiyun (ddr_period * phase1)) / adll_period);
291*4882a593Smuzhiyun adll1 = (adll1 > 31) ? 31 : adll1;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun /* The Read delay close the Read FIFO */
294*4882a593Smuzhiyun rd_ready_del[cs] = rd_sample_dly[cs] +
295*4882a593Smuzhiyun read_ready_delay_phase_offset[max_phase];
296*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
297*4882a593Smuzhiyun DEBUG_LEVEL_TRACE,
298*4882a593Smuzhiyun ("\tadll0 0x%x adll1 0x%x rd_ready_del[cs] 0x%x\n",
299*4882a593Smuzhiyun adll0, adll1, rd_ready_del[cs]));
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun /*
302*4882a593Smuzhiyun * Write to the phy of Interface (bit 0 \96 4 \96 ADLL,
303*4882a593Smuzhiyun * bit 6-8 phase)
304*4882a593Smuzhiyun */
305*4882a593Smuzhiyun data0 = ((phase0 << 6) + (adll0 & 0x1f));
306*4882a593Smuzhiyun data1 = ((phase1 << 6) + (adll1 & 0x1f));
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
309*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
310*4882a593Smuzhiyun (bus_index % 4), DDR_PHY_DATA, PHY_READ_DELAY(cs),
311*4882a593Smuzhiyun data0, 0x1df));
312*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
313*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
314*4882a593Smuzhiyun ((bus_index + 1) % 4), DDR_PHY_DATA,
315*4882a593Smuzhiyun PHY_READ_DELAY(cs), data1, 0x1df));
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun for (bus_index = 0; bus_index < bus_per_interface; bus_index++) {
319*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
320*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
321*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
322*4882a593Smuzhiyun bus_index, DDR_PHY_DATA, 0x3, data3, 0x1f));
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_if_write
325*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
326*4882a593Smuzhiyun READ_DATA_SAMPLE_DELAY,
327*4882a593Smuzhiyun (rd_sample_dly[0] + cl_value) + (rd_sample_dly[1] << 8),
328*4882a593Smuzhiyun MASK_ALL_BITS));
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* Read_ready_del0 bit 0-4 , CS bits 8-12 */
331*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_if_write
332*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id,
333*4882a593Smuzhiyun READ_DATA_READY_DELAY,
334*4882a593Smuzhiyun rd_ready_del[0] + (rd_ready_del[1] << 8) + cl_value,
335*4882a593Smuzhiyun MASK_ALL_BITS));
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun return MV_OK;
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /*
341*4882a593Smuzhiyun * DDR3 Static flow
342*4882a593Smuzhiyun */
ddr3_tip_run_static_alg(u32 dev_num,enum hws_ddr_freq freq)343*4882a593Smuzhiyun int ddr3_tip_run_static_alg(u32 dev_num, enum hws_ddr_freq freq)
344*4882a593Smuzhiyun {
345*4882a593Smuzhiyun u32 if_id = 0;
346*4882a593Smuzhiyun struct trip_delay_element *table_ptr;
347*4882a593Smuzhiyun u32 wl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
348*4882a593Smuzhiyun u32 rl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
349*4882a593Smuzhiyun struct init_cntr_param init_cntr_prm;
350*4882a593Smuzhiyun int ret;
351*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
354*4882a593Smuzhiyun ("ddr3_tip_run_static_alg"));
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun init_cntr_prm.do_mrs_phy = 1;
357*4882a593Smuzhiyun init_cntr_prm.is_ctrl64_bit = 0;
358*4882a593Smuzhiyun init_cntr_prm.init_phy = 1;
359*4882a593Smuzhiyun ret = hws_ddr3_tip_init_controller(dev_num, &init_cntr_prm);
360*4882a593Smuzhiyun if (ret != MV_OK) {
361*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(
362*4882a593Smuzhiyun DEBUG_LEVEL_ERROR,
363*4882a593Smuzhiyun ("hws_ddr3_tip_init_controller failure\n"));
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun /* calculate the round trip delay for Write Leveling */
367*4882a593Smuzhiyun table_ptr = static_config[dev_num].board_trace_arr;
368*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
369*4882a593Smuzhiyun (dev_num, table_ptr, 1,
370*4882a593Smuzhiyun wl_total_round_trip_delay_arr));
371*4882a593Smuzhiyun /* calculate the round trip delay for Read Leveling */
372*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
373*4882a593Smuzhiyun (dev_num, table_ptr, 0,
374*4882a593Smuzhiyun rl_total_round_trip_delay_arr));
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
377*4882a593Smuzhiyun /* check if the interface is enabled */
378*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->if_act_mask, if_id);
379*4882a593Smuzhiyun /*
380*4882a593Smuzhiyun * Static frequency is defined according to init-frequency
381*4882a593Smuzhiyun * (not target)
382*4882a593Smuzhiyun */
383*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
384*4882a593Smuzhiyun ("Static IF %d freq %d\n",
385*4882a593Smuzhiyun if_id, freq));
386*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_write_leveling_static_config
387*4882a593Smuzhiyun (dev_num, if_id, freq,
388*4882a593Smuzhiyun wl_total_round_trip_delay_arr));
389*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_read_leveling_static_config
390*4882a593Smuzhiyun (dev_num, if_id, freq,
391*4882a593Smuzhiyun rl_total_round_trip_delay_arr));
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun return MV_OK;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /*
398*4882a593Smuzhiyun * Init controller for static flow
399*4882a593Smuzhiyun */
ddr3_tip_static_init_controller(u32 dev_num)400*4882a593Smuzhiyun int ddr3_tip_static_init_controller(u32 dev_num)
401*4882a593Smuzhiyun {
402*4882a593Smuzhiyun u32 index_cnt = 0;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
405*4882a593Smuzhiyun ("ddr3_tip_static_init_controller\n"));
406*4882a593Smuzhiyun while (static_init_controller_config[dev_num][index_cnt].reg_addr !=
407*4882a593Smuzhiyun 0) {
408*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_if_write
409*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
410*4882a593Smuzhiyun static_init_controller_config[dev_num][index_cnt].
411*4882a593Smuzhiyun reg_addr,
412*4882a593Smuzhiyun static_init_controller_config[dev_num][index_cnt].
413*4882a593Smuzhiyun reg_data,
414*4882a593Smuzhiyun static_init_controller_config[dev_num][index_cnt].
415*4882a593Smuzhiyun reg_mask));
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
418*4882a593Smuzhiyun ("Init_controller index_cnt %d\n",
419*4882a593Smuzhiyun index_cnt));
420*4882a593Smuzhiyun index_cnt++;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun return MV_OK;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
ddr3_tip_static_phy_init_controller(u32 dev_num)426*4882a593Smuzhiyun int ddr3_tip_static_phy_init_controller(u32 dev_num)
427*4882a593Smuzhiyun {
428*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
429*4882a593Smuzhiyun ("Phy Init Controller 2\n"));
430*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
431*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
432*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa4,
433*4882a593Smuzhiyun 0x3dfe));
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
436*4882a593Smuzhiyun ("Phy Init Controller 3\n"));
437*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
438*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
439*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa6,
440*4882a593Smuzhiyun 0xcb2));
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
443*4882a593Smuzhiyun ("Phy Init Controller 4\n"));
444*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
445*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
446*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa9,
447*4882a593Smuzhiyun 0));
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
450*4882a593Smuzhiyun ("Static Receiver Calibration\n"));
451*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
452*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
453*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xd0,
454*4882a593Smuzhiyun 0x1f));
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
457*4882a593Smuzhiyun ("Static V-REF Calibration\n"));
458*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
459*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
460*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa8,
461*4882a593Smuzhiyun 0x434));
462*4882a593Smuzhiyun
463*4882a593Smuzhiyun return MV_OK;
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun #endif
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun /*
468*4882a593Smuzhiyun * Configure phy (called by static init controller) for static flow
469*4882a593Smuzhiyun */
ddr3_tip_configure_phy(u32 dev_num)470*4882a593Smuzhiyun int ddr3_tip_configure_phy(u32 dev_num)
471*4882a593Smuzhiyun {
472*4882a593Smuzhiyun u32 if_id, phy_id;
473*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
476*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
477*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
478*4882a593Smuzhiyun PAD_ZRI_CALIB_PHY_REG,
479*4882a593Smuzhiyun ((0x7f & g_zpri_data) << 7 | (0x7f & g_znri_data))));
480*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
481*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
482*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
483*4882a593Smuzhiyun PAD_ZRI_CALIB_PHY_REG,
484*4882a593Smuzhiyun ((0x7f & g_zpri_ctrl) << 7 | (0x7f & g_znri_ctrl))));
485*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
486*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
487*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
488*4882a593Smuzhiyun PAD_ODT_CALIB_PHY_REG,
489*4882a593Smuzhiyun ((0x3f & g_zpodt_data) << 6 | (0x3f & g_znodt_data))));
490*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
491*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
492*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
493*4882a593Smuzhiyun PAD_ODT_CALIB_PHY_REG,
494*4882a593Smuzhiyun ((0x3f & g_zpodt_ctrl) << 6 | (0x3f & g_znodt_ctrl))));
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
497*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
498*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
499*4882a593Smuzhiyun PAD_PRE_DISABLE_PHY_REG, 0));
500*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
501*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
502*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
503*4882a593Smuzhiyun CMOS_CONFIG_PHY_REG, 0));
504*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
505*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
506*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
507*4882a593Smuzhiyun CMOS_CONFIG_PHY_REG, 0));
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
510*4882a593Smuzhiyun /* check if the interface is enabled */
511*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->if_act_mask, if_id);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun for (phy_id = 0;
514*4882a593Smuzhiyun phy_id < tm->num_of_bus_per_interface;
515*4882a593Smuzhiyun phy_id++) {
516*4882a593Smuzhiyun VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
517*4882a593Smuzhiyun /* Vref & clamp */
518*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
519*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST,
520*4882a593Smuzhiyun if_id, phy_id, DDR_PHY_DATA,
521*4882a593Smuzhiyun PAD_CONFIG_PHY_REG,
522*4882a593Smuzhiyun ((clamp_tbl[if_id] << 4) | vref),
523*4882a593Smuzhiyun ((0x7 << 4) | 0x7)));
524*4882a593Smuzhiyun /* clamp not relevant for control */
525*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_read_modify_write
526*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST,
527*4882a593Smuzhiyun if_id, phy_id, DDR_PHY_CONTROL,
528*4882a593Smuzhiyun PAD_CONFIG_PHY_REG, 0x4, 0x7));
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_bus_write
533*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
534*4882a593Smuzhiyun ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0x90,
535*4882a593Smuzhiyun 0x6002));
536*4882a593Smuzhiyun
537*4882a593Smuzhiyun return MV_OK;
538*4882a593Smuzhiyun }
539