1*983e3700STom Rini /*
2*983e3700STom Rini  * Timing and Organization details of the Elpida parts used in OMAP4
3*983e3700STom Rini  * SDPs and Panda
4*983e3700STom Rini  *
5*983e3700STom Rini  * (C) Copyright 2010
6*983e3700STom Rini  * Texas Instruments, <www.ti.com>
7*983e3700STom Rini  *
8*983e3700STom Rini  * Aneesh V <aneesh@ti.com>
9*983e3700STom Rini  *
10*983e3700STom Rini  * SPDX-License-Identifier:	GPL-2.0+
11*983e3700STom Rini  */
12*983e3700STom Rini 
13*983e3700STom Rini #include <asm/emif.h>
14*983e3700STom Rini #include <asm/arch/sys_proto.h>
15*983e3700STom Rini 
16*983e3700STom Rini /*
17*983e3700STom Rini  * This file provides details of the LPDDR2 SDRAM parts used on OMAP4430
18*983e3700STom Rini  * SDP and Panda. Since the parts used and geometry are identical for
19*983e3700STom Rini  * SDP and Panda for a given OMAP4 revision, this information is kept
20*983e3700STom Rini  * here instead of being in board directory. However the key functions
21*983e3700STom Rini  * exported are weakly linked so that they can be over-ridden in the board
22*983e3700STom Rini  * directory if there is a OMAP4 board in the future that uses a different
23*983e3700STom Rini  * memory device or geometry.
24*983e3700STom Rini  *
25*983e3700STom Rini  * For any new board with different memory devices over-ride one or more
26*983e3700STom Rini  * of the following functions as per the CONFIG flags you intend to enable:
27*983e3700STom Rini  * - emif_get_reg_dump()
28*983e3700STom Rini  * - emif_get_dmm_regs()
29*983e3700STom Rini  * - emif_get_device_details()
30*983e3700STom Rini  * - emif_get_device_timings()
31*983e3700STom Rini  */
32*983e3700STom Rini 
33*983e3700STom Rini #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
34*983e3700STom Rini 
35*983e3700STom Rini const struct emif_regs emif_regs_elpida_200_mhz_2cs = {
36*983e3700STom Rini 	.sdram_config_init		= 0x80000eb9,
37*983e3700STom Rini 	.sdram_config			= 0x80001ab9,
38*983e3700STom Rini 	.ref_ctrl			= 0x0000030c,
39*983e3700STom Rini 	.sdram_tim1			= 0x08648311,
40*983e3700STom Rini 	.sdram_tim2			= 0x101b06ca,
41*983e3700STom Rini 	.sdram_tim3			= 0x0048a19f,
42*983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
43*983e3700STom Rini 	.zq_config			= 0x500b3214,
44*983e3700STom Rini 	.temp_alert_config		= 0xd8016893,
45*983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
46*983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff808
47*983e3700STom Rini };
48*983e3700STom Rini 
49*983e3700STom Rini const struct emif_regs emif_regs_elpida_380_mhz_1cs = {
50*983e3700STom Rini 	.sdram_config_init		= 0x80000eb1,
51*983e3700STom Rini 	.sdram_config			= 0x80001ab1,
52*983e3700STom Rini 	.ref_ctrl			= 0x000005cd,
53*983e3700STom Rini 	.sdram_tim1			= 0x10cb0622,
54*983e3700STom Rini 	.sdram_tim2			= 0x20350d52,
55*983e3700STom Rini 	.sdram_tim3			= 0x00b1431f,
56*983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
57*983e3700STom Rini 	.zq_config			= 0x500b3214,
58*983e3700STom Rini 	.temp_alert_config		= 0x58016893,
59*983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
60*983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
61*983e3700STom Rini };
62*983e3700STom Rini 
63*983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_1cs = {
64*983e3700STom Rini 	.sdram_config_init		= 0x80800eb2,
65*983e3700STom Rini 	.sdram_config			= 0x80801ab2,
66*983e3700STom Rini 	.ref_ctrl			= 0x00000618,
67*983e3700STom Rini 	.sdram_tim1			= 0x10eb0662,
68*983e3700STom Rini 	.sdram_tim2			= 0x20370dd2,
69*983e3700STom Rini 	.sdram_tim3			= 0x00b1c33f,
70*983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
71*983e3700STom Rini 	.zq_config			= 0x500b3215,
72*983e3700STom Rini 	.temp_alert_config		= 0x58016893,
73*983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
74*983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
75*983e3700STom Rini };
76*983e3700STom Rini 
77*983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
78*983e3700STom Rini 	.sdram_config_init		= 0x80000eb9,
79*983e3700STom Rini 	.sdram_config			= 0x80001ab9,
80*983e3700STom Rini 	.ref_ctrl			= 0x00000618,
81*983e3700STom Rini 	.sdram_tim1			= 0x10eb0662,
82*983e3700STom Rini 	.sdram_tim2			= 0x20370dd2,
83*983e3700STom Rini 	.sdram_tim3			= 0x00b1c33f,
84*983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
85*983e3700STom Rini 	.zq_config			= 0xd00b3214,
86*983e3700STom Rini 	.temp_alert_config		= 0xd8016893,
87*983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
88*983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
89*983e3700STom Rini };
90*983e3700STom Rini 
91*983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = {
92*983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
93*983e3700STom Rini 	.dmm_lisa_map_1 = 0,
94*983e3700STom Rini 	.dmm_lisa_map_2 = 0,
95*983e3700STom Rini 	.dmm_lisa_map_3 = 0x80540300,
96*983e3700STom Rini 	.is_ma_present	= 0x0
97*983e3700STom Rini };
98*983e3700STom Rini 
99*983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = {
100*983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
101*983e3700STom Rini 	.dmm_lisa_map_1 = 0,
102*983e3700STom Rini 	.dmm_lisa_map_2 = 0,
103*983e3700STom Rini 	.dmm_lisa_map_3 = 0x80640300,
104*983e3700STom Rini 	.is_ma_present	= 0x0
105*983e3700STom Rini };
106*983e3700STom Rini 
107*983e3700STom Rini const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2 = {
108*983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
109*983e3700STom Rini 	.dmm_lisa_map_1 = 0,
110*983e3700STom Rini 	.dmm_lisa_map_2 = 0,
111*983e3700STom Rini 	.dmm_lisa_map_3 = 0x80640300,
112*983e3700STom Rini 	.is_ma_present	= 0x1
113*983e3700STom Rini };
114*983e3700STom Rini 
115*983e3700STom Rini static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
116*983e3700STom Rini {
117*983e3700STom Rini 	u32 omap4_rev = omap_revision();
118*983e3700STom Rini 
119*983e3700STom Rini 	/* Same devices and geometry on both EMIFs */
120*983e3700STom Rini 	if (omap4_rev == OMAP4430_ES1_0)
121*983e3700STom Rini 		*regs = &emif_regs_elpida_380_mhz_1cs;
122*983e3700STom Rini 	else if (omap4_rev == OMAP4430_ES2_0)
123*983e3700STom Rini 		*regs = &emif_regs_elpida_200_mhz_2cs;
124*983e3700STom Rini 	else if (omap4_rev < OMAP4470_ES1_0)
125*983e3700STom Rini 		*regs = &emif_regs_elpida_400_mhz_2cs;
126*983e3700STom Rini 	else
127*983e3700STom Rini 		*regs = &emif_regs_elpida_400_mhz_1cs;
128*983e3700STom Rini }
129*983e3700STom Rini void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
130*983e3700STom Rini 	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
131*983e3700STom Rini 
132*983e3700STom Rini static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
133*983e3700STom Rini 						**dmm_lisa_regs)
134*983e3700STom Rini {
135*983e3700STom Rini 	u32 omap_rev = omap_revision();
136*983e3700STom Rini 
137*983e3700STom Rini 	if (omap_rev == OMAP4430_ES1_0)
138*983e3700STom Rini 		*dmm_lisa_regs = &lisa_map_2G_x_1_x_2;
139*983e3700STom Rini 	else if (omap_rev < OMAP4460_ES1_0)
140*983e3700STom Rini 		*dmm_lisa_regs = &lisa_map_2G_x_2_x_2;
141*983e3700STom Rini 	else
142*983e3700STom Rini 		*dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2;
143*983e3700STom Rini }
144*983e3700STom Rini 
145*983e3700STom Rini void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
146*983e3700STom Rini 	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
147*983e3700STom Rini 
148*983e3700STom Rini #else
149*983e3700STom Rini 
150*983e3700STom Rini const struct lpddr2_device_details elpida_2G_S4_details = {
151*983e3700STom Rini 	.type		= LPDDR2_TYPE_S4,
152*983e3700STom Rini 	.density	= LPDDR2_DENSITY_2Gb,
153*983e3700STom Rini 	.io_width	= LPDDR2_IO_WIDTH_32,
154*983e3700STom Rini 	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
155*983e3700STom Rini };
156*983e3700STom Rini 
157*983e3700STom Rini const struct lpddr2_device_details elpida_4G_S4_details = {
158*983e3700STom Rini 	.type		= LPDDR2_TYPE_S4,
159*983e3700STom Rini 	.density	= LPDDR2_DENSITY_4Gb,
160*983e3700STom Rini 	.io_width	= LPDDR2_IO_WIDTH_32,
161*983e3700STom Rini 	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
162*983e3700STom Rini };
163*983e3700STom Rini 
164*983e3700STom Rini struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs,
165*983e3700STom Rini 			struct lpddr2_device_details *lpddr2_dev_details)
166*983e3700STom Rini {
167*983e3700STom Rini 	u32 omap_rev = omap_revision();
168*983e3700STom Rini 
169*983e3700STom Rini 	/* EMIF1 & EMIF2 have identical configuration */
170*983e3700STom Rini 	if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
171*983e3700STom Rini 		&& (cs == CS1)) {
172*983e3700STom Rini 		/* Nothing connected on CS1 for 4430/4470 ES1.0 */
173*983e3700STom Rini 		return NULL;
174*983e3700STom Rini 	} else if (omap_rev < OMAP4470_ES1_0) {
175*983e3700STom Rini 		/* In all other 4430/4460 cases Elpida 2G device */
176*983e3700STom Rini 		*lpddr2_dev_details = elpida_2G_S4_details;
177*983e3700STom Rini 	} else {
178*983e3700STom Rini 		/* 4470: 4G device */
179*983e3700STom Rini 		*lpddr2_dev_details = elpida_4G_S4_details;
180*983e3700STom Rini 	}
181*983e3700STom Rini 	return lpddr2_dev_details;
182*983e3700STom Rini }
183*983e3700STom Rini 
184*983e3700STom Rini struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs,
185*983e3700STom Rini 			struct lpddr2_device_details *lpddr2_dev_details)
186*983e3700STom Rini 	__attribute__((weak, alias("emif_get_device_details_sdp")));
187*983e3700STom Rini 
188*983e3700STom Rini #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
189*983e3700STom Rini 
190*983e3700STom Rini #ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
191*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_400_mhz = {
192*983e3700STom Rini 	.max_freq	= 400000000,
193*983e3700STom Rini 	.RL		= 6,
194*983e3700STom Rini 	.tRPab		= 21,
195*983e3700STom Rini 	.tRCD		= 18,
196*983e3700STom Rini 	.tWR		= 15,
197*983e3700STom Rini 	.tRASmin	= 42,
198*983e3700STom Rini 	.tRRD		= 10,
199*983e3700STom Rini 	.tWTRx2		= 15,
200*983e3700STom Rini 	.tXSR		= 140,
201*983e3700STom Rini 	.tXPx2		= 15,
202*983e3700STom Rini 	.tRFCab		= 130,
203*983e3700STom Rini 	.tRTPx2		= 15,
204*983e3700STom Rini 	.tCKE		= 3,
205*983e3700STom Rini 	.tCKESR		= 15,
206*983e3700STom Rini 	.tZQCS		= 90,
207*983e3700STom Rini 	.tZQCL		= 360,
208*983e3700STom Rini 	.tZQINIT	= 1000,
209*983e3700STom Rini 	.tDQSCKMAXx2	= 11,
210*983e3700STom Rini 	.tRASmax	= 70,
211*983e3700STom Rini 	.tFAW		= 50
212*983e3700STom Rini };
213*983e3700STom Rini 
214*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_333_mhz = {
215*983e3700STom Rini 	.max_freq	= 333000000,
216*983e3700STom Rini 	.RL		= 5,
217*983e3700STom Rini 	.tRPab		= 21,
218*983e3700STom Rini 	.tRCD		= 18,
219*983e3700STom Rini 	.tWR		= 15,
220*983e3700STom Rini 	.tRASmin	= 42,
221*983e3700STom Rini 	.tRRD		= 10,
222*983e3700STom Rini 	.tWTRx2		= 15,
223*983e3700STom Rini 	.tXSR		= 140,
224*983e3700STom Rini 	.tXPx2		= 15,
225*983e3700STom Rini 	.tRFCab		= 130,
226*983e3700STom Rini 	.tRTPx2		= 15,
227*983e3700STom Rini 	.tCKE		= 3,
228*983e3700STom Rini 	.tCKESR		= 15,
229*983e3700STom Rini 	.tZQCS		= 90,
230*983e3700STom Rini 	.tZQCL		= 360,
231*983e3700STom Rini 	.tZQINIT	= 1000,
232*983e3700STom Rini 	.tDQSCKMAXx2	= 11,
233*983e3700STom Rini 	.tRASmax	= 70,
234*983e3700STom Rini 	.tFAW		= 50
235*983e3700STom Rini };
236*983e3700STom Rini 
237*983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_200_mhz = {
238*983e3700STom Rini 	.max_freq	= 200000000,
239*983e3700STom Rini 	.RL		= 3,
240*983e3700STom Rini 	.tRPab		= 21,
241*983e3700STom Rini 	.tRCD		= 18,
242*983e3700STom Rini 	.tWR		= 15,
243*983e3700STom Rini 	.tRASmin	= 42,
244*983e3700STom Rini 	.tRRD		= 10,
245*983e3700STom Rini 	.tWTRx2		= 20,
246*983e3700STom Rini 	.tXSR		= 140,
247*983e3700STom Rini 	.tXPx2		= 15,
248*983e3700STom Rini 	.tRFCab		= 130,
249*983e3700STom Rini 	.tRTPx2		= 15,
250*983e3700STom Rini 	.tCKE		= 3,
251*983e3700STom Rini 	.tCKESR		= 15,
252*983e3700STom Rini 	.tZQCS		= 90,
253*983e3700STom Rini 	.tZQCL		= 360,
254*983e3700STom Rini 	.tZQINIT	= 1000,
255*983e3700STom Rini 	.tDQSCKMAXx2	= 11,
256*983e3700STom Rini 	.tRASmax	= 70,
257*983e3700STom Rini 	.tFAW		= 50
258*983e3700STom Rini };
259*983e3700STom Rini 
260*983e3700STom Rini static const struct lpddr2_min_tck min_tck_elpida = {
261*983e3700STom Rini 	.tRL		= 3,
262*983e3700STom Rini 	.tRP_AB		= 3,
263*983e3700STom Rini 	.tRCD		= 3,
264*983e3700STom Rini 	.tWR		= 3,
265*983e3700STom Rini 	.tRAS_MIN	= 3,
266*983e3700STom Rini 	.tRRD		= 2,
267*983e3700STom Rini 	.tWTR		= 2,
268*983e3700STom Rini 	.tXP		= 2,
269*983e3700STom Rini 	.tRTP		= 2,
270*983e3700STom Rini 	.tCKE		= 3,
271*983e3700STom Rini 	.tCKESR		= 3,
272*983e3700STom Rini 	.tFAW		= 8
273*983e3700STom Rini };
274*983e3700STom Rini 
275*983e3700STom Rini static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = {
276*983e3700STom Rini 		&timings_elpida_200_mhz,
277*983e3700STom Rini 		&timings_elpida_333_mhz,
278*983e3700STom Rini 		&timings_elpida_400_mhz
279*983e3700STom Rini };
280*983e3700STom Rini 
281*983e3700STom Rini const struct lpddr2_device_timings elpida_2G_S4_timings = {
282*983e3700STom Rini 	.ac_timings	= elpida_ac_timings,
283*983e3700STom Rini 	.min_tck	= &min_tck_elpida,
284*983e3700STom Rini };
285*983e3700STom Rini 
286*983e3700STom Rini void emif_get_device_timings_sdp(u32 emif_nr,
287*983e3700STom Rini 		const struct lpddr2_device_timings **cs0_device_timings,
288*983e3700STom Rini 		const struct lpddr2_device_timings **cs1_device_timings)
289*983e3700STom Rini {
290*983e3700STom Rini 	u32 omap_rev = omap_revision();
291*983e3700STom Rini 
292*983e3700STom Rini 	/* Identical devices on EMIF1 & EMIF2 */
293*983e3700STom Rini 	*cs0_device_timings = &elpida_2G_S4_timings;
294*983e3700STom Rini 
295*983e3700STom Rini 	if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
296*983e3700STom Rini 		*cs1_device_timings = NULL;
297*983e3700STom Rini 	else
298*983e3700STom Rini 		*cs1_device_timings = &elpida_2G_S4_timings;
299*983e3700STom Rini }
300*983e3700STom Rini 
301*983e3700STom Rini void emif_get_device_timings(u32 emif_nr,
302*983e3700STom Rini 		const struct lpddr2_device_timings **cs0_device_timings,
303*983e3700STom Rini 		const struct lpddr2_device_timings **cs1_device_timings)
304*983e3700STom Rini 	__attribute__((weak, alias("emif_get_device_timings_sdp")));
305*983e3700STom Rini 
306*983e3700STom Rini #endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
307*983e3700STom Rini 
308*983e3700STom Rini const struct lpddr2_mr_regs mr_regs = {
309*983e3700STom Rini 	.mr1	= MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3,
310*983e3700STom Rini 	.mr2	= 0x4,
311*983e3700STom Rini 	.mr3	= -1,
312*983e3700STom Rini 	.mr10	= MR10_ZQ_ZQINIT,
313*983e3700STom Rini 	.mr16	= MR16_REF_FULL_ARRAY
314*983e3700STom Rini };
315*983e3700STom Rini 
316*983e3700STom Rini void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
317*983e3700STom Rini {
318*983e3700STom Rini 	*regs = &mr_regs;
319*983e3700STom Rini }
320*983e3700STom Rini 
321*983e3700STom Rini __weak const struct read_write_regs *get_bug_regs(u32 *iterations)
322*983e3700STom Rini {
323*983e3700STom Rini 	return 0;
324*983e3700STom Rini }
325