1*ff9112dfSStefan Roese /*
2*ff9112dfSStefan Roese * Copyright (C) Marvell International Ltd. and its affiliates
3*ff9112dfSStefan Roese *
4*ff9112dfSStefan Roese * SPDX-License-Identifier: GPL-2.0
5*ff9112dfSStefan Roese */
6*ff9112dfSStefan Roese
7*ff9112dfSStefan Roese #include <common.h>
8*ff9112dfSStefan Roese #include <i2c.h>
9*ff9112dfSStefan Roese #include <spl.h>
10*ff9112dfSStefan Roese #include <asm/io.h>
11*ff9112dfSStefan Roese #include <asm/arch/cpu.h>
12*ff9112dfSStefan Roese #include <asm/arch/soc.h>
13*ff9112dfSStefan Roese
14*ff9112dfSStefan Roese #include "ddr3_init.h"
15*ff9112dfSStefan Roese
16*ff9112dfSStefan Roese #if defined(MV88F78X60)
17*ff9112dfSStefan Roese #include "ddr3_axp_config.h"
18*ff9112dfSStefan Roese #elif defined(MV88F67XX)
19*ff9112dfSStefan Roese #include "ddr3_a370_config.h"
20*ff9112dfSStefan Roese #endif
21*ff9112dfSStefan Roese
22*ff9112dfSStefan Roese #if defined(MV88F672X)
23*ff9112dfSStefan Roese #include "ddr3_a375_config.h"
24*ff9112dfSStefan Roese #endif
25*ff9112dfSStefan Roese
26*ff9112dfSStefan Roese #ifdef DUNIT_SPD
27*ff9112dfSStefan Roese
28*ff9112dfSStefan Roese /* DIMM SPD offsets */
29*ff9112dfSStefan Roese #define SPD_DEV_TYPE_BYTE 2
30*ff9112dfSStefan Roese
31*ff9112dfSStefan Roese #define SPD_MODULE_TYPE_BYTE 3
32*ff9112dfSStefan Roese #define SPD_MODULE_MASK 0xf
33*ff9112dfSStefan Roese #define SPD_MODULE_TYPE_RDIMM 1
34*ff9112dfSStefan Roese #define SPD_MODULE_TYPE_UDIMM 2
35*ff9112dfSStefan Roese
36*ff9112dfSStefan Roese #define SPD_DEV_DENSITY_BYTE 4
37*ff9112dfSStefan Roese #define SPD_DEV_DENSITY_MASK 0xf
38*ff9112dfSStefan Roese
39*ff9112dfSStefan Roese #define SPD_ROW_NUM_BYTE 5
40*ff9112dfSStefan Roese #define SPD_ROW_NUM_MIN 12
41*ff9112dfSStefan Roese #define SPD_ROW_NUM_OFF 3
42*ff9112dfSStefan Roese #define SPD_ROW_NUM_MASK (7 << SPD_ROW_NUM_OFF)
43*ff9112dfSStefan Roese
44*ff9112dfSStefan Roese #define SPD_COL_NUM_BYTE 5
45*ff9112dfSStefan Roese #define SPD_COL_NUM_MIN 9
46*ff9112dfSStefan Roese #define SPD_COL_NUM_OFF 0
47*ff9112dfSStefan Roese #define SPD_COL_NUM_MASK (7 << SPD_COL_NUM_OFF)
48*ff9112dfSStefan Roese
49*ff9112dfSStefan Roese #define SPD_MODULE_ORG_BYTE 7
50*ff9112dfSStefan Roese #define SPD_MODULE_SDRAM_DEV_WIDTH_OFF 0
51*ff9112dfSStefan Roese #define SPD_MODULE_SDRAM_DEV_WIDTH_MASK (7 << SPD_MODULE_SDRAM_DEV_WIDTH_OFF)
52*ff9112dfSStefan Roese #define SPD_MODULE_BANK_NUM_MIN 1
53*ff9112dfSStefan Roese #define SPD_MODULE_BANK_NUM_OFF 3
54*ff9112dfSStefan Roese #define SPD_MODULE_BANK_NUM_MASK (7 << SPD_MODULE_BANK_NUM_OFF)
55*ff9112dfSStefan Roese
56*ff9112dfSStefan Roese #define SPD_BUS_WIDTH_BYTE 8
57*ff9112dfSStefan Roese #define SPD_BUS_WIDTH_OFF 0
58*ff9112dfSStefan Roese #define SPD_BUS_WIDTH_MASK (7 << SPD_BUS_WIDTH_OFF)
59*ff9112dfSStefan Roese #define SPD_BUS_ECC_OFF 3
60*ff9112dfSStefan Roese #define SPD_BUS_ECC_MASK (3 << SPD_BUS_ECC_OFF)
61*ff9112dfSStefan Roese
62*ff9112dfSStefan Roese #define SPD_MTB_DIVIDEND_BYTE 10
63*ff9112dfSStefan Roese #define SPD_MTB_DIVISOR_BYTE 11
64*ff9112dfSStefan Roese #define SPD_TCK_BYTE 12
65*ff9112dfSStefan Roese #define SPD_SUP_CAS_LAT_LSB_BYTE 14
66*ff9112dfSStefan Roese #define SPD_SUP_CAS_LAT_MSB_BYTE 15
67*ff9112dfSStefan Roese #define SPD_TAA_BYTE 16
68*ff9112dfSStefan Roese #define SPD_TWR_BYTE 17
69*ff9112dfSStefan Roese #define SPD_TRCD_BYTE 18
70*ff9112dfSStefan Roese #define SPD_TRRD_BYTE 19
71*ff9112dfSStefan Roese #define SPD_TRP_BYTE 20
72*ff9112dfSStefan Roese
73*ff9112dfSStefan Roese #define SPD_TRAS_MSB_BYTE 21
74*ff9112dfSStefan Roese #define SPD_TRAS_MSB_MASK 0xf
75*ff9112dfSStefan Roese
76*ff9112dfSStefan Roese #define SPD_TRC_MSB_BYTE 21
77*ff9112dfSStefan Roese #define SPD_TRC_MSB_MASK 0xf0
78*ff9112dfSStefan Roese
79*ff9112dfSStefan Roese #define SPD_TRAS_LSB_BYTE 22
80*ff9112dfSStefan Roese #define SPD_TRC_LSB_BYTE 23
81*ff9112dfSStefan Roese #define SPD_TRFC_LSB_BYTE 24
82*ff9112dfSStefan Roese #define SPD_TRFC_MSB_BYTE 25
83*ff9112dfSStefan Roese #define SPD_TWTR_BYTE 26
84*ff9112dfSStefan Roese #define SPD_TRTP_BYTE 27
85*ff9112dfSStefan Roese
86*ff9112dfSStefan Roese #define SPD_TFAW_MSB_BYTE 28
87*ff9112dfSStefan Roese #define SPD_TFAW_MSB_MASK 0xf
88*ff9112dfSStefan Roese
89*ff9112dfSStefan Roese #define SPD_TFAW_LSB_BYTE 29
90*ff9112dfSStefan Roese #define SPD_OPT_FEATURES_BYTE 30
91*ff9112dfSStefan Roese #define SPD_THERMAL_REFRESH_OPT_BYTE 31
92*ff9112dfSStefan Roese
93*ff9112dfSStefan Roese #define SPD_ADDR_MAP_BYTE 63
94*ff9112dfSStefan Roese #define SPD_ADDR_MAP_MIRROR_OFFS 0
95*ff9112dfSStefan Roese
96*ff9112dfSStefan Roese #define SPD_RDIMM_RC_BYTE 69
97*ff9112dfSStefan Roese #define SPD_RDIMM_RC_NIBBLE_MASK 0xF
98*ff9112dfSStefan Roese #define SPD_RDIMM_RC_NUM 16
99*ff9112dfSStefan Roese
100*ff9112dfSStefan Roese /* Dimm Memory Type values */
101*ff9112dfSStefan Roese #define SPD_MEM_TYPE_SDRAM 0x4
102*ff9112dfSStefan Roese #define SPD_MEM_TYPE_DDR1 0x7
103*ff9112dfSStefan Roese #define SPD_MEM_TYPE_DDR2 0x8
104*ff9112dfSStefan Roese #define SPD_MEM_TYPE_DDR3 0xB
105*ff9112dfSStefan Roese
106*ff9112dfSStefan Roese #define DIMM_MODULE_MANU_OFFS 64
107*ff9112dfSStefan Roese #define DIMM_MODULE_MANU_SIZE 8
108*ff9112dfSStefan Roese #define DIMM_MODULE_VEN_OFFS 73
109*ff9112dfSStefan Roese #define DIMM_MODULE_VEN_SIZE 25
110*ff9112dfSStefan Roese #define DIMM_MODULE_ID_OFFS 99
111*ff9112dfSStefan Roese #define DIMM_MODULE_ID_SIZE 18
112*ff9112dfSStefan Roese
113*ff9112dfSStefan Roese /* enumeration for voltage levels. */
114*ff9112dfSStefan Roese enum dimm_volt_if {
115*ff9112dfSStefan Roese TTL_5V_TOLERANT,
116*ff9112dfSStefan Roese LVTTL,
117*ff9112dfSStefan Roese HSTL_1_5V,
118*ff9112dfSStefan Roese SSTL_3_3V,
119*ff9112dfSStefan Roese SSTL_2_5V,
120*ff9112dfSStefan Roese VOLTAGE_UNKNOWN,
121*ff9112dfSStefan Roese };
122*ff9112dfSStefan Roese
123*ff9112dfSStefan Roese /* enumaration for SDRAM CAS Latencies. */
124*ff9112dfSStefan Roese enum dimm_sdram_cas {
125*ff9112dfSStefan Roese SD_CL_1 = 1,
126*ff9112dfSStefan Roese SD_CL_2,
127*ff9112dfSStefan Roese SD_CL_3,
128*ff9112dfSStefan Roese SD_CL_4,
129*ff9112dfSStefan Roese SD_CL_5,
130*ff9112dfSStefan Roese SD_CL_6,
131*ff9112dfSStefan Roese SD_CL_7,
132*ff9112dfSStefan Roese SD_FAULT
133*ff9112dfSStefan Roese };
134*ff9112dfSStefan Roese
135*ff9112dfSStefan Roese /* enumeration for memory types */
136*ff9112dfSStefan Roese enum memory_type {
137*ff9112dfSStefan Roese MEM_TYPE_SDRAM,
138*ff9112dfSStefan Roese MEM_TYPE_DDR1,
139*ff9112dfSStefan Roese MEM_TYPE_DDR2,
140*ff9112dfSStefan Roese MEM_TYPE_DDR3
141*ff9112dfSStefan Roese };
142*ff9112dfSStefan Roese
143*ff9112dfSStefan Roese /* DIMM information structure */
144*ff9112dfSStefan Roese typedef struct dimm_info {
145*ff9112dfSStefan Roese /* DIMM dimensions */
146*ff9112dfSStefan Roese u32 num_of_module_ranks;
147*ff9112dfSStefan Roese u32 data_width;
148*ff9112dfSStefan Roese u32 rank_capacity;
149*ff9112dfSStefan Roese u32 num_of_devices;
150*ff9112dfSStefan Roese
151*ff9112dfSStefan Roese u32 sdram_width;
152*ff9112dfSStefan Roese u32 num_of_banks_on_each_device;
153*ff9112dfSStefan Roese u32 sdram_capacity;
154*ff9112dfSStefan Roese
155*ff9112dfSStefan Roese u32 num_of_row_addr;
156*ff9112dfSStefan Roese u32 num_of_col_addr;
157*ff9112dfSStefan Roese
158*ff9112dfSStefan Roese u32 addr_mirroring;
159*ff9112dfSStefan Roese
160*ff9112dfSStefan Roese u32 err_check_type; /* ECC , PARITY.. */
161*ff9112dfSStefan Roese u32 type_info; /* DDR2 only */
162*ff9112dfSStefan Roese
163*ff9112dfSStefan Roese /* DIMM timing parameters */
164*ff9112dfSStefan Roese u32 supported_cas_latencies;
165*ff9112dfSStefan Roese u32 refresh_interval;
166*ff9112dfSStefan Roese u32 min_cycle_time;
167*ff9112dfSStefan Roese u32 min_row_precharge_time;
168*ff9112dfSStefan Roese u32 min_row_active_to_row_active;
169*ff9112dfSStefan Roese u32 min_ras_to_cas_delay;
170*ff9112dfSStefan Roese u32 min_write_recovery_time; /* DDR3/2 only */
171*ff9112dfSStefan Roese u32 min_write_to_read_cmd_delay; /* DDR3/2 only */
172*ff9112dfSStefan Roese u32 min_read_to_prech_cmd_delay; /* DDR3/2 only */
173*ff9112dfSStefan Roese u32 min_active_to_precharge;
174*ff9112dfSStefan Roese u32 min_refresh_recovery; /* DDR3/2 only */
175*ff9112dfSStefan Roese u32 min_cas_lat_time;
176*ff9112dfSStefan Roese u32 min_four_active_win_delay;
177*ff9112dfSStefan Roese u8 dimm_rc[SPD_RDIMM_RC_NUM];
178*ff9112dfSStefan Roese
179*ff9112dfSStefan Roese /* DIMM vendor ID */
180*ff9112dfSStefan Roese u32 vendor;
181*ff9112dfSStefan Roese } MV_DIMM_INFO;
182*ff9112dfSStefan Roese
183*ff9112dfSStefan Roese static int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info,
184*ff9112dfSStefan Roese u32 dimm);
185*ff9112dfSStefan Roese static u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val);
186*ff9112dfSStefan Roese static u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val);
187*ff9112dfSStefan Roese static int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width);
188*ff9112dfSStefan Roese static u32 ddr3_div(u32 val, u32 divider, u32 sub);
189*ff9112dfSStefan Roese
190*ff9112dfSStefan Roese extern u8 spd_data[SPD_SIZE];
191*ff9112dfSStefan Roese extern u32 odt_config[ODT_OPT];
192*ff9112dfSStefan Roese extern u16 odt_static[ODT_OPT][MAX_CS];
193*ff9112dfSStefan Roese extern u16 odt_dynamic[ODT_OPT][MAX_CS];
194*ff9112dfSStefan Roese
195*ff9112dfSStefan Roese #if !(defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710))
196*ff9112dfSStefan Roese /*
197*ff9112dfSStefan Roese * Name: ddr3_get_dimm_num - Find number of dimms and their addresses
198*ff9112dfSStefan Roese * Desc:
199*ff9112dfSStefan Roese * Args: dimm_addr - array of dimm addresses
200*ff9112dfSStefan Roese * Notes:
201*ff9112dfSStefan Roese * Returns: None.
202*ff9112dfSStefan Roese */
ddr3_get_dimm_num(u32 * dimm_addr)203*ff9112dfSStefan Roese static u32 ddr3_get_dimm_num(u32 *dimm_addr)
204*ff9112dfSStefan Roese {
205*ff9112dfSStefan Roese u32 dimm_cur_addr;
206*ff9112dfSStefan Roese u8 data[3];
207*ff9112dfSStefan Roese u32 dimm_num = 0;
208*ff9112dfSStefan Roese int ret;
209*ff9112dfSStefan Roese
210*ff9112dfSStefan Roese /* Read the dimm eeprom */
211*ff9112dfSStefan Roese for (dimm_cur_addr = MAX_DIMM_ADDR; dimm_cur_addr > MIN_DIMM_ADDR;
212*ff9112dfSStefan Roese dimm_cur_addr--) {
213*ff9112dfSStefan Roese data[SPD_DEV_TYPE_BYTE] = 0;
214*ff9112dfSStefan Roese
215*ff9112dfSStefan Roese /* Far-End DIMM must be connected */
216*ff9112dfSStefan Roese if ((dimm_num == 0) && (dimm_cur_addr < FAR_END_DIMM_ADDR))
217*ff9112dfSStefan Roese return 0;
218*ff9112dfSStefan Roese
219*ff9112dfSStefan Roese ret = i2c_read(dimm_cur_addr, 0, 1, (uchar *)data, 3);
220*ff9112dfSStefan Roese if (!ret) {
221*ff9112dfSStefan Roese if (data[SPD_DEV_TYPE_BYTE] == SPD_MEM_TYPE_DDR3) {
222*ff9112dfSStefan Roese dimm_addr[dimm_num] = dimm_cur_addr;
223*ff9112dfSStefan Roese dimm_num++;
224*ff9112dfSStefan Roese }
225*ff9112dfSStefan Roese }
226*ff9112dfSStefan Roese }
227*ff9112dfSStefan Roese
228*ff9112dfSStefan Roese return dimm_num;
229*ff9112dfSStefan Roese }
230*ff9112dfSStefan Roese #endif
231*ff9112dfSStefan Roese
232*ff9112dfSStefan Roese /*
233*ff9112dfSStefan Roese * Name: dimmSpdInit - Get the SPD parameters.
234*ff9112dfSStefan Roese * Desc: Read the DIMM SPD parameters into given struct parameter.
235*ff9112dfSStefan Roese * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
236*ff9112dfSStefan Roese * info - DIMM information structure.
237*ff9112dfSStefan Roese * Notes:
238*ff9112dfSStefan Roese * Returns: MV_OK if function could read DIMM parameters, 0 otherwise.
239*ff9112dfSStefan Roese */
ddr3_spd_init(MV_DIMM_INFO * info,u32 dimm_addr,u32 dimm_width)240*ff9112dfSStefan Roese int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width)
241*ff9112dfSStefan Roese {
242*ff9112dfSStefan Roese u32 tmp;
243*ff9112dfSStefan Roese u32 time_base;
244*ff9112dfSStefan Roese int ret;
245*ff9112dfSStefan Roese __maybe_unused u32 rc;
246*ff9112dfSStefan Roese __maybe_unused u8 vendor_high, vendor_low;
247*ff9112dfSStefan Roese
248*ff9112dfSStefan Roese if (dimm_addr != 0) {
249*ff9112dfSStefan Roese memset(spd_data, 0, SPD_SIZE * sizeof(u8));
250*ff9112dfSStefan Roese
251*ff9112dfSStefan Roese ret = i2c_read(dimm_addr, 0, 1, (uchar *)spd_data, SPD_SIZE);
252*ff9112dfSStefan Roese if (ret)
253*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_TWSI_FAIL;
254*ff9112dfSStefan Roese }
255*ff9112dfSStefan Roese
256*ff9112dfSStefan Roese /* Check if DDR3 */
257*ff9112dfSStefan Roese if (spd_data[SPD_DEV_TYPE_BYTE] != SPD_MEM_TYPE_DDR3)
258*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_TWSI_BAD_TYPE;
259*ff9112dfSStefan Roese
260*ff9112dfSStefan Roese /* Error Check Type */
261*ff9112dfSStefan Roese /* No byte for error check in DDR3 SPD, use DDR2 convention */
262*ff9112dfSStefan Roese info->err_check_type = 0;
263*ff9112dfSStefan Roese
264*ff9112dfSStefan Roese /* Check if ECC */
265*ff9112dfSStefan Roese if ((spd_data[SPD_BUS_WIDTH_BYTE] & 0x18) >> 3)
266*ff9112dfSStefan Roese info->err_check_type = 1;
267*ff9112dfSStefan Roese
268*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM err_check_type ", info->err_check_type, 1);
269*ff9112dfSStefan Roese switch (spd_data[SPD_MODULE_TYPE_BYTE]) {
270*ff9112dfSStefan Roese case 1:
271*ff9112dfSStefan Roese /* support RDIMM */
272*ff9112dfSStefan Roese info->type_info = SPD_MODULE_TYPE_RDIMM;
273*ff9112dfSStefan Roese break;
274*ff9112dfSStefan Roese case 2:
275*ff9112dfSStefan Roese /* support UDIMM */
276*ff9112dfSStefan Roese info->type_info = SPD_MODULE_TYPE_UDIMM;
277*ff9112dfSStefan Roese break;
278*ff9112dfSStefan Roese case 11: /* LRDIMM current not supported */
279*ff9112dfSStefan Roese default:
280*ff9112dfSStefan Roese info->type_info = (spd_data[SPD_MODULE_TYPE_BYTE]);
281*ff9112dfSStefan Roese break;
282*ff9112dfSStefan Roese }
283*ff9112dfSStefan Roese
284*ff9112dfSStefan Roese /* Size Calculations: */
285*ff9112dfSStefan Roese
286*ff9112dfSStefan Roese /* Number Of Row Addresses - 12/13/14/15/16 */
287*ff9112dfSStefan Roese info->num_of_row_addr =
288*ff9112dfSStefan Roese (spd_data[SPD_ROW_NUM_BYTE] & SPD_ROW_NUM_MASK) >>
289*ff9112dfSStefan Roese SPD_ROW_NUM_OFF;
290*ff9112dfSStefan Roese info->num_of_row_addr += SPD_ROW_NUM_MIN;
291*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM num_of_row_addr ", info->num_of_row_addr, 2);
292*ff9112dfSStefan Roese
293*ff9112dfSStefan Roese /* Number Of Column Addresses - 9/10/11/12 */
294*ff9112dfSStefan Roese info->num_of_col_addr =
295*ff9112dfSStefan Roese (spd_data[SPD_COL_NUM_BYTE] & SPD_COL_NUM_MASK) >>
296*ff9112dfSStefan Roese SPD_COL_NUM_OFF;
297*ff9112dfSStefan Roese info->num_of_col_addr += SPD_COL_NUM_MIN;
298*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM num_of_col_addr ", info->num_of_col_addr, 1);
299*ff9112dfSStefan Roese
300*ff9112dfSStefan Roese /* Number Of Ranks = number of CS on Dimm - 1/2/3/4 Ranks */
301*ff9112dfSStefan Roese info->num_of_module_ranks =
302*ff9112dfSStefan Roese (spd_data[SPD_MODULE_ORG_BYTE] & SPD_MODULE_BANK_NUM_MASK) >>
303*ff9112dfSStefan Roese SPD_MODULE_BANK_NUM_OFF;
304*ff9112dfSStefan Roese info->num_of_module_ranks += SPD_MODULE_BANK_NUM_MIN;
305*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM numOfModuleBanks ", info->num_of_module_ranks,
306*ff9112dfSStefan Roese 1);
307*ff9112dfSStefan Roese
308*ff9112dfSStefan Roese /* Data Width - 8/16/32/64 bits */
309*ff9112dfSStefan Roese info->data_width =
310*ff9112dfSStefan Roese 1 << (3 + (spd_data[SPD_BUS_WIDTH_BYTE] & SPD_BUS_WIDTH_MASK));
311*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM data_width ", info->data_width, 1);
312*ff9112dfSStefan Roese
313*ff9112dfSStefan Roese /* Number Of Banks On Each Device - 8/16/32/64 banks */
314*ff9112dfSStefan Roese info->num_of_banks_on_each_device =
315*ff9112dfSStefan Roese 1 << (3 + ((spd_data[SPD_DEV_DENSITY_BYTE] >> 4) & 0x7));
316*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM num_of_banks_on_each_device ",
317*ff9112dfSStefan Roese info->num_of_banks_on_each_device, 1);
318*ff9112dfSStefan Roese
319*ff9112dfSStefan Roese /* Total SDRAM capacity - 256Mb/512Mb/1Gb/2Gb/4Gb/8Gb/16Gb - MegaBits */
320*ff9112dfSStefan Roese info->sdram_capacity =
321*ff9112dfSStefan Roese spd_data[SPD_DEV_DENSITY_BYTE] & SPD_DEV_DENSITY_MASK;
322*ff9112dfSStefan Roese
323*ff9112dfSStefan Roese /* Sdram Width - 4/8/16/32 bits */
324*ff9112dfSStefan Roese info->sdram_width = 1 << (2 + (spd_data[SPD_MODULE_ORG_BYTE] &
325*ff9112dfSStefan Roese SPD_MODULE_SDRAM_DEV_WIDTH_MASK));
326*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM sdram_width ", info->sdram_width, 1);
327*ff9112dfSStefan Roese
328*ff9112dfSStefan Roese /* CS (Rank) Capacity - MB */
329*ff9112dfSStefan Roese /*
330*ff9112dfSStefan Roese * DDR3 device uiDensity val are: (device capacity/8) *
331*ff9112dfSStefan Roese * (Module_width/Device_width)
332*ff9112dfSStefan Roese */
333*ff9112dfSStefan Roese /* Jedec SPD DDR3 - page 7, Save spd_data in Mb - 2048=2GB */
334*ff9112dfSStefan Roese if (dimm_width == 32) {
335*ff9112dfSStefan Roese info->rank_capacity =
336*ff9112dfSStefan Roese ((1 << info->sdram_capacity) * 256 *
337*ff9112dfSStefan Roese (info->data_width / info->sdram_width)) << 16;
338*ff9112dfSStefan Roese /* CS size = CS size / 2 */
339*ff9112dfSStefan Roese } else {
340*ff9112dfSStefan Roese info->rank_capacity =
341*ff9112dfSStefan Roese ((1 << info->sdram_capacity) * 256 *
342*ff9112dfSStefan Roese (info->data_width / info->sdram_width) * 0x2) << 16;
343*ff9112dfSStefan Roese /* 0x2 => 0x100000-1Mbit / 8-bit->byte / 0x10000 */
344*ff9112dfSStefan Roese }
345*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM rank_capacity[31] ", info->rank_capacity, 1);
346*ff9112dfSStefan Roese
347*ff9112dfSStefan Roese /* Number of devices includeing Error correction */
348*ff9112dfSStefan Roese info->num_of_devices =
349*ff9112dfSStefan Roese ((info->data_width / info->sdram_width) *
350*ff9112dfSStefan Roese info->num_of_module_ranks) + info->err_check_type;
351*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM num_of_devices ", info->num_of_devices, 1);
352*ff9112dfSStefan Roese
353*ff9112dfSStefan Roese /* Address Mapping from Edge connector to DRAM - mirroring option */
354*ff9112dfSStefan Roese info->addr_mirroring =
355*ff9112dfSStefan Roese spd_data[SPD_ADDR_MAP_BYTE] & (1 << SPD_ADDR_MAP_MIRROR_OFFS);
356*ff9112dfSStefan Roese
357*ff9112dfSStefan Roese /* Timings - All in ps */
358*ff9112dfSStefan Roese
359*ff9112dfSStefan Roese time_base = (1000 * spd_data[SPD_MTB_DIVIDEND_BYTE]) /
360*ff9112dfSStefan Roese spd_data[SPD_MTB_DIVISOR_BYTE];
361*ff9112dfSStefan Roese
362*ff9112dfSStefan Roese /* Minimum Cycle Time At Max CasLatancy */
363*ff9112dfSStefan Roese info->min_cycle_time = spd_data[SPD_TCK_BYTE] * time_base;
364*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM tCKmin ", info->min_cycle_time, 1);
365*ff9112dfSStefan Roese
366*ff9112dfSStefan Roese /* Refresh Interval */
367*ff9112dfSStefan Roese /* No byte for refresh interval in DDR3 SPD, use DDR2 convention */
368*ff9112dfSStefan Roese /*
369*ff9112dfSStefan Roese * JEDEC param are 0 <= Tcase <= 85: 7.8uSec, 85 <= Tcase
370*ff9112dfSStefan Roese * <= 95: 3.9uSec
371*ff9112dfSStefan Roese */
372*ff9112dfSStefan Roese info->refresh_interval = 7800000; /* Set to 7.8uSec */
373*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM refresh_interval ", info->refresh_interval, 1);
374*ff9112dfSStefan Roese
375*ff9112dfSStefan Roese /* Suported Cas Latencies - DDR 3: */
376*ff9112dfSStefan Roese
377*ff9112dfSStefan Roese /*
378*ff9112dfSStefan Roese * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
379*ff9112dfSStefan Roese *******-******-******-******-******-******-******-*******-*******
380*ff9112dfSStefan Roese CAS = 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 *
381*ff9112dfSStefan Roese *********************************************************-*******
382*ff9112dfSStefan Roese *******-******-******-******-******-******-******-*******-*******
383*ff9112dfSStefan Roese * bit15 |bit14 |bit13 |bit12 |bit11 |bit10 | bit9 | bit8 *
384*ff9112dfSStefan Roese *******-******-******-******-******-******-******-*******-*******
385*ff9112dfSStefan Roese CAS = TBD | 18 | 17 | 16 | 15 | 14 | 13 | 12 *
386*ff9112dfSStefan Roese */
387*ff9112dfSStefan Roese
388*ff9112dfSStefan Roese /* DDR3 include 2 byte of CAS support */
389*ff9112dfSStefan Roese info->supported_cas_latencies =
390*ff9112dfSStefan Roese (spd_data[SPD_SUP_CAS_LAT_MSB_BYTE] << 8) |
391*ff9112dfSStefan Roese spd_data[SPD_SUP_CAS_LAT_LSB_BYTE];
392*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM supported_cas_latencies ",
393*ff9112dfSStefan Roese info->supported_cas_latencies, 1);
394*ff9112dfSStefan Roese
395*ff9112dfSStefan Roese /* Minimum Cycle Time At Max CasLatancy */
396*ff9112dfSStefan Roese info->min_cas_lat_time = (spd_data[SPD_TAA_BYTE] * time_base);
397*ff9112dfSStefan Roese /*
398*ff9112dfSStefan Roese * This field divided by the cycleTime will give us the CAS latency
399*ff9112dfSStefan Roese * to config
400*ff9112dfSStefan Roese */
401*ff9112dfSStefan Roese
402*ff9112dfSStefan Roese /*
403*ff9112dfSStefan Roese * For DDR3 and DDR2 includes Write Recovery Time field.
404*ff9112dfSStefan Roese * Other SDRAM ignore
405*ff9112dfSStefan Roese */
406*ff9112dfSStefan Roese info->min_write_recovery_time = spd_data[SPD_TWR_BYTE] * time_base;
407*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_write_recovery_time ",
408*ff9112dfSStefan Roese info->min_write_recovery_time, 1);
409*ff9112dfSStefan Roese
410*ff9112dfSStefan Roese /* Mininmum Ras to Cas Delay */
411*ff9112dfSStefan Roese info->min_ras_to_cas_delay = spd_data[SPD_TRCD_BYTE] * time_base;
412*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_ras_to_cas_delay ",
413*ff9112dfSStefan Roese info->min_ras_to_cas_delay, 1);
414*ff9112dfSStefan Roese
415*ff9112dfSStefan Roese /* Minimum Row Active to Row Active Time */
416*ff9112dfSStefan Roese info->min_row_active_to_row_active =
417*ff9112dfSStefan Roese spd_data[SPD_TRRD_BYTE] * time_base;
418*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_row_active_to_row_active ",
419*ff9112dfSStefan Roese info->min_row_active_to_row_active, 1);
420*ff9112dfSStefan Roese
421*ff9112dfSStefan Roese /* Minimum Row Precharge Delay Time */
422*ff9112dfSStefan Roese info->min_row_precharge_time = spd_data[SPD_TRP_BYTE] * time_base;
423*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_row_precharge_time ",
424*ff9112dfSStefan Roese info->min_row_precharge_time, 1);
425*ff9112dfSStefan Roese
426*ff9112dfSStefan Roese /* Minimum Active to Precharge Delay Time - tRAS ps */
427*ff9112dfSStefan Roese info->min_active_to_precharge =
428*ff9112dfSStefan Roese (spd_data[SPD_TRAS_MSB_BYTE] & SPD_TRAS_MSB_MASK) << 8;
429*ff9112dfSStefan Roese info->min_active_to_precharge |= spd_data[SPD_TRAS_LSB_BYTE];
430*ff9112dfSStefan Roese info->min_active_to_precharge *= time_base;
431*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_active_to_precharge ",
432*ff9112dfSStefan Roese info->min_active_to_precharge, 1);
433*ff9112dfSStefan Roese
434*ff9112dfSStefan Roese /* Minimum Refresh Recovery Delay Time - tRFC ps */
435*ff9112dfSStefan Roese info->min_refresh_recovery = spd_data[SPD_TRFC_MSB_BYTE] << 8;
436*ff9112dfSStefan Roese info->min_refresh_recovery |= spd_data[SPD_TRFC_LSB_BYTE];
437*ff9112dfSStefan Roese info->min_refresh_recovery *= time_base;
438*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_refresh_recovery ",
439*ff9112dfSStefan Roese info->min_refresh_recovery, 1);
440*ff9112dfSStefan Roese
441*ff9112dfSStefan Roese /*
442*ff9112dfSStefan Roese * For DDR3 and DDR2 includes Internal Write To Read Command Delay
443*ff9112dfSStefan Roese * field.
444*ff9112dfSStefan Roese */
445*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay = spd_data[SPD_TWTR_BYTE] * time_base;
446*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_write_to_read_cmd_delay ",
447*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay, 1);
448*ff9112dfSStefan Roese
449*ff9112dfSStefan Roese /*
450*ff9112dfSStefan Roese * For DDR3 and DDR2 includes Internal Read To Precharge Command Delay
451*ff9112dfSStefan Roese * field.
452*ff9112dfSStefan Roese */
453*ff9112dfSStefan Roese info->min_read_to_prech_cmd_delay = spd_data[SPD_TRTP_BYTE] * time_base;
454*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_read_to_prech_cmd_delay ",
455*ff9112dfSStefan Roese info->min_read_to_prech_cmd_delay, 1);
456*ff9112dfSStefan Roese
457*ff9112dfSStefan Roese /*
458*ff9112dfSStefan Roese * For DDR3 includes Minimum Activate to Activate/Refresh Command
459*ff9112dfSStefan Roese * field
460*ff9112dfSStefan Roese */
461*ff9112dfSStefan Roese tmp = ((spd_data[SPD_TFAW_MSB_BYTE] & SPD_TFAW_MSB_MASK) << 8) |
462*ff9112dfSStefan Roese spd_data[SPD_TFAW_LSB_BYTE];
463*ff9112dfSStefan Roese info->min_four_active_win_delay = tmp * time_base;
464*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DRAM min_four_active_win_delay ",
465*ff9112dfSStefan Roese info->min_four_active_win_delay, 1);
466*ff9112dfSStefan Roese
467*ff9112dfSStefan Roese #if defined(MV88F78X60) || defined(MV88F672X)
468*ff9112dfSStefan Roese /* Registered DIMM support */
469*ff9112dfSStefan Roese if (info->type_info == SPD_MODULE_TYPE_RDIMM) {
470*ff9112dfSStefan Roese for (rc = 2; rc < 6; rc += 2) {
471*ff9112dfSStefan Roese tmp = spd_data[SPD_RDIMM_RC_BYTE + rc / 2];
472*ff9112dfSStefan Roese info->dimm_rc[rc] =
473*ff9112dfSStefan Roese spd_data[SPD_RDIMM_RC_BYTE + rc / 2] &
474*ff9112dfSStefan Roese SPD_RDIMM_RC_NIBBLE_MASK;
475*ff9112dfSStefan Roese info->dimm_rc[rc + 1] =
476*ff9112dfSStefan Roese (spd_data[SPD_RDIMM_RC_BYTE + rc / 2] >> 4) &
477*ff9112dfSStefan Roese SPD_RDIMM_RC_NIBBLE_MASK;
478*ff9112dfSStefan Roese }
479*ff9112dfSStefan Roese
480*ff9112dfSStefan Roese vendor_low = spd_data[66];
481*ff9112dfSStefan Roese vendor_high = spd_data[65];
482*ff9112dfSStefan Roese info->vendor = (vendor_high << 8) + vendor_low;
483*ff9112dfSStefan Roese DEBUG_INIT_C("DDR3 Training Sequence - Registered DIMM vendor ID 0x",
484*ff9112dfSStefan Roese info->vendor, 4);
485*ff9112dfSStefan Roese
486*ff9112dfSStefan Roese info->dimm_rc[0] = RDIMM_RC0;
487*ff9112dfSStefan Roese info->dimm_rc[1] = RDIMM_RC1;
488*ff9112dfSStefan Roese info->dimm_rc[2] = RDIMM_RC2;
489*ff9112dfSStefan Roese info->dimm_rc[8] = RDIMM_RC8;
490*ff9112dfSStefan Roese info->dimm_rc[9] = RDIMM_RC9;
491*ff9112dfSStefan Roese info->dimm_rc[10] = RDIMM_RC10;
492*ff9112dfSStefan Roese info->dimm_rc[11] = RDIMM_RC11;
493*ff9112dfSStefan Roese }
494*ff9112dfSStefan Roese #endif
495*ff9112dfSStefan Roese
496*ff9112dfSStefan Roese return MV_OK;
497*ff9112dfSStefan Roese }
498*ff9112dfSStefan Roese
499*ff9112dfSStefan Roese /*
500*ff9112dfSStefan Roese * Name: ddr3_spd_sum_init - Get the SPD parameters.
501*ff9112dfSStefan Roese * Desc: Read the DIMM SPD parameters into given struct parameter.
502*ff9112dfSStefan Roese * Args: dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
503*ff9112dfSStefan Roese * info - DIMM information structure.
504*ff9112dfSStefan Roese * Notes:
505*ff9112dfSStefan Roese * Returns: MV_OK if function could read DIMM parameters, 0 otherwise.
506*ff9112dfSStefan Roese */
ddr3_spd_sum_init(MV_DIMM_INFO * info,MV_DIMM_INFO * sum_info,u32 dimm)507*ff9112dfSStefan Roese int ddr3_spd_sum_init(MV_DIMM_INFO *info, MV_DIMM_INFO *sum_info, u32 dimm)
508*ff9112dfSStefan Roese {
509*ff9112dfSStefan Roese if (dimm == 0) {
510*ff9112dfSStefan Roese memcpy(sum_info, info, sizeof(MV_DIMM_INFO));
511*ff9112dfSStefan Roese return MV_OK;
512*ff9112dfSStefan Roese }
513*ff9112dfSStefan Roese if (sum_info->type_info != info->type_info) {
514*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Dimm Compare - DIMM type does not match - FAIL\n");
515*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_DIMM_TYPE_NO_MATCH;
516*ff9112dfSStefan Roese }
517*ff9112dfSStefan Roese if (sum_info->err_check_type > info->err_check_type) {
518*ff9112dfSStefan Roese sum_info->err_check_type = info->err_check_type;
519*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Dimm Compare - ECC does not match. ECC is disabled\n");
520*ff9112dfSStefan Roese }
521*ff9112dfSStefan Roese if (sum_info->data_width != info->data_width) {
522*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Dimm Compare - DRAM bus width does not match - FAIL\n");
523*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_BUS_WIDTH_NOT_MATCH;
524*ff9112dfSStefan Roese }
525*ff9112dfSStefan Roese if (sum_info->min_cycle_time < info->min_cycle_time)
526*ff9112dfSStefan Roese sum_info->min_cycle_time = info->min_cycle_time;
527*ff9112dfSStefan Roese if (sum_info->refresh_interval < info->refresh_interval)
528*ff9112dfSStefan Roese sum_info->refresh_interval = info->refresh_interval;
529*ff9112dfSStefan Roese sum_info->supported_cas_latencies &= info->supported_cas_latencies;
530*ff9112dfSStefan Roese if (sum_info->min_cas_lat_time < info->min_cas_lat_time)
531*ff9112dfSStefan Roese sum_info->min_cas_lat_time = info->min_cas_lat_time;
532*ff9112dfSStefan Roese if (sum_info->min_write_recovery_time < info->min_write_recovery_time)
533*ff9112dfSStefan Roese sum_info->min_write_recovery_time =
534*ff9112dfSStefan Roese info->min_write_recovery_time;
535*ff9112dfSStefan Roese if (sum_info->min_ras_to_cas_delay < info->min_ras_to_cas_delay)
536*ff9112dfSStefan Roese sum_info->min_ras_to_cas_delay = info->min_ras_to_cas_delay;
537*ff9112dfSStefan Roese if (sum_info->min_row_active_to_row_active <
538*ff9112dfSStefan Roese info->min_row_active_to_row_active)
539*ff9112dfSStefan Roese sum_info->min_row_active_to_row_active =
540*ff9112dfSStefan Roese info->min_row_active_to_row_active;
541*ff9112dfSStefan Roese if (sum_info->min_row_precharge_time < info->min_row_precharge_time)
542*ff9112dfSStefan Roese sum_info->min_row_precharge_time = info->min_row_precharge_time;
543*ff9112dfSStefan Roese if (sum_info->min_active_to_precharge < info->min_active_to_precharge)
544*ff9112dfSStefan Roese sum_info->min_active_to_precharge =
545*ff9112dfSStefan Roese info->min_active_to_precharge;
546*ff9112dfSStefan Roese if (sum_info->min_refresh_recovery < info->min_refresh_recovery)
547*ff9112dfSStefan Roese sum_info->min_refresh_recovery = info->min_refresh_recovery;
548*ff9112dfSStefan Roese if (sum_info->min_write_to_read_cmd_delay <
549*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay)
550*ff9112dfSStefan Roese sum_info->min_write_to_read_cmd_delay =
551*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay;
552*ff9112dfSStefan Roese if (sum_info->min_read_to_prech_cmd_delay <
553*ff9112dfSStefan Roese info->min_read_to_prech_cmd_delay)
554*ff9112dfSStefan Roese sum_info->min_read_to_prech_cmd_delay =
555*ff9112dfSStefan Roese info->min_read_to_prech_cmd_delay;
556*ff9112dfSStefan Roese if (sum_info->min_four_active_win_delay <
557*ff9112dfSStefan Roese info->min_four_active_win_delay)
558*ff9112dfSStefan Roese sum_info->min_four_active_win_delay =
559*ff9112dfSStefan Roese info->min_four_active_win_delay;
560*ff9112dfSStefan Roese if (sum_info->min_write_to_read_cmd_delay <
561*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay)
562*ff9112dfSStefan Roese sum_info->min_write_to_read_cmd_delay =
563*ff9112dfSStefan Roese info->min_write_to_read_cmd_delay;
564*ff9112dfSStefan Roese
565*ff9112dfSStefan Roese return MV_OK;
566*ff9112dfSStefan Roese }
567*ff9112dfSStefan Roese
568*ff9112dfSStefan Roese /*
569*ff9112dfSStefan Roese * Name: ddr3_dunit_setup
570*ff9112dfSStefan Roese * Desc: Set the controller with the timing values.
571*ff9112dfSStefan Roese * Args: ecc_ena - User ECC setup
572*ff9112dfSStefan Roese * Notes:
573*ff9112dfSStefan Roese * Returns:
574*ff9112dfSStefan Roese */
ddr3_dunit_setup(u32 ecc_ena,u32 hclk_time,u32 * ddr_width)575*ff9112dfSStefan Roese int ddr3_dunit_setup(u32 ecc_ena, u32 hclk_time, u32 *ddr_width)
576*ff9112dfSStefan Roese {
577*ff9112dfSStefan Roese u32 reg, tmp, cwl;
578*ff9112dfSStefan Roese u32 ddr_clk_time;
579*ff9112dfSStefan Roese MV_DIMM_INFO dimm_info[2];
580*ff9112dfSStefan Roese MV_DIMM_INFO sum_info;
581*ff9112dfSStefan Roese u32 stat_val, spd_val;
582*ff9112dfSStefan Roese u32 cs, cl, cs_num, cs_ena;
583*ff9112dfSStefan Roese u32 dimm_num = 0;
584*ff9112dfSStefan Roese int status;
585*ff9112dfSStefan Roese u32 rc;
586*ff9112dfSStefan Roese __maybe_unused u32 dimm_cnt, cs_count, dimm;
587*ff9112dfSStefan Roese __maybe_unused u32 dimm_addr[2] = { 0, 0 };
588*ff9112dfSStefan Roese
589*ff9112dfSStefan Roese #if defined(DB_88F6710) || defined(DB_88F6710_PCAC) || defined(RD_88F6710)
590*ff9112dfSStefan Roese /* Armada 370 - SPD is not available on DIMM */
591*ff9112dfSStefan Roese /*
592*ff9112dfSStefan Roese * Set MC registers according to Static SPD values Values -
593*ff9112dfSStefan Roese * must be set manually
594*ff9112dfSStefan Roese */
595*ff9112dfSStefan Roese /*
596*ff9112dfSStefan Roese * We only have one optional DIMM for the DB and we already got the
597*ff9112dfSStefan Roese * SPD matching values
598*ff9112dfSStefan Roese */
599*ff9112dfSStefan Roese status = ddr3_spd_init(&dimm_info[0], 0, *ddr_width);
600*ff9112dfSStefan Roese if (MV_OK != status)
601*ff9112dfSStefan Roese return status;
602*ff9112dfSStefan Roese
603*ff9112dfSStefan Roese dimm_num = 1;
604*ff9112dfSStefan Roese /* Use JP8 to enable multiCS support for Armada 370 DB */
605*ff9112dfSStefan Roese if (!ddr3_check_config(EEPROM_MODULE_ADDR, CONFIG_MULTI_CS))
606*ff9112dfSStefan Roese dimm_info[0].num_of_module_ranks = 1;
607*ff9112dfSStefan Roese status = ddr3_spd_sum_init(&dimm_info[0], &sum_info, 0);
608*ff9112dfSStefan Roese if (MV_OK != status)
609*ff9112dfSStefan Roese return status;
610*ff9112dfSStefan Roese #else
611*ff9112dfSStefan Roese /* Dynamic D-Unit Setup - Read SPD values */
612*ff9112dfSStefan Roese #ifdef DUNIT_SPD
613*ff9112dfSStefan Roese dimm_num = ddr3_get_dimm_num(dimm_addr);
614*ff9112dfSStefan Roese if (dimm_num == 0) {
615*ff9112dfSStefan Roese #ifdef MIXED_DIMM_STATIC
616*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Training Sequence - No DIMMs detected\n");
617*ff9112dfSStefan Roese #else
618*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Training Sequence - FAILED (Wrong DIMMs Setup)\n");
619*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP;
620*ff9112dfSStefan Roese #endif
621*ff9112dfSStefan Roese } else {
622*ff9112dfSStefan Roese DEBUG_INIT_C("DDR3 Training Sequence - Number of DIMMs detected: ",
623*ff9112dfSStefan Roese dimm_num, 1);
624*ff9112dfSStefan Roese }
625*ff9112dfSStefan Roese
626*ff9112dfSStefan Roese for (dimm = 0; dimm < dimm_num; dimm++) {
627*ff9112dfSStefan Roese status = ddr3_spd_init(&dimm_info[dimm], dimm_addr[dimm],
628*ff9112dfSStefan Roese *ddr_width);
629*ff9112dfSStefan Roese if (MV_OK != status)
630*ff9112dfSStefan Roese return status;
631*ff9112dfSStefan Roese status = ddr3_spd_sum_init(&dimm_info[dimm], &sum_info, dimm);
632*ff9112dfSStefan Roese if (MV_OK != status)
633*ff9112dfSStefan Roese return status;
634*ff9112dfSStefan Roese }
635*ff9112dfSStefan Roese #endif
636*ff9112dfSStefan Roese #endif
637*ff9112dfSStefan Roese
638*ff9112dfSStefan Roese /* Set number of enabled CS */
639*ff9112dfSStefan Roese cs_num = 0;
640*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
641*ff9112dfSStefan Roese cs_num = ddr3_get_cs_num_from_reg();
642*ff9112dfSStefan Roese #endif
643*ff9112dfSStefan Roese #ifdef DUNIT_SPD
644*ff9112dfSStefan Roese for (dimm = 0; dimm < dimm_num; dimm++)
645*ff9112dfSStefan Roese cs_num += dimm_info[dimm].num_of_module_ranks;
646*ff9112dfSStefan Roese #endif
647*ff9112dfSStefan Roese if (cs_num > MAX_CS) {
648*ff9112dfSStefan Roese DEBUG_INIT_C("DDR3 Training Sequence - Number of CS exceed limit - ",
649*ff9112dfSStefan Roese MAX_CS, 1);
650*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_MAX_CS_LIMIT;
651*ff9112dfSStefan Roese }
652*ff9112dfSStefan Roese
653*ff9112dfSStefan Roese /* Set bitmap of enabled CS */
654*ff9112dfSStefan Roese cs_ena = 0;
655*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
656*ff9112dfSStefan Roese cs_ena = ddr3_get_cs_ena_from_reg();
657*ff9112dfSStefan Roese #endif
658*ff9112dfSStefan Roese #ifdef DUNIT_SPD
659*ff9112dfSStefan Roese dimm = 0;
660*ff9112dfSStefan Roese
661*ff9112dfSStefan Roese if (dimm_num) {
662*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs += 2) {
663*ff9112dfSStefan Roese if (((1 << cs) & DIMM_CS_BITMAP) &&
664*ff9112dfSStefan Roese !(cs_ena & (1 << cs))) {
665*ff9112dfSStefan Roese if (dimm_info[dimm].num_of_module_ranks == 1)
666*ff9112dfSStefan Roese cs_ena |= (0x1 << cs);
667*ff9112dfSStefan Roese else if (dimm_info[dimm].num_of_module_ranks == 2)
668*ff9112dfSStefan Roese cs_ena |= (0x3 << cs);
669*ff9112dfSStefan Roese else if (dimm_info[dimm].num_of_module_ranks == 3)
670*ff9112dfSStefan Roese cs_ena |= (0x7 << cs);
671*ff9112dfSStefan Roese else if (dimm_info[dimm].num_of_module_ranks == 4)
672*ff9112dfSStefan Roese cs_ena |= (0xF << cs);
673*ff9112dfSStefan Roese
674*ff9112dfSStefan Roese dimm++;
675*ff9112dfSStefan Roese if (dimm == dimm_num)
676*ff9112dfSStefan Roese break;
677*ff9112dfSStefan Roese }
678*ff9112dfSStefan Roese }
679*ff9112dfSStefan Roese }
680*ff9112dfSStefan Roese #endif
681*ff9112dfSStefan Roese
682*ff9112dfSStefan Roese if (cs_ena > 0xF) {
683*ff9112dfSStefan Roese DEBUG_INIT_C("DDR3 Training Sequence - Number of enabled CS exceed limit - ",
684*ff9112dfSStefan Roese MAX_CS, 1);
685*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_MAX_ENA_CS_LIMIT;
686*ff9112dfSStefan Roese }
687*ff9112dfSStefan Roese
688*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Number of CS = ", cs_num, 1);
689*ff9112dfSStefan Roese
690*ff9112dfSStefan Roese /* Check Ratio - '1' - 2:1, '0' - 1:1 */
691*ff9112dfSStefan Roese if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
692*ff9112dfSStefan Roese ddr_clk_time = hclk_time / 2;
693*ff9112dfSStefan Roese else
694*ff9112dfSStefan Roese ddr_clk_time = hclk_time;
695*ff9112dfSStefan Roese
696*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
697*ff9112dfSStefan Roese /* Get target CL value from set register */
698*ff9112dfSStefan Roese reg = (reg_read(REG_DDR3_MR0_ADDR) >> 2);
699*ff9112dfSStefan Roese reg = ((((reg >> 1) & 0xE)) | (reg & 0x1)) & 0xF;
700*ff9112dfSStefan Roese
701*ff9112dfSStefan Roese cl = ddr3_get_max_val(ddr3_div(sum_info.min_cas_lat_time,
702*ff9112dfSStefan Roese ddr_clk_time, 0),
703*ff9112dfSStefan Roese dimm_num, ddr3_valid_cl_to_cl(reg));
704*ff9112dfSStefan Roese #else
705*ff9112dfSStefan Roese cl = ddr3_div(sum_info.min_cas_lat_time, ddr_clk_time, 0);
706*ff9112dfSStefan Roese #endif
707*ff9112dfSStefan Roese if (cl < 5)
708*ff9112dfSStefan Roese cl = 5;
709*ff9112dfSStefan Roese
710*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - Cas Latency = ", cl, 1);
711*ff9112dfSStefan Roese
712*ff9112dfSStefan Roese /* {0x00001400} - DDR SDRAM Configuration Register */
713*ff9112dfSStefan Roese reg = 0x73004000;
714*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(
715*ff9112dfSStefan Roese REG_SDRAM_CONFIG_ADDR, REG_SDRAM_CONFIG_ECC_OFFS, 0x1, 0, 0);
716*ff9112dfSStefan Roese if (ecc_ena && ddr3_get_min_val(sum_info.err_check_type, dimm_num,
717*ff9112dfSStefan Roese stat_val)) {
718*ff9112dfSStefan Roese reg |= (1 << REG_SDRAM_CONFIG_ECC_OFFS);
719*ff9112dfSStefan Roese reg |= (1 << REG_SDRAM_CONFIG_IERR_OFFS);
720*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Enabled\n");
721*ff9112dfSStefan Roese } else {
722*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - ECC Disabled\n");
723*ff9112dfSStefan Roese }
724*ff9112dfSStefan Roese
725*ff9112dfSStefan Roese if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) {
726*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
727*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Training Sequence - FAIL - Illegal R-DIMM setup\n");
728*ff9112dfSStefan Roese return MV_DDR3_TRAINING_ERR_BAD_R_DIMM_SETUP;
729*ff9112dfSStefan Roese #endif
730*ff9112dfSStefan Roese reg |= (1 << REG_SDRAM_CONFIG_REGDIMM_OFFS);
731*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - R-DIMM\n");
732*ff9112dfSStefan Roese } else {
733*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - U-DIMM\n");
734*ff9112dfSStefan Roese }
735*ff9112dfSStefan Roese
736*ff9112dfSStefan Roese #ifndef MV88F67XX
737*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
738*ff9112dfSStefan Roese if (ddr3_get_min_val(sum_info.data_width, dimm_num, BUS_WIDTH) == 64) {
739*ff9112dfSStefan Roese #else
740*ff9112dfSStefan Roese if (*ddr_width == 64) {
741*ff9112dfSStefan Roese #endif
742*ff9112dfSStefan Roese reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS);
743*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 64Bits\n");
744*ff9112dfSStefan Roese } else {
745*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n");
746*ff9112dfSStefan Roese }
747*ff9112dfSStefan Roese #else
748*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n");
749*ff9112dfSStefan Roese #endif
750*ff9112dfSStefan Roese
751*ff9112dfSStefan Roese #if defined(MV88F672X)
752*ff9112dfSStefan Roese if (*ddr_width == 32) {
753*ff9112dfSStefan Roese reg |= (1 << REG_SDRAM_CONFIG_WIDTH_OFFS);
754*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 32Bits\n");
755*ff9112dfSStefan Roese } else {
756*ff9112dfSStefan Roese DEBUG_INIT_FULL_S("DDR3 - DUNIT-SET - Datawidth - 16Bits\n");
757*ff9112dfSStefan Roese }
758*ff9112dfSStefan Roese #endif
759*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_CONFIG_ADDR, 0,
760*ff9112dfSStefan Roese REG_SDRAM_CONFIG_RFRS_MASK, 0, 0);
761*ff9112dfSStefan Roese tmp = ddr3_get_min_val(sum_info.refresh_interval / hclk_time,
762*ff9112dfSStefan Roese dimm_num, stat_val);
763*ff9112dfSStefan Roese
764*ff9112dfSStefan Roese #ifdef TREFI_USER_EN
765*ff9112dfSStefan Roese tmp = min(TREFI_USER / hclk_time, tmp);
766*ff9112dfSStefan Roese #endif
767*ff9112dfSStefan Roese
768*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - RefreshInterval/Hclk = ", tmp, 4);
769*ff9112dfSStefan Roese reg |= tmp;
770*ff9112dfSStefan Roese
771*ff9112dfSStefan Roese if (cl != 3)
772*ff9112dfSStefan Roese reg |= (1 << 16); /* If 2:1 need to set P2DWr */
773*ff9112dfSStefan Roese
774*ff9112dfSStefan Roese #if defined(MV88F672X)
775*ff9112dfSStefan Roese reg |= (1 << 27); /* PhyRfRST = Disable */
776*ff9112dfSStefan Roese #endif
777*ff9112dfSStefan Roese reg_write(REG_SDRAM_CONFIG_ADDR, reg);
778*ff9112dfSStefan Roese
779*ff9112dfSStefan Roese /*{0x00001404} - DDR SDRAM Configuration Register */
780*ff9112dfSStefan Roese reg = 0x3630B800;
781*ff9112dfSStefan Roese #ifdef DUNIT_SPD
782*ff9112dfSStefan Roese reg |= (DRAM_2T << REG_DUNIT_CTRL_LOW_2T_OFFS);
783*ff9112dfSStefan Roese #endif
784*ff9112dfSStefan Roese reg_write(REG_DUNIT_CTRL_LOW_ADDR, reg);
785*ff9112dfSStefan Roese
786*ff9112dfSStefan Roese /* {0x00001408} - DDR SDRAM Timing (Low) Register */
787*ff9112dfSStefan Roese reg = 0x0;
788*ff9112dfSStefan Roese
789*ff9112dfSStefan Roese /* tRAS - (0:3,20) */
790*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_active_to_precharge,
791*ff9112dfSStefan Roese ddr_clk_time, 1);
792*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
793*ff9112dfSStefan Roese 0, 0xF, 16, 0x10);
794*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
795*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRAS-1 = ", tmp, 1);
796*ff9112dfSStefan Roese reg |= (tmp & 0xF);
797*ff9112dfSStefan Roese reg |= ((tmp & 0x10) << 16); /* to bit 20 */
798*ff9112dfSStefan Roese
799*ff9112dfSStefan Roese /* tRCD - (4:7) */
800*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_ras_to_cas_delay, ddr_clk_time, 1);
801*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
802*ff9112dfSStefan Roese 4, 0xF, 0, 0);
803*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
804*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRCD-1 = ", tmp, 1);
805*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 4);
806*ff9112dfSStefan Roese
807*ff9112dfSStefan Roese /* tRP - (8:11) */
808*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_row_precharge_time, ddr_clk_time, 1);
809*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
810*ff9112dfSStefan Roese 8, 0xF, 0, 0);
811*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
812*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRP-1 = ", tmp, 1);
813*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 8);
814*ff9112dfSStefan Roese
815*ff9112dfSStefan Roese /* tWR - (12:15) */
816*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_write_recovery_time, ddr_clk_time, 1);
817*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
818*ff9112dfSStefan Roese 12, 0xF, 0, 0);
819*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
820*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWR-1 = ", tmp, 1);
821*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 12);
822*ff9112dfSStefan Roese
823*ff9112dfSStefan Roese /* tWTR - (16:19) */
824*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_write_to_read_cmd_delay, ddr_clk_time, 1);
825*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
826*ff9112dfSStefan Roese 16, 0xF, 0, 0);
827*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
828*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tWTR-1 = ", tmp, 1);
829*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 16);
830*ff9112dfSStefan Roese
831*ff9112dfSStefan Roese /* tRRD - (24:27) */
832*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_row_active_to_row_active, ddr_clk_time, 1);
833*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
834*ff9112dfSStefan Roese 24, 0xF, 0, 0);
835*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
836*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRRD-1 = ", tmp, 1);
837*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 24);
838*ff9112dfSStefan Roese
839*ff9112dfSStefan Roese /* tRTP - (28:31) */
840*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_read_to_prech_cmd_delay, ddr_clk_time, 1);
841*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_LOW_ADDR,
842*ff9112dfSStefan Roese 28, 0xF, 0, 0);
843*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
844*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRTP-1 = ", tmp, 1);
845*ff9112dfSStefan Roese reg |= ((tmp & 0xF) << 28);
846*ff9112dfSStefan Roese
847*ff9112dfSStefan Roese if (cl < 7)
848*ff9112dfSStefan Roese reg = 0x33137663;
849*ff9112dfSStefan Roese
850*ff9112dfSStefan Roese reg_write(REG_SDRAM_TIMING_LOW_ADDR, reg);
851*ff9112dfSStefan Roese
852*ff9112dfSStefan Roese /*{0x0000140C} - DDR SDRAM Timing (High) Register */
853*ff9112dfSStefan Roese /* Add cycles to R2R W2W */
854*ff9112dfSStefan Roese reg = 0x39F8FF80;
855*ff9112dfSStefan Roese
856*ff9112dfSStefan Roese /* tRFC - (0:6,16:18) */
857*ff9112dfSStefan Roese spd_val = ddr3_div(sum_info.min_refresh_recovery, ddr_clk_time, 1);
858*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_TIMING_HIGH_ADDR,
859*ff9112dfSStefan Roese 0, 0x7F, 9, 0x380);
860*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
861*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tRFC-1 = ", tmp, 1);
862*ff9112dfSStefan Roese reg |= (tmp & 0x7F);
863*ff9112dfSStefan Roese reg |= ((tmp & 0x380) << 9); /* to bit 16 */
864*ff9112dfSStefan Roese reg_write(REG_SDRAM_TIMING_HIGH_ADDR, reg);
865*ff9112dfSStefan Roese
866*ff9112dfSStefan Roese /*{0x00001410} - DDR SDRAM Address Control Register */
867*ff9112dfSStefan Roese reg = 0x000F0000;
868*ff9112dfSStefan Roese
869*ff9112dfSStefan Roese /* tFAW - (24:28) */
870*ff9112dfSStefan Roese #if (defined(MV88F78X60) || defined(MV88F672X))
871*ff9112dfSStefan Roese tmp = sum_info.min_four_active_win_delay;
872*ff9112dfSStefan Roese spd_val = ddr3_div(tmp, ddr_clk_time, 0);
873*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR,
874*ff9112dfSStefan Roese 24, 0x3F, 0, 0);
875*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
876*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW = ", tmp, 1);
877*ff9112dfSStefan Roese reg |= ((tmp & 0x3F) << 24);
878*ff9112dfSStefan Roese #else
879*ff9112dfSStefan Roese tmp = sum_info.min_four_active_win_delay -
880*ff9112dfSStefan Roese 4 * (sum_info.min_row_active_to_row_active);
881*ff9112dfSStefan Roese spd_val = ddr3_div(tmp, ddr_clk_time, 0);
882*ff9112dfSStefan Roese stat_val = ddr3_get_static_mc_value(REG_SDRAM_ADDRESS_CTRL_ADDR,
883*ff9112dfSStefan Roese 24, 0x1F, 0, 0);
884*ff9112dfSStefan Roese tmp = ddr3_get_max_val(spd_val, dimm_num, stat_val);
885*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - DUNIT-SET - tFAW-4*tRRD = ", tmp, 1);
886*ff9112dfSStefan Roese reg |= ((tmp & 0x1F) << 24);
887*ff9112dfSStefan Roese #endif
888*ff9112dfSStefan Roese
889*ff9112dfSStefan Roese /* SDRAM device capacity */
890*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
891*ff9112dfSStefan Roese reg |= (reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR) & 0xF0FFFF);
892*ff9112dfSStefan Roese #endif
893*ff9112dfSStefan Roese
894*ff9112dfSStefan Roese #ifdef DUNIT_SPD
895*ff9112dfSStefan Roese cs_count = 0;
896*ff9112dfSStefan Roese dimm_cnt = 0;
897*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
898*ff9112dfSStefan Roese if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
899*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
900*ff9112dfSStefan Roese dimm_cnt++;
901*ff9112dfSStefan Roese cs_count = 0;
902*ff9112dfSStefan Roese }
903*ff9112dfSStefan Roese cs_count++;
904*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].sdram_capacity < 0x3) {
905*ff9112dfSStefan Roese reg |= ((dimm_info[dimm_cnt].sdram_capacity + 1) <<
906*ff9112dfSStefan Roese (REG_SDRAM_ADDRESS_SIZE_OFFS +
907*ff9112dfSStefan Roese (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs)));
908*ff9112dfSStefan Roese } else if (dimm_info[dimm_cnt].sdram_capacity > 0x3) {
909*ff9112dfSStefan Roese reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x3) <<
910*ff9112dfSStefan Roese (REG_SDRAM_ADDRESS_SIZE_OFFS +
911*ff9112dfSStefan Roese (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs)));
912*ff9112dfSStefan Roese reg |= ((dimm_info[dimm_cnt].sdram_capacity & 0x4) <<
913*ff9112dfSStefan Roese (REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS + cs));
914*ff9112dfSStefan Roese }
915*ff9112dfSStefan Roese }
916*ff9112dfSStefan Roese }
917*ff9112dfSStefan Roese
918*ff9112dfSStefan Roese /* SDRAM device structure */
919*ff9112dfSStefan Roese cs_count = 0;
920*ff9112dfSStefan Roese dimm_cnt = 0;
921*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
922*ff9112dfSStefan Roese if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
923*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
924*ff9112dfSStefan Roese dimm_cnt++;
925*ff9112dfSStefan Roese cs_count = 0;
926*ff9112dfSStefan Roese }
927*ff9112dfSStefan Roese cs_count++;
928*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].sdram_width == 16)
929*ff9112dfSStefan Roese reg |= (1 << (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs));
930*ff9112dfSStefan Roese }
931*ff9112dfSStefan Roese }
932*ff9112dfSStefan Roese #endif
933*ff9112dfSStefan Roese reg_write(REG_SDRAM_ADDRESS_CTRL_ADDR, reg);
934*ff9112dfSStefan Roese
935*ff9112dfSStefan Roese /*{0x00001418} - DDR SDRAM Operation Register */
936*ff9112dfSStefan Roese reg = 0xF00;
937*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
938*ff9112dfSStefan Roese if (cs_ena & (1 << cs))
939*ff9112dfSStefan Roese reg &= ~(1 << (cs + REG_SDRAM_OPERATION_CS_OFFS));
940*ff9112dfSStefan Roese }
941*ff9112dfSStefan Roese reg_write(REG_SDRAM_OPERATION_ADDR, reg);
942*ff9112dfSStefan Roese
943*ff9112dfSStefan Roese /*{0x00001420} - DDR SDRAM Extended Mode Register */
944*ff9112dfSStefan Roese reg = 0x00000004;
945*ff9112dfSStefan Roese reg_write(REG_SDRAM_EXT_MODE_ADDR, reg);
946*ff9112dfSStefan Roese
947*ff9112dfSStefan Roese /*{0x00001424} - DDR Controller Control (High) Register */
948*ff9112dfSStefan Roese #if (defined(MV88F78X60) || defined(MV88F672X))
949*ff9112dfSStefan Roese reg = 0x0000D3FF;
950*ff9112dfSStefan Roese #else
951*ff9112dfSStefan Roese reg = 0x0100D1FF;
952*ff9112dfSStefan Roese #endif
953*ff9112dfSStefan Roese reg_write(REG_DDR_CONT_HIGH_ADDR, reg);
954*ff9112dfSStefan Roese
955*ff9112dfSStefan Roese /*{0x0000142C} - DDR3 Timing Register */
956*ff9112dfSStefan Roese reg = 0x014C2F38;
957*ff9112dfSStefan Roese #if defined(MV88F78X60) || defined(MV88F672X)
958*ff9112dfSStefan Roese reg = 0x1FEC2F38;
959*ff9112dfSStefan Roese #endif
960*ff9112dfSStefan Roese reg_write(0x142C, reg);
961*ff9112dfSStefan Roese
962*ff9112dfSStefan Roese /*{0x00001484} - MBus CPU Block Register */
963*ff9112dfSStefan Roese #ifdef MV88F67XX
964*ff9112dfSStefan Roese if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
965*ff9112dfSStefan Roese reg_write(REG_MBUS_CPU_BLOCK_ADDR, 0x0000E907);
966*ff9112dfSStefan Roese #endif
967*ff9112dfSStefan Roese
968*ff9112dfSStefan Roese /*
969*ff9112dfSStefan Roese * In case of mixed dimm and on-board devices setup paramters will
970*ff9112dfSStefan Roese * be taken statically
971*ff9112dfSStefan Roese */
972*ff9112dfSStefan Roese /*{0x00001494} - DDR SDRAM ODT Control (Low) Register */
973*ff9112dfSStefan Roese reg = odt_config[cs_ena];
974*ff9112dfSStefan Roese reg_write(REG_SDRAM_ODT_CTRL_LOW_ADDR, reg);
975*ff9112dfSStefan Roese
976*ff9112dfSStefan Roese /*{0x00001498} - DDR SDRAM ODT Control (High) Register */
977*ff9112dfSStefan Roese reg = 0x00000000;
978*ff9112dfSStefan Roese reg_write(REG_SDRAM_ODT_CTRL_HIGH_ADDR, reg);
979*ff9112dfSStefan Roese
980*ff9112dfSStefan Roese /*{0x0000149C} - DDR Dunit ODT Control Register */
981*ff9112dfSStefan Roese reg = cs_ena;
982*ff9112dfSStefan Roese reg_write(REG_DUNIT_ODT_CTRL_ADDR, reg);
983*ff9112dfSStefan Roese
984*ff9112dfSStefan Roese /*{0x000014A0} - DDR Dunit ODT Control Register */
985*ff9112dfSStefan Roese #if defined(MV88F672X)
986*ff9112dfSStefan Roese reg = 0x000006A9;
987*ff9112dfSStefan Roese reg_write(REG_DRAM_FIFO_CTRL_ADDR, reg);
988*ff9112dfSStefan Roese #endif
989*ff9112dfSStefan Roese
990*ff9112dfSStefan Roese /*{0x000014C0} - DRAM address and Control Driving Strenght */
991*ff9112dfSStefan Roese reg_write(REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR, 0x192435e9);
992*ff9112dfSStefan Roese
993*ff9112dfSStefan Roese /*{0x000014C4} - DRAM Data and DQS Driving Strenght */
994*ff9112dfSStefan Roese reg_write(REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR, 0xB2C35E9);
995*ff9112dfSStefan Roese
996*ff9112dfSStefan Roese #if (defined(MV88F78X60) || defined(MV88F672X))
997*ff9112dfSStefan Roese /*{0x000014CC} - DRAM Main Pads Calibration Machine Control Register */
998*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR);
999*ff9112dfSStefan Roese reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg | (1 << 0));
1000*ff9112dfSStefan Roese #endif
1001*ff9112dfSStefan Roese
1002*ff9112dfSStefan Roese #if defined(MV88F672X)
1003*ff9112dfSStefan Roese /* DRAM Main Pads Calibration Machine Control Register */
1004*ff9112dfSStefan Roese /* 0x14CC[4:3] - CalUpdateControl = IntOnly */
1005*ff9112dfSStefan Roese reg = reg_read(REG_DRAM_MAIN_PADS_CAL_ADDR);
1006*ff9112dfSStefan Roese reg &= 0xFFFFFFE7;
1007*ff9112dfSStefan Roese reg |= (1 << 3);
1008*ff9112dfSStefan Roese reg_write(REG_DRAM_MAIN_PADS_CAL_ADDR, reg);
1009*ff9112dfSStefan Roese #endif
1010*ff9112dfSStefan Roese
1011*ff9112dfSStefan Roese #ifdef DUNIT_SPD
1012*ff9112dfSStefan Roese cs_count = 0;
1013*ff9112dfSStefan Roese dimm_cnt = 0;
1014*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1015*ff9112dfSStefan Roese if ((1 << cs) & DIMM_CS_BITMAP) {
1016*ff9112dfSStefan Roese if ((1 << cs) & cs_ena) {
1017*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].num_of_module_ranks ==
1018*ff9112dfSStefan Roese cs_count) {
1019*ff9112dfSStefan Roese dimm_cnt++;
1020*ff9112dfSStefan Roese cs_count = 0;
1021*ff9112dfSStefan Roese }
1022*ff9112dfSStefan Roese cs_count++;
1023*ff9112dfSStefan Roese reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8),
1024*ff9112dfSStefan Roese dimm_info[dimm_cnt].rank_capacity - 1);
1025*ff9112dfSStefan Roese } else {
1026*ff9112dfSStefan Roese reg_write(REG_CS_SIZE_SCRATCH_ADDR + (cs * 0x8), 0);
1027*ff9112dfSStefan Roese }
1028*ff9112dfSStefan Roese }
1029*ff9112dfSStefan Roese }
1030*ff9112dfSStefan Roese #endif
1031*ff9112dfSStefan Roese
1032*ff9112dfSStefan Roese /*{0x00020184} - Close FastPath - 2G */
1033*ff9112dfSStefan Roese reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, 0);
1034*ff9112dfSStefan Roese
1035*ff9112dfSStefan Roese /*{0x00001538} - Read Data Sample Delays Register */
1036*ff9112dfSStefan Roese reg = 0;
1037*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1038*ff9112dfSStefan Roese if (cs_ena & (1 << cs))
1039*ff9112dfSStefan Roese reg |= (cl << (REG_READ_DATA_SAMPLE_DELAYS_OFFS * cs));
1040*ff9112dfSStefan Roese }
1041*ff9112dfSStefan Roese
1042*ff9112dfSStefan Roese reg_write(REG_READ_DATA_SAMPLE_DELAYS_ADDR, reg);
1043*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Sample Delays = ", reg,
1044*ff9112dfSStefan Roese 1);
1045*ff9112dfSStefan Roese
1046*ff9112dfSStefan Roese /*{0x0000153C} - Read Data Ready Delay Register */
1047*ff9112dfSStefan Roese reg = 0;
1048*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1049*ff9112dfSStefan Roese if (cs_ena & (1 << cs)) {
1050*ff9112dfSStefan Roese reg |= ((cl + 2) <<
1051*ff9112dfSStefan Roese (REG_READ_DATA_READY_DELAYS_OFFS * cs));
1052*ff9112dfSStefan Roese }
1053*ff9112dfSStefan Roese }
1054*ff9112dfSStefan Roese reg_write(REG_READ_DATA_READY_DELAYS_ADDR, reg);
1055*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Read Data Ready Delays = ", reg, 1);
1056*ff9112dfSStefan Roese
1057*ff9112dfSStefan Roese /* Set MR registers */
1058*ff9112dfSStefan Roese /* MR0 */
1059*ff9112dfSStefan Roese reg = 0x00000600;
1060*ff9112dfSStefan Roese tmp = ddr3_cl_to_valid_cl(cl);
1061*ff9112dfSStefan Roese reg |= ((tmp & 0x1) << 2);
1062*ff9112dfSStefan Roese reg |= ((tmp & 0xE) << 3); /* to bit 4 */
1063*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1064*ff9112dfSStefan Roese if (cs_ena & (1 << cs)) {
1065*ff9112dfSStefan Roese reg_write(REG_DDR3_MR0_CS_ADDR +
1066*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1067*ff9112dfSStefan Roese }
1068*ff9112dfSStefan Roese }
1069*ff9112dfSStefan Roese
1070*ff9112dfSStefan Roese /* MR1 */
1071*ff9112dfSStefan Roese reg = 0x00000044 & REG_DDR3_MR1_ODT_MASK;
1072*ff9112dfSStefan Roese if (cs_num > 1)
1073*ff9112dfSStefan Roese reg = 0x00000046 & REG_DDR3_MR1_ODT_MASK;
1074*ff9112dfSStefan Roese
1075*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1076*ff9112dfSStefan Roese if (cs_ena & (1 << cs)) {
1077*ff9112dfSStefan Roese reg |= odt_static[cs_ena][cs];
1078*ff9112dfSStefan Roese reg_write(REG_DDR3_MR1_CS_ADDR +
1079*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1080*ff9112dfSStefan Roese }
1081*ff9112dfSStefan Roese }
1082*ff9112dfSStefan Roese
1083*ff9112dfSStefan Roese /* MR2 */
1084*ff9112dfSStefan Roese if (reg_read(REG_DDR_IO_ADDR) & (1 << REG_DDR_IO_CLK_RATIO_OFFS))
1085*ff9112dfSStefan Roese tmp = hclk_time / 2;
1086*ff9112dfSStefan Roese else
1087*ff9112dfSStefan Roese tmp = hclk_time;
1088*ff9112dfSStefan Roese
1089*ff9112dfSStefan Roese if (tmp >= 2500)
1090*ff9112dfSStefan Roese cwl = 5; /* CWL = 5 */
1091*ff9112dfSStefan Roese else if (tmp >= 1875 && tmp < 2500)
1092*ff9112dfSStefan Roese cwl = 6; /* CWL = 6 */
1093*ff9112dfSStefan Roese else if (tmp >= 1500 && tmp < 1875)
1094*ff9112dfSStefan Roese cwl = 7; /* CWL = 7 */
1095*ff9112dfSStefan Roese else if (tmp >= 1250 && tmp < 1500)
1096*ff9112dfSStefan Roese cwl = 8; /* CWL = 8 */
1097*ff9112dfSStefan Roese else if (tmp >= 1070 && tmp < 1250)
1098*ff9112dfSStefan Roese cwl = 9; /* CWL = 9 */
1099*ff9112dfSStefan Roese else if (tmp >= 935 && tmp < 1070)
1100*ff9112dfSStefan Roese cwl = 10; /* CWL = 10 */
1101*ff9112dfSStefan Roese else if (tmp >= 833 && tmp < 935)
1102*ff9112dfSStefan Roese cwl = 11; /* CWL = 11 */
1103*ff9112dfSStefan Roese else if (tmp >= 750 && tmp < 833)
1104*ff9112dfSStefan Roese cwl = 12; /* CWL = 12 */
1105*ff9112dfSStefan Roese else {
1106*ff9112dfSStefan Roese cwl = 12; /* CWL = 12 */
1107*ff9112dfSStefan Roese printf("Unsupported hclk %d MHz\n", tmp);
1108*ff9112dfSStefan Roese }
1109*ff9112dfSStefan Roese
1110*ff9112dfSStefan Roese reg = ((cwl - 5) << REG_DDR3_MR2_CWL_OFFS);
1111*ff9112dfSStefan Roese
1112*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1113*ff9112dfSStefan Roese if (cs_ena & (1 << cs)) {
1114*ff9112dfSStefan Roese reg &= REG_DDR3_MR2_ODT_MASK;
1115*ff9112dfSStefan Roese reg |= odt_dynamic[cs_ena][cs];
1116*ff9112dfSStefan Roese reg_write(REG_DDR3_MR2_CS_ADDR +
1117*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1118*ff9112dfSStefan Roese }
1119*ff9112dfSStefan Roese }
1120*ff9112dfSStefan Roese
1121*ff9112dfSStefan Roese /* MR3 */
1122*ff9112dfSStefan Roese reg = 0x00000000;
1123*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1124*ff9112dfSStefan Roese if (cs_ena & (1 << cs)) {
1125*ff9112dfSStefan Roese reg_write(REG_DDR3_MR3_CS_ADDR +
1126*ff9112dfSStefan Roese (cs << MR_CS_ADDR_OFFS), reg);
1127*ff9112dfSStefan Roese }
1128*ff9112dfSStefan Roese }
1129*ff9112dfSStefan Roese
1130*ff9112dfSStefan Roese /* {0x00001428} - DDR ODT Timing (Low) Register */
1131*ff9112dfSStefan Roese reg = 0;
1132*ff9112dfSStefan Roese reg |= (((cl - cwl + 1) & 0xF) << 4);
1133*ff9112dfSStefan Roese reg |= (((cl - cwl + 6) & 0xF) << 8);
1134*ff9112dfSStefan Roese reg |= ((((cl - cwl + 6) >> 4) & 0x1) << 21);
1135*ff9112dfSStefan Roese reg |= (((cl - 1) & 0xF) << 12);
1136*ff9112dfSStefan Roese reg |= (((cl + 6) & 0x1F) << 16);
1137*ff9112dfSStefan Roese reg_write(REG_ODT_TIME_LOW_ADDR, reg);
1138*ff9112dfSStefan Roese
1139*ff9112dfSStefan Roese /* {0x0000147C} - DDR ODT Timing (High) Register */
1140*ff9112dfSStefan Roese reg = 0x00000071;
1141*ff9112dfSStefan Roese reg |= ((cwl - 1) << 8);
1142*ff9112dfSStefan Roese reg |= ((cwl + 5) << 12);
1143*ff9112dfSStefan Roese reg_write(REG_ODT_TIME_HIGH_ADDR, reg);
1144*ff9112dfSStefan Roese
1145*ff9112dfSStefan Roese #ifdef DUNIT_SPD
1146*ff9112dfSStefan Roese /*{0x000015E0} - DDR3 Rank Control Register */
1147*ff9112dfSStefan Roese reg = cs_ena;
1148*ff9112dfSStefan Roese cs_count = 0;
1149*ff9112dfSStefan Roese dimm_cnt = 0;
1150*ff9112dfSStefan Roese for (cs = 0; cs < MAX_CS; cs++) {
1151*ff9112dfSStefan Roese if (cs_ena & (1 << cs) & DIMM_CS_BITMAP) {
1152*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].num_of_module_ranks == cs_count) {
1153*ff9112dfSStefan Roese dimm_cnt++;
1154*ff9112dfSStefan Roese cs_count = 0;
1155*ff9112dfSStefan Roese }
1156*ff9112dfSStefan Roese cs_count++;
1157*ff9112dfSStefan Roese
1158*ff9112dfSStefan Roese if (dimm_info[dimm_cnt].addr_mirroring &&
1159*ff9112dfSStefan Roese (cs == 1 || cs == 3) &&
1160*ff9112dfSStefan Roese (sum_info.type_info != SPD_MODULE_TYPE_RDIMM)) {
1161*ff9112dfSStefan Roese reg |= (1 << (REG_DDR3_RANK_CTRL_MIRROR_OFFS + cs));
1162*ff9112dfSStefan Roese DEBUG_INIT_FULL_C("DDR3 - SPD-SET - Setting Address Mirroring for CS = ",
1163*ff9112dfSStefan Roese cs, 1);
1164*ff9112dfSStefan Roese }
1165*ff9112dfSStefan Roese }
1166*ff9112dfSStefan Roese }
1167*ff9112dfSStefan Roese reg_write(REG_DDR3_RANK_CTRL_ADDR, reg);
1168*ff9112dfSStefan Roese #endif
1169*ff9112dfSStefan Roese
1170*ff9112dfSStefan Roese /*{0xD00015E4} - ZQDS Configuration Register */
1171*ff9112dfSStefan Roese reg = 0x00203c18;
1172*ff9112dfSStefan Roese reg_write(REG_ZQC_CONF_ADDR, reg);
1173*ff9112dfSStefan Roese
1174*ff9112dfSStefan Roese /* {0x00015EC} - DDR PHY */
1175*ff9112dfSStefan Roese #if defined(MV88F78X60)
1176*ff9112dfSStefan Roese reg = 0xF800AAA5;
1177*ff9112dfSStefan Roese if (mv_ctrl_rev_get() == MV_78XX0_B0_REV)
1178*ff9112dfSStefan Roese reg = 0xF800A225;
1179*ff9112dfSStefan Roese #else
1180*ff9112dfSStefan Roese reg = 0xDE000025;
1181*ff9112dfSStefan Roese #if defined(MV88F672X)
1182*ff9112dfSStefan Roese reg = 0xF800A225;
1183*ff9112dfSStefan Roese #endif
1184*ff9112dfSStefan Roese #endif
1185*ff9112dfSStefan Roese reg_write(REG_DRAM_PHY_CONFIG_ADDR, reg);
1186*ff9112dfSStefan Roese
1187*ff9112dfSStefan Roese #if (defined(MV88F78X60) || defined(MV88F672X))
1188*ff9112dfSStefan Roese /* Registered DIMM support - supported only in AXP A0 devices */
1189*ff9112dfSStefan Roese /* Currently supported for SPD detection only */
1190*ff9112dfSStefan Roese /*
1191*ff9112dfSStefan Roese * Flow is according to the Registered DIMM chapter in the
1192*ff9112dfSStefan Roese * Functional Spec
1193*ff9112dfSStefan Roese */
1194*ff9112dfSStefan Roese if (sum_info.type_info == SPD_MODULE_TYPE_RDIMM) {
1195*ff9112dfSStefan Roese DEBUG_INIT_S("DDR3 Training Sequence - Registered DIMM detected\n");
1196*ff9112dfSStefan Roese
1197*ff9112dfSStefan Roese /* Set commands parity completion */
1198*ff9112dfSStefan Roese reg = reg_read(REG_REGISTERED_DRAM_CTRL_ADDR);
1199*ff9112dfSStefan Roese reg &= ~REG_REGISTERED_DRAM_CTRL_PARITY_MASK;
1200*ff9112dfSStefan Roese reg |= 0x8;
1201*ff9112dfSStefan Roese reg_write(REG_REGISTERED_DRAM_CTRL_ADDR, reg);
1202*ff9112dfSStefan Roese
1203*ff9112dfSStefan Roese /* De-assert M_RESETn and assert M_CKE */
1204*ff9112dfSStefan Roese reg_write(REG_SDRAM_INIT_CTRL_ADDR,
1205*ff9112dfSStefan Roese 1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS);
1206*ff9112dfSStefan Roese do {
1207*ff9112dfSStefan Roese reg = (reg_read(REG_SDRAM_INIT_CTRL_ADDR)) &
1208*ff9112dfSStefan Roese (1 << REG_SDRAM_INIT_CKE_ASSERT_OFFS);
1209*ff9112dfSStefan Roese } while (reg);
1210*ff9112dfSStefan Roese
1211*ff9112dfSStefan Roese for (rc = 0; rc < SPD_RDIMM_RC_NUM; rc++) {
1212*ff9112dfSStefan Roese if (rc != 6 && rc != 7) {
1213*ff9112dfSStefan Roese /* Set CWA Command */
1214*ff9112dfSStefan Roese reg = (REG_SDRAM_OPERATION_CMD_CWA &
1215*ff9112dfSStefan Roese ~(0xF << REG_SDRAM_OPERATION_CS_OFFS));
1216*ff9112dfSStefan Roese reg |= ((dimm_info[0].dimm_rc[rc] &
1217*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_MASK) <<
1218*ff9112dfSStefan Roese REG_SDRAM_OPERATION_CWA_DATA_OFFS);
1219*ff9112dfSStefan Roese reg |= rc << REG_SDRAM_OPERATION_CWA_RC_OFFS;
1220*ff9112dfSStefan Roese /* Configure - Set Delay - tSTAB/tMRD */
1221*ff9112dfSStefan Roese if (rc == 2 || rc == 10)
1222*ff9112dfSStefan Roese reg |= (0x1 << REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS);
1223*ff9112dfSStefan Roese /* 0x1418 - SDRAM Operation Register */
1224*ff9112dfSStefan Roese reg_write(REG_SDRAM_OPERATION_ADDR, reg);
1225*ff9112dfSStefan Roese
1226*ff9112dfSStefan Roese /*
1227*ff9112dfSStefan Roese * Poll the "cmd" field in the SDRAM OP
1228*ff9112dfSStefan Roese * register for 0x0
1229*ff9112dfSStefan Roese */
1230*ff9112dfSStefan Roese do {
1231*ff9112dfSStefan Roese reg = reg_read(REG_SDRAM_OPERATION_ADDR) &
1232*ff9112dfSStefan Roese (REG_SDRAM_OPERATION_CMD_MASK);
1233*ff9112dfSStefan Roese } while (reg);
1234*ff9112dfSStefan Roese }
1235*ff9112dfSStefan Roese }
1236*ff9112dfSStefan Roese }
1237*ff9112dfSStefan Roese #endif
1238*ff9112dfSStefan Roese
1239*ff9112dfSStefan Roese return MV_OK;
1240*ff9112dfSStefan Roese }
1241*ff9112dfSStefan Roese
1242*ff9112dfSStefan Roese /*
1243*ff9112dfSStefan Roese * Name: ddr3_div - this function divides integers
1244*ff9112dfSStefan Roese * Desc:
1245*ff9112dfSStefan Roese * Args: val - the value
1246*ff9112dfSStefan Roese * divider - the divider
1247*ff9112dfSStefan Roese * sub - substruction value
1248*ff9112dfSStefan Roese * Notes:
1249*ff9112dfSStefan Roese * Returns: required value
1250*ff9112dfSStefan Roese */
1251*ff9112dfSStefan Roese u32 ddr3_div(u32 val, u32 divider, u32 sub)
1252*ff9112dfSStefan Roese {
1253*ff9112dfSStefan Roese return val / divider + (val % divider > 0 ? 1 : 0) - sub;
1254*ff9112dfSStefan Roese }
1255*ff9112dfSStefan Roese
1256*ff9112dfSStefan Roese /*
1257*ff9112dfSStefan Roese * Name: ddr3_get_max_val
1258*ff9112dfSStefan Roese * Desc:
1259*ff9112dfSStefan Roese * Args:
1260*ff9112dfSStefan Roese * Notes:
1261*ff9112dfSStefan Roese * Returns:
1262*ff9112dfSStefan Roese */
1263*ff9112dfSStefan Roese u32 ddr3_get_max_val(u32 spd_val, u32 dimm_num, u32 static_val)
1264*ff9112dfSStefan Roese {
1265*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
1266*ff9112dfSStefan Roese if (dimm_num > 0) {
1267*ff9112dfSStefan Roese if (spd_val >= static_val)
1268*ff9112dfSStefan Roese return spd_val;
1269*ff9112dfSStefan Roese else
1270*ff9112dfSStefan Roese return static_val;
1271*ff9112dfSStefan Roese } else {
1272*ff9112dfSStefan Roese return static_val;
1273*ff9112dfSStefan Roese }
1274*ff9112dfSStefan Roese #else
1275*ff9112dfSStefan Roese return spd_val;
1276*ff9112dfSStefan Roese #endif
1277*ff9112dfSStefan Roese }
1278*ff9112dfSStefan Roese
1279*ff9112dfSStefan Roese /*
1280*ff9112dfSStefan Roese * Name: ddr3_get_min_val
1281*ff9112dfSStefan Roese * Desc:
1282*ff9112dfSStefan Roese * Args:
1283*ff9112dfSStefan Roese * Notes:
1284*ff9112dfSStefan Roese * Returns:
1285*ff9112dfSStefan Roese */
1286*ff9112dfSStefan Roese u32 ddr3_get_min_val(u32 spd_val, u32 dimm_num, u32 static_val)
1287*ff9112dfSStefan Roese {
1288*ff9112dfSStefan Roese #ifdef DUNIT_STATIC
1289*ff9112dfSStefan Roese if (dimm_num > 0) {
1290*ff9112dfSStefan Roese if (spd_val <= static_val)
1291*ff9112dfSStefan Roese return spd_val;
1292*ff9112dfSStefan Roese else
1293*ff9112dfSStefan Roese return static_val;
1294*ff9112dfSStefan Roese } else
1295*ff9112dfSStefan Roese return static_val;
1296*ff9112dfSStefan Roese #else
1297*ff9112dfSStefan Roese return spd_val;
1298*ff9112dfSStefan Roese #endif
1299*ff9112dfSStefan Roese }
1300*ff9112dfSStefan Roese #endif
1301