]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
0cc11dea TH |
2 | /* |
3 | * Copyright (C) 2014 Gateworks Corporation | |
4 | * Author: Tim Harvey <[email protected]> | |
0cc11dea TH |
5 | */ |
6 | ||
7 | #include <common.h> | |
6bf6dbee | 8 | #include <env.h> |
29a4a9f1 | 9 | #include <hang.h> |
0cc11dea | 10 | #include <asm/io.h> |
e25fbe3f | 11 | #include <asm/arch/crm_regs.h> |
0cc11dea TH |
12 | #include <asm/arch/mx6-ddr.h> |
13 | #include <asm/arch/mx6-pins.h> | |
14 | #include <asm/arch/sys_proto.h> | |
552a848e SB |
15 | #include <asm/mach-imx/boot_mode.h> |
16 | #include <asm/mach-imx/iomux-v3.h> | |
17 | #include <asm/mach-imx/mxc_i2c.h> | |
4bfd1f5d | 18 | #include <env.h> |
3c0fd17f | 19 | #include <i2c.h> |
0cc11dea TH |
20 | #include <spl.h> |
21 | ||
2089b7be TH |
22 | #include "gsc.h" |
23 | #include "common.h" | |
0cc11dea | 24 | |
0cc11dea | 25 | #define RTT_NOM_120OHM /* use 120ohm Rtt_nom vs 60ohm (lower power) */ |
0cc11dea TH |
26 | #define GSC_EEPROM_DDR_SIZE 0x2B /* enum (512,1024,2048) MB */ |
27 | #define GSC_EEPROM_DDR_WIDTH 0x2D /* enum (32,64) bit */ | |
0cc11dea TH |
28 | |
29 | /* configure MX6Q/DUAL mmdc DDR io registers */ | |
30 | struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = { | |
31 | /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ | |
32 | .dram_sdclk_0 = 0x00020030, | |
33 | .dram_sdclk_1 = 0x00020030, | |
34 | .dram_cas = 0x00020030, | |
35 | .dram_ras = 0x00020030, | |
36 | .dram_reset = 0x00020030, | |
37 | /* SDCKE[0:1]: 100k pull-up */ | |
38 | .dram_sdcke0 = 0x00003000, | |
39 | .dram_sdcke1 = 0x00003000, | |
40 | /* SDBA2: pull-up disabled */ | |
41 | .dram_sdba2 = 0x00000000, | |
42 | /* SDODT[0:1]: 100k pull-up, 40 ohm */ | |
43 | .dram_sdodt0 = 0x00003030, | |
44 | .dram_sdodt1 = 0x00003030, | |
45 | /* SDQS[0:7]: Differential input, 40 ohm */ | |
46 | .dram_sdqs0 = 0x00000030, | |
47 | .dram_sdqs1 = 0x00000030, | |
48 | .dram_sdqs2 = 0x00000030, | |
49 | .dram_sdqs3 = 0x00000030, | |
50 | .dram_sdqs4 = 0x00000030, | |
51 | .dram_sdqs5 = 0x00000030, | |
52 | .dram_sdqs6 = 0x00000030, | |
53 | .dram_sdqs7 = 0x00000030, | |
54 | ||
55 | /* DQM[0:7]: Differential input, 40 ohm */ | |
56 | .dram_dqm0 = 0x00020030, | |
57 | .dram_dqm1 = 0x00020030, | |
58 | .dram_dqm2 = 0x00020030, | |
59 | .dram_dqm3 = 0x00020030, | |
60 | .dram_dqm4 = 0x00020030, | |
61 | .dram_dqm5 = 0x00020030, | |
62 | .dram_dqm6 = 0x00020030, | |
63 | .dram_dqm7 = 0x00020030, | |
64 | }; | |
65 | ||
66 | /* configure MX6Q/DUAL mmdc GRP io registers */ | |
67 | struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = { | |
68 | /* DDR3 */ | |
69 | .grp_ddr_type = 0x000c0000, | |
70 | .grp_ddrmode_ctl = 0x00020000, | |
71 | /* disable DDR pullups */ | |
72 | .grp_ddrpke = 0x00000000, | |
73 | /* ADDR[00:16], SDBA[0:1]: 40 ohm */ | |
74 | .grp_addds = 0x00000030, | |
75 | /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ | |
76 | .grp_ctlds = 0x00000030, | |
77 | /* DATA[00:63]: Differential input, 40 ohm */ | |
78 | .grp_ddrmode = 0x00020000, | |
79 | .grp_b0ds = 0x00000030, | |
80 | .grp_b1ds = 0x00000030, | |
81 | .grp_b2ds = 0x00000030, | |
82 | .grp_b3ds = 0x00000030, | |
83 | .grp_b4ds = 0x00000030, | |
84 | .grp_b5ds = 0x00000030, | |
85 | .grp_b6ds = 0x00000030, | |
86 | .grp_b7ds = 0x00000030, | |
87 | }; | |
88 | ||
89 | /* configure MX6SOLO/DUALLITE mmdc DDR io registers */ | |
90 | struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = { | |
91 | /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ | |
92 | .dram_sdclk_0 = 0x00020030, | |
93 | .dram_sdclk_1 = 0x00020030, | |
94 | .dram_cas = 0x00020030, | |
95 | .dram_ras = 0x00020030, | |
96 | .dram_reset = 0x00020030, | |
97 | /* SDCKE[0:1]: 100k pull-up */ | |
98 | .dram_sdcke0 = 0x00003000, | |
99 | .dram_sdcke1 = 0x00003000, | |
100 | /* SDBA2: pull-up disabled */ | |
101 | .dram_sdba2 = 0x00000000, | |
102 | /* SDODT[0:1]: 100k pull-up, 40 ohm */ | |
103 | .dram_sdodt0 = 0x00003030, | |
104 | .dram_sdodt1 = 0x00003030, | |
105 | /* SDQS[0:7]: Differential input, 40 ohm */ | |
106 | .dram_sdqs0 = 0x00000030, | |
107 | .dram_sdqs1 = 0x00000030, | |
108 | .dram_sdqs2 = 0x00000030, | |
109 | .dram_sdqs3 = 0x00000030, | |
110 | .dram_sdqs4 = 0x00000030, | |
111 | .dram_sdqs5 = 0x00000030, | |
112 | .dram_sdqs6 = 0x00000030, | |
113 | .dram_sdqs7 = 0x00000030, | |
114 | ||
115 | /* DQM[0:7]: Differential input, 40 ohm */ | |
116 | .dram_dqm0 = 0x00020030, | |
117 | .dram_dqm1 = 0x00020030, | |
118 | .dram_dqm2 = 0x00020030, | |
119 | .dram_dqm3 = 0x00020030, | |
120 | .dram_dqm4 = 0x00020030, | |
121 | .dram_dqm5 = 0x00020030, | |
122 | .dram_dqm6 = 0x00020030, | |
123 | .dram_dqm7 = 0x00020030, | |
124 | }; | |
125 | ||
126 | /* configure MX6SOLO/DUALLITE mmdc GRP io registers */ | |
127 | struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = { | |
128 | /* DDR3 */ | |
129 | .grp_ddr_type = 0x000c0000, | |
130 | /* SDQS[0:7]: Differential input, 40 ohm */ | |
131 | .grp_ddrmode_ctl = 0x00020000, | |
132 | /* disable DDR pullups */ | |
133 | .grp_ddrpke = 0x00000000, | |
134 | /* ADDR[00:16], SDBA[0:1]: 40 ohm */ | |
135 | .grp_addds = 0x00000030, | |
136 | /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ | |
137 | .grp_ctlds = 0x00000030, | |
138 | /* DATA[00:63]: Differential input, 40 ohm */ | |
139 | .grp_ddrmode = 0x00020000, | |
140 | .grp_b0ds = 0x00000030, | |
141 | .grp_b1ds = 0x00000030, | |
142 | .grp_b2ds = 0x00000030, | |
143 | .grp_b3ds = 0x00000030, | |
144 | .grp_b4ds = 0x00000030, | |
145 | .grp_b5ds = 0x00000030, | |
146 | .grp_b6ds = 0x00000030, | |
147 | .grp_b7ds = 0x00000030, | |
148 | }; | |
149 | ||
767d88b0 PS |
150 | /* MT41K64M16JT-125 (1Gb density) */ |
151 | static struct mx6_ddr3_cfg mt41k64m16jt_125 = { | |
152 | .mem_speed = 1600, | |
153 | .density = 1, | |
154 | .width = 16, | |
155 | .banks = 8, | |
156 | .rowaddr = 13, | |
157 | .coladdr = 10, | |
158 | .pagesz = 2, | |
159 | .trcd = 1375, | |
160 | .trcmin = 4875, | |
161 | .trasmin = 3500, | |
162 | }; | |
163 | ||
b0b83347 | 164 | /* MT41K128M16JT-125 (2Gb density) */ |
0cc11dea TH |
165 | static struct mx6_ddr3_cfg mt41k128m16jt_125 = { |
166 | .mem_speed = 1600, | |
167 | .density = 2, | |
168 | .width = 16, | |
169 | .banks = 8, | |
170 | .rowaddr = 14, | |
171 | .coladdr = 10, | |
172 | .pagesz = 2, | |
173 | .trcd = 1375, | |
174 | .trcmin = 4875, | |
175 | .trasmin = 3500, | |
176 | }; | |
177 | ||
b0b83347 | 178 | /* MT41K256M16HA-125 (4Gb density) */ |
c91e4b8b TH |
179 | static struct mx6_ddr3_cfg mt41k256m16ha_125 = { |
180 | .mem_speed = 1600, | |
181 | .density = 4, | |
182 | .width = 16, | |
183 | .banks = 8, | |
184 | .rowaddr = 15, | |
185 | .coladdr = 10, | |
186 | .pagesz = 2, | |
187 | .trcd = 1375, | |
188 | .trcmin = 4875, | |
189 | .trasmin = 3500, | |
190 | }; | |
191 | ||
6052b1c6 TH |
192 | /* MT41K512M16HA-125 (8Gb density) */ |
193 | static struct mx6_ddr3_cfg mt41k512m16ha_125 = { | |
194 | .mem_speed = 1600, | |
195 | .density = 8, | |
196 | .width = 16, | |
197 | .banks = 8, | |
198 | .rowaddr = 16, | |
199 | .coladdr = 10, | |
200 | .pagesz = 2, | |
201 | .trcd = 1375, | |
202 | .trcmin = 4875, | |
203 | .trasmin = 3500, | |
204 | }; | |
205 | ||
c91e4b8b TH |
206 | /* |
207 | * calibration - these are the various CPU/DDR3 combinations we support | |
208 | */ | |
767d88b0 PS |
209 | static struct mx6_mmdc_calibration mx6sdl_64x16_mmdc_calib = { |
210 | /* write leveling calibration determine */ | |
211 | .p0_mpwldectrl0 = 0x004C004E, | |
212 | .p0_mpwldectrl1 = 0x00440044, | |
213 | /* Read DQS Gating calibration */ | |
214 | .p0_mpdgctrl0 = 0x42440247, | |
215 | .p0_mpdgctrl1 = 0x02310232, | |
216 | /* Read Calibration: DQS delay relative to DQ read access */ | |
217 | .p0_mprddlctl = 0x45424746, | |
218 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
219 | .p0_mpwrdlctl = 0x33382C31, | |
220 | }; | |
c91e4b8b | 221 | |
ebe07ef7 TH |
222 | /* TODO: update with calibrated values */ |
223 | static struct mx6_mmdc_calibration mx6dq_64x64_mmdc_calib = { | |
224 | /* write leveling calibration determine */ | |
225 | .p0_mpwldectrl0 = 0x00190017, | |
226 | .p0_mpwldectrl1 = 0x00140026, | |
227 | .p1_mpwldectrl0 = 0x0021001C, | |
228 | .p1_mpwldectrl1 = 0x0011001D, | |
229 | /* Read DQS Gating calibration */ | |
230 | .p0_mpdgctrl0 = 0x43380347, | |
231 | .p0_mpdgctrl1 = 0x433C034D, | |
232 | .p1_mpdgctrl0 = 0x032C0324, | |
233 | .p1_mpdgctrl1 = 0x03310232, | |
234 | /* Read Calibration: DQS delay relative to DQ read access */ | |
235 | .p0_mprddlctl = 0x3C313539, | |
236 | .p1_mprddlctl = 0x37343141, | |
237 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
238 | .p0_mpwrdlctl = 0x36393C39, | |
239 | .p1_mpwrdlctl = 0x42344438, | |
240 | }; | |
241 | ||
242 | /* TODO: update with calibrated values */ | |
243 | static struct mx6_mmdc_calibration mx6sdl_64x64_mmdc_calib = { | |
244 | /* write leveling calibration determine */ | |
245 | .p0_mpwldectrl0 = 0x003C003C, | |
246 | .p0_mpwldectrl1 = 0x001F002A, | |
247 | .p1_mpwldectrl0 = 0x00330038, | |
248 | .p1_mpwldectrl1 = 0x0022003F, | |
249 | /* Read DQS Gating calibration */ | |
250 | .p0_mpdgctrl0 = 0x42410244, | |
251 | .p0_mpdgctrl1 = 0x4234023A, | |
252 | .p1_mpdgctrl0 = 0x022D022D, | |
253 | .p1_mpdgctrl1 = 0x021C0228, | |
254 | /* Read Calibration: DQS delay relative to DQ read access */ | |
255 | .p0_mprddlctl = 0x484A4C4B, | |
256 | .p1_mprddlctl = 0x4B4D4E4B, | |
257 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
258 | .p0_mpwrdlctl = 0x33342B32, | |
259 | .p1_mpwrdlctl = 0x3933332B, | |
260 | }; | |
261 | ||
75f21e31 TH |
262 | static struct mx6_mmdc_calibration mx6dq_256x16_mmdc_calib = { |
263 | /* write leveling calibration determine */ | |
06edcb9d TH |
264 | .p0_mpwldectrl0 = 0x001B0016, |
265 | .p0_mpwldectrl1 = 0x000C000E, | |
75f21e31 | 266 | /* Read DQS Gating calibration */ |
06edcb9d TH |
267 | .p0_mpdgctrl0 = 0x4324033A, |
268 | .p0_mpdgctrl1 = 0x00000000, | |
75f21e31 | 269 | /* Read Calibration: DQS delay relative to DQ read access */ |
06edcb9d | 270 | .p0_mprddlctl = 0x40403438, |
75f21e31 | 271 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
06edcb9d | 272 | .p0_mpwrdlctl = 0x40403D36, |
75f21e31 TH |
273 | }; |
274 | ||
75f21e31 TH |
275 | static struct mx6_mmdc_calibration mx6sdl_256x16_mmdc_calib = { |
276 | /* write leveling calibration determine */ | |
06edcb9d TH |
277 | .p0_mpwldectrl0 = 0x00420043, |
278 | .p0_mpwldectrl1 = 0x0016001A, | |
75f21e31 | 279 | /* Read DQS Gating calibration */ |
06edcb9d TH |
280 | .p0_mpdgctrl0 = 0x4238023B, |
281 | .p0_mpdgctrl1 = 0x00000000, | |
75f21e31 | 282 | /* Read Calibration: DQS delay relative to DQ read access */ |
06edcb9d | 283 | .p0_mprddlctl = 0x40404849, |
75f21e31 | 284 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
06edcb9d | 285 | .p0_mpwrdlctl = 0x40402E2F, |
75f21e31 TH |
286 | }; |
287 | ||
c91e4b8b | 288 | static struct mx6_mmdc_calibration mx6dq_128x32_mmdc_calib = { |
0cc11dea | 289 | /* write leveling calibration determine */ |
c91e4b8b TH |
290 | .p0_mpwldectrl0 = 0x00190017, |
291 | .p0_mpwldectrl1 = 0x00140026, | |
0cc11dea | 292 | /* Read DQS Gating calibration */ |
c91e4b8b TH |
293 | .p0_mpdgctrl0 = 0x43380347, |
294 | .p0_mpdgctrl1 = 0x433C034D, | |
0cc11dea TH |
295 | /* Read Calibration: DQS delay relative to DQ read access */ |
296 | .p0_mprddlctl = 0x3C313539, | |
0cc11dea | 297 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
c91e4b8b TH |
298 | .p0_mpwrdlctl = 0x36393C39, |
299 | }; | |
300 | ||
301 | static struct mx6_mmdc_calibration mx6sdl_128x32_mmdc_calib = { | |
302 | /* write leveling calibration determine */ | |
303 | .p0_mpwldectrl0 = 0x003C003C, | |
304 | .p0_mpwldectrl1 = 0x001F002A, | |
305 | /* Read DQS Gating calibration */ | |
306 | .p0_mpdgctrl0 = 0x42410244, | |
307 | .p0_mpdgctrl1 = 0x4234023A, | |
308 | /* Read Calibration: DQS delay relative to DQ read access */ | |
309 | .p0_mprddlctl = 0x484A4C4B, | |
310 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
311 | .p0_mpwrdlctl = 0x33342B32, | |
0cc11dea TH |
312 | }; |
313 | ||
c91e4b8b | 314 | static struct mx6_mmdc_calibration mx6dq_128x64_mmdc_calib = { |
0cc11dea | 315 | /* write leveling calibration determine */ |
c91e4b8b TH |
316 | .p0_mpwldectrl0 = 0x00190017, |
317 | .p0_mpwldectrl1 = 0x00140026, | |
318 | .p1_mpwldectrl0 = 0x0021001C, | |
319 | .p1_mpwldectrl1 = 0x0011001D, | |
0cc11dea | 320 | /* Read DQS Gating calibration */ |
c91e4b8b TH |
321 | .p0_mpdgctrl0 = 0x43380347, |
322 | .p0_mpdgctrl1 = 0x433C034D, | |
323 | .p1_mpdgctrl0 = 0x032C0324, | |
324 | .p1_mpdgctrl1 = 0x03310232, | |
0cc11dea | 325 | /* Read Calibration: DQS delay relative to DQ read access */ |
c91e4b8b TH |
326 | .p0_mprddlctl = 0x3C313539, |
327 | .p1_mprddlctl = 0x37343141, | |
0cc11dea | 328 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
c91e4b8b TH |
329 | .p0_mpwrdlctl = 0x36393C39, |
330 | .p1_mpwrdlctl = 0x42344438, | |
0cc11dea | 331 | }; |
c91e4b8b TH |
332 | |
333 | static struct mx6_mmdc_calibration mx6sdl_128x64_mmdc_calib = { | |
0cc11dea TH |
334 | /* write leveling calibration determine */ |
335 | .p0_mpwldectrl0 = 0x003C003C, | |
c91e4b8b TH |
336 | .p0_mpwldectrl1 = 0x001F002A, |
337 | .p1_mpwldectrl0 = 0x00330038, | |
0cc11dea TH |
338 | .p1_mpwldectrl1 = 0x0022003F, |
339 | /* Read DQS Gating calibration */ | |
340 | .p0_mpdgctrl0 = 0x42410244, | |
c91e4b8b TH |
341 | .p0_mpdgctrl1 = 0x4234023A, |
342 | .p1_mpdgctrl0 = 0x022D022D, | |
0cc11dea TH |
343 | .p1_mpdgctrl1 = 0x021C0228, |
344 | /* Read Calibration: DQS delay relative to DQ read access */ | |
345 | .p0_mprddlctl = 0x484A4C4B, | |
346 | .p1_mprddlctl = 0x4B4D4E4B, | |
347 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
348 | .p0_mpwrdlctl = 0x33342B32, | |
349 | .p1_mpwrdlctl = 0x3933332B, | |
350 | }; | |
351 | ||
c91e4b8b | 352 | static struct mx6_mmdc_calibration mx6dq_256x32_mmdc_calib = { |
0cc11dea | 353 | /* write leveling calibration determine */ |
c91e4b8b TH |
354 | .p0_mpwldectrl0 = 0x001E001A, |
355 | .p0_mpwldectrl1 = 0x0026001F, | |
0cc11dea | 356 | /* Read DQS Gating calibration */ |
c91e4b8b TH |
357 | .p0_mpdgctrl0 = 0x43370349, |
358 | .p0_mpdgctrl1 = 0x032D0327, | |
0cc11dea | 359 | /* Read Calibration: DQS delay relative to DQ read access */ |
c91e4b8b | 360 | .p0_mprddlctl = 0x3D303639, |
0cc11dea | 361 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
c91e4b8b | 362 | .p0_mpwrdlctl = 0x32363934, |
0cc11dea TH |
363 | }; |
364 | ||
b0b83347 TH |
365 | static struct mx6_mmdc_calibration mx6sdl_256x32_mmdc_calib = { |
366 | /* write leveling calibration determine */ | |
367 | .p0_mpwldectrl0 = 0X00480047, | |
368 | .p0_mpwldectrl1 = 0X003D003F, | |
369 | /* Read DQS Gating calibration */ | |
370 | .p0_mpdgctrl0 = 0X423E0241, | |
371 | .p0_mpdgctrl1 = 0X022B022C, | |
372 | /* Read Calibration: DQS delay relative to DQ read access */ | |
373 | .p0_mprddlctl = 0X49454A4A, | |
374 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
375 | .p0_mpwrdlctl = 0X2E372C32, | |
376 | }; | |
377 | ||
c91e4b8b | 378 | static struct mx6_mmdc_calibration mx6dq_256x64_mmdc_calib = { |
0cc11dea | 379 | /* write leveling calibration determine */ |
c91e4b8b TH |
380 | .p0_mpwldectrl0 = 0X00220021, |
381 | .p0_mpwldectrl1 = 0X00200030, | |
382 | .p1_mpwldectrl0 = 0X002D0027, | |
383 | .p1_mpwldectrl1 = 0X00150026, | |
0cc11dea | 384 | /* Read DQS Gating calibration */ |
c91e4b8b TH |
385 | .p0_mpdgctrl0 = 0x43330342, |
386 | .p0_mpdgctrl1 = 0x0339034A, | |
387 | .p1_mpdgctrl0 = 0x032F0325, | |
388 | .p1_mpdgctrl1 = 0x032F022E, | |
0cc11dea | 389 | /* Read Calibration: DQS delay relative to DQ read access */ |
c91e4b8b TH |
390 | .p0_mprddlctl = 0X3A2E3437, |
391 | .p1_mprddlctl = 0X35312F3F, | |
0cc11dea | 392 | /* Write Calibration: DQ/DM delay relative to DQS write access */ |
c91e4b8b TH |
393 | .p0_mpwrdlctl = 0X33363B37, |
394 | .p1_mpwrdlctl = 0X40304239, | |
0cc11dea TH |
395 | }; |
396 | ||
ad68d7b8 TH |
397 | static struct mx6_mmdc_calibration mx6sdl_256x64_mmdc_calib = { |
398 | /* write leveling calibration determine */ | |
399 | .p0_mpwldectrl0 = 0x0048004A, | |
400 | .p0_mpwldectrl1 = 0x003F004A, | |
401 | .p1_mpwldectrl0 = 0x001E0028, | |
402 | .p1_mpwldectrl1 = 0x002C0043, | |
403 | /* Read DQS Gating calibration */ | |
404 | .p0_mpdgctrl0 = 0x02250219, | |
405 | .p0_mpdgctrl1 = 0x01790202, | |
406 | .p1_mpdgctrl0 = 0x02080208, | |
407 | .p1_mpdgctrl1 = 0x016C0175, | |
408 | /* Read Calibration: DQS delay relative to DQ read access */ | |
409 | .p0_mprddlctl = 0x4A4C4D4C, | |
410 | .p1_mprddlctl = 0x494C4A48, | |
411 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
412 | .p0_mpwrdlctl = 0x403F3437, | |
413 | .p1_mpwrdlctl = 0x383A3930, | |
414 | }; | |
415 | ||
214fb19b TH |
416 | static struct mx6_mmdc_calibration mx6sdl_256x64x2_mmdc_calib = { |
417 | /* write leveling calibration determine */ | |
418 | .p0_mpwldectrl0 = 0x001F003F, | |
419 | .p0_mpwldectrl1 = 0x001F001F, | |
420 | .p1_mpwldectrl0 = 0x001F004E, | |
421 | .p1_mpwldectrl1 = 0x0059001F, | |
422 | /* Read DQS Gating calibration */ | |
423 | .p0_mpdgctrl0 = 0x42220225, | |
424 | .p0_mpdgctrl1 = 0x0213021F, | |
425 | .p1_mpdgctrl0 = 0x022C0242, | |
426 | .p1_mpdgctrl1 = 0x022C0244, | |
427 | /* Read Calibration: DQS delay relative to DQ read access */ | |
428 | .p0_mprddlctl = 0x474A4C4A, | |
429 | .p1_mprddlctl = 0x48494C45, | |
430 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
431 | .p0_mpwrdlctl = 0x3F3F3F36, | |
432 | .p1_mpwrdlctl = 0x3F36363F, | |
433 | }; | |
434 | ||
d1c3867a TH |
435 | static struct mx6_mmdc_calibration mx6sdl_128x64x2_mmdc_calib = { |
436 | /* write leveling calibration determine */ | |
437 | .p0_mpwldectrl0 = 0x001F003F, | |
438 | .p0_mpwldectrl1 = 0x001F001F, | |
439 | .p1_mpwldectrl0 = 0x001F004E, | |
440 | .p1_mpwldectrl1 = 0x0059001F, | |
441 | /* Read DQS Gating calibration */ | |
442 | .p0_mpdgctrl0 = 0x42220225, | |
443 | .p0_mpdgctrl1 = 0x0213021F, | |
444 | .p1_mpdgctrl0 = 0x022C0242, | |
445 | .p1_mpdgctrl1 = 0x022C0244, | |
446 | /* Read Calibration: DQS delay relative to DQ read access */ | |
447 | .p0_mprddlctl = 0x474A4C4A, | |
448 | .p1_mprddlctl = 0x48494C45, | |
449 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
450 | .p0_mpwrdlctl = 0x3F3F3F36, | |
451 | .p1_mpwrdlctl = 0x3F36363F, | |
452 | }; | |
453 | ||
6052b1c6 TH |
454 | static struct mx6_mmdc_calibration mx6dq_512x32_mmdc_calib = { |
455 | /* write leveling calibration determine */ | |
456 | .p0_mpwldectrl0 = 0x002A0025, | |
457 | .p0_mpwldectrl1 = 0x003A002A, | |
458 | /* Read DQS Gating calibration */ | |
459 | .p0_mpdgctrl0 = 0x43430356, | |
460 | .p0_mpdgctrl1 = 0x033C0335, | |
461 | /* Read Calibration: DQS delay relative to DQ read access */ | |
462 | .p0_mprddlctl = 0x4B373F42, | |
463 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
464 | .p0_mpwrdlctl = 0x303E3C36, | |
465 | }; | |
466 | ||
ad68d7b8 TH |
467 | static struct mx6_mmdc_calibration mx6dq_512x64_mmdc_calib = { |
468 | /* write leveling calibration determine */ | |
469 | .p0_mpwldectrl0 = 0x00230020, | |
470 | .p0_mpwldectrl1 = 0x002F002A, | |
471 | .p1_mpwldectrl0 = 0x001D0027, | |
472 | .p1_mpwldectrl1 = 0x00100023, | |
473 | /* Read DQS Gating calibration */ | |
474 | .p0_mpdgctrl0 = 0x03250339, | |
475 | .p0_mpdgctrl1 = 0x031C0316, | |
476 | .p1_mpdgctrl0 = 0x03210331, | |
477 | .p1_mpdgctrl1 = 0x031C025A, | |
478 | /* Read Calibration: DQS delay relative to DQ read access */ | |
479 | .p0_mprddlctl = 0x40373C40, | |
480 | .p1_mprddlctl = 0x3A373646, | |
481 | /* Write Calibration: DQ/DM delay relative to DQS write access */ | |
482 | .p0_mpwrdlctl = 0x2E353933, | |
483 | .p1_mpwrdlctl = 0x3C2F3F35, | |
484 | }; | |
485 | ||
c91e4b8b | 486 | static void spl_dram_init(int width, int size_mb, int board_model) |
0cc11dea | 487 | { |
c91e4b8b TH |
488 | struct mx6_ddr3_cfg *mem = NULL; |
489 | struct mx6_mmdc_calibration *calib = NULL; | |
0cc11dea TH |
490 | struct mx6_ddr_sysinfo sysinfo = { |
491 | /* width of data bus:0=16,1=32,2=64 */ | |
492 | .dsize = width/32, | |
493 | /* config for full 4GB range so that get_mem_size() works */ | |
494 | .cs_density = 32, /* 32Gb per CS */ | |
495 | /* single chip select */ | |
496 | .ncs = 1, | |
497 | .cs1_mirror = 0, | |
498 | .rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */ | |
499 | #ifdef RTT_NOM_120OHM | |
500 | .rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */ | |
501 | #else | |
502 | .rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */ | |
503 | #endif | |
504 | .walat = 1, /* Write additional latency */ | |
505 | .ralat = 5, /* Read additional latency */ | |
506 | .mif3_mode = 3, /* Command prediction working mode */ | |
507 | .bi_on = 1, /* Bank interleaving enabled */ | |
508 | .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ | |
509 | .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ | |
29f0d6b1 | 510 | .pd_fast_exit = 1, /* enable precharge power-down fast exit */ |
f2ff8343 | 511 | .ddr_type = DDR_TYPE_DDR3, |
edf00937 FE |
512 | .refsel = 1, /* Refresh cycles at 32KHz */ |
513 | .refr = 7, /* 8 refresh commands per refresh cycle */ | |
0cc11dea TH |
514 | }; |
515 | ||
516 | /* | |
517 | * MMDC Calibration requires the following data: | |
518 | * mx6_mmdc_calibration - board-specific calibration (routing delays) | |
c91e4b8b | 519 | * these calibration values depend on board routing, SoC, and DDR |
0cc11dea TH |
520 | * mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc) |
521 | * mx6_ddr_cfg - chip specific timing/layout details | |
522 | */ | |
767d88b0 PS |
523 | if (width == 16 && size_mb == 128) { |
524 | mem = &mt41k64m16jt_125; | |
525 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
526 | ; | |
527 | else | |
528 | calib = &mx6sdl_64x16_mmdc_calib; | |
529 | debug("1gB density\n"); | |
530 | } else if (width == 16 && size_mb == 256) { | |
7f14c31b | 531 | /* 1x 2Gb density chip - same calib as 2x 2Gb */ |
75f21e31 TH |
532 | mem = &mt41k128m16jt_125; |
533 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
7f14c31b | 534 | calib = &mx6dq_128x32_mmdc_calib; |
75f21e31 | 535 | else |
7f14c31b | 536 | calib = &mx6sdl_128x32_mmdc_calib; |
75f21e31 TH |
537 | debug("2gB density\n"); |
538 | } else if (width == 16 && size_mb == 512) { | |
539 | mem = &mt41k256m16ha_125; | |
540 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
541 | calib = &mx6dq_256x16_mmdc_calib; | |
542 | else | |
543 | calib = &mx6sdl_256x16_mmdc_calib; | |
544 | debug("4gB density\n"); | |
0ab327a7 TH |
545 | } else if (width == 16 && size_mb == 1024) { |
546 | mem = &mt41k512m16ha_125; | |
547 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
548 | calib = &mx6dq_512x32_mmdc_calib; | |
549 | debug("8gB density\n"); | |
767d88b0 PS |
550 | } else if (width == 32 && size_mb == 256) { |
551 | /* Same calib as width==16, size==128 */ | |
552 | mem = &mt41k64m16jt_125; | |
553 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
554 | ; | |
555 | else | |
556 | calib = &mx6sdl_64x16_mmdc_calib; | |
557 | debug("1gB density\n"); | |
75f21e31 | 558 | } else if (width == 32 && size_mb == 512) { |
c91e4b8b | 559 | mem = &mt41k128m16jt_125; |
0cc11dea | 560 | if (is_cpu_type(MXC_CPU_MX6Q)) |
c91e4b8b | 561 | calib = &mx6dq_128x32_mmdc_calib; |
0cc11dea | 562 | else |
c91e4b8b TH |
563 | calib = &mx6sdl_128x32_mmdc_calib; |
564 | debug("2gB density\n"); | |
767d88b0 PS |
565 | } else if (width == 32 && size_mb == 1024) { |
566 | mem = &mt41k256m16ha_125; | |
567 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
568 | calib = &mx6dq_256x32_mmdc_calib; | |
569 | else | |
570 | calib = &mx6sdl_256x32_mmdc_calib; | |
571 | debug("4gB density\n"); | |
6052b1c6 TH |
572 | } else if (width == 32 && size_mb == 2048) { |
573 | mem = &mt41k512m16ha_125; | |
574 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
575 | calib = &mx6dq_512x32_mmdc_calib; | |
576 | debug("8gB density\n"); | |
767d88b0 PS |
577 | } else if (width == 64 && size_mb == 512) { |
578 | mem = &mt41k64m16jt_125; | |
579 | debug("1gB density\n"); | |
ebe07ef7 TH |
580 | if (is_cpu_type(MXC_CPU_MX6Q)) |
581 | calib = &mx6dq_64x64_mmdc_calib; | |
582 | else | |
583 | calib = &mx6sdl_64x64_mmdc_calib; | |
c91e4b8b TH |
584 | } else if (width == 64 && size_mb == 1024) { |
585 | mem = &mt41k128m16jt_125; | |
0cc11dea | 586 | if (is_cpu_type(MXC_CPU_MX6Q)) |
c91e4b8b | 587 | calib = &mx6dq_128x64_mmdc_calib; |
0cc11dea | 588 | else |
c91e4b8b TH |
589 | calib = &mx6sdl_128x64_mmdc_calib; |
590 | debug("2gB density\n"); | |
c91e4b8b | 591 | } else if (width == 64 && size_mb == 2048) { |
d1c3867a TH |
592 | switch(board_model) { |
593 | case GW5905: | |
594 | /* 8xMT41K128M16 (2GiB) fly-by mirrored 2-chipsels */ | |
595 | mem = &mt41k128m16jt_125; | |
596 | debug("2gB density - 2 chipsel\n"); | |
597 | if (!is_cpu_type(MXC_CPU_MX6Q)) { | |
598 | calib = &mx6sdl_128x64x2_mmdc_calib; | |
599 | sysinfo.ncs = 2; | |
600 | sysinfo.cs_density = 10; /* CS0_END=39 */ | |
601 | sysinfo.cs1_mirror = 1; /* mirror enabled */ | |
602 | } | |
603 | break; | |
604 | default: | |
605 | mem = &mt41k256m16ha_125; | |
606 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
607 | calib = &mx6dq_256x64_mmdc_calib; | |
608 | else | |
609 | calib = &mx6sdl_256x64_mmdc_calib; | |
610 | debug("4gB density\n"); | |
611 | break; | |
612 | } | |
ad68d7b8 | 613 | } else if (width == 64 && size_mb == 4096) { |
214fb19b TH |
614 | switch(board_model) { |
615 | case GW5903: | |
616 | /* 8xMT41K256M16 (4GiB) fly-by mirrored 2-chipsels */ | |
617 | mem = &mt41k256m16ha_125; | |
d1c3867a | 618 | debug("4gB density - 2 chipsel\n"); |
214fb19b TH |
619 | if (!is_cpu_type(MXC_CPU_MX6Q)) { |
620 | calib = &mx6sdl_256x64x2_mmdc_calib; | |
621 | sysinfo.ncs = 2; | |
622 | sysinfo.cs_density = 18; /* CS0_END=71 */ | |
623 | sysinfo.cs1_mirror = 1; /* mirror enabled */ | |
624 | } | |
625 | break; | |
626 | default: | |
627 | mem = &mt41k512m16ha_125; | |
628 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
629 | calib = &mx6dq_512x64_mmdc_calib; | |
630 | debug("8gB density\n"); | |
631 | break; | |
632 | } | |
c91e4b8b TH |
633 | } |
634 | ||
9e2b0c2d PS |
635 | if (!(mem && calib)) { |
636 | puts("Error: Invalid Calibration/Board Configuration\n"); | |
637 | printf("MEM : %s\n", mem ? "OKAY" : "NULL"); | |
638 | printf("CALIB : %s\n", calib ? "OKAY" : "NULL"); | |
639 | printf("CPUTYPE: %s\n", | |
640 | is_cpu_type(MXC_CPU_MX6Q) ? "IMX6Q" : "IMX6DL"); | |
641 | printf("SIZE_MB: %d\n", size_mb); | |
642 | printf("WIDTH : %d\n", width); | |
c91e4b8b | 643 | hang(); |
0cc11dea TH |
644 | } |
645 | ||
646 | if (is_cpu_type(MXC_CPU_MX6Q)) | |
647 | mx6dq_dram_iocfg(width, &mx6dq_ddr_ioregs, | |
648 | &mx6dq_grp_ioregs); | |
649 | else | |
650 | mx6sdl_dram_iocfg(width, &mx6sdl_ddr_ioregs, | |
651 | &mx6sdl_grp_ioregs); | |
652 | mx6_dram_cfg(&sysinfo, calib, mem); | |
653 | } | |
654 | ||
e25fbe3f FE |
655 | static void ccgr_init(void) |
656 | { | |
657 | struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; | |
658 | ||
659 | writel(0x00C03F3F, &ccm->CCGR0); | |
660 | writel(0x0030FC03, &ccm->CCGR1); | |
661 | writel(0x0FFFC000, &ccm->CCGR2); | |
662 | writel(0x3FF00000, &ccm->CCGR3); | |
576cd6b3 | 663 | writel(0xFFFFF300, &ccm->CCGR4); /* enable NAND/GPMI/BCH clks */ |
e25fbe3f FE |
664 | writel(0x0F0000C3, &ccm->CCGR5); |
665 | writel(0x000003FF, &ccm->CCGR6); | |
666 | } | |
667 | ||
0cc11dea TH |
668 | /* |
669 | * called from C runtime startup code (arch/arm/lib/crt0.S:_main) | |
670 | * - we have a stack and a place to store GD, both in SRAM | |
671 | * - no variable global data is available | |
672 | */ | |
673 | void board_init_f(ulong dummy) | |
674 | { | |
675 | struct ventana_board_info ventana_info; | |
676 | int board_model; | |
677 | ||
d783c274 TH |
678 | /* setup clock gating */ |
679 | ccgr_init(); | |
680 | ||
0cc11dea TH |
681 | /* setup AIPS and disable watchdog */ |
682 | arch_cpu_init(); | |
683 | ||
d783c274 | 684 | /* setup AXI */ |
e25fbe3f FE |
685 | gpr_init(); |
686 | ||
3f0da874 | 687 | /* iomux and setup of uart/i2c */ |
2089b7be | 688 | setup_iomux_uart(); |
3f0da874 TH |
689 | setup_ventana_i2c(0); |
690 | setup_ventana_i2c(1); | |
0cc11dea TH |
691 | |
692 | /* setup GP timer */ | |
693 | timer_init(); | |
694 | ||
695 | /* UART clocks enabled and gd valid - init serial console */ | |
696 | preloader_console_init(); | |
697 | ||
698 | /* read/validate EEPROM info to determine board model and SDRAM cfg */ | |
2089b7be | 699 | board_model = read_eeprom(CONFIG_I2C_GSC, &ventana_info); |
0cc11dea | 700 | |
c4b44d76 TH |
701 | /* configure model-specific gpio */ |
702 | setup_iomux_gpio(board_model, &ventana_info); | |
703 | ||
0cc11dea | 704 | /* provide some some default: 32bit 128MB */ |
fdead4be TH |
705 | if (GW_UNKNOWN == board_model) |
706 | hang(); | |
0cc11dea TH |
707 | |
708 | /* configure MMDC for SDRAM width/size and per-model calibration */ | |
709 | spl_dram_init(8 << ventana_info.sdram_width, | |
710 | 16 << ventana_info.sdram_size, | |
711 | board_model); | |
0cc11dea TH |
712 | } |
713 | ||
8d1a6ff8 TH |
714 | void board_boot_order(u32 *spl_boot_list) |
715 | { | |
716 | spl_boot_list[0] = spl_boot_device(); | |
717 | switch (spl_boot_list[0]) { | |
718 | case BOOT_DEVICE_NAND: | |
719 | spl_boot_list[1] = BOOT_DEVICE_MMC1; | |
720 | spl_boot_list[2] = BOOT_DEVICE_UART; | |
721 | break; | |
722 | case BOOT_DEVICE_MMC1: | |
723 | spl_boot_list[1] = BOOT_DEVICE_UART; | |
724 | break; | |
725 | } | |
726 | } | |
727 | ||
06c3564d TH |
728 | /* called from board_init_r after gd setup if CONFIG_SPL_BOARD_INIT defined */ |
729 | /* its our chance to print info about boot device */ | |
730 | void spl_board_init(void) | |
731 | { | |
732 | /* determine boot device from SRC_SBMR1 (BOOT_CFG[4:1]) or SRC_GPR9 */ | |
733 | u32 boot_device = spl_boot_device(); | |
734 | ||
735 | switch (boot_device) { | |
736 | case BOOT_DEVICE_MMC1: | |
737 | puts("Booting from MMC\n"); | |
738 | break; | |
739 | case BOOT_DEVICE_NAND: | |
740 | puts("Booting from NAND\n"); | |
741 | break; | |
742 | case BOOT_DEVICE_SATA: | |
743 | puts("Booting from SATA\n"); | |
744 | break; | |
745 | default: | |
746 | puts("Unknown boot device\n"); | |
747 | } | |
e06a0362 TH |
748 | |
749 | /* PMIC init */ | |
750 | setup_pmic(); | |
06c3564d TH |
751 | } |
752 | ||
53940a50 TH |
753 | #ifdef CONFIG_SPL_OS_BOOT |
754 | /* return 1 if we wish to boot to uboot vs os (falcon mode) */ | |
755 | int spl_start_uboot(void) | |
756 | { | |
3c0fd17f | 757 | unsigned char ret = 1; |
53940a50 TH |
758 | |
759 | debug("%s\n", __func__); | |
760 | #ifdef CONFIG_SPL_ENV_SUPPORT | |
761 | env_init(); | |
310fb14b | 762 | env_load(); |
00caae6d | 763 | debug("boot_os=%s\n", env_get("boot_os")); |
bfebc8c9 | 764 | if (env_get_yesno("boot_os") == 1) |
53940a50 | 765 | ret = 0; |
3c0fd17f TH |
766 | #else |
767 | /* use i2c-0:0x50:0x00 for falcon boot mode (0=linux, else uboot) */ | |
768 | i2c_set_bus_num(0); | |
769 | gsc_i2c_read(0x50, 0x0, 1, &ret, 1); | |
53940a50 | 770 | #endif |
1b99103f TH |
771 | if (!ret) |
772 | gsc_boot_wd_disable(); | |
773 | ||
53940a50 TH |
774 | debug("%s booting %s\n", __func__, ret ? "uboot" : "linux"); |
775 | return ret; | |
776 | } | |
777 | #endif |