1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) Marvell International Ltd. and its affiliates
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <i2c.h>
9*4882a593Smuzhiyun #include <spl.h>
10*4882a593Smuzhiyun #include <asm/io.h>
11*4882a593Smuzhiyun #include <asm/arch/cpu.h>
12*4882a593Smuzhiyun #include <asm/arch/soc.h>
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun #include "ddr3_init.h"
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define A38X_NUMBER_OF_INTERFACES 5
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #define SAR_DEV_ID_OFFS 27
19*4882a593Smuzhiyun #define SAR_DEV_ID_MASK 0x7
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* Termal Sensor Registers */
22*4882a593Smuzhiyun #define TSEN_STATE_REG 0xe4070
23*4882a593Smuzhiyun #define TSEN_STATE_OFFSET 31
24*4882a593Smuzhiyun #define TSEN_STATE_MASK (0x1 << TSEN_STATE_OFFSET)
25*4882a593Smuzhiyun #define TSEN_CONF_REG 0xe4074
26*4882a593Smuzhiyun #define TSEN_CONF_RST_OFFSET 8
27*4882a593Smuzhiyun #define TSEN_CONF_RST_MASK (0x1 << TSEN_CONF_RST_OFFSET)
28*4882a593Smuzhiyun #define TSEN_STATUS_REG 0xe4078
29*4882a593Smuzhiyun #define TSEN_STATUS_READOUT_VALID_OFFSET 10
30*4882a593Smuzhiyun #define TSEN_STATUS_READOUT_VALID_MASK (0x1 << \
31*4882a593Smuzhiyun TSEN_STATUS_READOUT_VALID_OFFSET)
32*4882a593Smuzhiyun #define TSEN_STATUS_TEMP_OUT_OFFSET 0
33*4882a593Smuzhiyun #define TSEN_STATUS_TEMP_OUT_MASK (0x3ff << TSEN_STATUS_TEMP_OUT_OFFSET)
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun static struct dfx_access interface_map[] = {
36*4882a593Smuzhiyun /* Pipe Client */
37*4882a593Smuzhiyun { 0, 17 },
38*4882a593Smuzhiyun { 1, 7 },
39*4882a593Smuzhiyun { 1, 11 },
40*4882a593Smuzhiyun { 0, 3 },
41*4882a593Smuzhiyun { 1, 25 },
42*4882a593Smuzhiyun { 0, 0 },
43*4882a593Smuzhiyun { 0, 0 },
44*4882a593Smuzhiyun { 0, 0 },
45*4882a593Smuzhiyun { 0, 0 },
46*4882a593Smuzhiyun { 0, 0 },
47*4882a593Smuzhiyun { 0, 0 },
48*4882a593Smuzhiyun { 0, 0 }
49*4882a593Smuzhiyun };
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /* This array hold the board round trip delay (DQ and CK) per <interface,bus> */
52*4882a593Smuzhiyun struct trip_delay_element a38x_board_round_trip_delay_array[] = {
53*4882a593Smuzhiyun /* 1st board */
54*4882a593Smuzhiyun /* Interface bus DQS-delay CK-delay */
55*4882a593Smuzhiyun { 3952, 5060 },
56*4882a593Smuzhiyun { 3192, 4493 },
57*4882a593Smuzhiyun { 4785, 6677 },
58*4882a593Smuzhiyun { 3413, 7267 },
59*4882a593Smuzhiyun { 4282, 6086 }, /* ECC PUP */
60*4882a593Smuzhiyun { 3952, 5134 },
61*4882a593Smuzhiyun { 3192, 4567 },
62*4882a593Smuzhiyun { 4785, 6751 },
63*4882a593Smuzhiyun { 3413, 7341 },
64*4882a593Smuzhiyun { 4282, 6160 }, /* ECC PUP */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /* 2nd board */
67*4882a593Smuzhiyun /* Interface bus DQS-delay CK-delay */
68*4882a593Smuzhiyun { 3952, 5060 },
69*4882a593Smuzhiyun { 3192, 4493 },
70*4882a593Smuzhiyun { 4785, 6677 },
71*4882a593Smuzhiyun { 3413, 7267 },
72*4882a593Smuzhiyun { 4282, 6086 }, /* ECC PUP */
73*4882a593Smuzhiyun { 3952, 5134 },
74*4882a593Smuzhiyun { 3192, 4567 },
75*4882a593Smuzhiyun { 4785, 6751 },
76*4882a593Smuzhiyun { 3413, 7341 },
77*4882a593Smuzhiyun { 4282, 6160 } /* ECC PUP */
78*4882a593Smuzhiyun };
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun #ifdef STATIC_ALGO_SUPPORT
81*4882a593Smuzhiyun /* package trace */
82*4882a593Smuzhiyun static struct trip_delay_element a38x_package_round_trip_delay_array[] = {
83*4882a593Smuzhiyun /* IF BUS DQ_DELAY CK_DELAY */
84*4882a593Smuzhiyun { 0, 0 },
85*4882a593Smuzhiyun { 0, 0 },
86*4882a593Smuzhiyun { 0, 0 },
87*4882a593Smuzhiyun { 0, 0 },
88*4882a593Smuzhiyun { 0, 0 },
89*4882a593Smuzhiyun { 0, 0 },
90*4882a593Smuzhiyun { 0, 0 },
91*4882a593Smuzhiyun { 0, 0 },
92*4882a593Smuzhiyun { 0, 0 },
93*4882a593Smuzhiyun { 0, 0 },
94*4882a593Smuzhiyun { 0, 0 },
95*4882a593Smuzhiyun { 0, 0 },
96*4882a593Smuzhiyun { 0, 0 },
97*4882a593Smuzhiyun { 0, 0 },
98*4882a593Smuzhiyun { 0, 0 },
99*4882a593Smuzhiyun { 0, 0 },
100*4882a593Smuzhiyun { 0, 0 },
101*4882a593Smuzhiyun { 0, 0 },
102*4882a593Smuzhiyun { 0, 0 },
103*4882a593Smuzhiyun { 0, 0 }
104*4882a593Smuzhiyun };
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun static int a38x_silicon_delay_offset[] = {
107*4882a593Smuzhiyun /* board 0 */
108*4882a593Smuzhiyun 0,
109*4882a593Smuzhiyun /* board 1 */
110*4882a593Smuzhiyun 0,
111*4882a593Smuzhiyun /* board 2 */
112*4882a593Smuzhiyun 0
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun #endif
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun static u8 a38x_bw_per_freq[DDR_FREQ_LIMIT] = {
117*4882a593Smuzhiyun 0x3, /* DDR_FREQ_100 */
118*4882a593Smuzhiyun 0x4, /* DDR_FREQ_400 */
119*4882a593Smuzhiyun 0x4, /* DDR_FREQ_533 */
120*4882a593Smuzhiyun 0x5, /* DDR_FREQ_667 */
121*4882a593Smuzhiyun 0x5, /* DDR_FREQ_800 */
122*4882a593Smuzhiyun 0x5, /* DDR_FREQ_933 */
123*4882a593Smuzhiyun 0x5, /* DDR_FREQ_1066 */
124*4882a593Smuzhiyun 0x3, /* DDR_FREQ_311 */
125*4882a593Smuzhiyun 0x3, /* DDR_FREQ_333 */
126*4882a593Smuzhiyun 0x4, /* DDR_FREQ_467 */
127*4882a593Smuzhiyun 0x5, /* DDR_FREQ_850 */
128*4882a593Smuzhiyun 0x5, /* DDR_FREQ_600 */
129*4882a593Smuzhiyun 0x3, /* DDR_FREQ_300 */
130*4882a593Smuzhiyun 0x5, /* DDR_FREQ_900 */
131*4882a593Smuzhiyun 0x3, /* DDR_FREQ_360 */
132*4882a593Smuzhiyun 0x5 /* DDR_FREQ_1000 */
133*4882a593Smuzhiyun };
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun static u8 a38x_rate_per_freq[DDR_FREQ_LIMIT] = {
136*4882a593Smuzhiyun /*TBD*/ 0x1, /* DDR_FREQ_100 */
137*4882a593Smuzhiyun 0x2, /* DDR_FREQ_400 */
138*4882a593Smuzhiyun 0x2, /* DDR_FREQ_533 */
139*4882a593Smuzhiyun 0x2, /* DDR_FREQ_667 */
140*4882a593Smuzhiyun 0x2, /* DDR_FREQ_800 */
141*4882a593Smuzhiyun 0x3, /* DDR_FREQ_933 */
142*4882a593Smuzhiyun 0x3, /* DDR_FREQ_1066 */
143*4882a593Smuzhiyun 0x1, /* DDR_FREQ_311 */
144*4882a593Smuzhiyun 0x1, /* DDR_FREQ_333 */
145*4882a593Smuzhiyun 0x2, /* DDR_FREQ_467 */
146*4882a593Smuzhiyun 0x2, /* DDR_FREQ_850 */
147*4882a593Smuzhiyun 0x2, /* DDR_FREQ_600 */
148*4882a593Smuzhiyun 0x1, /* DDR_FREQ_300 */
149*4882a593Smuzhiyun 0x2, /* DDR_FREQ_900 */
150*4882a593Smuzhiyun 0x1, /* DDR_FREQ_360 */
151*4882a593Smuzhiyun 0x2 /* DDR_FREQ_1000 */
152*4882a593Smuzhiyun };
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun static u16 a38x_vco_freq_per_sar[] = {
155*4882a593Smuzhiyun 666, /* 0 */
156*4882a593Smuzhiyun 1332,
157*4882a593Smuzhiyun 800,
158*4882a593Smuzhiyun 1600,
159*4882a593Smuzhiyun 1066,
160*4882a593Smuzhiyun 2132,
161*4882a593Smuzhiyun 1200,
162*4882a593Smuzhiyun 2400,
163*4882a593Smuzhiyun 1332,
164*4882a593Smuzhiyun 1332,
165*4882a593Smuzhiyun 1500,
166*4882a593Smuzhiyun 1500,
167*4882a593Smuzhiyun 1600, /* 12 */
168*4882a593Smuzhiyun 1600,
169*4882a593Smuzhiyun 1700,
170*4882a593Smuzhiyun 1700,
171*4882a593Smuzhiyun 1866,
172*4882a593Smuzhiyun 1866,
173*4882a593Smuzhiyun 1800, /* 18 */
174*4882a593Smuzhiyun 2000,
175*4882a593Smuzhiyun 2000,
176*4882a593Smuzhiyun 4000,
177*4882a593Smuzhiyun 2132,
178*4882a593Smuzhiyun 2132,
179*4882a593Smuzhiyun 2300,
180*4882a593Smuzhiyun 2300,
181*4882a593Smuzhiyun 2400,
182*4882a593Smuzhiyun 2400,
183*4882a593Smuzhiyun 2500,
184*4882a593Smuzhiyun 2500,
185*4882a593Smuzhiyun 800
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun u32 pipe_multicast_mask;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun u32 dq_bit_map_2_phy_pin[] = {
191*4882a593Smuzhiyun 1, 0, 2, 6, 9, 8, 3, 7, /* 0 */
192*4882a593Smuzhiyun 8, 9, 1, 7, 2, 6, 3, 0, /* 1 */
193*4882a593Smuzhiyun 3, 9, 7, 8, 1, 0, 2, 6, /* 2 */
194*4882a593Smuzhiyun 1, 0, 6, 2, 8, 3, 7, 9, /* 3 */
195*4882a593Smuzhiyun 0, 1, 2, 9, 7, 8, 3, 6, /* 4 */
196*4882a593Smuzhiyun };
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
199*4882a593Smuzhiyun enum hws_ddr_freq freq);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /*
202*4882a593Smuzhiyun * Read temperature TJ value
203*4882a593Smuzhiyun */
ddr3_ctrl_get_junc_temp(u8 dev_num)204*4882a593Smuzhiyun u32 ddr3_ctrl_get_junc_temp(u8 dev_num)
205*4882a593Smuzhiyun {
206*4882a593Smuzhiyun int reg = 0;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* Initiates TSEN hardware reset once */
209*4882a593Smuzhiyun if ((reg_read(TSEN_CONF_REG) & TSEN_CONF_RST_MASK) == 0)
210*4882a593Smuzhiyun reg_bit_set(TSEN_CONF_REG, TSEN_CONF_RST_MASK);
211*4882a593Smuzhiyun mdelay(10);
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun /* Check if the readout field is valid */
214*4882a593Smuzhiyun if ((reg_read(TSEN_STATUS_REG) & TSEN_STATUS_READOUT_VALID_MASK) == 0) {
215*4882a593Smuzhiyun printf("%s: TSEN not ready\n", __func__);
216*4882a593Smuzhiyun return 0;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun reg = reg_read(TSEN_STATUS_REG);
220*4882a593Smuzhiyun reg = (reg & TSEN_STATUS_TEMP_OUT_MASK) >> TSEN_STATUS_TEMP_OUT_OFFSET;
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun return ((((10000 * reg) / 21445) * 1000) - 272674) / 1000;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun /*
226*4882a593Smuzhiyun * Name: ddr3_tip_a38x_get_freq_config.
227*4882a593Smuzhiyun * Desc:
228*4882a593Smuzhiyun * Args:
229*4882a593Smuzhiyun * Notes:
230*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
231*4882a593Smuzhiyun */
ddr3_tip_a38x_get_freq_config(u8 dev_num,enum hws_ddr_freq freq,struct hws_tip_freq_config_info * freq_config_info)232*4882a593Smuzhiyun int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
233*4882a593Smuzhiyun struct hws_tip_freq_config_info
234*4882a593Smuzhiyun *freq_config_info)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun if (a38x_bw_per_freq[freq] == 0xff)
237*4882a593Smuzhiyun return MV_NOT_SUPPORTED;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (freq_config_info == NULL)
240*4882a593Smuzhiyun return MV_BAD_PARAM;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun freq_config_info->bw_per_freq = a38x_bw_per_freq[freq];
243*4882a593Smuzhiyun freq_config_info->rate_per_freq = a38x_rate_per_freq[freq];
244*4882a593Smuzhiyun freq_config_info->is_supported = 1;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun return MV_OK;
247*4882a593Smuzhiyun }
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun /*
250*4882a593Smuzhiyun * Name: ddr3_tip_a38x_pipe_enable.
251*4882a593Smuzhiyun * Desc:
252*4882a593Smuzhiyun * Args:
253*4882a593Smuzhiyun * Notes:
254*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
255*4882a593Smuzhiyun */
ddr3_tip_a38x_pipe_enable(u8 dev_num,enum hws_access_type interface_access,u32 if_id,int enable)256*4882a593Smuzhiyun int ddr3_tip_a38x_pipe_enable(u8 dev_num, enum hws_access_type interface_access,
257*4882a593Smuzhiyun u32 if_id, int enable)
258*4882a593Smuzhiyun {
259*4882a593Smuzhiyun u32 data_value, pipe_enable_mask = 0;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun if (enable == 0) {
262*4882a593Smuzhiyun pipe_enable_mask = 0;
263*4882a593Smuzhiyun } else {
264*4882a593Smuzhiyun if (interface_access == ACCESS_TYPE_MULTICAST)
265*4882a593Smuzhiyun pipe_enable_mask = pipe_multicast_mask;
266*4882a593Smuzhiyun else
267*4882a593Smuzhiyun pipe_enable_mask = (1 << interface_map[if_id].pipe);
268*4882a593Smuzhiyun }
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_reg_read
271*4882a593Smuzhiyun (dev_num, PIPE_ENABLE_ADDR, &data_value, MASK_ALL_BITS));
272*4882a593Smuzhiyun data_value = (data_value & (~0xff)) | pipe_enable_mask;
273*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_reg_write(dev_num, PIPE_ENABLE_ADDR, data_value));
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun return MV_OK;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun * Name: ddr3_tip_a38x_if_write.
280*4882a593Smuzhiyun * Desc:
281*4882a593Smuzhiyun * Args:
282*4882a593Smuzhiyun * Notes:
283*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
284*4882a593Smuzhiyun */
ddr3_tip_a38x_if_write(u8 dev_num,enum hws_access_type interface_access,u32 if_id,u32 reg_addr,u32 data_value,u32 mask)285*4882a593Smuzhiyun int ddr3_tip_a38x_if_write(u8 dev_num, enum hws_access_type interface_access,
286*4882a593Smuzhiyun u32 if_id, u32 reg_addr, u32 data_value,
287*4882a593Smuzhiyun u32 mask)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun u32 ui_data_read;
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun if (mask != MASK_ALL_BITS) {
292*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_read
293*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, reg_addr,
294*4882a593Smuzhiyun &ui_data_read, MASK_ALL_BITS));
295*4882a593Smuzhiyun data_value = (ui_data_read & (~mask)) | (data_value & mask);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun reg_write(reg_addr, data_value);
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun return MV_OK;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun /*
304*4882a593Smuzhiyun * Name: ddr3_tip_a38x_if_read.
305*4882a593Smuzhiyun * Desc:
306*4882a593Smuzhiyun * Args:
307*4882a593Smuzhiyun * Notes:
308*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
309*4882a593Smuzhiyun */
ddr3_tip_a38x_if_read(u8 dev_num,enum hws_access_type interface_access,u32 if_id,u32 reg_addr,u32 * data,u32 mask)310*4882a593Smuzhiyun int ddr3_tip_a38x_if_read(u8 dev_num, enum hws_access_type interface_access,
311*4882a593Smuzhiyun u32 if_id, u32 reg_addr, u32 *data, u32 mask)
312*4882a593Smuzhiyun {
313*4882a593Smuzhiyun *data = reg_read(reg_addr) & mask;
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun return MV_OK;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun * Name: ddr3_tip_a38x_select_ddr_controller.
320*4882a593Smuzhiyun * Desc: Enable/Disable access to Marvell's server.
321*4882a593Smuzhiyun * Args: dev_num - device number
322*4882a593Smuzhiyun * enable - whether to enable or disable the server
323*4882a593Smuzhiyun * Notes:
324*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
325*4882a593Smuzhiyun */
ddr3_tip_a38x_select_ddr_controller(u8 dev_num,int enable)326*4882a593Smuzhiyun int ddr3_tip_a38x_select_ddr_controller(u8 dev_num, int enable)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun u32 reg;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun reg = reg_read(CS_ENABLE_REG);
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun if (enable)
333*4882a593Smuzhiyun reg |= (1 << 6);
334*4882a593Smuzhiyun else
335*4882a593Smuzhiyun reg &= ~(1 << 6);
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun reg_write(CS_ENABLE_REG, reg);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun return MV_OK;
340*4882a593Smuzhiyun }
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /*
343*4882a593Smuzhiyun * Name: ddr3_tip_init_a38x_silicon.
344*4882a593Smuzhiyun * Desc: init Training SW DB.
345*4882a593Smuzhiyun * Args:
346*4882a593Smuzhiyun * Notes:
347*4882a593Smuzhiyun * Returns: MV_OK if success, other error code if fail.
348*4882a593Smuzhiyun */
ddr3_tip_init_a38x_silicon(u32 dev_num,u32 board_id)349*4882a593Smuzhiyun static int ddr3_tip_init_a38x_silicon(u32 dev_num, u32 board_id)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun struct hws_tip_config_func_db config_func;
352*4882a593Smuzhiyun enum hws_ddr_freq ddr_freq;
353*4882a593Smuzhiyun int status;
354*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* new read leveling version */
357*4882a593Smuzhiyun config_func.tip_dunit_read_func = ddr3_tip_a38x_if_read;
358*4882a593Smuzhiyun config_func.tip_dunit_write_func = ddr3_tip_a38x_if_write;
359*4882a593Smuzhiyun config_func.tip_dunit_mux_select_func =
360*4882a593Smuzhiyun ddr3_tip_a38x_select_ddr_controller;
361*4882a593Smuzhiyun config_func.tip_get_freq_config_info_func =
362*4882a593Smuzhiyun ddr3_tip_a38x_get_freq_config;
363*4882a593Smuzhiyun config_func.tip_set_freq_divider_func = ddr3_tip_a38x_set_divider;
364*4882a593Smuzhiyun config_func.tip_get_device_info_func = ddr3_tip_a38x_get_device_info;
365*4882a593Smuzhiyun config_func.tip_get_temperature = ddr3_ctrl_get_junc_temp;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun ddr3_tip_init_config_func(dev_num, &config_func);
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin);
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun #ifdef STATIC_ALGO_SUPPORT
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun struct hws_tip_static_config_info static_config;
374*4882a593Smuzhiyun u32 board_offset =
375*4882a593Smuzhiyun board_id * A38X_NUMBER_OF_INTERFACES *
376*4882a593Smuzhiyun tm->num_of_bus_per_interface;
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun static_config.silicon_delay =
379*4882a593Smuzhiyun a38x_silicon_delay_offset[board_id];
380*4882a593Smuzhiyun static_config.package_trace_arr =
381*4882a593Smuzhiyun a38x_package_round_trip_delay_array;
382*4882a593Smuzhiyun static_config.board_trace_arr =
383*4882a593Smuzhiyun &a38x_board_round_trip_delay_array[board_offset];
384*4882a593Smuzhiyun ddr3_tip_init_static_config_db(dev_num, &static_config);
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun #endif
387*4882a593Smuzhiyun status = ddr3_tip_a38x_get_init_freq(dev_num, &ddr_freq);
388*4882a593Smuzhiyun if (MV_OK != status) {
389*4882a593Smuzhiyun DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
390*4882a593Smuzhiyun ("DDR3 silicon get target frequency - FAILED 0x%x\n",
391*4882a593Smuzhiyun status));
392*4882a593Smuzhiyun return status;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun rl_version = 1;
396*4882a593Smuzhiyun mask_tune_func = (SET_LOW_FREQ_MASK_BIT |
397*4882a593Smuzhiyun LOAD_PATTERN_MASK_BIT |
398*4882a593Smuzhiyun SET_MEDIUM_FREQ_MASK_BIT | WRITE_LEVELING_MASK_BIT |
399*4882a593Smuzhiyun /* LOAD_PATTERN_2_MASK_BIT | */
400*4882a593Smuzhiyun WRITE_LEVELING_SUPP_MASK_BIT |
401*4882a593Smuzhiyun READ_LEVELING_MASK_BIT |
402*4882a593Smuzhiyun PBS_RX_MASK_BIT |
403*4882a593Smuzhiyun PBS_TX_MASK_BIT |
404*4882a593Smuzhiyun SET_TARGET_FREQ_MASK_BIT |
405*4882a593Smuzhiyun WRITE_LEVELING_TF_MASK_BIT |
406*4882a593Smuzhiyun WRITE_LEVELING_SUPP_TF_MASK_BIT |
407*4882a593Smuzhiyun READ_LEVELING_TF_MASK_BIT |
408*4882a593Smuzhiyun CENTRALIZATION_RX_MASK_BIT |
409*4882a593Smuzhiyun CENTRALIZATION_TX_MASK_BIT);
410*4882a593Smuzhiyun rl_mid_freq_wa = 1;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) {
413*4882a593Smuzhiyun mask_tune_func = (WRITE_LEVELING_MASK_BIT |
414*4882a593Smuzhiyun LOAD_PATTERN_2_MASK_BIT |
415*4882a593Smuzhiyun WRITE_LEVELING_SUPP_MASK_BIT |
416*4882a593Smuzhiyun READ_LEVELING_MASK_BIT |
417*4882a593Smuzhiyun PBS_RX_MASK_BIT |
418*4882a593Smuzhiyun PBS_TX_MASK_BIT |
419*4882a593Smuzhiyun CENTRALIZATION_RX_MASK_BIT |
420*4882a593Smuzhiyun CENTRALIZATION_TX_MASK_BIT);
421*4882a593Smuzhiyun rl_mid_freq_wa = 0; /* WA not needed if 333/400 is TF */
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /* Supplementary not supported for ECC modes */
425*4882a593Smuzhiyun if (1 == ddr3_if_ecc_enabled()) {
426*4882a593Smuzhiyun mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT;
427*4882a593Smuzhiyun mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT;
428*4882a593Smuzhiyun mask_tune_func &= ~PBS_TX_MASK_BIT;
429*4882a593Smuzhiyun mask_tune_func &= ~PBS_RX_MASK_BIT;
430*4882a593Smuzhiyun }
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun if (ck_delay == -1)
433*4882a593Smuzhiyun ck_delay = 160;
434*4882a593Smuzhiyun if (ck_delay_16 == -1)
435*4882a593Smuzhiyun ck_delay_16 = 160;
436*4882a593Smuzhiyun ca_delay = 0;
437*4882a593Smuzhiyun delay_enable = 1;
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun calibration_update_control = 1;
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun init_freq = tm->interface_params[first_active_if].memory_freq;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun return MV_OK;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
ddr3_a38x_update_topology_map(u32 dev_num,struct hws_topology_map * tm)448*4882a593Smuzhiyun int ddr3_a38x_update_topology_map(u32 dev_num, struct hws_topology_map *tm)
449*4882a593Smuzhiyun {
450*4882a593Smuzhiyun u32 if_id = 0;
451*4882a593Smuzhiyun enum hws_ddr_freq freq;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun ddr3_tip_a38x_get_init_freq(dev_num, &freq);
454*4882a593Smuzhiyun tm->interface_params[if_id].memory_freq = freq;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun /*
457*4882a593Smuzhiyun * re-calc topology parameters according to topology updates
458*4882a593Smuzhiyun * (if needed)
459*4882a593Smuzhiyun */
460*4882a593Smuzhiyun CHECK_STATUS(hws_ddr3_tip_load_topology_map(dev_num, tm));
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun return MV_OK;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
ddr3_tip_init_a38x(u32 dev_num,u32 board_id)465*4882a593Smuzhiyun int ddr3_tip_init_a38x(u32 dev_num, u32 board_id)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun if (NULL == tm)
470*4882a593Smuzhiyun return MV_FAIL;
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun ddr3_a38x_update_topology_map(dev_num, tm);
473*4882a593Smuzhiyun ddr3_tip_init_a38x_silicon(dev_num, board_id);
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun return MV_OK;
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun
ddr3_tip_a38x_get_init_freq(int dev_num,enum hws_ddr_freq * freq)478*4882a593Smuzhiyun int ddr3_tip_a38x_get_init_freq(int dev_num, enum hws_ddr_freq *freq)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun u32 reg;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* Read sample at reset setting */
483*4882a593Smuzhiyun reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
484*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
485*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
486*4882a593Smuzhiyun switch (reg) {
487*4882a593Smuzhiyun case 0x0:
488*4882a593Smuzhiyun case 0x1:
489*4882a593Smuzhiyun *freq = DDR_FREQ_333;
490*4882a593Smuzhiyun break;
491*4882a593Smuzhiyun case 0x2:
492*4882a593Smuzhiyun case 0x3:
493*4882a593Smuzhiyun *freq = DDR_FREQ_400;
494*4882a593Smuzhiyun break;
495*4882a593Smuzhiyun case 0x4:
496*4882a593Smuzhiyun case 0xd:
497*4882a593Smuzhiyun *freq = DDR_FREQ_533;
498*4882a593Smuzhiyun break;
499*4882a593Smuzhiyun case 0x6:
500*4882a593Smuzhiyun *freq = DDR_FREQ_600;
501*4882a593Smuzhiyun break;
502*4882a593Smuzhiyun case 0x8:
503*4882a593Smuzhiyun case 0x11:
504*4882a593Smuzhiyun case 0x14:
505*4882a593Smuzhiyun *freq = DDR_FREQ_667;
506*4882a593Smuzhiyun break;
507*4882a593Smuzhiyun case 0xc:
508*4882a593Smuzhiyun case 0x15:
509*4882a593Smuzhiyun case 0x1b:
510*4882a593Smuzhiyun *freq = DDR_FREQ_800;
511*4882a593Smuzhiyun break;
512*4882a593Smuzhiyun case 0x10:
513*4882a593Smuzhiyun *freq = DDR_FREQ_933;
514*4882a593Smuzhiyun break;
515*4882a593Smuzhiyun case 0x12:
516*4882a593Smuzhiyun *freq = DDR_FREQ_900;
517*4882a593Smuzhiyun break;
518*4882a593Smuzhiyun case 0x13:
519*4882a593Smuzhiyun *freq = DDR_FREQ_900;
520*4882a593Smuzhiyun break;
521*4882a593Smuzhiyun default:
522*4882a593Smuzhiyun *freq = 0;
523*4882a593Smuzhiyun return MV_NOT_SUPPORTED;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun return MV_OK;
527*4882a593Smuzhiyun }
528*4882a593Smuzhiyun
ddr3_tip_a38x_get_medium_freq(int dev_num,enum hws_ddr_freq * freq)529*4882a593Smuzhiyun int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq)
530*4882a593Smuzhiyun {
531*4882a593Smuzhiyun u32 reg;
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun /* Read sample at reset setting */
534*4882a593Smuzhiyun reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
535*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
536*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
537*4882a593Smuzhiyun switch (reg) {
538*4882a593Smuzhiyun case 0x0:
539*4882a593Smuzhiyun case 0x1:
540*4882a593Smuzhiyun /* Medium is same as TF to run PBS in this freq */
541*4882a593Smuzhiyun *freq = DDR_FREQ_333;
542*4882a593Smuzhiyun break;
543*4882a593Smuzhiyun case 0x2:
544*4882a593Smuzhiyun case 0x3:
545*4882a593Smuzhiyun /* Medium is same as TF to run PBS in this freq */
546*4882a593Smuzhiyun *freq = DDR_FREQ_400;
547*4882a593Smuzhiyun break;
548*4882a593Smuzhiyun case 0x4:
549*4882a593Smuzhiyun case 0xd:
550*4882a593Smuzhiyun *freq = DDR_FREQ_533;
551*4882a593Smuzhiyun break;
552*4882a593Smuzhiyun case 0x8:
553*4882a593Smuzhiyun case 0x11:
554*4882a593Smuzhiyun case 0x14:
555*4882a593Smuzhiyun *freq = DDR_FREQ_333;
556*4882a593Smuzhiyun break;
557*4882a593Smuzhiyun case 0xc:
558*4882a593Smuzhiyun case 0x15:
559*4882a593Smuzhiyun case 0x1b:
560*4882a593Smuzhiyun *freq = DDR_FREQ_400;
561*4882a593Smuzhiyun break;
562*4882a593Smuzhiyun case 0x6:
563*4882a593Smuzhiyun *freq = DDR_FREQ_300;
564*4882a593Smuzhiyun break;
565*4882a593Smuzhiyun case 0x12:
566*4882a593Smuzhiyun *freq = DDR_FREQ_360;
567*4882a593Smuzhiyun break;
568*4882a593Smuzhiyun case 0x13:
569*4882a593Smuzhiyun *freq = DDR_FREQ_400;
570*4882a593Smuzhiyun break;
571*4882a593Smuzhiyun default:
572*4882a593Smuzhiyun *freq = 0;
573*4882a593Smuzhiyun return MV_NOT_SUPPORTED;
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun return MV_OK;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
ddr3_tip_get_init_freq(void)579*4882a593Smuzhiyun u32 ddr3_tip_get_init_freq(void)
580*4882a593Smuzhiyun {
581*4882a593Smuzhiyun enum hws_ddr_freq freq;
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun ddr3_tip_a38x_get_init_freq(0, &freq);
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun return freq;
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun
ddr3_tip_a38x_set_divider(u8 dev_num,u32 if_id,enum hws_ddr_freq frequency)588*4882a593Smuzhiyun static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
589*4882a593Smuzhiyun enum hws_ddr_freq frequency)
590*4882a593Smuzhiyun {
591*4882a593Smuzhiyun u32 divider = 0;
592*4882a593Smuzhiyun u32 sar_val;
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (if_id != 0) {
595*4882a593Smuzhiyun DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
596*4882a593Smuzhiyun ("A38x does not support interface 0x%x\n",
597*4882a593Smuzhiyun if_id));
598*4882a593Smuzhiyun return MV_BAD_PARAM;
599*4882a593Smuzhiyun }
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun /* get VCO freq index */
602*4882a593Smuzhiyun sar_val = (reg_read(REG_DEVICE_SAR1_ADDR) >>
603*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
604*4882a593Smuzhiyun RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
605*4882a593Smuzhiyun divider = a38x_vco_freq_per_sar[sar_val] / freq_val[frequency];
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun /* Set Sync mode */
608*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
609*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x20220, 0x0,
610*4882a593Smuzhiyun 0x1000));
611*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
612*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe42f4, 0x0,
613*4882a593Smuzhiyun 0x200));
614*4882a593Smuzhiyun
615*4882a593Smuzhiyun /* cpupll_clkdiv_reset_mask */
616*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
617*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0x1f,
618*4882a593Smuzhiyun 0xff));
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun /* cpupll_clkdiv_reload_smooth */
621*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
622*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
623*4882a593Smuzhiyun (0x2 << 8), (0xff << 8)));
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun /* cpupll_clkdiv_relax_en */
626*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
627*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
628*4882a593Smuzhiyun (0x2 << 24), (0xff << 24)));
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun /* write the divider */
631*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
632*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4268,
633*4882a593Smuzhiyun (divider << 8), (0x3f << 8)));
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun /* set cpupll_clkdiv_reload_ratio */
636*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
637*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264,
638*4882a593Smuzhiyun (1 << 8), (1 << 8)));
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /* undet cpupll_clkdiv_reload_ratio */
641*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
642*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
643*4882a593Smuzhiyun (1 << 8)));
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun /* clear cpupll_clkdiv_reload_force */
646*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
647*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
648*4882a593Smuzhiyun (0xff << 8)));
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun /* clear cpupll_clkdiv_relax_en */
651*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
652*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
653*4882a593Smuzhiyun (0xff << 24)));
654*4882a593Smuzhiyun
655*4882a593Smuzhiyun /* clear cpupll_clkdiv_reset_mask */
656*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
657*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
658*4882a593Smuzhiyun 0xff));
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun /* Dunit training clock + 1:1 mode */
661*4882a593Smuzhiyun if ((frequency == DDR_FREQ_LOW_FREQ) || (freq_val[frequency] <= 400)) {
662*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
663*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
664*4882a593Smuzhiyun (1 << 16), (1 << 16)));
665*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
666*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
667*4882a593Smuzhiyun (0 << 15), (1 << 15)));
668*4882a593Smuzhiyun } else {
669*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
670*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
671*4882a593Smuzhiyun 0, (1 << 16)));
672*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_a38x_if_write
673*4882a593Smuzhiyun (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
674*4882a593Smuzhiyun (1 << 15), (1 << 15)));
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun return MV_OK;
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun /*
681*4882a593Smuzhiyun * external read from memory
682*4882a593Smuzhiyun */
ddr3_tip_ext_read(u32 dev_num,u32 if_id,u32 reg_addr,u32 num_of_bursts,u32 * data)683*4882a593Smuzhiyun int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
684*4882a593Smuzhiyun u32 num_of_bursts, u32 *data)
685*4882a593Smuzhiyun {
686*4882a593Smuzhiyun u32 burst_num;
687*4882a593Smuzhiyun
688*4882a593Smuzhiyun for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
689*4882a593Smuzhiyun data[burst_num] = readl(reg_addr + 4 * burst_num);
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun return MV_OK;
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun /*
695*4882a593Smuzhiyun * external write to memory
696*4882a593Smuzhiyun */
ddr3_tip_ext_write(u32 dev_num,u32 if_id,u32 reg_addr,u32 num_of_bursts,u32 * data)697*4882a593Smuzhiyun int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
698*4882a593Smuzhiyun u32 num_of_bursts, u32 *data) {
699*4882a593Smuzhiyun u32 burst_num;
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
702*4882a593Smuzhiyun writel(data[burst_num], reg_addr + 4 * burst_num);
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun return MV_OK;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
ddr3_silicon_pre_init(void)707*4882a593Smuzhiyun int ddr3_silicon_pre_init(void)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun return ddr3_silicon_init();
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
ddr3_post_run_alg(void)712*4882a593Smuzhiyun int ddr3_post_run_alg(void)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun return MV_OK;
715*4882a593Smuzhiyun }
716*4882a593Smuzhiyun
ddr3_silicon_post_init(void)717*4882a593Smuzhiyun int ddr3_silicon_post_init(void)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun struct hws_topology_map *tm = ddr3_get_topology_map();
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun /* Set half bus width */
722*4882a593Smuzhiyun if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)) {
723*4882a593Smuzhiyun CHECK_STATUS(ddr3_tip_if_write
724*4882a593Smuzhiyun (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
725*4882a593Smuzhiyun REG_SDRAM_CONFIG_ADDR, 0x0, 0x8000));
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
728*4882a593Smuzhiyun return MV_OK;
729*4882a593Smuzhiyun }
730*4882a593Smuzhiyun
ddr3_tip_a38x_get_device_info(u8 dev_num,struct ddr3_device_info * info_ptr)731*4882a593Smuzhiyun int ddr3_tip_a38x_get_device_info(u8 dev_num, struct ddr3_device_info *info_ptr)
732*4882a593Smuzhiyun {
733*4882a593Smuzhiyun info_ptr->device_id = 0x6800;
734*4882a593Smuzhiyun info_ptr->ck_delay = ck_delay;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun return MV_OK;
737*4882a593Smuzhiyun }
738