1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2983e3700STom Rini /*
3983e3700STom Rini  * Timing and Organization details of the Elpida parts used in OMAP4
4983e3700STom Rini  * SDPs and Panda
5983e3700STom Rini  *
6983e3700STom Rini  * (C) Copyright 2010
7983e3700STom Rini  * Texas Instruments, <www.ti.com>
8983e3700STom Rini  *
9983e3700STom Rini  * Aneesh V <aneesh@ti.com>
10983e3700STom Rini  */
11983e3700STom Rini 
12983e3700STom Rini #include <asm/emif.h>
13983e3700STom Rini #include <asm/arch/sys_proto.h>
14983e3700STom Rini 
15983e3700STom Rini /*
16983e3700STom Rini  * This file provides details of the LPDDR2 SDRAM parts used on OMAP4430
17983e3700STom Rini  * SDP and Panda. Since the parts used and geometry are identical for
18983e3700STom Rini  * SDP and Panda for a given OMAP4 revision, this information is kept
19983e3700STom Rini  * here instead of being in board directory. However the key functions
20983e3700STom Rini  * exported are weakly linked so that they can be over-ridden in the board
21983e3700STom Rini  * directory if there is a OMAP4 board in the future that uses a different
22983e3700STom Rini  * memory device or geometry.
23983e3700STom Rini  *
24983e3700STom Rini  * For any new board with different memory devices over-ride one or more
25983e3700STom Rini  * of the following functions as per the CONFIG flags you intend to enable:
26983e3700STom Rini  * - emif_get_reg_dump()
27983e3700STom Rini  * - emif_get_dmm_regs()
28983e3700STom Rini  * - emif_get_device_details()
29983e3700STom Rini  * - emif_get_device_timings()
30983e3700STom Rini  */
31983e3700STom Rini 
32983e3700STom Rini #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
33983e3700STom Rini 
34983e3700STom Rini const struct emif_regs emif_regs_elpida_200_mhz_2cs = {
35983e3700STom Rini 	.sdram_config_init		= 0x80000eb9,
36983e3700STom Rini 	.sdram_config			= 0x80001ab9,
37983e3700STom Rini 	.ref_ctrl			= 0x0000030c,
38983e3700STom Rini 	.sdram_tim1			= 0x08648311,
39983e3700STom Rini 	.sdram_tim2			= 0x101b06ca,
40983e3700STom Rini 	.sdram_tim3			= 0x0048a19f,
41983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
42983e3700STom Rini 	.zq_config			= 0x500b3214,
43983e3700STom Rini 	.temp_alert_config		= 0xd8016893,
44983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
45983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff808
46983e3700STom Rini };
47983e3700STom Rini 
48983e3700STom Rini const struct emif_regs emif_regs_elpida_380_mhz_1cs = {
49983e3700STom Rini 	.sdram_config_init		= 0x80000eb1,
50983e3700STom Rini 	.sdram_config			= 0x80001ab1,
51983e3700STom Rini 	.ref_ctrl			= 0x000005cd,
52983e3700STom Rini 	.sdram_tim1			= 0x10cb0622,
53983e3700STom Rini 	.sdram_tim2			= 0x20350d52,
54983e3700STom Rini 	.sdram_tim3			= 0x00b1431f,
55983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
56983e3700STom Rini 	.zq_config			= 0x500b3214,
57983e3700STom Rini 	.temp_alert_config		= 0x58016893,
58983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
59983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
60983e3700STom Rini };
61983e3700STom Rini 
62983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_1cs = {
63983e3700STom Rini 	.sdram_config_init		= 0x80800eb2,
64983e3700STom Rini 	.sdram_config			= 0x80801ab2,
65983e3700STom Rini 	.ref_ctrl			= 0x00000618,
66983e3700STom Rini 	.sdram_tim1			= 0x10eb0662,
67983e3700STom Rini 	.sdram_tim2			= 0x20370dd2,
68983e3700STom Rini 	.sdram_tim3			= 0x00b1c33f,
69983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
70983e3700STom Rini 	.zq_config			= 0x500b3215,
71983e3700STom Rini 	.temp_alert_config		= 0x58016893,
72983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
73983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
74983e3700STom Rini };
75983e3700STom Rini 
76983e3700STom Rini const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
77983e3700STom Rini 	.sdram_config_init		= 0x80000eb9,
78983e3700STom Rini 	.sdram_config			= 0x80001ab9,
79983e3700STom Rini 	.ref_ctrl			= 0x00000618,
80983e3700STom Rini 	.sdram_tim1			= 0x10eb0662,
81983e3700STom Rini 	.sdram_tim2			= 0x20370dd2,
82983e3700STom Rini 	.sdram_tim3			= 0x00b1c33f,
83983e3700STom Rini 	.read_idle_ctrl			= 0x000501ff,
84983e3700STom Rini 	.zq_config			= 0xd00b3214,
85983e3700STom Rini 	.temp_alert_config		= 0xd8016893,
86983e3700STom Rini 	.emif_ddr_phy_ctlr_1_init	= 0x049ffff5,
87983e3700STom Rini 	.emif_ddr_phy_ctlr_1		= 0x049ff418
88983e3700STom Rini };
89983e3700STom Rini 
90983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_1_x_2 = {
91983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
92983e3700STom Rini 	.dmm_lisa_map_1 = 0,
93983e3700STom Rini 	.dmm_lisa_map_2 = 0,
94983e3700STom Rini 	.dmm_lisa_map_3 = 0x80540300,
95983e3700STom Rini 	.is_ma_present	= 0x0
96983e3700STom Rini };
97983e3700STom Rini 
98983e3700STom Rini const struct dmm_lisa_map_regs lisa_map_2G_x_2_x_2 = {
99983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
100983e3700STom Rini 	.dmm_lisa_map_1 = 0,
101983e3700STom Rini 	.dmm_lisa_map_2 = 0,
102983e3700STom Rini 	.dmm_lisa_map_3 = 0x80640300,
103983e3700STom Rini 	.is_ma_present	= 0x0
104983e3700STom Rini };
105983e3700STom Rini 
106983e3700STom Rini const struct dmm_lisa_map_regs ma_lisa_map_2G_x_2_x_2 = {
107983e3700STom Rini 	.dmm_lisa_map_0 = 0xFF020100,
108983e3700STom Rini 	.dmm_lisa_map_1 = 0,
109983e3700STom Rini 	.dmm_lisa_map_2 = 0,
110983e3700STom Rini 	.dmm_lisa_map_3 = 0x80640300,
111983e3700STom Rini 	.is_ma_present	= 0x1
112983e3700STom Rini };
113983e3700STom Rini 
emif_get_reg_dump_sdp(u32 emif_nr,const struct emif_regs ** regs)114983e3700STom Rini static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
115983e3700STom Rini {
116983e3700STom Rini 	u32 omap4_rev = omap_revision();
117983e3700STom Rini 
118983e3700STom Rini 	/* Same devices and geometry on both EMIFs */
119983e3700STom Rini 	if (omap4_rev == OMAP4430_ES1_0)
120983e3700STom Rini 		*regs = &emif_regs_elpida_380_mhz_1cs;
121983e3700STom Rini 	else if (omap4_rev == OMAP4430_ES2_0)
122983e3700STom Rini 		*regs = &emif_regs_elpida_200_mhz_2cs;
123983e3700STom Rini 	else if (omap4_rev < OMAP4470_ES1_0)
124983e3700STom Rini 		*regs = &emif_regs_elpida_400_mhz_2cs;
125983e3700STom Rini 	else
126983e3700STom Rini 		*regs = &emif_regs_elpida_400_mhz_1cs;
127983e3700STom Rini }
128983e3700STom Rini void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
129983e3700STom Rini 	__attribute__((weak, alias("emif_get_reg_dump_sdp")));
130983e3700STom Rini 
emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs ** dmm_lisa_regs)131983e3700STom Rini static void emif_get_dmm_regs_sdp(const struct dmm_lisa_map_regs
132983e3700STom Rini 						**dmm_lisa_regs)
133983e3700STom Rini {
134983e3700STom Rini 	u32 omap_rev = omap_revision();
135983e3700STom Rini 
136983e3700STom Rini 	if (omap_rev == OMAP4430_ES1_0)
137983e3700STom Rini 		*dmm_lisa_regs = &lisa_map_2G_x_1_x_2;
138983e3700STom Rini 	else if (omap_rev < OMAP4460_ES1_0)
139983e3700STom Rini 		*dmm_lisa_regs = &lisa_map_2G_x_2_x_2;
140983e3700STom Rini 	else
141983e3700STom Rini 		*dmm_lisa_regs = &ma_lisa_map_2G_x_2_x_2;
142983e3700STom Rini }
143983e3700STom Rini 
144983e3700STom Rini void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
145983e3700STom Rini 	__attribute__((weak, alias("emif_get_dmm_regs_sdp")));
146983e3700STom Rini 
147983e3700STom Rini #else
148983e3700STom Rini 
149983e3700STom Rini const struct lpddr2_device_details elpida_2G_S4_details = {
150983e3700STom Rini 	.type		= LPDDR2_TYPE_S4,
151983e3700STom Rini 	.density	= LPDDR2_DENSITY_2Gb,
152983e3700STom Rini 	.io_width	= LPDDR2_IO_WIDTH_32,
153983e3700STom Rini 	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
154983e3700STom Rini };
155983e3700STom Rini 
156983e3700STom Rini const struct lpddr2_device_details elpida_4G_S4_details = {
157983e3700STom Rini 	.type		= LPDDR2_TYPE_S4,
158983e3700STom Rini 	.density	= LPDDR2_DENSITY_4Gb,
159983e3700STom Rini 	.io_width	= LPDDR2_IO_WIDTH_32,
160983e3700STom Rini 	.manufacturer	= LPDDR2_MANUFACTURER_ELPIDA
161983e3700STom Rini };
162983e3700STom Rini 
emif_get_device_details_sdp(u32 emif_nr,u8 cs,struct lpddr2_device_details * lpddr2_dev_details)163983e3700STom Rini struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs,
164983e3700STom Rini 			struct lpddr2_device_details *lpddr2_dev_details)
165983e3700STom Rini {
166983e3700STom Rini 	u32 omap_rev = omap_revision();
167983e3700STom Rini 
168983e3700STom Rini 	/* EMIF1 & EMIF2 have identical configuration */
169983e3700STom Rini 	if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
170983e3700STom Rini 		&& (cs == CS1)) {
171983e3700STom Rini 		/* Nothing connected on CS1 for 4430/4470 ES1.0 */
172983e3700STom Rini 		return NULL;
173983e3700STom Rini 	} else if (omap_rev < OMAP4470_ES1_0) {
174983e3700STom Rini 		/* In all other 4430/4460 cases Elpida 2G device */
175983e3700STom Rini 		*lpddr2_dev_details = elpida_2G_S4_details;
176983e3700STom Rini 	} else {
177983e3700STom Rini 		/* 4470: 4G device */
178983e3700STom Rini 		*lpddr2_dev_details = elpida_4G_S4_details;
179983e3700STom Rini 	}
180983e3700STom Rini 	return lpddr2_dev_details;
181983e3700STom Rini }
182983e3700STom Rini 
183983e3700STom Rini struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs,
184983e3700STom Rini 			struct lpddr2_device_details *lpddr2_dev_details)
185983e3700STom Rini 	__attribute__((weak, alias("emif_get_device_details_sdp")));
186983e3700STom Rini 
187983e3700STom Rini #endif /* CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS */
188983e3700STom Rini 
189983e3700STom Rini #ifndef CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
190983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_400_mhz = {
191983e3700STom Rini 	.max_freq	= 400000000,
192983e3700STom Rini 	.RL		= 6,
193983e3700STom Rini 	.tRPab		= 21,
194983e3700STom Rini 	.tRCD		= 18,
195983e3700STom Rini 	.tWR		= 15,
196983e3700STom Rini 	.tRASmin	= 42,
197983e3700STom Rini 	.tRRD		= 10,
198983e3700STom Rini 	.tWTRx2		= 15,
199983e3700STom Rini 	.tXSR		= 140,
200983e3700STom Rini 	.tXPx2		= 15,
201983e3700STom Rini 	.tRFCab		= 130,
202983e3700STom Rini 	.tRTPx2		= 15,
203983e3700STom Rini 	.tCKE		= 3,
204983e3700STom Rini 	.tCKESR		= 15,
205983e3700STom Rini 	.tZQCS		= 90,
206983e3700STom Rini 	.tZQCL		= 360,
207983e3700STom Rini 	.tZQINIT	= 1000,
208983e3700STom Rini 	.tDQSCKMAXx2	= 11,
209983e3700STom Rini 	.tRASmax	= 70,
210983e3700STom Rini 	.tFAW		= 50
211983e3700STom Rini };
212983e3700STom Rini 
213983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_333_mhz = {
214983e3700STom Rini 	.max_freq	= 333000000,
215983e3700STom Rini 	.RL		= 5,
216983e3700STom Rini 	.tRPab		= 21,
217983e3700STom Rini 	.tRCD		= 18,
218983e3700STom Rini 	.tWR		= 15,
219983e3700STom Rini 	.tRASmin	= 42,
220983e3700STom Rini 	.tRRD		= 10,
221983e3700STom Rini 	.tWTRx2		= 15,
222983e3700STom Rini 	.tXSR		= 140,
223983e3700STom Rini 	.tXPx2		= 15,
224983e3700STom Rini 	.tRFCab		= 130,
225983e3700STom Rini 	.tRTPx2		= 15,
226983e3700STom Rini 	.tCKE		= 3,
227983e3700STom Rini 	.tCKESR		= 15,
228983e3700STom Rini 	.tZQCS		= 90,
229983e3700STom Rini 	.tZQCL		= 360,
230983e3700STom Rini 	.tZQINIT	= 1000,
231983e3700STom Rini 	.tDQSCKMAXx2	= 11,
232983e3700STom Rini 	.tRASmax	= 70,
233983e3700STom Rini 	.tFAW		= 50
234983e3700STom Rini };
235983e3700STom Rini 
236983e3700STom Rini static const struct lpddr2_ac_timings timings_elpida_200_mhz = {
237983e3700STom Rini 	.max_freq	= 200000000,
238983e3700STom Rini 	.RL		= 3,
239983e3700STom Rini 	.tRPab		= 21,
240983e3700STom Rini 	.tRCD		= 18,
241983e3700STom Rini 	.tWR		= 15,
242983e3700STom Rini 	.tRASmin	= 42,
243983e3700STom Rini 	.tRRD		= 10,
244983e3700STom Rini 	.tWTRx2		= 20,
245983e3700STom Rini 	.tXSR		= 140,
246983e3700STom Rini 	.tXPx2		= 15,
247983e3700STom Rini 	.tRFCab		= 130,
248983e3700STom Rini 	.tRTPx2		= 15,
249983e3700STom Rini 	.tCKE		= 3,
250983e3700STom Rini 	.tCKESR		= 15,
251983e3700STom Rini 	.tZQCS		= 90,
252983e3700STom Rini 	.tZQCL		= 360,
253983e3700STom Rini 	.tZQINIT	= 1000,
254983e3700STom Rini 	.tDQSCKMAXx2	= 11,
255983e3700STom Rini 	.tRASmax	= 70,
256983e3700STom Rini 	.tFAW		= 50
257983e3700STom Rini };
258983e3700STom Rini 
259983e3700STom Rini static const struct lpddr2_min_tck min_tck_elpida = {
260983e3700STom Rini 	.tRL		= 3,
261983e3700STom Rini 	.tRP_AB		= 3,
262983e3700STom Rini 	.tRCD		= 3,
263983e3700STom Rini 	.tWR		= 3,
264983e3700STom Rini 	.tRAS_MIN	= 3,
265983e3700STom Rini 	.tRRD		= 2,
266983e3700STom Rini 	.tWTR		= 2,
267983e3700STom Rini 	.tXP		= 2,
268983e3700STom Rini 	.tRTP		= 2,
269983e3700STom Rini 	.tCKE		= 3,
270983e3700STom Rini 	.tCKESR		= 3,
271983e3700STom Rini 	.tFAW		= 8
272983e3700STom Rini };
273983e3700STom Rini 
274983e3700STom Rini static const struct lpddr2_ac_timings *elpida_ac_timings[MAX_NUM_SPEEDBINS] = {
275983e3700STom Rini 		&timings_elpida_200_mhz,
276983e3700STom Rini 		&timings_elpida_333_mhz,
277983e3700STom Rini 		&timings_elpida_400_mhz
278983e3700STom Rini };
279983e3700STom Rini 
280983e3700STom Rini const struct lpddr2_device_timings elpida_2G_S4_timings = {
281983e3700STom Rini 	.ac_timings	= elpida_ac_timings,
282983e3700STom Rini 	.min_tck	= &min_tck_elpida,
283983e3700STom Rini };
284983e3700STom Rini 
emif_get_device_timings_sdp(u32 emif_nr,const struct lpddr2_device_timings ** cs0_device_timings,const struct lpddr2_device_timings ** cs1_device_timings)285983e3700STom Rini void emif_get_device_timings_sdp(u32 emif_nr,
286983e3700STom Rini 		const struct lpddr2_device_timings **cs0_device_timings,
287983e3700STom Rini 		const struct lpddr2_device_timings **cs1_device_timings)
288983e3700STom Rini {
289983e3700STom Rini 	u32 omap_rev = omap_revision();
290983e3700STom Rini 
291983e3700STom Rini 	/* Identical devices on EMIF1 & EMIF2 */
292983e3700STom Rini 	*cs0_device_timings = &elpida_2G_S4_timings;
293983e3700STom Rini 
294983e3700STom Rini 	if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
295983e3700STom Rini 		*cs1_device_timings = NULL;
296983e3700STom Rini 	else
297983e3700STom Rini 		*cs1_device_timings = &elpida_2G_S4_timings;
298983e3700STom Rini }
299983e3700STom Rini 
300983e3700STom Rini void emif_get_device_timings(u32 emif_nr,
301983e3700STom Rini 		const struct lpddr2_device_timings **cs0_device_timings,
302983e3700STom Rini 		const struct lpddr2_device_timings **cs1_device_timings)
303983e3700STom Rini 	__attribute__((weak, alias("emif_get_device_timings_sdp")));
304983e3700STom Rini 
305983e3700STom Rini #endif /* CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS */
306983e3700STom Rini 
307983e3700STom Rini const struct lpddr2_mr_regs mr_regs = {
308983e3700STom Rini 	.mr1	= MR1_BL_8_BT_SEQ_WRAP_EN_NWR_3,
309983e3700STom Rini 	.mr2	= 0x4,
310983e3700STom Rini 	.mr3	= -1,
311983e3700STom Rini 	.mr10	= MR10_ZQ_ZQINIT,
312983e3700STom Rini 	.mr16	= MR16_REF_FULL_ARRAY
313983e3700STom Rini };
314983e3700STom Rini 
get_lpddr2_mr_regs(const struct lpddr2_mr_regs ** regs)315983e3700STom Rini void get_lpddr2_mr_regs(const struct lpddr2_mr_regs **regs)
316983e3700STom Rini {
317983e3700STom Rini 	*regs = &mr_regs;
318983e3700STom Rini }
319983e3700STom Rini 
get_bug_regs(u32 * iterations)320983e3700STom Rini __weak const struct read_write_regs *get_bug_regs(u32 *iterations)
321983e3700STom Rini {
322983e3700STom Rini 	return 0;
323983e3700STom Rini }
324