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