1f1df9364SStefan Roese /*
2f1df9364SStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3f1df9364SStefan Roese *
4f1df9364SStefan Roese * SPDX-License-Identifier: GPL-2.0
5f1df9364SStefan Roese */
6f1df9364SStefan Roese
7f1df9364SStefan Roese #include <common.h>
8f1df9364SStefan Roese #include <spl.h>
9f1df9364SStefan Roese #include <asm/io.h>
10f1df9364SStefan Roese #include <asm/arch/cpu.h>
11f1df9364SStefan Roese #include <asm/arch/soc.h>
12f1df9364SStefan Roese
13f1df9364SStefan Roese #include "ddr3_init.h"
14f1df9364SStefan Roese
15f1df9364SStefan Roese #define GET_MAX_VALUE(x, y) \
16f1df9364SStefan Roese ((x) > (y)) ? (x) : (y)
17f1df9364SStefan Roese #define CEIL_DIVIDE(x, y) \
18f1df9364SStefan Roese ((x - (x / y) * y) == 0) ? ((x / y) - 1) : (x / y)
19f1df9364SStefan Roese
20f1df9364SStefan Roese #define TIME_2_CLOCK_CYCLES CEIL_DIVIDE
21f1df9364SStefan Roese
22f1df9364SStefan Roese #define GET_CS_FROM_MASK(mask) (cs_mask2_num[mask])
23f1df9364SStefan Roese #define CS_CBE_VALUE(cs_num) (cs_cbe_reg[cs_num])
24f1df9364SStefan Roese
25f1df9364SStefan Roese u32 window_mem_addr = 0;
26f1df9364SStefan Roese u32 phy_reg0_val = 0;
27f1df9364SStefan Roese u32 phy_reg1_val = 8;
28f1df9364SStefan Roese u32 phy_reg2_val = 0;
29f1df9364SStefan Roese u32 phy_reg3_val = 0xa;
30f1df9364SStefan Roese enum hws_ddr_freq init_freq = DDR_FREQ_667;
31f1df9364SStefan Roese enum hws_ddr_freq low_freq = DDR_FREQ_LOW_FREQ;
32f1df9364SStefan Roese enum hws_ddr_freq medium_freq;
33f1df9364SStefan Roese u32 debug_dunit = 0;
34f1df9364SStefan Roese u32 odt_additional = 1;
35f1df9364SStefan Roese u32 *dq_map_table = NULL;
36f1df9364SStefan Roese u32 odt_config = 1;
37f1df9364SStefan Roese
38f1df9364SStefan Roese #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || \
39f1df9364SStefan Roese defined(CONFIG_ARMADA_39X)
40f1df9364SStefan Roese u32 is_pll_before_init = 0, is_adll_calib_before_init = 0, is_dfs_in_init = 0;
41f1df9364SStefan Roese u32 dfs_low_freq = 130;
42f1df9364SStefan Roese #else
43f1df9364SStefan Roese u32 is_pll_before_init = 0, is_adll_calib_before_init = 1, is_dfs_in_init = 0;
44f1df9364SStefan Roese u32 dfs_low_freq = 100;
45f1df9364SStefan Roese #endif
46f1df9364SStefan Roese u32 g_rtt_nom_c_s0, g_rtt_nom_c_s1;
47f1df9364SStefan Roese u8 calibration_update_control; /* 2 external only, 1 is internal only */
48f1df9364SStefan Roese
49f1df9364SStefan Roese enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
50f1df9364SStefan Roese enum auto_tune_stage training_stage = INIT_CONTROLLER;
51f1df9364SStefan Roese u32 finger_test = 0, p_finger_start = 11, p_finger_end = 64,
52f1df9364SStefan Roese n_finger_start = 11, n_finger_end = 64,
53f1df9364SStefan Roese p_finger_step = 3, n_finger_step = 3;
54f1df9364SStefan Roese u32 clamp_tbl[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
55f1df9364SStefan Roese
56f1df9364SStefan Roese /* Initiate to 0xff, this variable is define by user in debug mode */
57f1df9364SStefan Roese u32 mode2_t = 0xff;
58f1df9364SStefan Roese u32 xsb_validate_type = 0;
59f1df9364SStefan Roese u32 xsb_validation_base_address = 0xf000;
60f1df9364SStefan Roese u32 first_active_if = 0;
61f1df9364SStefan Roese u32 dfs_low_phy1 = 0x1f;
62f1df9364SStefan Roese u32 multicast_id = 0;
63f1df9364SStefan Roese int use_broadcast = 0;
64f1df9364SStefan Roese struct hws_tip_freq_config_info *freq_info_table = NULL;
65f1df9364SStefan Roese u8 is_cbe_required = 0;
66f1df9364SStefan Roese u32 debug_mode = 0;
67f1df9364SStefan Roese u32 delay_enable = 0;
68f1df9364SStefan Roese int rl_mid_freq_wa = 0;
69f1df9364SStefan Roese
70f1df9364SStefan Roese u32 effective_cs = 0;
71f1df9364SStefan Roese
72f1df9364SStefan Roese u32 mask_tune_func = (SET_MEDIUM_FREQ_MASK_BIT |
73f1df9364SStefan Roese WRITE_LEVELING_MASK_BIT |
74f1df9364SStefan Roese LOAD_PATTERN_2_MASK_BIT |
75f1df9364SStefan Roese READ_LEVELING_MASK_BIT |
76f1df9364SStefan Roese SET_TARGET_FREQ_MASK_BIT | WRITE_LEVELING_TF_MASK_BIT |
77f1df9364SStefan Roese READ_LEVELING_TF_MASK_BIT |
78f1df9364SStefan Roese CENTRALIZATION_RX_MASK_BIT | CENTRALIZATION_TX_MASK_BIT);
79f1df9364SStefan Roese
ddr3_print_version(void)80f1df9364SStefan Roese void ddr3_print_version(void)
81f1df9364SStefan Roese {
82f1df9364SStefan Roese printf(DDR3_TIP_VERSION_STRING);
83f1df9364SStefan Roese }
84f1df9364SStefan Roese
85f1df9364SStefan Roese static int ddr3_tip_ddr3_training_main_flow(u32 dev_num);
86f1df9364SStefan Roese static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
87f1df9364SStefan Roese u32 if_id, u32 cl_value, u32 cwl_value);
88f1df9364SStefan Roese static int ddr3_tip_ddr3_auto_tune(u32 dev_num);
89f1df9364SStefan Roese static int is_bus_access_done(u32 dev_num, u32 if_id,
90f1df9364SStefan Roese u32 dunit_reg_adrr, u32 bit);
91f1df9364SStefan Roese #ifdef ODT_TEST_SUPPORT
92f1df9364SStefan Roese static int odt_test(u32 dev_num, enum hws_algo_type algo_type);
93f1df9364SStefan Roese #endif
94f1df9364SStefan Roese
95f1df9364SStefan Roese int adll_calibration(u32 dev_num, enum hws_access_type access_type,
96f1df9364SStefan Roese u32 if_id, enum hws_ddr_freq frequency);
97f1df9364SStefan Roese static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
98f1df9364SStefan Roese u32 if_id, enum hws_ddr_freq frequency);
99f1df9364SStefan Roese
100f1df9364SStefan Roese static struct page_element page_param[] = {
101f1df9364SStefan Roese /*
102f1df9364SStefan Roese * 8bits 16 bits
103f1df9364SStefan Roese * page-size(K) page-size(K) mask
104f1df9364SStefan Roese */
105f1df9364SStefan Roese { 1, 2, 2},
106f1df9364SStefan Roese /* 512M */
107f1df9364SStefan Roese { 1, 2, 3},
108f1df9364SStefan Roese /* 1G */
109f1df9364SStefan Roese { 1, 2, 0},
110f1df9364SStefan Roese /* 2G */
111f1df9364SStefan Roese { 1, 2, 4},
112f1df9364SStefan Roese /* 4G */
113f1df9364SStefan Roese { 2, 2, 5}
114f1df9364SStefan Roese /* 8G */
115f1df9364SStefan Roese };
116f1df9364SStefan Roese
117f1df9364SStefan Roese static u8 mem_size_config[MEM_SIZE_LAST] = {
118f1df9364SStefan Roese 0x2, /* 512Mbit */
119f1df9364SStefan Roese 0x3, /* 1Gbit */
120f1df9364SStefan Roese 0x0, /* 2Gbit */
121f1df9364SStefan Roese 0x4, /* 4Gbit */
122f1df9364SStefan Roese 0x5 /* 8Gbit */
123f1df9364SStefan Roese };
124f1df9364SStefan Roese
125f1df9364SStefan Roese static u8 cs_mask2_num[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
126f1df9364SStefan Roese
127f1df9364SStefan Roese static struct reg_data odpg_default_value[] = {
128f1df9364SStefan Roese {0x1034, 0x38000, MASK_ALL_BITS},
129f1df9364SStefan Roese {0x1038, 0x0, MASK_ALL_BITS},
130f1df9364SStefan Roese {0x10b0, 0x0, MASK_ALL_BITS},
131f1df9364SStefan Roese {0x10b8, 0x0, MASK_ALL_BITS},
132f1df9364SStefan Roese {0x10c0, 0x0, MASK_ALL_BITS},
133f1df9364SStefan Roese {0x10f0, 0x0, MASK_ALL_BITS},
134f1df9364SStefan Roese {0x10f4, 0x0, MASK_ALL_BITS},
135f1df9364SStefan Roese {0x10f8, 0xff, MASK_ALL_BITS},
136f1df9364SStefan Roese {0x10fc, 0xffff, MASK_ALL_BITS},
137f1df9364SStefan Roese {0x1130, 0x0, MASK_ALL_BITS},
138f1df9364SStefan Roese {0x1830, 0x2000000, MASK_ALL_BITS},
139f1df9364SStefan Roese {0x14d0, 0x0, MASK_ALL_BITS},
140f1df9364SStefan Roese {0x14d4, 0x0, MASK_ALL_BITS},
141f1df9364SStefan Roese {0x14d8, 0x0, MASK_ALL_BITS},
142f1df9364SStefan Roese {0x14dc, 0x0, MASK_ALL_BITS},
143f1df9364SStefan Roese {0x1454, 0x0, MASK_ALL_BITS},
144f1df9364SStefan Roese {0x1594, 0x0, MASK_ALL_BITS},
145f1df9364SStefan Roese {0x1598, 0x0, MASK_ALL_BITS},
146f1df9364SStefan Roese {0x159c, 0x0, MASK_ALL_BITS},
147f1df9364SStefan Roese {0x15a0, 0x0, MASK_ALL_BITS},
148f1df9364SStefan Roese {0x15a4, 0x0, MASK_ALL_BITS},
149f1df9364SStefan Roese {0x15a8, 0x0, MASK_ALL_BITS},
150f1df9364SStefan Roese {0x15ac, 0x0, MASK_ALL_BITS},
151f1df9364SStefan Roese {0x1604, 0x0, MASK_ALL_BITS},
152f1df9364SStefan Roese {0x1608, 0x0, MASK_ALL_BITS},
153f1df9364SStefan Roese {0x160c, 0x0, MASK_ALL_BITS},
154f1df9364SStefan Roese {0x1610, 0x0, MASK_ALL_BITS},
155f1df9364SStefan Roese {0x1614, 0x0, MASK_ALL_BITS},
156f1df9364SStefan Roese {0x1618, 0x0, MASK_ALL_BITS},
157f1df9364SStefan Roese {0x1624, 0x0, MASK_ALL_BITS},
158f1df9364SStefan Roese {0x1690, 0x0, MASK_ALL_BITS},
159f1df9364SStefan Roese {0x1694, 0x0, MASK_ALL_BITS},
160f1df9364SStefan Roese {0x1698, 0x0, MASK_ALL_BITS},
161f1df9364SStefan Roese {0x169c, 0x0, MASK_ALL_BITS},
162f1df9364SStefan Roese {0x14b8, 0x6f67, MASK_ALL_BITS},
163f1df9364SStefan Roese {0x1630, 0x0, MASK_ALL_BITS},
164f1df9364SStefan Roese {0x1634, 0x0, MASK_ALL_BITS},
165f1df9364SStefan Roese {0x1638, 0x0, MASK_ALL_BITS},
166f1df9364SStefan Roese {0x163c, 0x0, MASK_ALL_BITS},
167f1df9364SStefan Roese {0x16b0, 0x0, MASK_ALL_BITS},
168f1df9364SStefan Roese {0x16b4, 0x0, MASK_ALL_BITS},
169f1df9364SStefan Roese {0x16b8, 0x0, MASK_ALL_BITS},
170f1df9364SStefan Roese {0x16bc, 0x0, MASK_ALL_BITS},
171f1df9364SStefan Roese {0x16c0, 0x0, MASK_ALL_BITS},
172f1df9364SStefan Roese {0x16c4, 0x0, MASK_ALL_BITS},
173f1df9364SStefan Roese {0x16c8, 0x0, MASK_ALL_BITS},
174f1df9364SStefan Roese {0x16cc, 0x1, MASK_ALL_BITS},
175f1df9364SStefan Roese {0x16f0, 0x1, MASK_ALL_BITS},
176f1df9364SStefan Roese {0x16f4, 0x0, MASK_ALL_BITS},
177f1df9364SStefan Roese {0x16f8, 0x0, MASK_ALL_BITS},
178f1df9364SStefan Roese {0x16fc, 0x0, MASK_ALL_BITS}
179f1df9364SStefan Roese };
180f1df9364SStefan Roese
181f1df9364SStefan Roese static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
182f1df9364SStefan Roese u32 if_id, enum hws_access_type phy_access,
183f1df9364SStefan Roese u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
184f1df9364SStefan Roese u32 data_value, enum hws_operation oper_type);
185f1df9364SStefan Roese static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id);
186f1df9364SStefan Roese static int ddr3_tip_rank_control(u32 dev_num, u32 if_id);
187f1df9364SStefan Roese
188f1df9364SStefan Roese /*
189f1df9364SStefan Roese * Update global training parameters by data from user
190f1df9364SStefan Roese */
ddr3_tip_tune_training_params(u32 dev_num,struct tune_train_params * params)191f1df9364SStefan Roese int ddr3_tip_tune_training_params(u32 dev_num,
192f1df9364SStefan Roese struct tune_train_params *params)
193f1df9364SStefan Roese {
194f1df9364SStefan Roese if (params->ck_delay != -1)
195f1df9364SStefan Roese ck_delay = params->ck_delay;
196f1df9364SStefan Roese if (params->ck_delay_16 != -1)
197f1df9364SStefan Roese ck_delay_16 = params->ck_delay_16;
198f1df9364SStefan Roese if (params->phy_reg3_val != -1)
199f1df9364SStefan Roese phy_reg3_val = params->phy_reg3_val;
200f1df9364SStefan Roese
201f1df9364SStefan Roese return MV_OK;
202f1df9364SStefan Roese }
203f1df9364SStefan Roese
204f1df9364SStefan Roese /*
205f1df9364SStefan Roese * Configure CS
206f1df9364SStefan Roese */
ddr3_tip_configure_cs(u32 dev_num,u32 if_id,u32 cs_num,u32 enable)207f1df9364SStefan Roese int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable)
208f1df9364SStefan Roese {
209f1df9364SStefan Roese u32 data, addr_hi, data_high;
210f1df9364SStefan Roese u32 mem_index;
211f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
212f1df9364SStefan Roese
213f1df9364SStefan Roese if (enable == 1) {
214f1df9364SStefan Roese data = (tm->interface_params[if_id].bus_width ==
215f1df9364SStefan Roese BUS_WIDTH_8) ? 0 : 1;
216f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
217f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
218f1df9364SStefan Roese SDRAM_ACCESS_CONTROL_REG, (data << (cs_num * 4)),
219f1df9364SStefan Roese 0x3 << (cs_num * 4)));
220f1df9364SStefan Roese mem_index = tm->interface_params[if_id].memory_size;
221f1df9364SStefan Roese
222f1df9364SStefan Roese addr_hi = mem_size_config[mem_index] & 0x3;
223f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
224f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
225f1df9364SStefan Roese SDRAM_ACCESS_CONTROL_REG,
226f1df9364SStefan Roese (addr_hi << (2 + cs_num * 4)),
227f1df9364SStefan Roese 0x3 << (2 + cs_num * 4)));
228f1df9364SStefan Roese
229f1df9364SStefan Roese data_high = (mem_size_config[mem_index] & 0x4) >> 2;
230f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
231f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
232f1df9364SStefan Roese SDRAM_ACCESS_CONTROL_REG,
233f1df9364SStefan Roese data_high << (20 + cs_num), 1 << (20 + cs_num)));
234f1df9364SStefan Roese
235f1df9364SStefan Roese /* Enable Address Select Mode */
236f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
237f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
238f1df9364SStefan Roese SDRAM_ACCESS_CONTROL_REG, 1 << (16 + cs_num),
239f1df9364SStefan Roese 1 << (16 + cs_num)));
240f1df9364SStefan Roese }
241f1df9364SStefan Roese switch (cs_num) {
242f1df9364SStefan Roese case 0:
243f1df9364SStefan Roese case 1:
244f1df9364SStefan Roese case 2:
245f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
246f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
247f1df9364SStefan Roese DDR_CONTROL_LOW_REG, (enable << (cs_num + 11)),
248f1df9364SStefan Roese 1 << (cs_num + 11)));
249f1df9364SStefan Roese break;
250f1df9364SStefan Roese case 3:
251f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
252f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
253f1df9364SStefan Roese DDR_CONTROL_LOW_REG, (enable << 15), 1 << 15));
254f1df9364SStefan Roese break;
255f1df9364SStefan Roese }
256f1df9364SStefan Roese
257f1df9364SStefan Roese return MV_OK;
258f1df9364SStefan Roese }
259f1df9364SStefan Roese
260f1df9364SStefan Roese /*
261f1df9364SStefan Roese * Calculate number of CS
262f1df9364SStefan Roese */
calc_cs_num(u32 dev_num,u32 if_id,u32 * cs_num)263f1df9364SStefan Roese static int calc_cs_num(u32 dev_num, u32 if_id, u32 *cs_num)
264f1df9364SStefan Roese {
265f1df9364SStefan Roese u32 cs;
266f1df9364SStefan Roese u32 bus_cnt;
267f1df9364SStefan Roese u32 cs_count;
268f1df9364SStefan Roese u32 cs_bitmask;
269f1df9364SStefan Roese u32 curr_cs_num = 0;
270f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
271f1df9364SStefan Roese
272f1df9364SStefan Roese for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
273f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
274f1df9364SStefan Roese cs_count = 0;
275f1df9364SStefan Roese cs_bitmask = tm->interface_params[if_id].
276f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask;
277f1df9364SStefan Roese for (cs = 0; cs < MAX_CS_NUM; cs++) {
278f1df9364SStefan Roese if ((cs_bitmask >> cs) & 1)
279f1df9364SStefan Roese cs_count++;
280f1df9364SStefan Roese }
281f1df9364SStefan Roese
282f1df9364SStefan Roese if (curr_cs_num == 0) {
283f1df9364SStefan Roese curr_cs_num = cs_count;
284f1df9364SStefan Roese } else if (cs_count != curr_cs_num) {
285f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
286f1df9364SStefan Roese ("CS number is different per bus (IF %d BUS %d cs_num %d curr_cs_num %d)\n",
287f1df9364SStefan Roese if_id, bus_cnt, cs_count,
288f1df9364SStefan Roese curr_cs_num));
289f1df9364SStefan Roese return MV_NOT_SUPPORTED;
290f1df9364SStefan Roese }
291f1df9364SStefan Roese }
292f1df9364SStefan Roese *cs_num = curr_cs_num;
293f1df9364SStefan Roese
294f1df9364SStefan Roese return MV_OK;
295f1df9364SStefan Roese }
296f1df9364SStefan Roese
297f1df9364SStefan Roese /*
298f1df9364SStefan Roese * Init Controller Flow
299f1df9364SStefan Roese */
hws_ddr3_tip_init_controller(u32 dev_num,struct init_cntr_param * init_cntr_prm)300f1df9364SStefan Roese int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_prm)
301f1df9364SStefan Roese {
302f1df9364SStefan Roese u32 if_id;
303f1df9364SStefan Roese u32 cs_num;
304f1df9364SStefan Roese u32 t_refi = 0, t_hclk = 0, t_ckclk = 0, t_faw = 0, t_pd = 0,
305f1df9364SStefan Roese t_wr = 0, t2t = 0, txpdll = 0;
306f1df9364SStefan Roese u32 data_value = 0, bus_width = 0, page_size = 0, cs_cnt = 0,
307f1df9364SStefan Roese mem_mask = 0, bus_index = 0;
308f1df9364SStefan Roese enum hws_speed_bin speed_bin_index = SPEED_BIN_DDR_2133N;
309f1df9364SStefan Roese enum hws_mem_size memory_size = MEM_2G;
310f1df9364SStefan Roese enum hws_ddr_freq freq = init_freq;
311*90bcc3d3SMarek Behún enum hws_timing timing;
312f1df9364SStefan Roese u32 cs_mask = 0;
313f1df9364SStefan Roese u32 cl_value = 0, cwl_val = 0;
314f1df9364SStefan Roese u32 refresh_interval_cnt = 0, bus_cnt = 0, adll_tap = 0;
315f1df9364SStefan Roese enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
316f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM];
317f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
318f1df9364SStefan Roese
319f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
320f1df9364SStefan Roese ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n",
321f1df9364SStefan Roese init_cntr_prm->do_mrs_phy,
322f1df9364SStefan Roese init_cntr_prm->is_ctrl64_bit));
323f1df9364SStefan Roese
324f1df9364SStefan Roese if (init_cntr_prm->init_phy == 1) {
325f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_configure_phy(dev_num));
326f1df9364SStefan Roese }
327f1df9364SStefan Roese
328f1df9364SStefan Roese if (generic_init_controller == 1) {
329f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
330f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
331f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
332f1df9364SStefan Roese ("active IF %d\n", if_id));
333f1df9364SStefan Roese mem_mask = 0;
334f1df9364SStefan Roese for (bus_index = 0;
335f1df9364SStefan Roese bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
336f1df9364SStefan Roese bus_index++) {
337f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
338f1df9364SStefan Roese mem_mask |=
339f1df9364SStefan Roese tm->interface_params[if_id].
340f1df9364SStefan Roese as_bus_params[bus_index].mirror_enable_bitmask;
341f1df9364SStefan Roese }
342f1df9364SStefan Roese
343f1df9364SStefan Roese if (mem_mask != 0) {
344f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
345f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST,
346f1df9364SStefan Roese if_id, CS_ENABLE_REG, 0,
347f1df9364SStefan Roese 0x8));
348f1df9364SStefan Roese }
349f1df9364SStefan Roese
350f1df9364SStefan Roese memory_size =
351f1df9364SStefan Roese tm->interface_params[if_id].
352f1df9364SStefan Roese memory_size;
353f1df9364SStefan Roese speed_bin_index =
354f1df9364SStefan Roese tm->interface_params[if_id].
355f1df9364SStefan Roese speed_bin_index;
356f1df9364SStefan Roese freq = init_freq;
357f1df9364SStefan Roese t_refi =
358f1df9364SStefan Roese (tm->interface_params[if_id].
359f1df9364SStefan Roese interface_temp ==
360f1df9364SStefan Roese HWS_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW;
361f1df9364SStefan Roese t_refi *= 1000; /* psec */
362f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
363f1df9364SStefan Roese ("memy_size %d speed_bin_ind %d freq %d t_refi %d\n",
364f1df9364SStefan Roese memory_size, speed_bin_index, freq,
365f1df9364SStefan Roese t_refi));
366f1df9364SStefan Roese /* HCLK & CK CLK in 2:1[ps] */
367f1df9364SStefan Roese /* t_ckclk is external clock */
368f1df9364SStefan Roese t_ckclk = (MEGA / freq_val[freq]);
369f1df9364SStefan Roese /* t_hclk is internal clock */
370f1df9364SStefan Roese t_hclk = 2 * t_ckclk;
371f1df9364SStefan Roese refresh_interval_cnt = t_refi / t_hclk; /* no units */
372f1df9364SStefan Roese bus_width =
373f1df9364SStefan Roese (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)
374f1df9364SStefan Roese == 1) ? (16) : (32);
375f1df9364SStefan Roese
376f1df9364SStefan Roese if (init_cntr_prm->is_ctrl64_bit)
377f1df9364SStefan Roese bus_width = 64;
378f1df9364SStefan Roese
379f1df9364SStefan Roese data_value =
380f1df9364SStefan Roese (refresh_interval_cnt | 0x4000 |
381f1df9364SStefan Roese ((bus_width ==
382f1df9364SStefan Roese 32) ? 0x8000 : 0) | 0x1000000) & ~(1 << 26);
383f1df9364SStefan Roese
384f1df9364SStefan Roese /* Interface Bus Width */
385f1df9364SStefan Roese /* SRMode */
386f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
387f1df9364SStefan Roese (dev_num, access_type, if_id,
388f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, data_value,
389f1df9364SStefan Roese 0x100ffff));
390f1df9364SStefan Roese
391f1df9364SStefan Roese /* Interleave first command pre-charge enable (TBD) */
392f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
393f1df9364SStefan Roese (dev_num, access_type, if_id,
394f1df9364SStefan Roese SDRAM_OPEN_PAGE_CONTROL_REG, (1 << 10),
395f1df9364SStefan Roese (1 << 10)));
396f1df9364SStefan Roese
397f1df9364SStefan Roese /* PHY configuration */
398f1df9364SStefan Roese /*
399f1df9364SStefan Roese * Postamble Length = 1.5cc, Addresscntl to clk skew
400f1df9364SStefan Roese * \BD, Preamble length normal, parralal ADLL enable
401f1df9364SStefan Roese */
402f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
403f1df9364SStefan Roese (dev_num, access_type, if_id,
404f1df9364SStefan Roese DRAM_PHY_CONFIGURATION, 0x28, 0x3e));
405f1df9364SStefan Roese if (init_cntr_prm->is_ctrl64_bit) {
406f1df9364SStefan Roese /* positive edge */
407f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
408f1df9364SStefan Roese (dev_num, access_type, if_id,
409f1df9364SStefan Roese DRAM_PHY_CONFIGURATION, 0x0,
410f1df9364SStefan Roese 0xff80));
411f1df9364SStefan Roese }
412f1df9364SStefan Roese
413f1df9364SStefan Roese /* calibration block disable */
414f1df9364SStefan Roese /* Xbar Read buffer select (for Internal access) */
415f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
416f1df9364SStefan Roese (dev_num, access_type, if_id,
417f1df9364SStefan Roese CALIB_MACHINE_CTRL_REG, 0x1200c,
418f1df9364SStefan Roese 0x7dffe01c));
419f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
420f1df9364SStefan Roese (dev_num, access_type, if_id,
421f1df9364SStefan Roese CALIB_MACHINE_CTRL_REG,
422f1df9364SStefan Roese calibration_update_control << 3, 0x3 << 3));
423f1df9364SStefan Roese
424f1df9364SStefan Roese /* Pad calibration control - enable */
425f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
426f1df9364SStefan Roese (dev_num, access_type, if_id,
427f1df9364SStefan Roese CALIB_MACHINE_CTRL_REG, 0x1, 0x1));
428f1df9364SStefan Roese
429f1df9364SStefan Roese cs_mask = 0;
430f1df9364SStefan Roese data_value = 0x7;
431f1df9364SStefan Roese /*
432f1df9364SStefan Roese * Address ctrl \96 Part of the Generic code
433f1df9364SStefan Roese * The next configuration is done:
434f1df9364SStefan Roese * 1) Memory Size
435f1df9364SStefan Roese * 2) Bus_width
436f1df9364SStefan Roese * 3) CS#
437f1df9364SStefan Roese * 4) Page Number
438f1df9364SStefan Roese * 5) t_faw
439f1df9364SStefan Roese * Per Dunit get from the Map_topology the parameters:
440f1df9364SStefan Roese * Bus_width
441f1df9364SStefan Roese * t_faw is per Dunit not per CS
442f1df9364SStefan Roese */
443f1df9364SStefan Roese page_size =
444f1df9364SStefan Roese (tm->interface_params[if_id].
445f1df9364SStefan Roese bus_width ==
446f1df9364SStefan Roese BUS_WIDTH_8) ? page_param[memory_size].
447f1df9364SStefan Roese page_size_8bit : page_param[memory_size].
448f1df9364SStefan Roese page_size_16bit;
449f1df9364SStefan Roese
450f1df9364SStefan Roese t_faw =
451f1df9364SStefan Roese (page_size == 1) ? speed_bin_table(speed_bin_index,
452f1df9364SStefan Roese SPEED_BIN_TFAW1K)
453f1df9364SStefan Roese : speed_bin_table(speed_bin_index,
454f1df9364SStefan Roese SPEED_BIN_TFAW2K);
455f1df9364SStefan Roese
456f1df9364SStefan Roese data_value = TIME_2_CLOCK_CYCLES(t_faw, t_ckclk);
457f1df9364SStefan Roese data_value = data_value << 24;
458f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
459f1df9364SStefan Roese (dev_num, access_type, if_id,
460f1df9364SStefan Roese SDRAM_ACCESS_CONTROL_REG, data_value,
461f1df9364SStefan Roese 0x7f000000));
462f1df9364SStefan Roese
463f1df9364SStefan Roese data_value =
464f1df9364SStefan Roese (tm->interface_params[if_id].
465f1df9364SStefan Roese bus_width == BUS_WIDTH_8) ? 0 : 1;
466f1df9364SStefan Roese
467f1df9364SStefan Roese /* create merge cs mask for all cs available in dunit */
468f1df9364SStefan Roese for (bus_cnt = 0;
469f1df9364SStefan Roese bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
470f1df9364SStefan Roese bus_cnt++) {
471f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
472f1df9364SStefan Roese cs_mask |=
473f1df9364SStefan Roese tm->interface_params[if_id].
474f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask;
475f1df9364SStefan Roese }
476f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
477f1df9364SStefan Roese ("Init_controller IF %d cs_mask %d\n",
478f1df9364SStefan Roese if_id, cs_mask));
479f1df9364SStefan Roese /*
480f1df9364SStefan Roese * Configure the next upon the Map Topology \96 If the
481f1df9364SStefan Roese * Dunit is CS0 Configure CS0 if it is multi CS
482f1df9364SStefan Roese * configure them both: The Bust_width it\92s the
483f1df9364SStefan Roese * Memory Bus width \96 x8 or x16
484f1df9364SStefan Roese */
485f1df9364SStefan Roese for (cs_cnt = 0; cs_cnt < NUM_OF_CS; cs_cnt++) {
486f1df9364SStefan Roese ddr3_tip_configure_cs(dev_num, if_id, cs_cnt,
487f1df9364SStefan Roese ((cs_mask & (1 << cs_cnt)) ? 1
488f1df9364SStefan Roese : 0));
489f1df9364SStefan Roese }
490f1df9364SStefan Roese
491f1df9364SStefan Roese if (init_cntr_prm->do_mrs_phy) {
492f1df9364SStefan Roese /*
493f1df9364SStefan Roese * MR0 \96 Part of the Generic code
494f1df9364SStefan Roese * The next configuration is done:
495f1df9364SStefan Roese * 1) Burst Length
496f1df9364SStefan Roese * 2) CAS Latency
497f1df9364SStefan Roese * get for each dunit what is it Speed_bin &
498f1df9364SStefan Roese * Target Frequency. From those both parameters
499f1df9364SStefan Roese * get the appropriate Cas_l from the CL table
500f1df9364SStefan Roese */
501f1df9364SStefan Roese cl_value =
502f1df9364SStefan Roese tm->interface_params[if_id].
503f1df9364SStefan Roese cas_l;
504f1df9364SStefan Roese cwl_val =
505f1df9364SStefan Roese tm->interface_params[if_id].
506f1df9364SStefan Roese cas_wl;
507f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
508f1df9364SStefan Roese ("cl_value 0x%x cwl_val 0x%x\n",
509f1df9364SStefan Roese cl_value, cwl_val));
510f1df9364SStefan Roese
511f1df9364SStefan Roese data_value =
512f1df9364SStefan Roese ((cl_mask_table[cl_value] & 0x1) << 2) |
513f1df9364SStefan Roese ((cl_mask_table[cl_value] & 0xe) << 3);
514f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
515f1df9364SStefan Roese (dev_num, access_type, if_id,
516f1df9364SStefan Roese MR0_REG, data_value,
517f1df9364SStefan Roese (0x7 << 4) | (1 << 2)));
518f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
519f1df9364SStefan Roese (dev_num, access_type, if_id,
520f1df9364SStefan Roese MR0_REG, twr_mask_table[t_wr + 1],
521f1df9364SStefan Roese 0xe00));
522f1df9364SStefan Roese
523f1df9364SStefan Roese /*
524f1df9364SStefan Roese * MR1: Set RTT and DIC Design GL values
525f1df9364SStefan Roese * configured by user
526f1df9364SStefan Roese */
527f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
528f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST,
529f1df9364SStefan Roese PARAM_NOT_CARE, MR1_REG,
530f1df9364SStefan Roese g_dic | g_rtt_nom, 0x266));
531f1df9364SStefan Roese
532f1df9364SStefan Roese /* MR2 - Part of the Generic code */
533f1df9364SStefan Roese /*
534f1df9364SStefan Roese * The next configuration is done:
535f1df9364SStefan Roese * 1) SRT
536f1df9364SStefan Roese * 2) CAS Write Latency
537f1df9364SStefan Roese */
538f1df9364SStefan Roese data_value = (cwl_mask_table[cwl_val] << 3);
539f1df9364SStefan Roese data_value |=
540f1df9364SStefan Roese ((tm->interface_params[if_id].
541f1df9364SStefan Roese interface_temp ==
542f1df9364SStefan Roese HWS_TEMP_HIGH) ? (1 << 7) : 0);
543f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
544f1df9364SStefan Roese (dev_num, access_type, if_id,
545f1df9364SStefan Roese MR2_REG, data_value,
546f1df9364SStefan Roese (0x7 << 3) | (0x1 << 7) | (0x3 <<
547f1df9364SStefan Roese 9)));
548f1df9364SStefan Roese }
549f1df9364SStefan Roese
550f1df9364SStefan Roese ddr3_tip_write_odt(dev_num, access_type, if_id,
551f1df9364SStefan Roese cl_value, cwl_val);
552f1df9364SStefan Roese ddr3_tip_set_timing(dev_num, access_type, if_id, freq);
553f1df9364SStefan Roese
554f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
555f1df9364SStefan Roese (dev_num, access_type, if_id,
556f1df9364SStefan Roese DUNIT_CONTROL_HIGH_REG, 0x177,
557f1df9364SStefan Roese 0x1000177));
558f1df9364SStefan Roese
559f1df9364SStefan Roese if (init_cntr_prm->is_ctrl64_bit) {
560f1df9364SStefan Roese /* disable 0.25 cc delay */
561f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
562f1df9364SStefan Roese (dev_num, access_type, if_id,
563f1df9364SStefan Roese DUNIT_CONTROL_HIGH_REG, 0x0,
564f1df9364SStefan Roese 0x800));
565f1df9364SStefan Roese }
566f1df9364SStefan Roese
567f1df9364SStefan Roese /* reset bit 7 */
568f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
569f1df9364SStefan Roese (dev_num, access_type, if_id,
570f1df9364SStefan Roese DUNIT_CONTROL_HIGH_REG,
571f1df9364SStefan Roese (init_cntr_prm->msys_init << 7), (1 << 7)));
572f1df9364SStefan Roese
573*90bcc3d3SMarek Behún timing = tm->interface_params[if_id].timing;
574*90bcc3d3SMarek Behún
575f1df9364SStefan Roese if (mode2_t != 0xff) {
576f1df9364SStefan Roese t2t = mode2_t;
577*90bcc3d3SMarek Behún } else if (timing != HWS_TIM_DEFAULT) {
578*90bcc3d3SMarek Behún /* Board topology map is forcing timing */
579*90bcc3d3SMarek Behún t2t = (timing == HWS_TIM_2T) ? 1 : 0;
580f1df9364SStefan Roese } else {
581f1df9364SStefan Roese /* calculate number of CS (per interface) */
582f1df9364SStefan Roese CHECK_STATUS(calc_cs_num
583f1df9364SStefan Roese (dev_num, if_id, &cs_num));
584f1df9364SStefan Roese t2t = (cs_num == 1) ? 0 : 1;
585f1df9364SStefan Roese }
586f1df9364SStefan Roese
587f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
588f1df9364SStefan Roese (dev_num, access_type, if_id,
589f1df9364SStefan Roese DDR_CONTROL_LOW_REG, t2t << 3,
590f1df9364SStefan Roese 0x3 << 3));
591f1df9364SStefan Roese /* move the block to ddr3_tip_set_timing - start */
592f1df9364SStefan Roese t_pd = GET_MAX_VALUE(t_ckclk * 3,
593f1df9364SStefan Roese speed_bin_table(speed_bin_index,
594f1df9364SStefan Roese SPEED_BIN_TPD));
595f1df9364SStefan Roese t_pd = TIME_2_CLOCK_CYCLES(t_pd, t_ckclk);
596f1df9364SStefan Roese txpdll = GET_MAX_VALUE(t_ckclk * 10, 24);
597f1df9364SStefan Roese txpdll = CEIL_DIVIDE((txpdll - 1), t_ckclk);
598f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
599f1df9364SStefan Roese (dev_num, access_type, if_id,
600f1df9364SStefan Roese DDR_TIMING_REG, txpdll << 4,
601f1df9364SStefan Roese 0x1f << 4));
602f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
603f1df9364SStefan Roese (dev_num, access_type, if_id,
604f1df9364SStefan Roese DDR_TIMING_REG, 0x28 << 9, 0x3f << 9));
605f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
606f1df9364SStefan Roese (dev_num, access_type, if_id,
607f1df9364SStefan Roese DDR_TIMING_REG, 0xa << 21, 0xff << 21));
608f1df9364SStefan Roese
609f1df9364SStefan Roese /* move the block to ddr3_tip_set_timing - end */
610f1df9364SStefan Roese /* AUTO_ZQC_TIMING */
611f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
612f1df9364SStefan Roese (dev_num, access_type, if_id,
613f1df9364SStefan Roese TIMING_REG, (AUTO_ZQC_TIMING | (2 << 20)),
614f1df9364SStefan Roese 0x3fffff));
615f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
616f1df9364SStefan Roese (dev_num, access_type, if_id,
617f1df9364SStefan Roese DRAM_PHY_CONFIGURATION, data_read, 0x30));
618f1df9364SStefan Roese data_value =
619f1df9364SStefan Roese (data_read[if_id] == 0) ? (1 << 11) : 0;
620f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
621f1df9364SStefan Roese (dev_num, access_type, if_id,
622f1df9364SStefan Roese DUNIT_CONTROL_HIGH_REG, data_value,
623f1df9364SStefan Roese (1 << 11)));
624f1df9364SStefan Roese
625f1df9364SStefan Roese /* Set Active control for ODT write transactions */
626f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
627f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST,
628f1df9364SStefan Roese PARAM_NOT_CARE, 0x1494, g_odt_config,
629f1df9364SStefan Roese MASK_ALL_BITS));
630f1df9364SStefan Roese }
631f1df9364SStefan Roese } else {
632f1df9364SStefan Roese #ifdef STATIC_ALGO_SUPPORT
633f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_static_init_controller(dev_num));
634f1df9364SStefan Roese #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
635f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_static_phy_init_controller(dev_num));
636f1df9364SStefan Roese #endif
637f1df9364SStefan Roese #endif /* STATIC_ALGO_SUPPORT */
638f1df9364SStefan Roese }
639f1df9364SStefan Roese
640f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
641f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
642f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_rank_control(dev_num, if_id));
643f1df9364SStefan Roese
644f1df9364SStefan Roese if (init_cntr_prm->do_mrs_phy) {
645f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_pad_inv(dev_num, if_id));
646f1df9364SStefan Roese }
647f1df9364SStefan Roese
648f1df9364SStefan Roese /* Pad calibration control - disable */
649f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
650f1df9364SStefan Roese (dev_num, access_type, if_id,
651f1df9364SStefan Roese CALIB_MACHINE_CTRL_REG, 0x0, 0x1));
652f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
653f1df9364SStefan Roese (dev_num, access_type, if_id,
654f1df9364SStefan Roese CALIB_MACHINE_CTRL_REG,
655f1df9364SStefan Roese calibration_update_control << 3, 0x3 << 3));
656f1df9364SStefan Roese }
657f1df9364SStefan Roese
658f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_enable_init_sequence(dev_num));
659f1df9364SStefan Roese
660f1df9364SStefan Roese if (delay_enable != 0) {
661f1df9364SStefan Roese adll_tap = MEGA / (freq_val[freq] * 64);
662f1df9364SStefan Roese ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap);
663f1df9364SStefan Roese }
664f1df9364SStefan Roese
665f1df9364SStefan Roese return MV_OK;
666f1df9364SStefan Roese }
667f1df9364SStefan Roese
668f1df9364SStefan Roese /*
669f1df9364SStefan Roese * Load Topology map
670f1df9364SStefan Roese */
hws_ddr3_tip_load_topology_map(u32 dev_num,struct hws_topology_map * tm)671f1df9364SStefan Roese int hws_ddr3_tip_load_topology_map(u32 dev_num, struct hws_topology_map *tm)
672f1df9364SStefan Roese {
673f1df9364SStefan Roese enum hws_speed_bin speed_bin_index;
674f1df9364SStefan Roese enum hws_ddr_freq freq = DDR_FREQ_LIMIT;
675f1df9364SStefan Roese u32 if_id;
676f1df9364SStefan Roese
677f1df9364SStefan Roese freq_val[DDR_FREQ_LOW_FREQ] = dfs_low_freq;
678f1df9364SStefan Roese tm = ddr3_get_topology_map();
679f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_get_first_active_if
680f1df9364SStefan Roese ((u8)dev_num, tm->if_act_mask,
681f1df9364SStefan Roese &first_active_if));
682f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
683f1df9364SStefan Roese ("board IF_Mask=0x%x num_of_bus_per_interface=0x%x\n",
684f1df9364SStefan Roese tm->if_act_mask,
685f1df9364SStefan Roese tm->num_of_bus_per_interface));
686f1df9364SStefan Roese
687f1df9364SStefan Roese /*
688f1df9364SStefan Roese * if CL, CWL values are missing in topology map, then fill them
689f1df9364SStefan Roese * according to speedbin tables
690f1df9364SStefan Roese */
691f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
692f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
693f1df9364SStefan Roese speed_bin_index =
694f1df9364SStefan Roese tm->interface_params[if_id].speed_bin_index;
695f1df9364SStefan Roese /* TBD memory frequency of interface 0 only is used ! */
696f1df9364SStefan Roese freq = tm->interface_params[first_active_if].memory_freq;
697f1df9364SStefan Roese
698f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
699f1df9364SStefan Roese ("speed_bin_index =%d freq=%d cl=%d cwl=%d\n",
700f1df9364SStefan Roese speed_bin_index, freq_val[freq],
701f1df9364SStefan Roese tm->interface_params[if_id].
702f1df9364SStefan Roese cas_l,
703f1df9364SStefan Roese tm->interface_params[if_id].
704f1df9364SStefan Roese cas_wl));
705f1df9364SStefan Roese
706f1df9364SStefan Roese if (tm->interface_params[if_id].cas_l == 0) {
707f1df9364SStefan Roese tm->interface_params[if_id].cas_l =
708f1df9364SStefan Roese cas_latency_table[speed_bin_index].cl_val[freq];
709f1df9364SStefan Roese }
710f1df9364SStefan Roese
711f1df9364SStefan Roese if (tm->interface_params[if_id].cas_wl == 0) {
712f1df9364SStefan Roese tm->interface_params[if_id].cas_wl =
713f1df9364SStefan Roese cas_write_latency_table[speed_bin_index].cl_val[freq];
714f1df9364SStefan Roese }
715f1df9364SStefan Roese }
716f1df9364SStefan Roese
717f1df9364SStefan Roese return MV_OK;
718f1df9364SStefan Roese }
719f1df9364SStefan Roese
720f1df9364SStefan Roese /*
721f1df9364SStefan Roese * RANK Control Flow
722f1df9364SStefan Roese */
ddr3_tip_rank_control(u32 dev_num,u32 if_id)723f1df9364SStefan Roese static int ddr3_tip_rank_control(u32 dev_num, u32 if_id)
724f1df9364SStefan Roese {
725f1df9364SStefan Roese u32 data_value = 0, bus_cnt;
726f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
727f1df9364SStefan Roese
728f1df9364SStefan Roese for (bus_cnt = 1; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
729f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
730f1df9364SStefan Roese if ((tm->interface_params[if_id].
731f1df9364SStefan Roese as_bus_params[0].cs_bitmask !=
732f1df9364SStefan Roese tm->interface_params[if_id].
733f1df9364SStefan Roese as_bus_params[bus_cnt].cs_bitmask) ||
734f1df9364SStefan Roese (tm->interface_params[if_id].
735f1df9364SStefan Roese as_bus_params[0].mirror_enable_bitmask !=
736f1df9364SStefan Roese tm->interface_params[if_id].
737f1df9364SStefan Roese as_bus_params[bus_cnt].mirror_enable_bitmask))
738f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
739f1df9364SStefan Roese ("WARNING:Wrong configuration for pup #%d CS mask and CS mirroring for all pups should be the same\n",
740f1df9364SStefan Roese bus_cnt));
741f1df9364SStefan Roese }
742f1df9364SStefan Roese
743f1df9364SStefan Roese data_value |= tm->interface_params[if_id].
744f1df9364SStefan Roese as_bus_params[0].cs_bitmask;
745f1df9364SStefan Roese data_value |= tm->interface_params[if_id].
746f1df9364SStefan Roese as_bus_params[0].mirror_enable_bitmask << 4;
747f1df9364SStefan Roese
748f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
749f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, RANK_CTRL_REG,
750f1df9364SStefan Roese data_value, 0xff));
751f1df9364SStefan Roese
752f1df9364SStefan Roese return MV_OK;
753f1df9364SStefan Roese }
754f1df9364SStefan Roese
755f1df9364SStefan Roese /*
756f1df9364SStefan Roese * PAD Inverse Flow
757f1df9364SStefan Roese */
ddr3_tip_pad_inv(u32 dev_num,u32 if_id)758f1df9364SStefan Roese static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id)
759f1df9364SStefan Roese {
760f1df9364SStefan Roese u32 bus_cnt, data_value, ck_swap_pup_ctrl;
761f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
762f1df9364SStefan Roese
763f1df9364SStefan Roese for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
764f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
765f1df9364SStefan Roese if (tm->interface_params[if_id].
766f1df9364SStefan Roese as_bus_params[bus_cnt].is_dqs_swap == 1) {
767f1df9364SStefan Roese /* dqs swap */
768f1df9364SStefan Roese ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
769f1df9364SStefan Roese if_id, bus_cnt,
770f1df9364SStefan Roese DDR_PHY_DATA,
771f1df9364SStefan Roese PHY_CONTROL_PHY_REG, 0xc0,
772f1df9364SStefan Roese 0xc0);
773f1df9364SStefan Roese }
774f1df9364SStefan Roese
775f1df9364SStefan Roese if (tm->interface_params[if_id].
776f1df9364SStefan Roese as_bus_params[bus_cnt].is_ck_swap == 1) {
777f1df9364SStefan Roese if (bus_cnt <= 1)
778f1df9364SStefan Roese data_value = 0x5 << 2;
779f1df9364SStefan Roese else
780f1df9364SStefan Roese data_value = 0xa << 2;
781f1df9364SStefan Roese
782f1df9364SStefan Roese /* mask equals data */
783f1df9364SStefan Roese /* ck swap pup is only control pup #0 ! */
784f1df9364SStefan Roese ck_swap_pup_ctrl = 0;
785f1df9364SStefan Roese ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
786f1df9364SStefan Roese if_id, ck_swap_pup_ctrl,
787f1df9364SStefan Roese DDR_PHY_CONTROL,
788f1df9364SStefan Roese PHY_CONTROL_PHY_REG,
789f1df9364SStefan Roese data_value, data_value);
790f1df9364SStefan Roese }
791f1df9364SStefan Roese }
792f1df9364SStefan Roese
793f1df9364SStefan Roese return MV_OK;
794f1df9364SStefan Roese }
795f1df9364SStefan Roese
796f1df9364SStefan Roese /*
797f1df9364SStefan Roese * Run Training Flow
798f1df9364SStefan Roese */
hws_ddr3_tip_run_alg(u32 dev_num,enum hws_algo_type algo_type)799f1df9364SStefan Roese int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type)
800f1df9364SStefan Roese {
801f1df9364SStefan Roese int ret = MV_OK, ret_tune = MV_OK;
802f1df9364SStefan Roese
803f1df9364SStefan Roese #ifdef ODT_TEST_SUPPORT
804f1df9364SStefan Roese if (finger_test == 1)
805f1df9364SStefan Roese return odt_test(dev_num, algo_type);
806f1df9364SStefan Roese #endif
807f1df9364SStefan Roese
808f1df9364SStefan Roese if (algo_type == ALGO_TYPE_DYNAMIC) {
809f1df9364SStefan Roese ret = ddr3_tip_ddr3_auto_tune(dev_num);
810f1df9364SStefan Roese } else {
811f1df9364SStefan Roese #ifdef STATIC_ALGO_SUPPORT
812f1df9364SStefan Roese {
813f1df9364SStefan Roese enum hws_ddr_freq freq;
814f1df9364SStefan Roese freq = init_freq;
815f1df9364SStefan Roese
816f1df9364SStefan Roese /* add to mask */
817f1df9364SStefan Roese if (is_adll_calib_before_init != 0) {
818f1df9364SStefan Roese printf("with adll calib before init\n");
819f1df9364SStefan Roese adll_calibration(dev_num, ACCESS_TYPE_MULTICAST,
820f1df9364SStefan Roese 0, freq);
821f1df9364SStefan Roese }
822f1df9364SStefan Roese /*
823f1df9364SStefan Roese * Frequency per interface is not relevant,
824f1df9364SStefan Roese * only interface 0
825f1df9364SStefan Roese */
826f1df9364SStefan Roese ret = ddr3_tip_run_static_alg(dev_num,
827f1df9364SStefan Roese freq);
828f1df9364SStefan Roese }
829f1df9364SStefan Roese #endif
830f1df9364SStefan Roese }
831f1df9364SStefan Roese
832f1df9364SStefan Roese if (ret != MV_OK) {
833f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
834f1df9364SStefan Roese ("Run_alg: tuning failed %d\n", ret_tune));
835f1df9364SStefan Roese }
836f1df9364SStefan Roese
837f1df9364SStefan Roese return ret;
838f1df9364SStefan Roese }
839f1df9364SStefan Roese
840f1df9364SStefan Roese #ifdef ODT_TEST_SUPPORT
841f1df9364SStefan Roese /*
842f1df9364SStefan Roese * ODT Test
843f1df9364SStefan Roese */
odt_test(u32 dev_num,enum hws_algo_type algo_type)844f1df9364SStefan Roese static int odt_test(u32 dev_num, enum hws_algo_type algo_type)
845f1df9364SStefan Roese {
846f1df9364SStefan Roese int ret = MV_OK, ret_tune = MV_OK;
847f1df9364SStefan Roese int pfinger_val = 0, nfinger_val;
848f1df9364SStefan Roese
849f1df9364SStefan Roese for (pfinger_val = p_finger_start; pfinger_val <= p_finger_end;
850f1df9364SStefan Roese pfinger_val += p_finger_step) {
851f1df9364SStefan Roese for (nfinger_val = n_finger_start; nfinger_val <= n_finger_end;
852f1df9364SStefan Roese nfinger_val += n_finger_step) {
853f1df9364SStefan Roese if (finger_test != 0) {
854f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
855f1df9364SStefan Roese ("pfinger_val %d nfinger_val %d\n",
856f1df9364SStefan Roese pfinger_val, nfinger_val));
857f1df9364SStefan Roese p_finger = pfinger_val;
858f1df9364SStefan Roese n_finger = nfinger_val;
859f1df9364SStefan Roese }
860f1df9364SStefan Roese
861f1df9364SStefan Roese if (algo_type == ALGO_TYPE_DYNAMIC) {
862f1df9364SStefan Roese ret = ddr3_tip_ddr3_auto_tune(dev_num);
863f1df9364SStefan Roese } else {
864f1df9364SStefan Roese /*
865f1df9364SStefan Roese * Frequency per interface is not relevant,
866f1df9364SStefan Roese * only interface 0
867f1df9364SStefan Roese */
868f1df9364SStefan Roese ret = ddr3_tip_run_static_alg(dev_num,
869f1df9364SStefan Roese init_freq);
870f1df9364SStefan Roese }
871f1df9364SStefan Roese }
872f1df9364SStefan Roese }
873f1df9364SStefan Roese
874f1df9364SStefan Roese if (ret_tune != MV_OK) {
875f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
876f1df9364SStefan Roese ("Run_alg: tuning failed %d\n", ret_tune));
877f1df9364SStefan Roese ret = (ret == MV_OK) ? ret_tune : ret;
878f1df9364SStefan Roese }
879f1df9364SStefan Roese
880f1df9364SStefan Roese return ret;
881f1df9364SStefan Roese }
882f1df9364SStefan Roese #endif
883f1df9364SStefan Roese
884f1df9364SStefan Roese /*
885f1df9364SStefan Roese * Select Controller
886f1df9364SStefan Roese */
hws_ddr3_tip_select_ddr_controller(u32 dev_num,int enable)887f1df9364SStefan Roese int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable)
888f1df9364SStefan Roese {
889f1df9364SStefan Roese if (config_func_info[dev_num].tip_dunit_mux_select_func != NULL) {
890f1df9364SStefan Roese return config_func_info[dev_num].
891f1df9364SStefan Roese tip_dunit_mux_select_func((u8)dev_num, enable);
892f1df9364SStefan Roese }
893f1df9364SStefan Roese
894f1df9364SStefan Roese return MV_FAIL;
895f1df9364SStefan Roese }
896f1df9364SStefan Roese
897f1df9364SStefan Roese /*
898f1df9364SStefan Roese * Dunit Register Write
899f1df9364SStefan Roese */
ddr3_tip_if_write(u32 dev_num,enum hws_access_type interface_access,u32 if_id,u32 reg_addr,u32 data_value,u32 mask)900f1df9364SStefan Roese int ddr3_tip_if_write(u32 dev_num, enum hws_access_type interface_access,
901f1df9364SStefan Roese u32 if_id, u32 reg_addr, u32 data_value, u32 mask)
902f1df9364SStefan Roese {
903f1df9364SStefan Roese if (config_func_info[dev_num].tip_dunit_write_func != NULL) {
904f1df9364SStefan Roese return config_func_info[dev_num].
905f1df9364SStefan Roese tip_dunit_write_func((u8)dev_num, interface_access,
906f1df9364SStefan Roese if_id, reg_addr,
907f1df9364SStefan Roese data_value, mask);
908f1df9364SStefan Roese }
909f1df9364SStefan Roese
910f1df9364SStefan Roese return MV_FAIL;
911f1df9364SStefan Roese }
912f1df9364SStefan Roese
913f1df9364SStefan Roese /*
914f1df9364SStefan Roese * Dunit Register Read
915f1df9364SStefan Roese */
ddr3_tip_if_read(u32 dev_num,enum hws_access_type interface_access,u32 if_id,u32 reg_addr,u32 * data,u32 mask)916f1df9364SStefan Roese int ddr3_tip_if_read(u32 dev_num, enum hws_access_type interface_access,
917f1df9364SStefan Roese u32 if_id, u32 reg_addr, u32 *data, u32 mask)
918f1df9364SStefan Roese {
919f1df9364SStefan Roese if (config_func_info[dev_num].tip_dunit_read_func != NULL) {
920f1df9364SStefan Roese return config_func_info[dev_num].
921f1df9364SStefan Roese tip_dunit_read_func((u8)dev_num, interface_access,
922f1df9364SStefan Roese if_id, reg_addr,
923f1df9364SStefan Roese data, mask);
924f1df9364SStefan Roese }
925f1df9364SStefan Roese
926f1df9364SStefan Roese return MV_FAIL;
927f1df9364SStefan Roese }
928f1df9364SStefan Roese
929f1df9364SStefan Roese /*
930f1df9364SStefan Roese * Dunit Register Polling
931f1df9364SStefan Roese */
ddr3_tip_if_polling(u32 dev_num,enum hws_access_type access_type,u32 if_id,u32 exp_value,u32 mask,u32 offset,u32 poll_tries)932f1df9364SStefan Roese int ddr3_tip_if_polling(u32 dev_num, enum hws_access_type access_type,
933f1df9364SStefan Roese u32 if_id, u32 exp_value, u32 mask, u32 offset,
934f1df9364SStefan Roese u32 poll_tries)
935f1df9364SStefan Roese {
936f1df9364SStefan Roese u32 poll_cnt = 0, interface_num = 0, start_if, end_if;
937f1df9364SStefan Roese u32 read_data[MAX_INTERFACE_NUM];
938f1df9364SStefan Roese int ret;
939f1df9364SStefan Roese int is_fail = 0, is_if_fail;
940f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
941f1df9364SStefan Roese
942f1df9364SStefan Roese if (access_type == ACCESS_TYPE_MULTICAST) {
943f1df9364SStefan Roese start_if = 0;
944f1df9364SStefan Roese end_if = MAX_INTERFACE_NUM - 1;
945f1df9364SStefan Roese } else {
946f1df9364SStefan Roese start_if = if_id;
947f1df9364SStefan Roese end_if = if_id;
948f1df9364SStefan Roese }
949f1df9364SStefan Roese
950f1df9364SStefan Roese for (interface_num = start_if; interface_num <= end_if; interface_num++) {
951f1df9364SStefan Roese /* polling bit 3 for n times */
952f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
953f1df9364SStefan Roese
954f1df9364SStefan Roese is_if_fail = 0;
955f1df9364SStefan Roese for (poll_cnt = 0; poll_cnt < poll_tries; poll_cnt++) {
956f1df9364SStefan Roese ret =
957f1df9364SStefan Roese ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
958f1df9364SStefan Roese interface_num, offset, read_data,
959f1df9364SStefan Roese mask);
960f1df9364SStefan Roese if (ret != MV_OK)
961f1df9364SStefan Roese return ret;
962f1df9364SStefan Roese
963f1df9364SStefan Roese if (read_data[interface_num] == exp_value)
964f1df9364SStefan Roese break;
965f1df9364SStefan Roese }
966f1df9364SStefan Roese
967f1df9364SStefan Roese if (poll_cnt >= poll_tries) {
968f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
969f1df9364SStefan Roese ("max poll IF #%d\n", interface_num));
970f1df9364SStefan Roese is_fail = 1;
971f1df9364SStefan Roese is_if_fail = 1;
972f1df9364SStefan Roese }
973f1df9364SStefan Roese
974f1df9364SStefan Roese training_result[training_stage][interface_num] =
975f1df9364SStefan Roese (is_if_fail == 1) ? TEST_FAILED : TEST_SUCCESS;
976f1df9364SStefan Roese }
977f1df9364SStefan Roese
978f1df9364SStefan Roese return (is_fail == 0) ? MV_OK : MV_FAIL;
979f1df9364SStefan Roese }
980f1df9364SStefan Roese
981f1df9364SStefan Roese /*
982f1df9364SStefan Roese * Bus read access
983f1df9364SStefan Roese */
ddr3_tip_bus_read(u32 dev_num,u32 if_id,enum hws_access_type phy_access,u32 phy_id,enum hws_ddr_phy phy_type,u32 reg_addr,u32 * data)984f1df9364SStefan Roese int ddr3_tip_bus_read(u32 dev_num, u32 if_id,
985f1df9364SStefan Roese enum hws_access_type phy_access, u32 phy_id,
986f1df9364SStefan Roese enum hws_ddr_phy phy_type, u32 reg_addr, u32 *data)
987f1df9364SStefan Roese {
988f1df9364SStefan Roese u32 bus_index = 0;
989f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM];
990f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
991f1df9364SStefan Roese
992f1df9364SStefan Roese if (phy_access == ACCESS_TYPE_MULTICAST) {
993f1df9364SStefan Roese for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
994f1df9364SStefan Roese bus_index++) {
995f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
996f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_access
997f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
998f1df9364SStefan Roese if_id, ACCESS_TYPE_UNICAST,
999f1df9364SStefan Roese bus_index, phy_type, reg_addr, 0,
1000f1df9364SStefan Roese OPERATION_READ));
1001f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1002f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1003f1df9364SStefan Roese PHY_REG_FILE_ACCESS, data_read,
1004f1df9364SStefan Roese MASK_ALL_BITS));
1005f1df9364SStefan Roese data[bus_index] = (data_read[if_id] & 0xffff);
1006f1df9364SStefan Roese }
1007f1df9364SStefan Roese } else {
1008f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_access
1009f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1010f1df9364SStefan Roese phy_access, phy_id, phy_type, reg_addr, 0,
1011f1df9364SStefan Roese OPERATION_READ));
1012f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1013f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1014f1df9364SStefan Roese PHY_REG_FILE_ACCESS, data_read, MASK_ALL_BITS));
1015f1df9364SStefan Roese
1016f1df9364SStefan Roese /*
1017f1df9364SStefan Roese * only 16 lsb bit are valid in Phy (each register is different,
1018f1df9364SStefan Roese * some can actually be less than 16 bits)
1019f1df9364SStefan Roese */
1020f1df9364SStefan Roese *data = (data_read[if_id] & 0xffff);
1021f1df9364SStefan Roese }
1022f1df9364SStefan Roese
1023f1df9364SStefan Roese return MV_OK;
1024f1df9364SStefan Roese }
1025f1df9364SStefan Roese
1026f1df9364SStefan Roese /*
1027f1df9364SStefan Roese * Bus write access
1028f1df9364SStefan Roese */
ddr3_tip_bus_write(u32 dev_num,enum hws_access_type interface_access,u32 if_id,enum hws_access_type phy_access,u32 phy_id,enum hws_ddr_phy phy_type,u32 reg_addr,u32 data_value)1029f1df9364SStefan Roese int ddr3_tip_bus_write(u32 dev_num, enum hws_access_type interface_access,
1030f1df9364SStefan Roese u32 if_id, enum hws_access_type phy_access,
1031f1df9364SStefan Roese u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
1032f1df9364SStefan Roese u32 data_value)
1033f1df9364SStefan Roese {
1034f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_access
1035f1df9364SStefan Roese (dev_num, interface_access, if_id, phy_access,
1036f1df9364SStefan Roese phy_id, phy_type, reg_addr, data_value, OPERATION_WRITE));
1037f1df9364SStefan Roese
1038f1df9364SStefan Roese return MV_OK;
1039f1df9364SStefan Roese }
1040f1df9364SStefan Roese
1041f1df9364SStefan Roese /*
1042f1df9364SStefan Roese * Bus access routine (relevant for both read & write)
1043f1df9364SStefan Roese */
ddr3_tip_bus_access(u32 dev_num,enum hws_access_type interface_access,u32 if_id,enum hws_access_type phy_access,u32 phy_id,enum hws_ddr_phy phy_type,u32 reg_addr,u32 data_value,enum hws_operation oper_type)1044f1df9364SStefan Roese static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
1045f1df9364SStefan Roese u32 if_id, enum hws_access_type phy_access,
1046f1df9364SStefan Roese u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
1047f1df9364SStefan Roese u32 data_value, enum hws_operation oper_type)
1048f1df9364SStefan Roese {
1049f1df9364SStefan Roese u32 addr_low = 0x3f & reg_addr;
1050f1df9364SStefan Roese u32 addr_hi = ((0xc0 & reg_addr) >> 6);
1051f1df9364SStefan Roese u32 data_p1 =
1052f1df9364SStefan Roese (oper_type << 30) + (addr_hi << 28) + (phy_access << 27) +
1053f1df9364SStefan Roese (phy_type << 26) + (phy_id << 22) + (addr_low << 16) +
1054f1df9364SStefan Roese (data_value & 0xffff);
1055f1df9364SStefan Roese u32 data_p2 = data_p1 + (1 << 31);
1056f1df9364SStefan Roese u32 start_if, end_if;
1057f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1058f1df9364SStefan Roese
1059f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1060f1df9364SStefan Roese (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
1061f1df9364SStefan Roese data_p1, MASK_ALL_BITS));
1062f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1063f1df9364SStefan Roese (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
1064f1df9364SStefan Roese data_p2, MASK_ALL_BITS));
1065f1df9364SStefan Roese
1066f1df9364SStefan Roese if (interface_access == ACCESS_TYPE_UNICAST) {
1067f1df9364SStefan Roese start_if = if_id;
1068f1df9364SStefan Roese end_if = if_id;
1069f1df9364SStefan Roese } else {
1070f1df9364SStefan Roese start_if = 0;
1071f1df9364SStefan Roese end_if = MAX_INTERFACE_NUM - 1;
1072f1df9364SStefan Roese }
1073f1df9364SStefan Roese
1074f1df9364SStefan Roese /* polling for read/write execution done */
1075f1df9364SStefan Roese for (if_id = start_if; if_id <= end_if; if_id++) {
1076f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1077f1df9364SStefan Roese CHECK_STATUS(is_bus_access_done
1078f1df9364SStefan Roese (dev_num, if_id, PHY_REG_FILE_ACCESS, 31));
1079f1df9364SStefan Roese }
1080f1df9364SStefan Roese
1081f1df9364SStefan Roese return MV_OK;
1082f1df9364SStefan Roese }
1083f1df9364SStefan Roese
1084f1df9364SStefan Roese /*
1085f1df9364SStefan Roese * Check bus access done
1086f1df9364SStefan Roese */
is_bus_access_done(u32 dev_num,u32 if_id,u32 dunit_reg_adrr,u32 bit)1087f1df9364SStefan Roese static int is_bus_access_done(u32 dev_num, u32 if_id, u32 dunit_reg_adrr,
1088f1df9364SStefan Roese u32 bit)
1089f1df9364SStefan Roese {
1090f1df9364SStefan Roese u32 rd_data = 1;
1091f1df9364SStefan Roese u32 cnt = 0;
1092f1df9364SStefan Roese u32 data_read[MAX_INTERFACE_NUM];
1093f1df9364SStefan Roese
1094f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1095f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, dunit_reg_adrr,
1096f1df9364SStefan Roese data_read, MASK_ALL_BITS));
1097f1df9364SStefan Roese rd_data = data_read[if_id];
1098f1df9364SStefan Roese rd_data &= (1 << bit);
1099f1df9364SStefan Roese
1100f1df9364SStefan Roese while (rd_data != 0) {
1101f1df9364SStefan Roese if (cnt++ >= MAX_POLLING_ITERATIONS)
1102f1df9364SStefan Roese break;
1103f1df9364SStefan Roese
1104f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_read
1105f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1106f1df9364SStefan Roese dunit_reg_adrr, data_read, MASK_ALL_BITS));
1107f1df9364SStefan Roese rd_data = data_read[if_id];
1108f1df9364SStefan Roese rd_data &= (1 << bit);
1109f1df9364SStefan Roese }
1110f1df9364SStefan Roese
1111f1df9364SStefan Roese if (cnt < MAX_POLLING_ITERATIONS)
1112f1df9364SStefan Roese return MV_OK;
1113f1df9364SStefan Roese else
1114f1df9364SStefan Roese return MV_FAIL;
1115f1df9364SStefan Roese }
1116f1df9364SStefan Roese
1117f1df9364SStefan Roese /*
1118f1df9364SStefan Roese * Phy read-modify-write
1119f1df9364SStefan Roese */
ddr3_tip_bus_read_modify_write(u32 dev_num,enum hws_access_type access_type,u32 interface_id,u32 phy_id,enum hws_ddr_phy phy_type,u32 reg_addr,u32 data_value,u32 reg_mask)1120f1df9364SStefan Roese int ddr3_tip_bus_read_modify_write(u32 dev_num, enum hws_access_type access_type,
1121f1df9364SStefan Roese u32 interface_id, u32 phy_id,
1122f1df9364SStefan Roese enum hws_ddr_phy phy_type, u32 reg_addr,
1123f1df9364SStefan Roese u32 data_value, u32 reg_mask)
1124f1df9364SStefan Roese {
1125f1df9364SStefan Roese u32 data_val = 0, if_id, start_if, end_if;
1126f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1127f1df9364SStefan Roese
1128f1df9364SStefan Roese if (access_type == ACCESS_TYPE_MULTICAST) {
1129f1df9364SStefan Roese start_if = 0;
1130f1df9364SStefan Roese end_if = MAX_INTERFACE_NUM - 1;
1131f1df9364SStefan Roese } else {
1132f1df9364SStefan Roese start_if = interface_id;
1133f1df9364SStefan Roese end_if = interface_id;
1134f1df9364SStefan Roese }
1135f1df9364SStefan Roese
1136f1df9364SStefan Roese for (if_id = start_if; if_id <= end_if; if_id++) {
1137f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1138f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read
1139f1df9364SStefan Roese (dev_num, if_id, ACCESS_TYPE_UNICAST, phy_id,
1140f1df9364SStefan Roese phy_type, reg_addr, &data_val));
1141f1df9364SStefan Roese data_value = (data_val & (~reg_mask)) | (data_value & reg_mask);
1142f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1143f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1144f1df9364SStefan Roese ACCESS_TYPE_UNICAST, phy_id, phy_type, reg_addr,
1145f1df9364SStefan Roese data_value));
1146f1df9364SStefan Roese }
1147f1df9364SStefan Roese
1148f1df9364SStefan Roese return MV_OK;
1149f1df9364SStefan Roese }
1150f1df9364SStefan Roese
1151f1df9364SStefan Roese /*
1152f1df9364SStefan Roese * ADLL Calibration
1153f1df9364SStefan Roese */
adll_calibration(u32 dev_num,enum hws_access_type access_type,u32 if_id,enum hws_ddr_freq frequency)1154f1df9364SStefan Roese int adll_calibration(u32 dev_num, enum hws_access_type access_type,
1155f1df9364SStefan Roese u32 if_id, enum hws_ddr_freq frequency)
1156f1df9364SStefan Roese {
1157f1df9364SStefan Roese struct hws_tip_freq_config_info freq_config_info;
1158f1df9364SStefan Roese u32 bus_cnt = 0;
1159f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1160f1df9364SStefan Roese
1161f1df9364SStefan Roese /* Reset Diver_b assert -> de-assert */
1162f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1163f1df9364SStefan Roese (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
1164f1df9364SStefan Roese 0, 0x10000000));
1165f1df9364SStefan Roese mdelay(10);
1166f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1167f1df9364SStefan Roese (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
1168f1df9364SStefan Roese 0x10000000, 0x10000000));
1169f1df9364SStefan Roese
1170f1df9364SStefan Roese if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
1171f1df9364SStefan Roese CHECK_STATUS(config_func_info[dev_num].
1172f1df9364SStefan Roese tip_get_freq_config_info_func((u8)dev_num, frequency,
1173f1df9364SStefan Roese &freq_config_info));
1174f1df9364SStefan Roese } else {
1175f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1176f1df9364SStefan Roese ("tip_get_freq_config_info_func is NULL"));
1177f1df9364SStefan Roese return MV_NOT_INITIALIZED;
1178f1df9364SStefan Roese }
1179f1df9364SStefan Roese
1180f1df9364SStefan Roese for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
1181f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
1182f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1183f1df9364SStefan Roese (dev_num, access_type, if_id, bus_cnt,
1184f1df9364SStefan Roese DDR_PHY_DATA, BW_PHY_REG,
1185f1df9364SStefan Roese freq_config_info.bw_per_freq << 8, 0x700));
1186f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1187f1df9364SStefan Roese (dev_num, access_type, if_id, bus_cnt,
1188f1df9364SStefan Roese DDR_PHY_DATA, RATE_PHY_REG,
1189f1df9364SStefan Roese freq_config_info.rate_per_freq, 0x7));
1190f1df9364SStefan Roese }
1191f1df9364SStefan Roese
1192f1df9364SStefan Roese /* DUnit to Phy drive post edge, ADLL reset assert de-assert */
1193f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1194f1df9364SStefan Roese (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
1195f1df9364SStefan Roese 0, (0x80000000 | 0x40000000)));
1196f1df9364SStefan Roese mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
1197f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1198f1df9364SStefan Roese (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
1199f1df9364SStefan Roese (0x80000000 | 0x40000000), (0x80000000 | 0x40000000)));
1200f1df9364SStefan Roese
1201f1df9364SStefan Roese /* polling for ADLL Done */
1202f1df9364SStefan Roese if (ddr3_tip_if_polling(dev_num, access_type, if_id,
1203f1df9364SStefan Roese 0x3ff03ff, 0x3ff03ff, PHY_LOCK_STATUS_REG,
1204f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1205f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1206f1df9364SStefan Roese ("Freq_set: DDR3 poll failed(1)"));
1207f1df9364SStefan Roese }
1208f1df9364SStefan Roese
1209f1df9364SStefan Roese /* pup data_pup reset assert-> deassert */
1210f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1211f1df9364SStefan Roese (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
1212f1df9364SStefan Roese 0, 0x60000000));
1213f1df9364SStefan Roese mdelay(10);
1214f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1215f1df9364SStefan Roese (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
1216f1df9364SStefan Roese 0x60000000, 0x60000000));
1217f1df9364SStefan Roese
1218f1df9364SStefan Roese return MV_OK;
1219f1df9364SStefan Roese }
1220f1df9364SStefan Roese
ddr3_tip_freq_set(u32 dev_num,enum hws_access_type access_type,u32 if_id,enum hws_ddr_freq frequency)1221f1df9364SStefan Roese int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
1222f1df9364SStefan Roese u32 if_id, enum hws_ddr_freq frequency)
1223f1df9364SStefan Roese {
1224f1df9364SStefan Roese u32 cl_value = 0, cwl_value = 0, mem_mask = 0, val = 0,
1225f1df9364SStefan Roese bus_cnt = 0, t_hclk = 0, t_wr = 0,
1226f1df9364SStefan Roese refresh_interval_cnt = 0, cnt_id;
1227f1df9364SStefan Roese u32 t_refi = 0, end_if, start_if;
1228f1df9364SStefan Roese u32 bus_index = 0;
1229f1df9364SStefan Roese int is_dll_off = 0;
1230f1df9364SStefan Roese enum hws_speed_bin speed_bin_index = 0;
1231f1df9364SStefan Roese struct hws_tip_freq_config_info freq_config_info;
1232f1df9364SStefan Roese enum hws_result *flow_result = training_result[training_stage];
1233f1df9364SStefan Roese u32 adll_tap = 0;
1234f1df9364SStefan Roese u32 cs_mask[MAX_INTERFACE_NUM];
1235f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1236f1df9364SStefan Roese
1237f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
1238f1df9364SStefan Roese ("dev %d access %d IF %d freq %d\n", dev_num,
1239f1df9364SStefan Roese access_type, if_id, frequency));
1240f1df9364SStefan Roese
1241f1df9364SStefan Roese if (frequency == DDR_FREQ_LOW_FREQ)
1242f1df9364SStefan Roese is_dll_off = 1;
1243f1df9364SStefan Roese if (access_type == ACCESS_TYPE_MULTICAST) {
1244f1df9364SStefan Roese start_if = 0;
1245f1df9364SStefan Roese end_if = MAX_INTERFACE_NUM - 1;
1246f1df9364SStefan Roese } else {
1247f1df9364SStefan Roese start_if = if_id;
1248f1df9364SStefan Roese end_if = if_id;
1249f1df9364SStefan Roese }
1250f1df9364SStefan Roese
1251f1df9364SStefan Roese /* calculate interface cs mask - Oferb 4/11 */
1252f1df9364SStefan Roese /* speed bin can be different for each interface */
1253f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1254f1df9364SStefan Roese /* cs enable is active low */
1255f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1256f1df9364SStefan Roese cs_mask[if_id] = CS_BIT_MASK;
1257f1df9364SStefan Roese training_result[training_stage][if_id] = TEST_SUCCESS;
1258f1df9364SStefan Roese ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
1259f1df9364SStefan Roese &cs_mask[if_id]);
1260f1df9364SStefan Roese }
1261f1df9364SStefan Roese
1262f1df9364SStefan Roese /* speed bin can be different for each interface */
1263f1df9364SStefan Roese /*
1264f1df9364SStefan Roese * moti b - need to remove the loop for multicas access functions
1265f1df9364SStefan Roese * and loop the unicast access functions
1266f1df9364SStefan Roese */
1267f1df9364SStefan Roese for (if_id = start_if; if_id <= end_if; if_id++) {
1268f1df9364SStefan Roese if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
1269f1df9364SStefan Roese continue;
1270f1df9364SStefan Roese
1271f1df9364SStefan Roese flow_result[if_id] = TEST_SUCCESS;
1272f1df9364SStefan Roese speed_bin_index =
1273f1df9364SStefan Roese tm->interface_params[if_id].speed_bin_index;
1274f1df9364SStefan Roese if (tm->interface_params[if_id].memory_freq ==
1275f1df9364SStefan Roese frequency) {
1276f1df9364SStefan Roese cl_value =
1277f1df9364SStefan Roese tm->interface_params[if_id].cas_l;
1278f1df9364SStefan Roese cwl_value =
1279f1df9364SStefan Roese tm->interface_params[if_id].cas_wl;
1280f1df9364SStefan Roese } else {
1281f1df9364SStefan Roese cl_value =
1282f1df9364SStefan Roese cas_latency_table[speed_bin_index].cl_val[frequency];
1283f1df9364SStefan Roese cwl_value =
1284f1df9364SStefan Roese cas_write_latency_table[speed_bin_index].
1285f1df9364SStefan Roese cl_val[frequency];
1286f1df9364SStefan Roese }
1287f1df9364SStefan Roese
1288f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
1289f1df9364SStefan Roese ("Freq_set dev 0x%x access 0x%x if 0x%x freq 0x%x speed %d:\n\t",
1290f1df9364SStefan Roese dev_num, access_type, if_id,
1291f1df9364SStefan Roese frequency, speed_bin_index));
1292f1df9364SStefan Roese
1293f1df9364SStefan Roese for (cnt_id = 0; cnt_id < DDR_FREQ_LIMIT; cnt_id++) {
1294f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
1295f1df9364SStefan Roese ("%d ",
1296f1df9364SStefan Roese cas_latency_table[speed_bin_index].
1297f1df9364SStefan Roese cl_val[cnt_id]));
1298f1df9364SStefan Roese }
1299f1df9364SStefan Roese
1300f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n"));
1301f1df9364SStefan Roese mem_mask = 0;
1302f1df9364SStefan Roese for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
1303f1df9364SStefan Roese bus_index++) {
1304f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
1305f1df9364SStefan Roese mem_mask |=
1306f1df9364SStefan Roese tm->interface_params[if_id].
1307f1df9364SStefan Roese as_bus_params[bus_index].mirror_enable_bitmask;
1308f1df9364SStefan Roese }
1309f1df9364SStefan Roese
1310f1df9364SStefan Roese if (mem_mask != 0) {
1311fc0b5948SRobert P. J. Day /* motib redundant in KW28 */
1312f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1313f1df9364SStefan Roese if_id,
1314f1df9364SStefan Roese CS_ENABLE_REG, 0, 0x8));
1315f1df9364SStefan Roese }
1316f1df9364SStefan Roese
1317f1df9364SStefan Roese /* dll state after exiting SR */
1318f1df9364SStefan Roese if (is_dll_off == 1) {
1319f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1320f1df9364SStefan Roese (dev_num, access_type, if_id,
1321f1df9364SStefan Roese DFS_REG, 0x1, 0x1));
1322f1df9364SStefan Roese } else {
1323f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1324f1df9364SStefan Roese (dev_num, access_type, if_id,
1325f1df9364SStefan Roese DFS_REG, 0, 0x1));
1326f1df9364SStefan Roese }
1327f1df9364SStefan Roese
1328f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1329f1df9364SStefan Roese (dev_num, access_type, if_id,
1330f1df9364SStefan Roese DUNIT_MMASK_REG, 0, 0x1));
1331f1df9364SStefan Roese /* DFS - block transactions */
1332f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1333f1df9364SStefan Roese (dev_num, access_type, if_id,
1334f1df9364SStefan Roese DFS_REG, 0x2, 0x2));
1335f1df9364SStefan Roese
1336f1df9364SStefan Roese /* disable ODT in case of dll off */
1337f1df9364SStefan Roese if (is_dll_off == 1) {
1338f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1339f1df9364SStefan Roese (dev_num, access_type, if_id,
1340f1df9364SStefan Roese 0x1874, 0, 0x244));
1341f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1342f1df9364SStefan Roese (dev_num, access_type, if_id,
1343f1df9364SStefan Roese 0x1884, 0, 0x244));
1344f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1345f1df9364SStefan Roese (dev_num, access_type, if_id,
1346f1df9364SStefan Roese 0x1894, 0, 0x244));
1347f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1348f1df9364SStefan Roese (dev_num, access_type, if_id,
1349f1df9364SStefan Roese 0x18a4, 0, 0x244));
1350f1df9364SStefan Roese }
1351f1df9364SStefan Roese
1352f1df9364SStefan Roese /* DFS - Enter Self-Refresh */
1353f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1354f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG, 0x4,
1355f1df9364SStefan Roese 0x4));
1356f1df9364SStefan Roese /* polling on self refresh entry */
1357f1df9364SStefan Roese if (ddr3_tip_if_polling(dev_num, ACCESS_TYPE_UNICAST,
1358f1df9364SStefan Roese if_id, 0x8, 0x8, DFS_REG,
1359f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1360f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1361f1df9364SStefan Roese ("Freq_set: DDR3 poll failed on SR entry\n"));
1362f1df9364SStefan Roese }
1363f1df9364SStefan Roese
1364f1df9364SStefan Roese /* PLL configuration */
1365f1df9364SStefan Roese if (config_func_info[dev_num].tip_set_freq_divider_func != NULL) {
1366f1df9364SStefan Roese config_func_info[dev_num].
1367f1df9364SStefan Roese tip_set_freq_divider_func(dev_num, if_id,
1368f1df9364SStefan Roese frequency);
1369f1df9364SStefan Roese }
1370f1df9364SStefan Roese
1371f1df9364SStefan Roese /* PLL configuration End */
1372f1df9364SStefan Roese
1373f1df9364SStefan Roese /* adjust t_refi to new frequency */
1374f1df9364SStefan Roese t_refi = (tm->interface_params[if_id].interface_temp ==
1375f1df9364SStefan Roese HWS_TEMP_HIGH) ? TREFI_LOW : TREFI_HIGH;
1376f1df9364SStefan Roese t_refi *= 1000; /*psec */
1377f1df9364SStefan Roese
1378f1df9364SStefan Roese /* HCLK in[ps] */
1379f1df9364SStefan Roese t_hclk = MEGA / (freq_val[frequency] / 2);
1380f1df9364SStefan Roese refresh_interval_cnt = t_refi / t_hclk; /* no units */
1381f1df9364SStefan Roese val = 0x4000 | refresh_interval_cnt;
1382f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1383f1df9364SStefan Roese (dev_num, access_type, if_id,
1384f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, val, 0x7fff));
1385f1df9364SStefan Roese
1386f1df9364SStefan Roese /* DFS - CL/CWL/WR parameters after exiting SR */
1387f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1388f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG,
1389f1df9364SStefan Roese (cl_mask_table[cl_value] << 8), 0xf00));
1390f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1391f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG,
1392f1df9364SStefan Roese (cwl_mask_table[cwl_value] << 12), 0x7000));
1393f1df9364SStefan Roese t_wr = speed_bin_table(speed_bin_index, SPEED_BIN_TWR);
1394f1df9364SStefan Roese t_wr = (t_wr / 1000);
1395f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1396f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG,
1397f1df9364SStefan Roese (twr_mask_table[t_wr + 1] << 16), 0x70000));
1398f1df9364SStefan Roese
1399f1df9364SStefan Roese /* Restore original RTT values if returning from DLL OFF mode */
1400f1df9364SStefan Roese if (is_dll_off == 1) {
1401f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1402f1df9364SStefan Roese (dev_num, access_type, if_id, 0x1874,
1403f1df9364SStefan Roese g_dic | g_rtt_nom, 0x266));
1404f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1405f1df9364SStefan Roese (dev_num, access_type, if_id, 0x1884,
1406f1df9364SStefan Roese g_dic | g_rtt_nom, 0x266));
1407f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1408f1df9364SStefan Roese (dev_num, access_type, if_id, 0x1894,
1409f1df9364SStefan Roese g_dic | g_rtt_nom, 0x266));
1410f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1411f1df9364SStefan Roese (dev_num, access_type, if_id, 0x18a4,
1412f1df9364SStefan Roese g_dic | g_rtt_nom, 0x266));
1413f1df9364SStefan Roese }
1414f1df9364SStefan Roese
1415f1df9364SStefan Roese /* Reset Diver_b assert -> de-assert */
1416f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1417f1df9364SStefan Roese (dev_num, access_type, if_id,
1418f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0, 0x10000000));
1419f1df9364SStefan Roese mdelay(10);
1420f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1421f1df9364SStefan Roese (dev_num, access_type, if_id,
1422f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0x10000000, 0x10000000));
1423f1df9364SStefan Roese
1424f1df9364SStefan Roese /* Adll configuration function of process and Frequency */
1425f1df9364SStefan Roese if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
1426f1df9364SStefan Roese CHECK_STATUS(config_func_info[dev_num].
1427f1df9364SStefan Roese tip_get_freq_config_info_func(dev_num, frequency,
1428f1df9364SStefan Roese &freq_config_info));
1429f1df9364SStefan Roese }
1430f1df9364SStefan Roese /* TBD check milo5 using device ID ? */
1431f1df9364SStefan Roese for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
1432f1df9364SStefan Roese bus_cnt++) {
1433f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
1434f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1435f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1436f1df9364SStefan Roese if_id, bus_cnt, DDR_PHY_DATA,
1437f1df9364SStefan Roese 0x92,
1438f1df9364SStefan Roese freq_config_info.
1439f1df9364SStefan Roese bw_per_freq << 8
1440f1df9364SStefan Roese /*freq_mask[dev_num][frequency] << 8 */
1441f1df9364SStefan Roese , 0x700));
1442f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_read_modify_write
1443f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1444f1df9364SStefan Roese bus_cnt, DDR_PHY_DATA, 0x94,
1445f1df9364SStefan Roese freq_config_info.rate_per_freq, 0x7));
1446f1df9364SStefan Roese }
1447f1df9364SStefan Roese
1448f1df9364SStefan Roese /* DUnit to Phy drive post edge, ADLL reset assert de-assert */
1449f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1450f1df9364SStefan Roese (dev_num, access_type, if_id,
1451f1df9364SStefan Roese DRAM_PHY_CONFIGURATION, 0,
1452f1df9364SStefan Roese (0x80000000 | 0x40000000)));
1453f1df9364SStefan Roese mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
1454f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1455f1df9364SStefan Roese (dev_num, access_type, if_id,
1456f1df9364SStefan Roese DRAM_PHY_CONFIGURATION, (0x80000000 | 0x40000000),
1457f1df9364SStefan Roese (0x80000000 | 0x40000000)));
1458f1df9364SStefan Roese
1459f1df9364SStefan Roese /* polling for ADLL Done */
1460f1df9364SStefan Roese if (ddr3_tip_if_polling
1461f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x3ff03ff,
1462f1df9364SStefan Roese 0x3ff03ff, PHY_LOCK_STATUS_REG,
1463f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1464f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1465f1df9364SStefan Roese ("Freq_set: DDR3 poll failed(1)\n"));
1466f1df9364SStefan Roese }
1467f1df9364SStefan Roese
1468f1df9364SStefan Roese /* pup data_pup reset assert-> deassert */
1469f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1470f1df9364SStefan Roese (dev_num, access_type, if_id,
1471f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0, 0x60000000));
1472f1df9364SStefan Roese mdelay(10);
1473f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1474f1df9364SStefan Roese (dev_num, access_type, if_id,
1475f1df9364SStefan Roese SDRAM_CONFIGURATION_REG, 0x60000000, 0x60000000));
1476f1df9364SStefan Roese
1477f1df9364SStefan Roese /* Set proper timing params before existing Self-Refresh */
1478f1df9364SStefan Roese ddr3_tip_set_timing(dev_num, access_type, if_id, frequency);
1479f1df9364SStefan Roese if (delay_enable != 0) {
1480f1df9364SStefan Roese adll_tap = MEGA / (freq_val[frequency] * 64);
1481f1df9364SStefan Roese ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap);
1482f1df9364SStefan Roese }
1483f1df9364SStefan Roese
1484f1df9364SStefan Roese /* Exit SR */
1485f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1486f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG, 0,
1487f1df9364SStefan Roese 0x4));
1488f1df9364SStefan Roese if (ddr3_tip_if_polling
1489f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x8, DFS_REG,
1490f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1491f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1492f1df9364SStefan Roese ("Freq_set: DDR3 poll failed(2)"));
1493f1df9364SStefan Roese }
1494f1df9364SStefan Roese
1495f1df9364SStefan Roese /* Refresh Command */
1496f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1497f1df9364SStefan Roese (dev_num, access_type, if_id,
1498f1df9364SStefan Roese SDRAM_OPERATION_REG, 0x2, 0xf1f));
1499f1df9364SStefan Roese if (ddr3_tip_if_polling
1500f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
1501f1df9364SStefan Roese SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
1502f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1503f1df9364SStefan Roese ("Freq_set: DDR3 poll failed(3)"));
1504f1df9364SStefan Roese }
1505f1df9364SStefan Roese
1506f1df9364SStefan Roese /* Release DFS Block */
1507f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1508f1df9364SStefan Roese (dev_num, access_type, if_id, DFS_REG, 0,
1509f1df9364SStefan Roese 0x2));
1510f1df9364SStefan Roese /* Controller to MBUS Retry - normal */
1511f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1512f1df9364SStefan Roese (dev_num, access_type, if_id, DUNIT_MMASK_REG,
1513f1df9364SStefan Roese 0x1, 0x1));
1514f1df9364SStefan Roese
1515f1df9364SStefan Roese /* MRO: Burst Length 8, CL , Auto_precharge 0x16cc */
1516f1df9364SStefan Roese val =
1517f1df9364SStefan Roese ((cl_mask_table[cl_value] & 0x1) << 2) |
1518f1df9364SStefan Roese ((cl_mask_table[cl_value] & 0xe) << 3);
1519f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1520f1df9364SStefan Roese (dev_num, access_type, if_id, MR0_REG,
1521f1df9364SStefan Roese val, (0x7 << 4) | (1 << 2)));
1522f1df9364SStefan Roese /* MR2: CWL = 10 , Auto Self-Refresh - disable */
1523f1df9364SStefan Roese val = (cwl_mask_table[cwl_value] << 3);
1524f1df9364SStefan Roese /*
1525f1df9364SStefan Roese * nklein 24.10.13 - should not be here - leave value as set in
1526f1df9364SStefan Roese * the init configuration val |= (1 << 9);
1527f1df9364SStefan Roese * val |= ((tm->interface_params[if_id].
1528f1df9364SStefan Roese * interface_temp == HWS_TEMP_HIGH) ? (1 << 7) : 0);
1529f1df9364SStefan Roese */
1530f1df9364SStefan Roese /* nklein 24.10.13 - see above comment */
1531f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1532f1df9364SStefan Roese if_id, MR2_REG,
1533f1df9364SStefan Roese val, (0x7 << 3)));
1534f1df9364SStefan Roese
1535f1df9364SStefan Roese /* ODT TIMING */
1536f1df9364SStefan Roese val = ((cl_value - cwl_value + 1) << 4) |
1537f1df9364SStefan Roese ((cl_value - cwl_value + 6) << 8) |
1538f1df9364SStefan Roese ((cl_value - 1) << 12) | ((cl_value + 6) << 16);
1539f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1540f1df9364SStefan Roese if_id, ODT_TIMING_LOW,
1541f1df9364SStefan Roese val, 0xffff0));
1542f1df9364SStefan Roese val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
1543f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1544f1df9364SStefan Roese if_id, ODT_TIMING_HI_REG,
1545f1df9364SStefan Roese val, 0xffff));
1546f1df9364SStefan Roese
1547f1df9364SStefan Roese /* ODT Active */
1548f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1549f1df9364SStefan Roese if_id,
1550f1df9364SStefan Roese DUNIT_ODT_CONTROL_REG,
1551f1df9364SStefan Roese 0xf, 0xf));
1552f1df9364SStefan Roese
1553f1df9364SStefan Roese /* re-write CL */
1554f1df9364SStefan Roese val = ((cl_mask_table[cl_value] & 0x1) << 2) |
1555f1df9364SStefan Roese ((cl_mask_table[cl_value] & 0xe) << 3);
1556f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1557f1df9364SStefan Roese 0, MR0_REG, val,
1558f1df9364SStefan Roese (0x7 << 4) | (1 << 2)));
1559f1df9364SStefan Roese
1560f1df9364SStefan Roese /* re-write CWL */
1561f1df9364SStefan Roese val = (cwl_mask_table[cwl_value] << 3);
1562f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MRS2_CMD,
1563f1df9364SStefan Roese val, (0x7 << 3)));
1564f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1565f1df9364SStefan Roese 0, MR2_REG, val, (0x7 << 3)));
1566f1df9364SStefan Roese
1567f1df9364SStefan Roese if (mem_mask != 0) {
1568f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1569f1df9364SStefan Roese if_id,
1570f1df9364SStefan Roese CS_ENABLE_REG,
1571f1df9364SStefan Roese 1 << 3, 0x8));
1572f1df9364SStefan Roese }
1573f1df9364SStefan Roese }
1574f1df9364SStefan Roese
1575f1df9364SStefan Roese return MV_OK;
1576f1df9364SStefan Roese }
1577f1df9364SStefan Roese
1578f1df9364SStefan Roese /*
1579f1df9364SStefan Roese * Set ODT values
1580f1df9364SStefan Roese */
ddr3_tip_write_odt(u32 dev_num,enum hws_access_type access_type,u32 if_id,u32 cl_value,u32 cwl_value)1581f1df9364SStefan Roese static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
1582f1df9364SStefan Roese u32 if_id, u32 cl_value, u32 cwl_value)
1583f1df9364SStefan Roese {
1584f1df9364SStefan Roese /* ODT TIMING */
1585f1df9364SStefan Roese u32 val = (cl_value - cwl_value + 6);
1586f1df9364SStefan Roese
1587f1df9364SStefan Roese val = ((cl_value - cwl_value + 1) << 4) | ((val & 0xf) << 8) |
1588f1df9364SStefan Roese (((cl_value - 1) & 0xf) << 12) |
1589f1df9364SStefan Roese (((cl_value + 6) & 0xf) << 16) | (((val & 0x10) >> 4) << 21);
1590f1df9364SStefan Roese val |= (((cl_value - 1) >> 4) << 22) | (((cl_value + 6) >> 4) << 23);
1591f1df9364SStefan Roese
1592f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1593f1df9364SStefan Roese ODT_TIMING_LOW, val, 0xffff0));
1594f1df9364SStefan Roese val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
1595f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1596f1df9364SStefan Roese ODT_TIMING_HI_REG, val, 0xffff));
1597f1df9364SStefan Roese if (odt_additional == 1) {
1598f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
1599f1df9364SStefan Roese if_id,
1600f1df9364SStefan Roese SDRAM_ODT_CONTROL_HIGH_REG,
1601f1df9364SStefan Roese 0xf, 0xf));
1602f1df9364SStefan Roese }
1603f1df9364SStefan Roese
1604f1df9364SStefan Roese /* ODT Active */
1605f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1606f1df9364SStefan Roese DUNIT_ODT_CONTROL_REG, 0xf, 0xf));
1607f1df9364SStefan Roese
1608f1df9364SStefan Roese return MV_OK;
1609f1df9364SStefan Roese }
1610f1df9364SStefan Roese
1611f1df9364SStefan Roese /*
1612f1df9364SStefan Roese * Set Timing values for training
1613f1df9364SStefan Roese */
ddr3_tip_set_timing(u32 dev_num,enum hws_access_type access_type,u32 if_id,enum hws_ddr_freq frequency)1614f1df9364SStefan Roese static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
1615f1df9364SStefan Roese u32 if_id, enum hws_ddr_freq frequency)
1616f1df9364SStefan Roese {
1617f1df9364SStefan Roese u32 t_ckclk = 0, t_ras = 0;
1618f1df9364SStefan Roese u32 t_rcd = 0, t_rp = 0, t_wr = 0, t_wtr = 0, t_rrd = 0, t_rtp = 0,
1619f1df9364SStefan Roese t_rfc = 0, t_mod = 0;
1620f1df9364SStefan Roese u32 val = 0, page_size = 0;
1621f1df9364SStefan Roese enum hws_speed_bin speed_bin_index;
1622f1df9364SStefan Roese enum hws_mem_size memory_size = MEM_2G;
1623f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1624f1df9364SStefan Roese
1625f1df9364SStefan Roese speed_bin_index = tm->interface_params[if_id].speed_bin_index;
1626f1df9364SStefan Roese memory_size = tm->interface_params[if_id].memory_size;
1627f1df9364SStefan Roese page_size =
1628f1df9364SStefan Roese (tm->interface_params[if_id].bus_width ==
1629f1df9364SStefan Roese BUS_WIDTH_8) ? page_param[memory_size].
1630f1df9364SStefan Roese page_size_8bit : page_param[memory_size].page_size_16bit;
1631f1df9364SStefan Roese t_ckclk = (MEGA / freq_val[frequency]);
1632f1df9364SStefan Roese t_rrd = (page_size == 1) ? speed_bin_table(speed_bin_index,
1633f1df9364SStefan Roese SPEED_BIN_TRRD1K) :
1634f1df9364SStefan Roese speed_bin_table(speed_bin_index, SPEED_BIN_TRRD2K);
1635f1df9364SStefan Roese t_rrd = GET_MAX_VALUE(t_ckclk * 4, t_rrd);
1636f1df9364SStefan Roese t_rtp = GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
1637f1df9364SStefan Roese SPEED_BIN_TRTP));
1638f1df9364SStefan Roese t_wtr = GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
1639f1df9364SStefan Roese SPEED_BIN_TWTR));
1640f1df9364SStefan Roese t_ras = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
1641f1df9364SStefan Roese SPEED_BIN_TRAS),
1642f1df9364SStefan Roese t_ckclk);
1643f1df9364SStefan Roese t_rcd = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
1644f1df9364SStefan Roese SPEED_BIN_TRCD),
1645f1df9364SStefan Roese t_ckclk);
1646f1df9364SStefan Roese t_rp = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
1647f1df9364SStefan Roese SPEED_BIN_TRP),
1648f1df9364SStefan Roese t_ckclk);
1649f1df9364SStefan Roese t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
1650f1df9364SStefan Roese SPEED_BIN_TWR),
1651f1df9364SStefan Roese t_ckclk);
1652f1df9364SStefan Roese t_wtr = TIME_2_CLOCK_CYCLES(t_wtr, t_ckclk);
1653f1df9364SStefan Roese t_rrd = TIME_2_CLOCK_CYCLES(t_rrd, t_ckclk);
1654f1df9364SStefan Roese t_rtp = TIME_2_CLOCK_CYCLES(t_rtp, t_ckclk);
1655f1df9364SStefan Roese t_rfc = TIME_2_CLOCK_CYCLES(rfc_table[memory_size] * 1000, t_ckclk);
1656f1df9364SStefan Roese t_mod = GET_MAX_VALUE(t_ckclk * 24, 15000);
1657f1df9364SStefan Roese t_mod = TIME_2_CLOCK_CYCLES(t_mod, t_ckclk);
1658f1df9364SStefan Roese
1659f1df9364SStefan Roese /* SDRAM Timing Low */
1660f1df9364SStefan Roese val = (t_ras & 0xf) | (t_rcd << 4) | (t_rp << 8) | (t_wr << 12) |
1661f1df9364SStefan Roese (t_wtr << 16) | (((t_ras & 0x30) >> 4) << 20) | (t_rrd << 24) |
1662f1df9364SStefan Roese (t_rtp << 28);
1663f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1664f1df9364SStefan Roese SDRAM_TIMING_LOW_REG, val, 0xff3fffff));
1665f1df9364SStefan Roese
1666f1df9364SStefan Roese /* SDRAM Timing High */
1667f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1668f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1669f1df9364SStefan Roese t_rfc & 0x7f, 0x7f));
1670f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1671f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1672f1df9364SStefan Roese 0x180, 0x180));
1673f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1674f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1675f1df9364SStefan Roese 0x600, 0x600));
1676f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1677f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1678f1df9364SStefan Roese 0x1800, 0xf800));
1679f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1680f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1681f1df9364SStefan Roese ((t_rfc & 0x380) >> 7) << 16, 0x70000));
1682f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1683f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG, 0,
1684f1df9364SStefan Roese 0x380000));
1685f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1686f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1687f1df9364SStefan Roese (t_mod & 0xf) << 25, 0x1e00000));
1688f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1689f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1690f1df9364SStefan Roese (t_mod >> 4) << 30, 0xc0000000));
1691f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1692f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1693f1df9364SStefan Roese 0x16000000, 0x1e000000));
1694f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
1695f1df9364SStefan Roese SDRAM_TIMING_HIGH_REG,
1696f1df9364SStefan Roese 0x40000000, 0xc0000000));
1697f1df9364SStefan Roese
1698f1df9364SStefan Roese return MV_OK;
1699f1df9364SStefan Roese }
1700f1df9364SStefan Roese
1701f1df9364SStefan Roese /*
1702f1df9364SStefan Roese * Mode Read
1703f1df9364SStefan Roese */
hws_ddr3_tip_mode_read(u32 dev_num,struct mode_info * mode_info)1704f1df9364SStefan Roese int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info)
1705f1df9364SStefan Roese {
1706f1df9364SStefan Roese u32 ret;
1707f1df9364SStefan Roese
1708f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1709f1df9364SStefan Roese MR0_REG, mode_info->reg_mr0, MASK_ALL_BITS);
1710f1df9364SStefan Roese if (ret != MV_OK)
1711f1df9364SStefan Roese return ret;
1712f1df9364SStefan Roese
1713f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1714f1df9364SStefan Roese MR1_REG, mode_info->reg_mr1, MASK_ALL_BITS);
1715f1df9364SStefan Roese if (ret != MV_OK)
1716f1df9364SStefan Roese return ret;
1717f1df9364SStefan Roese
1718f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1719f1df9364SStefan Roese MR2_REG, mode_info->reg_mr2, MASK_ALL_BITS);
1720f1df9364SStefan Roese if (ret != MV_OK)
1721f1df9364SStefan Roese return ret;
1722f1df9364SStefan Roese
1723f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1724f1df9364SStefan Roese MR3_REG, mode_info->reg_mr2, MASK_ALL_BITS);
1725f1df9364SStefan Roese if (ret != MV_OK)
1726f1df9364SStefan Roese return ret;
1727f1df9364SStefan Roese
1728f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1729f1df9364SStefan Roese READ_DATA_SAMPLE_DELAY, mode_info->read_data_sample,
1730f1df9364SStefan Roese MASK_ALL_BITS);
1731f1df9364SStefan Roese if (ret != MV_OK)
1732f1df9364SStefan Roese return ret;
1733f1df9364SStefan Roese
1734f1df9364SStefan Roese ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1735f1df9364SStefan Roese READ_DATA_READY_DELAY, mode_info->read_data_ready,
1736f1df9364SStefan Roese MASK_ALL_BITS);
1737f1df9364SStefan Roese if (ret != MV_OK)
1738f1df9364SStefan Roese return ret;
1739f1df9364SStefan Roese
1740f1df9364SStefan Roese return MV_OK;
1741f1df9364SStefan Roese }
1742f1df9364SStefan Roese
1743f1df9364SStefan Roese /*
1744f1df9364SStefan Roese * Get first active IF
1745f1df9364SStefan Roese */
ddr3_tip_get_first_active_if(u8 dev_num,u32 interface_mask,u32 * interface_id)1746f1df9364SStefan Roese int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask,
1747f1df9364SStefan Roese u32 *interface_id)
1748f1df9364SStefan Roese {
1749f1df9364SStefan Roese u32 if_id;
1750f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1751f1df9364SStefan Roese
1752f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1753f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1754f1df9364SStefan Roese if (interface_mask & (1 << if_id)) {
1755f1df9364SStefan Roese *interface_id = if_id;
1756f1df9364SStefan Roese break;
1757f1df9364SStefan Roese }
1758f1df9364SStefan Roese }
1759f1df9364SStefan Roese
1760f1df9364SStefan Roese return MV_OK;
1761f1df9364SStefan Roese }
1762f1df9364SStefan Roese
1763f1df9364SStefan Roese /*
1764f1df9364SStefan Roese * Write CS Result
1765f1df9364SStefan Roese */
ddr3_tip_write_cs_result(u32 dev_num,u32 offset)1766f1df9364SStefan Roese int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
1767f1df9364SStefan Roese {
1768f1df9364SStefan Roese u32 if_id, bus_num, cs_bitmask, data_val, cs_num;
1769f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1770f1df9364SStefan Roese
1771f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1772f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1773f1df9364SStefan Roese for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
1774f1df9364SStefan Roese bus_num++) {
1775f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
1776f1df9364SStefan Roese cs_bitmask =
1777f1df9364SStefan Roese tm->interface_params[if_id].
1778f1df9364SStefan Roese as_bus_params[bus_num].cs_bitmask;
1779f1df9364SStefan Roese if (cs_bitmask != effective_cs) {
1780f1df9364SStefan Roese cs_num = GET_CS_FROM_MASK(cs_bitmask);
1781f1df9364SStefan Roese ddr3_tip_bus_read(dev_num, if_id,
1782f1df9364SStefan Roese ACCESS_TYPE_UNICAST, bus_num,
1783f1df9364SStefan Roese DDR_PHY_DATA,
1784f1df9364SStefan Roese offset +
1785f1df9364SStefan Roese CS_REG_VALUE(effective_cs),
1786f1df9364SStefan Roese &data_val);
1787f1df9364SStefan Roese ddr3_tip_bus_write(dev_num,
1788f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1789f1df9364SStefan Roese if_id,
1790f1df9364SStefan Roese ACCESS_TYPE_UNICAST,
1791f1df9364SStefan Roese bus_num, DDR_PHY_DATA,
1792f1df9364SStefan Roese offset +
1793f1df9364SStefan Roese CS_REG_VALUE(cs_num),
1794f1df9364SStefan Roese data_val);
1795f1df9364SStefan Roese }
1796f1df9364SStefan Roese }
1797f1df9364SStefan Roese }
1798f1df9364SStefan Roese
1799f1df9364SStefan Roese return MV_OK;
1800f1df9364SStefan Roese }
1801f1df9364SStefan Roese
1802f1df9364SStefan Roese /*
1803f1df9364SStefan Roese * Write MRS
1804f1df9364SStefan Roese */
ddr3_tip_write_mrs_cmd(u32 dev_num,u32 * cs_mask_arr,u32 cmd,u32 data,u32 mask)1805f1df9364SStefan Roese int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, u32 cmd,
1806f1df9364SStefan Roese u32 data, u32 mask)
1807f1df9364SStefan Roese {
1808f1df9364SStefan Roese u32 if_id, reg;
1809f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1810f1df9364SStefan Roese
1811f1df9364SStefan Roese reg = (cmd == MRS1_CMD) ? MR1_REG : MR2_REG;
1812f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1813f1df9364SStefan Roese PARAM_NOT_CARE, reg, data, mask));
1814f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1815f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1816f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1817f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1818f1df9364SStefan Roese SDRAM_OPERATION_REG,
1819f1df9364SStefan Roese (cs_mask_arr[if_id] << 8) | cmd, 0xf1f));
1820f1df9364SStefan Roese }
1821f1df9364SStefan Roese
1822f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1823f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1824f1df9364SStefan Roese if (ddr3_tip_if_polling(dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
1825f1df9364SStefan Roese 0x1f, SDRAM_OPERATION_REG,
1826f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
1827f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
1828f1df9364SStefan Roese ("write_mrs_cmd: Poll cmd fail"));
1829f1df9364SStefan Roese }
1830f1df9364SStefan Roese }
1831f1df9364SStefan Roese
1832f1df9364SStefan Roese return MV_OK;
1833f1df9364SStefan Roese }
1834f1df9364SStefan Roese
1835f1df9364SStefan Roese /*
1836f1df9364SStefan Roese * Reset XSB Read FIFO
1837f1df9364SStefan Roese */
ddr3_tip_reset_fifo_ptr(u32 dev_num)1838f1df9364SStefan Roese int ddr3_tip_reset_fifo_ptr(u32 dev_num)
1839f1df9364SStefan Roese {
1840f1df9364SStefan Roese u32 if_id = 0;
1841f1df9364SStefan Roese
1842f1df9364SStefan Roese /* Configure PHY reset value to 0 in order to "clean" the FIFO */
1843f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1844f1df9364SStefan Roese if_id, 0x15c8, 0, 0xff000000));
1845f1df9364SStefan Roese /*
1846f1df9364SStefan Roese * Move PHY to RL mode (only in RL mode the PHY overrides FIFO values
1847f1df9364SStefan Roese * during FIFO reset)
1848f1df9364SStefan Roese */
1849f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1850f1df9364SStefan Roese if_id, TRAINING_SW_2_REG,
1851f1df9364SStefan Roese 0x1, 0x9));
1852f1df9364SStefan Roese /* In order that above configuration will influence the PHY */
1853f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1854f1df9364SStefan Roese if_id, 0x15b0,
1855f1df9364SStefan Roese 0x80000000, 0x80000000));
1856f1df9364SStefan Roese /* Reset read fifo assertion */
1857f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1858f1df9364SStefan Roese if_id, 0x1400, 0, 0x40000000));
1859f1df9364SStefan Roese /* Reset read fifo deassertion */
1860f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1861f1df9364SStefan Roese if_id, 0x1400,
1862f1df9364SStefan Roese 0x40000000, 0x40000000));
1863f1df9364SStefan Roese /* Move PHY back to functional mode */
1864f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1865f1df9364SStefan Roese if_id, TRAINING_SW_2_REG,
1866f1df9364SStefan Roese 0x8, 0x9));
1867f1df9364SStefan Roese /* Stop training machine */
1868f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1869f1df9364SStefan Roese if_id, 0x15b4, 0x10000, 0x10000));
1870f1df9364SStefan Roese
1871f1df9364SStefan Roese return MV_OK;
1872f1df9364SStefan Roese }
1873f1df9364SStefan Roese
1874f1df9364SStefan Roese /*
1875f1df9364SStefan Roese * Reset Phy registers
1876f1df9364SStefan Roese */
ddr3_tip_ddr3_reset_phy_regs(u32 dev_num)1877f1df9364SStefan Roese int ddr3_tip_ddr3_reset_phy_regs(u32 dev_num)
1878f1df9364SStefan Roese {
1879f1df9364SStefan Roese u32 if_id, phy_id, cs;
1880f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1881f1df9364SStefan Roese
1882f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
1883f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1884f1df9364SStefan Roese for (phy_id = 0; phy_id < tm->num_of_bus_per_interface;
1885f1df9364SStefan Roese phy_id++) {
1886f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
1887f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1888f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST,
1889f1df9364SStefan Roese if_id, ACCESS_TYPE_UNICAST,
1890f1df9364SStefan Roese phy_id, DDR_PHY_DATA,
1891f1df9364SStefan Roese WL_PHY_REG +
1892f1df9364SStefan Roese CS_REG_VALUE(effective_cs),
1893f1df9364SStefan Roese phy_reg0_val));
1894f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1895f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1896f1df9364SStefan Roese ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
1897f1df9364SStefan Roese RL_PHY_REG + CS_REG_VALUE(effective_cs),
1898f1df9364SStefan Roese phy_reg2_val));
1899f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1900f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1901f1df9364SStefan Roese ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
1902f1df9364SStefan Roese READ_CENTRALIZATION_PHY_REG +
1903f1df9364SStefan Roese CS_REG_VALUE(effective_cs), phy_reg3_val));
1904f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1905f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id,
1906f1df9364SStefan Roese ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
1907f1df9364SStefan Roese WRITE_CENTRALIZATION_PHY_REG +
1908f1df9364SStefan Roese CS_REG_VALUE(effective_cs), phy_reg3_val));
1909f1df9364SStefan Roese }
1910f1df9364SStefan Roese }
1911f1df9364SStefan Roese
1912f1df9364SStefan Roese /* Set Receiver Calibration value */
1913f1df9364SStefan Roese for (cs = 0; cs < MAX_CS_NUM; cs++) {
1914f1df9364SStefan Roese /* PHY register 0xdb bits[5:0] - configure to 63 */
1915f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_bus_write
1916f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1917f1df9364SStefan Roese ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1918f1df9364SStefan Roese DDR_PHY_DATA, CSN_IOB_VREF_REG(cs), 63));
1919f1df9364SStefan Roese }
1920f1df9364SStefan Roese
1921f1df9364SStefan Roese return MV_OK;
1922f1df9364SStefan Roese }
1923f1df9364SStefan Roese
1924f1df9364SStefan Roese /*
1925f1df9364SStefan Roese * Restore Dunit registers
1926f1df9364SStefan Roese */
ddr3_tip_restore_dunit_regs(u32 dev_num)1927f1df9364SStefan Roese int ddr3_tip_restore_dunit_regs(u32 dev_num)
1928f1df9364SStefan Roese {
1929f1df9364SStefan Roese u32 index_cnt;
1930f1df9364SStefan Roese
1931f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1932f1df9364SStefan Roese PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
1933f1df9364SStefan Roese 0x1, 0x1));
1934f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1935f1df9364SStefan Roese PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
1936f1df9364SStefan Roese calibration_update_control << 3,
1937f1df9364SStefan Roese 0x3 << 3));
1938f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
1939f1df9364SStefan Roese PARAM_NOT_CARE,
1940f1df9364SStefan Roese ODPG_WRITE_READ_MODE_ENABLE_REG,
1941f1df9364SStefan Roese 0xffff, MASK_ALL_BITS));
1942f1df9364SStefan Roese
1943f1df9364SStefan Roese for (index_cnt = 0; index_cnt < ARRAY_SIZE(odpg_default_value);
1944f1df9364SStefan Roese index_cnt++) {
1945f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
1946f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
1947f1df9364SStefan Roese odpg_default_value[index_cnt].reg_addr,
1948f1df9364SStefan Roese odpg_default_value[index_cnt].reg_data,
1949f1df9364SStefan Roese odpg_default_value[index_cnt].reg_mask));
1950f1df9364SStefan Roese }
1951f1df9364SStefan Roese
1952f1df9364SStefan Roese return MV_OK;
1953f1df9364SStefan Roese }
1954f1df9364SStefan Roese
1955f1df9364SStefan Roese /*
1956f1df9364SStefan Roese * Auto tune main flow
1957f1df9364SStefan Roese */
ddr3_tip_ddr3_training_main_flow(u32 dev_num)1958f1df9364SStefan Roese static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
1959f1df9364SStefan Roese {
1960f1df9364SStefan Roese enum hws_ddr_freq freq = init_freq;
1961f1df9364SStefan Roese struct init_cntr_param init_cntr_prm;
1962f1df9364SStefan Roese int ret = MV_OK;
1963f1df9364SStefan Roese u32 if_id;
1964f1df9364SStefan Roese u32 max_cs = hws_ddr3_tip_max_cs_get();
1965f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
1966f1df9364SStefan Roese
1967f1df9364SStefan Roese #ifndef EXCLUDE_SWITCH_DEBUG
1968f1df9364SStefan Roese if (debug_training == DEBUG_LEVEL_TRACE) {
1969f1df9364SStefan Roese CHECK_STATUS(print_device_info((u8)dev_num));
1970f1df9364SStefan Roese }
1971f1df9364SStefan Roese #endif
1972f1df9364SStefan Roese
1973f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
1974f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_ddr3_reset_phy_regs(dev_num));
1975f1df9364SStefan Roese }
1976f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
1977f1df9364SStefan Roese effective_cs = 0;
1978f1df9364SStefan Roese
1979f1df9364SStefan Roese freq = init_freq;
1980f1df9364SStefan Roese if (is_pll_before_init != 0) {
1981f1df9364SStefan Roese for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
1982f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
1983f1df9364SStefan Roese config_func_info[dev_num].tip_set_freq_divider_func(
1984f1df9364SStefan Roese (u8)dev_num, if_id, freq);
1985f1df9364SStefan Roese }
1986f1df9364SStefan Roese }
1987f1df9364SStefan Roese
1988f1df9364SStefan Roese if (is_adll_calib_before_init != 0) {
1989f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
1990f1df9364SStefan Roese ("with adll calib before init\n"));
1991f1df9364SStefan Roese adll_calibration(dev_num, ACCESS_TYPE_MULTICAST, 0, freq);
1992f1df9364SStefan Roese }
1993f1df9364SStefan Roese
1994f1df9364SStefan Roese if (is_reg_dump != 0) {
1995f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
1996f1df9364SStefan Roese ("Dump before init controller\n"));
1997f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
1998f1df9364SStefan Roese }
1999f1df9364SStefan Roese
2000f1df9364SStefan Roese if (mask_tune_func & INIT_CONTROLLER_MASK_BIT) {
2001f1df9364SStefan Roese training_stage = INIT_CONTROLLER;
2002f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2003f1df9364SStefan Roese ("INIT_CONTROLLER_MASK_BIT\n"));
2004f1df9364SStefan Roese init_cntr_prm.do_mrs_phy = 1;
2005f1df9364SStefan Roese init_cntr_prm.is_ctrl64_bit = 0;
2006f1df9364SStefan Roese init_cntr_prm.init_phy = 1;
2007f1df9364SStefan Roese init_cntr_prm.msys_init = 0;
2008f1df9364SStefan Roese ret = hws_ddr3_tip_init_controller(dev_num, &init_cntr_prm);
2009f1df9364SStefan Roese if (is_reg_dump != 0)
2010f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2011f1df9364SStefan Roese if (ret != MV_OK) {
2012f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2013f1df9364SStefan Roese ("hws_ddr3_tip_init_controller failure\n"));
2014f1df9364SStefan Roese if (debug_mode == 0)
2015f1df9364SStefan Roese return MV_FAIL;
2016f1df9364SStefan Roese }
2017f1df9364SStefan Roese }
2018f1df9364SStefan Roese
2019f1df9364SStefan Roese #ifdef STATIC_ALGO_SUPPORT
2020f1df9364SStefan Roese if (mask_tune_func & STATIC_LEVELING_MASK_BIT) {
2021f1df9364SStefan Roese training_stage = STATIC_LEVELING;
2022f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2023f1df9364SStefan Roese ("STATIC_LEVELING_MASK_BIT\n"));
2024f1df9364SStefan Roese ret = ddr3_tip_run_static_alg(dev_num, freq);
2025f1df9364SStefan Roese if (is_reg_dump != 0)
2026f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2027f1df9364SStefan Roese if (ret != MV_OK) {
2028f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2029f1df9364SStefan Roese ("ddr3_tip_run_static_alg failure\n"));
2030f1df9364SStefan Roese if (debug_mode == 0)
2031f1df9364SStefan Roese return MV_FAIL;
2032f1df9364SStefan Roese }
2033f1df9364SStefan Roese }
2034f1df9364SStefan Roese #endif
2035f1df9364SStefan Roese
2036f1df9364SStefan Roese if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
2037f1df9364SStefan Roese training_stage = SET_LOW_FREQ;
2038f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2039f1df9364SStefan Roese ("SET_LOW_FREQ_MASK_BIT %d\n",
2040f1df9364SStefan Roese freq_val[low_freq]));
2041f1df9364SStefan Roese ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
2042f1df9364SStefan Roese PARAM_NOT_CARE, low_freq);
2043f1df9364SStefan Roese if (is_reg_dump != 0)
2044f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2045f1df9364SStefan Roese if (ret != MV_OK) {
2046f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2047f1df9364SStefan Roese ("ddr3_tip_freq_set failure\n"));
2048f1df9364SStefan Roese if (debug_mode == 0)
2049f1df9364SStefan Roese return MV_FAIL;
2050f1df9364SStefan Roese }
2051f1df9364SStefan Roese }
2052f1df9364SStefan Roese
2053f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2054f1df9364SStefan Roese if (mask_tune_func & LOAD_PATTERN_MASK_BIT) {
2055f1df9364SStefan Roese training_stage = LOAD_PATTERN;
2056f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2057f1df9364SStefan Roese ("LOAD_PATTERN_MASK_BIT #%d\n",
2058f1df9364SStefan Roese effective_cs));
2059f1df9364SStefan Roese ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
2060f1df9364SStefan Roese if (is_reg_dump != 0)
2061f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2062f1df9364SStefan Roese if (ret != MV_OK) {
2063f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2064f1df9364SStefan Roese ("ddr3_tip_load_all_pattern_to_mem failure CS #%d\n",
2065f1df9364SStefan Roese effective_cs));
2066f1df9364SStefan Roese if (debug_mode == 0)
2067f1df9364SStefan Roese return MV_FAIL;
2068f1df9364SStefan Roese }
2069f1df9364SStefan Roese }
2070f1df9364SStefan Roese }
2071f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2072f1df9364SStefan Roese effective_cs = 0;
2073f1df9364SStefan Roese
2074f1df9364SStefan Roese if (mask_tune_func & SET_MEDIUM_FREQ_MASK_BIT) {
2075f1df9364SStefan Roese training_stage = SET_MEDIUM_FREQ;
2076f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2077f1df9364SStefan Roese ("SET_MEDIUM_FREQ_MASK_BIT %d\n",
2078f1df9364SStefan Roese freq_val[medium_freq]));
2079f1df9364SStefan Roese ret =
2080f1df9364SStefan Roese ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
2081f1df9364SStefan Roese PARAM_NOT_CARE, medium_freq);
2082f1df9364SStefan Roese if (is_reg_dump != 0)
2083f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2084f1df9364SStefan Roese if (ret != MV_OK) {
2085f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2086f1df9364SStefan Roese ("ddr3_tip_freq_set failure\n"));
2087f1df9364SStefan Roese if (debug_mode == 0)
2088f1df9364SStefan Roese return MV_FAIL;
2089f1df9364SStefan Roese }
2090f1df9364SStefan Roese }
2091f1df9364SStefan Roese
2092f1df9364SStefan Roese if (mask_tune_func & WRITE_LEVELING_MASK_BIT) {
2093f1df9364SStefan Roese training_stage = WRITE_LEVELING;
2094f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2095f1df9364SStefan Roese ("WRITE_LEVELING_MASK_BIT\n"));
2096f1df9364SStefan Roese if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) {
2097f1df9364SStefan Roese ret = ddr3_tip_dynamic_write_leveling(dev_num);
2098f1df9364SStefan Roese } else {
2099f1df9364SStefan Roese /* Use old WL */
2100f1df9364SStefan Roese ret = ddr3_tip_legacy_dynamic_write_leveling(dev_num);
2101f1df9364SStefan Roese }
2102f1df9364SStefan Roese
2103f1df9364SStefan Roese if (is_reg_dump != 0)
2104f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2105f1df9364SStefan Roese if (ret != MV_OK) {
2106f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2107f1df9364SStefan Roese ("ddr3_tip_dynamic_write_leveling failure\n"));
2108f1df9364SStefan Roese if (debug_mode == 0)
2109f1df9364SStefan Roese return MV_FAIL;
2110f1df9364SStefan Roese }
2111f1df9364SStefan Roese }
2112f1df9364SStefan Roese
2113f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2114f1df9364SStefan Roese if (mask_tune_func & LOAD_PATTERN_2_MASK_BIT) {
2115f1df9364SStefan Roese training_stage = LOAD_PATTERN_2;
2116f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2117f1df9364SStefan Roese ("LOAD_PATTERN_2_MASK_BIT CS #%d\n",
2118f1df9364SStefan Roese effective_cs));
2119f1df9364SStefan Roese ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
2120f1df9364SStefan Roese if (is_reg_dump != 0)
2121f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2122f1df9364SStefan Roese if (ret != MV_OK) {
2123f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2124f1df9364SStefan Roese ("ddr3_tip_load_all_pattern_to_mem failure CS #%d\n",
2125f1df9364SStefan Roese effective_cs));
2126f1df9364SStefan Roese if (debug_mode == 0)
2127f1df9364SStefan Roese return MV_FAIL;
2128f1df9364SStefan Roese }
2129f1df9364SStefan Roese }
2130f1df9364SStefan Roese }
2131f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2132f1df9364SStefan Roese effective_cs = 0;
2133f1df9364SStefan Roese
2134f1df9364SStefan Roese if (mask_tune_func & READ_LEVELING_MASK_BIT) {
2135f1df9364SStefan Roese training_stage = READ_LEVELING;
2136f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2137f1df9364SStefan Roese ("READ_LEVELING_MASK_BIT\n"));
2138f1df9364SStefan Roese if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) {
2139f1df9364SStefan Roese ret = ddr3_tip_dynamic_read_leveling(dev_num, medium_freq);
2140f1df9364SStefan Roese } else {
2141f1df9364SStefan Roese /* Use old RL */
2142f1df9364SStefan Roese ret = ddr3_tip_legacy_dynamic_read_leveling(dev_num);
2143f1df9364SStefan Roese }
2144f1df9364SStefan Roese
2145f1df9364SStefan Roese if (is_reg_dump != 0)
2146f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2147f1df9364SStefan Roese if (ret != MV_OK) {
2148f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2149f1df9364SStefan Roese ("ddr3_tip_dynamic_read_leveling failure\n"));
2150f1df9364SStefan Roese if (debug_mode == 0)
2151f1df9364SStefan Roese return MV_FAIL;
2152f1df9364SStefan Roese }
2153f1df9364SStefan Roese }
2154f1df9364SStefan Roese
2155f1df9364SStefan Roese if (mask_tune_func & WRITE_LEVELING_SUPP_MASK_BIT) {
2156f1df9364SStefan Roese training_stage = WRITE_LEVELING_SUPP;
2157f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2158f1df9364SStefan Roese ("WRITE_LEVELING_SUPP_MASK_BIT\n"));
2159f1df9364SStefan Roese ret = ddr3_tip_dynamic_write_leveling_supp(dev_num);
2160f1df9364SStefan Roese if (is_reg_dump != 0)
2161f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2162f1df9364SStefan Roese if (ret != MV_OK) {
2163f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2164f1df9364SStefan Roese ("ddr3_tip_dynamic_write_leveling_supp failure\n"));
2165f1df9364SStefan Roese if (debug_mode == 0)
2166f1df9364SStefan Roese return MV_FAIL;
2167f1df9364SStefan Roese }
2168f1df9364SStefan Roese }
2169f1df9364SStefan Roese
2170f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2171f1df9364SStefan Roese if (mask_tune_func & PBS_RX_MASK_BIT) {
2172f1df9364SStefan Roese training_stage = PBS_RX;
2173f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2174f1df9364SStefan Roese ("PBS_RX_MASK_BIT CS #%d\n",
2175f1df9364SStefan Roese effective_cs));
2176f1df9364SStefan Roese ret = ddr3_tip_pbs_rx(dev_num);
2177f1df9364SStefan Roese if (is_reg_dump != 0)
2178f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2179f1df9364SStefan Roese if (ret != MV_OK) {
2180f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2181f1df9364SStefan Roese ("ddr3_tip_pbs_rx failure CS #%d\n",
2182f1df9364SStefan Roese effective_cs));
2183f1df9364SStefan Roese if (debug_mode == 0)
2184f1df9364SStefan Roese return MV_FAIL;
2185f1df9364SStefan Roese }
2186f1df9364SStefan Roese }
2187f1df9364SStefan Roese }
2188f1df9364SStefan Roese
2189f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2190f1df9364SStefan Roese if (mask_tune_func & PBS_TX_MASK_BIT) {
2191f1df9364SStefan Roese training_stage = PBS_TX;
2192f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2193f1df9364SStefan Roese ("PBS_TX_MASK_BIT CS #%d\n",
2194f1df9364SStefan Roese effective_cs));
2195f1df9364SStefan Roese ret = ddr3_tip_pbs_tx(dev_num);
2196f1df9364SStefan Roese if (is_reg_dump != 0)
2197f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2198f1df9364SStefan Roese if (ret != MV_OK) {
2199f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2200f1df9364SStefan Roese ("ddr3_tip_pbs_tx failure CS #%d\n",
2201f1df9364SStefan Roese effective_cs));
2202f1df9364SStefan Roese if (debug_mode == 0)
2203f1df9364SStefan Roese return MV_FAIL;
2204f1df9364SStefan Roese }
2205f1df9364SStefan Roese }
2206f1df9364SStefan Roese }
2207f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2208f1df9364SStefan Roese effective_cs = 0;
2209f1df9364SStefan Roese
2210f1df9364SStefan Roese if (mask_tune_func & SET_TARGET_FREQ_MASK_BIT) {
2211f1df9364SStefan Roese training_stage = SET_TARGET_FREQ;
2212f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2213f1df9364SStefan Roese ("SET_TARGET_FREQ_MASK_BIT %d\n",
2214f1df9364SStefan Roese freq_val[tm->
2215f1df9364SStefan Roese interface_params[first_active_if].
2216f1df9364SStefan Roese memory_freq]));
2217f1df9364SStefan Roese ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
2218f1df9364SStefan Roese PARAM_NOT_CARE,
2219f1df9364SStefan Roese tm->interface_params[first_active_if].
2220f1df9364SStefan Roese memory_freq);
2221f1df9364SStefan Roese if (is_reg_dump != 0)
2222f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2223f1df9364SStefan Roese if (ret != MV_OK) {
2224f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2225f1df9364SStefan Roese ("ddr3_tip_freq_set failure\n"));
2226f1df9364SStefan Roese if (debug_mode == 0)
2227f1df9364SStefan Roese return MV_FAIL;
2228f1df9364SStefan Roese }
2229f1df9364SStefan Roese }
2230f1df9364SStefan Roese
2231f1df9364SStefan Roese if (mask_tune_func & WRITE_LEVELING_TF_MASK_BIT) {
2232f1df9364SStefan Roese training_stage = WRITE_LEVELING_TF;
2233f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2234f1df9364SStefan Roese ("WRITE_LEVELING_TF_MASK_BIT\n"));
2235f1df9364SStefan Roese ret = ddr3_tip_dynamic_write_leveling(dev_num);
2236f1df9364SStefan Roese if (is_reg_dump != 0)
2237f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2238f1df9364SStefan Roese if (ret != MV_OK) {
2239f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2240f1df9364SStefan Roese ("ddr3_tip_dynamic_write_leveling TF failure\n"));
2241f1df9364SStefan Roese if (debug_mode == 0)
2242f1df9364SStefan Roese return MV_FAIL;
2243f1df9364SStefan Roese }
2244f1df9364SStefan Roese }
2245f1df9364SStefan Roese
2246f1df9364SStefan Roese if (mask_tune_func & LOAD_PATTERN_HIGH_MASK_BIT) {
2247f1df9364SStefan Roese training_stage = LOAD_PATTERN_HIGH;
2248f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("LOAD_PATTERN_HIGH\n"));
2249f1df9364SStefan Roese ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
2250f1df9364SStefan Roese if (is_reg_dump != 0)
2251f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2252f1df9364SStefan Roese if (ret != MV_OK) {
2253f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2254f1df9364SStefan Roese ("ddr3_tip_load_all_pattern_to_mem failure\n"));
2255f1df9364SStefan Roese if (debug_mode == 0)
2256f1df9364SStefan Roese return MV_FAIL;
2257f1df9364SStefan Roese }
2258f1df9364SStefan Roese }
2259f1df9364SStefan Roese
2260f1df9364SStefan Roese if (mask_tune_func & READ_LEVELING_TF_MASK_BIT) {
2261f1df9364SStefan Roese training_stage = READ_LEVELING_TF;
2262f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2263f1df9364SStefan Roese ("READ_LEVELING_TF_MASK_BIT\n"));
2264f1df9364SStefan Roese ret = ddr3_tip_dynamic_read_leveling(dev_num, tm->
2265f1df9364SStefan Roese interface_params[first_active_if].
2266f1df9364SStefan Roese memory_freq);
2267f1df9364SStefan Roese if (is_reg_dump != 0)
2268f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2269f1df9364SStefan Roese if (ret != MV_OK) {
2270f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2271f1df9364SStefan Roese ("ddr3_tip_dynamic_read_leveling TF failure\n"));
2272f1df9364SStefan Roese if (debug_mode == 0)
2273f1df9364SStefan Roese return MV_FAIL;
2274f1df9364SStefan Roese }
2275f1df9364SStefan Roese }
2276f1df9364SStefan Roese
2277f1df9364SStefan Roese if (mask_tune_func & DM_PBS_TX_MASK_BIT) {
2278f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DM_PBS_TX_MASK_BIT\n"));
2279f1df9364SStefan Roese }
2280f1df9364SStefan Roese
2281f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2282f1df9364SStefan Roese if (mask_tune_func & VREF_CALIBRATION_MASK_BIT) {
2283f1df9364SStefan Roese training_stage = VREF_CALIBRATION;
2284f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("VREF\n"));
2285f1df9364SStefan Roese ret = ddr3_tip_vref(dev_num);
2286f1df9364SStefan Roese if (is_reg_dump != 0) {
2287f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2288f1df9364SStefan Roese ("VREF Dump\n"));
2289f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2290f1df9364SStefan Roese }
2291f1df9364SStefan Roese if (ret != MV_OK) {
2292f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2293f1df9364SStefan Roese ("ddr3_tip_vref failure\n"));
2294f1df9364SStefan Roese if (debug_mode == 0)
2295f1df9364SStefan Roese return MV_FAIL;
2296f1df9364SStefan Roese }
2297f1df9364SStefan Roese }
2298f1df9364SStefan Roese }
2299f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2300f1df9364SStefan Roese effective_cs = 0;
2301f1df9364SStefan Roese
2302f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2303f1df9364SStefan Roese if (mask_tune_func & CENTRALIZATION_RX_MASK_BIT) {
2304f1df9364SStefan Roese training_stage = CENTRALIZATION_RX;
2305f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2306f1df9364SStefan Roese ("CENTRALIZATION_RX_MASK_BIT CS #%d\n",
2307f1df9364SStefan Roese effective_cs));
2308f1df9364SStefan Roese ret = ddr3_tip_centralization_rx(dev_num);
2309f1df9364SStefan Roese if (is_reg_dump != 0)
2310f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2311f1df9364SStefan Roese if (ret != MV_OK) {
2312f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2313f1df9364SStefan Roese ("ddr3_tip_centralization_rx failure CS #%d\n",
2314f1df9364SStefan Roese effective_cs));
2315f1df9364SStefan Roese if (debug_mode == 0)
2316f1df9364SStefan Roese return MV_FAIL;
2317f1df9364SStefan Roese }
2318f1df9364SStefan Roese }
2319f1df9364SStefan Roese }
2320f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2321f1df9364SStefan Roese effective_cs = 0;
2322f1df9364SStefan Roese
2323f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2324f1df9364SStefan Roese if (mask_tune_func & WRITE_LEVELING_SUPP_TF_MASK_BIT) {
2325f1df9364SStefan Roese training_stage = WRITE_LEVELING_SUPP_TF;
2326f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2327f1df9364SStefan Roese ("WRITE_LEVELING_SUPP_TF_MASK_BIT CS #%d\n",
2328f1df9364SStefan Roese effective_cs));
2329f1df9364SStefan Roese ret = ddr3_tip_dynamic_write_leveling_supp(dev_num);
2330f1df9364SStefan Roese if (is_reg_dump != 0)
2331f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2332f1df9364SStefan Roese if (ret != MV_OK) {
2333f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2334f1df9364SStefan Roese ("ddr3_tip_dynamic_write_leveling_supp TF failure CS #%d\n",
2335f1df9364SStefan Roese effective_cs));
2336f1df9364SStefan Roese if (debug_mode == 0)
2337f1df9364SStefan Roese return MV_FAIL;
2338f1df9364SStefan Roese }
2339f1df9364SStefan Roese }
2340f1df9364SStefan Roese }
2341f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2342f1df9364SStefan Roese effective_cs = 0;
2343f1df9364SStefan Roese
2344f1df9364SStefan Roese for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
2345f1df9364SStefan Roese if (mask_tune_func & CENTRALIZATION_TX_MASK_BIT) {
2346f1df9364SStefan Roese training_stage = CENTRALIZATION_TX;
2347f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2348f1df9364SStefan Roese ("CENTRALIZATION_TX_MASK_BIT CS #%d\n",
2349f1df9364SStefan Roese effective_cs));
2350f1df9364SStefan Roese ret = ddr3_tip_centralization_tx(dev_num);
2351f1df9364SStefan Roese if (is_reg_dump != 0)
2352f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2353f1df9364SStefan Roese if (ret != MV_OK) {
2354f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2355f1df9364SStefan Roese ("ddr3_tip_centralization_tx failure CS #%d\n",
2356f1df9364SStefan Roese effective_cs));
2357f1df9364SStefan Roese if (debug_mode == 0)
2358f1df9364SStefan Roese return MV_FAIL;
2359f1df9364SStefan Roese }
2360f1df9364SStefan Roese }
2361f1df9364SStefan Roese }
2362f1df9364SStefan Roese /* Set to 0 after each loop to avoid illegal value may be used */
2363f1df9364SStefan Roese effective_cs = 0;
2364f1df9364SStefan Roese
2365f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("restore registers to default\n"));
2366f1df9364SStefan Roese /* restore register values */
2367f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_restore_dunit_regs(dev_num));
2368f1df9364SStefan Roese
2369f1df9364SStefan Roese if (is_reg_dump != 0)
2370f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2371f1df9364SStefan Roese
2372f1df9364SStefan Roese return MV_OK;
2373f1df9364SStefan Roese }
2374f1df9364SStefan Roese
2375f1df9364SStefan Roese /*
2376f1df9364SStefan Roese * DDR3 Dynamic training flow
2377f1df9364SStefan Roese */
ddr3_tip_ddr3_auto_tune(u32 dev_num)2378f1df9364SStefan Roese static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
2379f1df9364SStefan Roese {
2380f1df9364SStefan Roese u32 if_id, stage, ret;
2381f1df9364SStefan Roese int is_if_fail = 0, is_auto_tune_fail = 0;
2382f1df9364SStefan Roese
2383f1df9364SStefan Roese training_stage = INIT_CONTROLLER;
2384f1df9364SStefan Roese
2385f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
2386f1df9364SStefan Roese for (stage = 0; stage < MAX_STAGE_LIMIT; stage++)
2387f1df9364SStefan Roese training_result[stage][if_id] = NO_TEST_DONE;
2388f1df9364SStefan Roese }
2389f1df9364SStefan Roese
2390f1df9364SStefan Roese ret = ddr3_tip_ddr3_training_main_flow(dev_num);
2391f1df9364SStefan Roese
2392f1df9364SStefan Roese /* activate XSB test */
2393f1df9364SStefan Roese if (xsb_validate_type != 0) {
2394f1df9364SStefan Roese run_xsb_test(dev_num, xsb_validation_base_address, 1, 1,
2395f1df9364SStefan Roese 0x1024);
2396f1df9364SStefan Roese }
2397f1df9364SStefan Roese
2398f1df9364SStefan Roese if (is_reg_dump != 0)
2399f1df9364SStefan Roese ddr3_tip_reg_dump(dev_num);
2400f1df9364SStefan Roese
2401f1df9364SStefan Roese /* print log */
2402f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_print_log(dev_num, window_mem_addr));
2403f1df9364SStefan Roese
2404f1df9364SStefan Roese if (ret != MV_OK) {
2405f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_print_stability_log(dev_num));
2406f1df9364SStefan Roese }
2407f1df9364SStefan Roese
2408f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
2409f1df9364SStefan Roese is_if_fail = 0;
2410f1df9364SStefan Roese for (stage = 0; stage < MAX_STAGE_LIMIT; stage++) {
2411f1df9364SStefan Roese if (training_result[stage][if_id] == TEST_FAILED)
2412f1df9364SStefan Roese is_if_fail = 1;
2413f1df9364SStefan Roese }
2414f1df9364SStefan Roese if (is_if_fail == 1) {
2415f1df9364SStefan Roese is_auto_tune_fail = 1;
2416f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
2417f1df9364SStefan Roese ("Auto Tune failed for IF %d\n",
2418f1df9364SStefan Roese if_id));
2419f1df9364SStefan Roese }
2420f1df9364SStefan Roese }
2421f1df9364SStefan Roese
2422f1df9364SStefan Roese if ((ret == MV_FAIL) || (is_auto_tune_fail == 1))
2423f1df9364SStefan Roese return MV_FAIL;
2424f1df9364SStefan Roese else
2425f1df9364SStefan Roese return MV_OK;
2426f1df9364SStefan Roese }
2427f1df9364SStefan Roese
2428f1df9364SStefan Roese /*
2429f1df9364SStefan Roese * Enable init sequence
2430f1df9364SStefan Roese */
ddr3_tip_enable_init_sequence(u32 dev_num)2431f1df9364SStefan Roese int ddr3_tip_enable_init_sequence(u32 dev_num)
2432f1df9364SStefan Roese {
2433f1df9364SStefan Roese int is_fail = 0;
2434f1df9364SStefan Roese u32 if_id = 0, mem_mask = 0, bus_index = 0;
2435f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
2436f1df9364SStefan Roese
2437f1df9364SStefan Roese /* Enable init sequence */
2438f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, 0,
2439f1df9364SStefan Roese SDRAM_INIT_CONTROL_REG, 0x1, 0x1));
2440f1df9364SStefan Roese
2441f1df9364SStefan Roese for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
2442f1df9364SStefan Roese VALIDATE_ACTIVE(tm->if_act_mask, if_id);
2443f1df9364SStefan Roese
2444f1df9364SStefan Roese if (ddr3_tip_if_polling
2445f1df9364SStefan Roese (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1,
2446f1df9364SStefan Roese SDRAM_INIT_CONTROL_REG,
2447f1df9364SStefan Roese MAX_POLLING_ITERATIONS) != MV_OK) {
2448f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2449f1df9364SStefan Roese ("polling failed IF %d\n",
2450f1df9364SStefan Roese if_id));
2451f1df9364SStefan Roese is_fail = 1;
2452f1df9364SStefan Roese continue;
2453f1df9364SStefan Roese }
2454f1df9364SStefan Roese
2455f1df9364SStefan Roese mem_mask = 0;
2456f1df9364SStefan Roese for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
2457f1df9364SStefan Roese bus_index++) {
2458f1df9364SStefan Roese VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
2459f1df9364SStefan Roese mem_mask |=
2460f1df9364SStefan Roese tm->interface_params[if_id].
2461f1df9364SStefan Roese as_bus_params[bus_index].mirror_enable_bitmask;
2462f1df9364SStefan Roese }
2463f1df9364SStefan Roese
2464f1df9364SStefan Roese if (mem_mask != 0) {
2465f1df9364SStefan Roese /* Disable Multi CS */
2466f1df9364SStefan Roese CHECK_STATUS(ddr3_tip_if_write
2467f1df9364SStefan Roese (dev_num, ACCESS_TYPE_MULTICAST,
2468f1df9364SStefan Roese if_id, CS_ENABLE_REG, 1 << 3,
2469f1df9364SStefan Roese 1 << 3));
2470f1df9364SStefan Roese }
2471f1df9364SStefan Roese }
2472f1df9364SStefan Roese
2473f1df9364SStefan Roese return (is_fail == 0) ? MV_OK : MV_FAIL;
2474f1df9364SStefan Roese }
2475f1df9364SStefan Roese
ddr3_tip_register_dq_table(u32 dev_num,u32 * table)2476f1df9364SStefan Roese int ddr3_tip_register_dq_table(u32 dev_num, u32 *table)
2477f1df9364SStefan Roese {
2478f1df9364SStefan Roese dq_map_table = table;
2479f1df9364SStefan Roese
2480f1df9364SStefan Roese return MV_OK;
2481f1df9364SStefan Roese }
2482f1df9364SStefan Roese
2483f1df9364SStefan Roese /*
2484f1df9364SStefan Roese * Check if pup search is locked
2485f1df9364SStefan Roese */
ddr3_tip_is_pup_lock(u32 * pup_buf,enum hws_training_result read_mode)2486f1df9364SStefan Roese int ddr3_tip_is_pup_lock(u32 *pup_buf, enum hws_training_result read_mode)
2487f1df9364SStefan Roese {
2488f1df9364SStefan Roese u32 bit_start = 0, bit_end = 0, bit_id;
2489f1df9364SStefan Roese
2490f1df9364SStefan Roese if (read_mode == RESULT_PER_BIT) {
2491f1df9364SStefan Roese bit_start = 0;
2492f1df9364SStefan Roese bit_end = BUS_WIDTH_IN_BITS - 1;
2493f1df9364SStefan Roese } else {
2494f1df9364SStefan Roese bit_start = 0;
2495f1df9364SStefan Roese bit_end = 0;
2496f1df9364SStefan Roese }
2497f1df9364SStefan Roese
2498f1df9364SStefan Roese for (bit_id = bit_start; bit_id <= bit_end; bit_id++) {
2499f1df9364SStefan Roese if (GET_LOCK_RESULT(pup_buf[bit_id]) == 0)
2500f1df9364SStefan Roese return 0;
2501f1df9364SStefan Roese }
2502f1df9364SStefan Roese
2503f1df9364SStefan Roese return 1;
2504f1df9364SStefan Roese }
2505f1df9364SStefan Roese
2506f1df9364SStefan Roese /*
2507f1df9364SStefan Roese * Get minimum buffer value
2508f1df9364SStefan Roese */
ddr3_tip_get_buf_min(u8 * buf_ptr)2509f1df9364SStefan Roese u8 ddr3_tip_get_buf_min(u8 *buf_ptr)
2510f1df9364SStefan Roese {
2511f1df9364SStefan Roese u8 min_val = 0xff;
2512f1df9364SStefan Roese u8 cnt = 0;
2513f1df9364SStefan Roese
2514f1df9364SStefan Roese for (cnt = 0; cnt < BUS_WIDTH_IN_BITS; cnt++) {
2515f1df9364SStefan Roese if (buf_ptr[cnt] < min_val)
2516f1df9364SStefan Roese min_val = buf_ptr[cnt];
2517f1df9364SStefan Roese }
2518f1df9364SStefan Roese
2519f1df9364SStefan Roese return min_val;
2520f1df9364SStefan Roese }
2521f1df9364SStefan Roese
2522f1df9364SStefan Roese /*
2523f1df9364SStefan Roese * Get maximum buffer value
2524f1df9364SStefan Roese */
ddr3_tip_get_buf_max(u8 * buf_ptr)2525f1df9364SStefan Roese u8 ddr3_tip_get_buf_max(u8 *buf_ptr)
2526f1df9364SStefan Roese {
2527f1df9364SStefan Roese u8 max_val = 0;
2528f1df9364SStefan Roese u8 cnt = 0;
2529f1df9364SStefan Roese
2530f1df9364SStefan Roese for (cnt = 0; cnt < BUS_WIDTH_IN_BITS; cnt++) {
2531f1df9364SStefan Roese if (buf_ptr[cnt] > max_val)
2532f1df9364SStefan Roese max_val = buf_ptr[cnt];
2533f1df9364SStefan Roese }
2534f1df9364SStefan Roese
2535f1df9364SStefan Roese return max_val;
2536f1df9364SStefan Roese }
2537f1df9364SStefan Roese
2538f1df9364SStefan Roese /*
2539f1df9364SStefan Roese * The following functions return memory parameters:
2540f1df9364SStefan Roese * bus and device width, device size
2541f1df9364SStefan Roese */
2542f1df9364SStefan Roese
hws_ddr3_get_bus_width(void)2543f1df9364SStefan Roese u32 hws_ddr3_get_bus_width(void)
2544f1df9364SStefan Roese {
2545f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
2546f1df9364SStefan Roese
2547f1df9364SStefan Roese return (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) ==
2548f1df9364SStefan Roese 1) ? 16 : 32;
2549f1df9364SStefan Roese }
2550f1df9364SStefan Roese
hws_ddr3_get_device_width(u32 if_id)2551f1df9364SStefan Roese u32 hws_ddr3_get_device_width(u32 if_id)
2552f1df9364SStefan Roese {
2553f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
2554f1df9364SStefan Roese
2555f1df9364SStefan Roese return (tm->interface_params[if_id].bus_width ==
2556f1df9364SStefan Roese BUS_WIDTH_8) ? 8 : 16;
2557f1df9364SStefan Roese }
2558f1df9364SStefan Roese
hws_ddr3_get_device_size(u32 if_id)2559f1df9364SStefan Roese u32 hws_ddr3_get_device_size(u32 if_id)
2560f1df9364SStefan Roese {
2561f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
2562f1df9364SStefan Roese
2563f1df9364SStefan Roese if (tm->interface_params[if_id].memory_size >=
2564f1df9364SStefan Roese MEM_SIZE_LAST) {
2565f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2566f1df9364SStefan Roese ("Error: Wrong device size of Cs: %d",
2567f1df9364SStefan Roese tm->interface_params[if_id].memory_size));
2568f1df9364SStefan Roese return 0;
2569f1df9364SStefan Roese } else {
2570f1df9364SStefan Roese return 1 << tm->interface_params[if_id].memory_size;
2571f1df9364SStefan Roese }
2572f1df9364SStefan Roese }
2573f1df9364SStefan Roese
hws_ddr3_calc_mem_cs_size(u32 if_id,u32 cs,u32 * cs_size)2574f1df9364SStefan Roese int hws_ddr3_calc_mem_cs_size(u32 if_id, u32 cs, u32 *cs_size)
2575f1df9364SStefan Roese {
2576f1df9364SStefan Roese u32 cs_mem_size, dev_size;
2577f1df9364SStefan Roese
2578f1df9364SStefan Roese dev_size = hws_ddr3_get_device_size(if_id);
2579f1df9364SStefan Roese if (dev_size != 0) {
2580f1df9364SStefan Roese cs_mem_size = ((hws_ddr3_get_bus_width() /
2581f1df9364SStefan Roese hws_ddr3_get_device_width(if_id)) * dev_size);
2582f1df9364SStefan Roese
2583f1df9364SStefan Roese /* the calculated result in Gbytex16 to avoid float using */
2584f1df9364SStefan Roese
2585f1df9364SStefan Roese if (cs_mem_size == 2) {
2586f1df9364SStefan Roese *cs_size = _128M;
2587f1df9364SStefan Roese } else if (cs_mem_size == 4) {
2588f1df9364SStefan Roese *cs_size = _256M;
2589f1df9364SStefan Roese } else if (cs_mem_size == 8) {
2590f1df9364SStefan Roese *cs_size = _512M;
2591f1df9364SStefan Roese } else if (cs_mem_size == 16) {
2592f1df9364SStefan Roese *cs_size = _1G;
2593f1df9364SStefan Roese } else if (cs_mem_size == 32) {
2594f1df9364SStefan Roese *cs_size = _2G;
2595f1df9364SStefan Roese } else {
2596f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2597f1df9364SStefan Roese ("Error: Wrong Memory size of Cs: %d", cs));
2598f1df9364SStefan Roese return MV_FAIL;
2599f1df9364SStefan Roese }
2600f1df9364SStefan Roese return MV_OK;
2601f1df9364SStefan Roese } else {
2602f1df9364SStefan Roese return MV_FAIL;
2603f1df9364SStefan Roese }
2604f1df9364SStefan Roese }
2605f1df9364SStefan Roese
hws_ddr3_cs_base_adr_calc(u32 if_id,u32 cs,u32 * cs_base_addr)2606f1df9364SStefan Roese int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr)
2607f1df9364SStefan Roese {
2608f1df9364SStefan Roese u32 cs_mem_size = 0;
2609f1df9364SStefan Roese #ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
2610f1df9364SStefan Roese u32 physical_mem_size;
2611f1df9364SStefan Roese u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
2612f1df9364SStefan Roese #endif
2613f1df9364SStefan Roese
2614f1df9364SStefan Roese if (hws_ddr3_calc_mem_cs_size(if_id, cs, &cs_mem_size) != MV_OK)
2615f1df9364SStefan Roese return MV_FAIL;
2616f1df9364SStefan Roese
2617f1df9364SStefan Roese #ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
2618f1df9364SStefan Roese struct hws_topology_map *tm = ddr3_get_topology_map();
2619f1df9364SStefan Roese /*
2620f1df9364SStefan Roese * if number of address pins doesn't allow to use max mem size that
2621f1df9364SStefan Roese * is defined in topology mem size is defined by
2622f1df9364SStefan Roese * DEVICE_MAX_DRAM_ADDRESS_SIZE
2623f1df9364SStefan Roese */
2624f1df9364SStefan Roese physical_mem_size =
2625f1df9364SStefan Roese mv_hwsmem_size[tm->interface_params[0].memory_size];
2626f1df9364SStefan Roese
2627f1df9364SStefan Roese if (hws_ddr3_get_device_width(cs) == 16) {
2628f1df9364SStefan Roese /*
2629f1df9364SStefan Roese * 16bit mem device can be twice more - no need in less
2630f1df9364SStefan Roese * significant pin
2631f1df9364SStefan Roese */
2632f1df9364SStefan Roese max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2;
2633f1df9364SStefan Roese }
2634f1df9364SStefan Roese
2635f1df9364SStefan Roese if (physical_mem_size > max_mem_size) {
2636f1df9364SStefan Roese cs_mem_size = max_mem_size *
2637f1df9364SStefan Roese (hws_ddr3_get_bus_width() /
2638f1df9364SStefan Roese hws_ddr3_get_device_width(if_id));
2639f1df9364SStefan Roese DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
2640f1df9364SStefan Roese ("Updated Physical Mem size is from 0x%x to %x\n",
2641f1df9364SStefan Roese physical_mem_size,
2642f1df9364SStefan Roese DEVICE_MAX_DRAM_ADDRESS_SIZE));
2643f1df9364SStefan Roese }
2644f1df9364SStefan Roese #endif
2645f1df9364SStefan Roese
2646f1df9364SStefan Roese /* calculate CS base addr */
2647f1df9364SStefan Roese *cs_base_addr = ((cs_mem_size) * cs) & 0xffff0000;
2648f1df9364SStefan Roese
2649f1df9364SStefan Roese return MV_OK;
2650f1df9364SStefan Roese }
2651