xref: /OK3568_Linux_fs/u-boot/drivers/ddr/marvell/a38x/ddr3_training_static.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) Marvell International Ltd. and its affiliates
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <spl.h>
9*4882a593Smuzhiyun #include <asm/io.h>
10*4882a593Smuzhiyun #include <asm/arch/cpu.h>
11*4882a593Smuzhiyun #include <asm/arch/soc.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include "ddr3_init.h"
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* 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