blob: 0ffa2bc21f4742800d9e2d4e0152f52fd72065b8 [file] [log] [blame]
Ionela Voinescud6aaca92015-01-19 01:03:44 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Imagination Technologies
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19 * MA 02110-1301 USA
20 */
21
22#include <stdint.h>
23#include <arch/cpu.h>
24#include <delay.h>
25#include <arch/io.h>
26#include <soc/ddr_init.h>
27#include <timer.h>
28
29#define MAX_WAIT_MICROS 100000
30
31#define TOPLEVEL_REGS 0xB8149000
32
33#define DDR_CTRL_OFFSET (0x0020)
34#define DDR_CLK_EN_MASK (0x00000002)
35#define DDR_CLK_EN_SHIFT (1)
36#define DDR_CLK_EN_LENGTH (1)
37
38#define DDR_PCTL 0xB8180000
39#define DDR_PCTL_TOGCNT1U_OFFSET (0x00C0)
40#define DDR_PCTL_TINIT_OFFSET (0x00C4)
41#define DDR_PCTL_TRSTH_OFFSET (0x00C8)
42#define DDR_PCTL_TOGG_CNTR_100NS_OFFSET (0x00CC)
43#define DDR_PCTL_MCFG_OFFSET (0x0080)
44#define DDR_PCTL_MCFG1_OFFSET (0x007C)
45#define DDR_PCTL_MSTAT_OFFSET (0x0088)
46#define DDR_PCTL_DFISTAT0_OFFSET (0x02C0)
47#define DDR_PCTL_POWCTL_OFFSET (0x0044)
48#define DDR_PCTL_POWSTAT_OFFSET (0x0048)
49#define DDR_PCTL_DTUAWDT_OFFSET (0x00B0)
50#define DDR_PCTL_TREFI_OFFSET (0x00D0)
51#define DDR_PCTL_TMRD_OFFSET (0x00D4)
52#define DDR_PCTL_TRFC_OFFSET (0x00D8)
53#define DDR_PCTL_TRP_OFFSET (0x00DC)
54#define DDR_PCTL_TAL_OFFSET (0x00E4)
55#define DDR_PCTL_TCL_OFFSET (0x00E8)
56#define DDR_PCTL_TCWL_OFFSET (0x00EC)
57#define DDR_PCTL_TRAS_OFFSET (0x00F0)
58#define DDR_PCTL_TRC_OFFSET (0x00F4)
59#define DDR_PCTL_TRCD_OFFSET (0x00F8)
60#define DDR_PCTL_TRRD_OFFSET (0x00FC)
61#define DDR_PCTL_TRTP_OFFSET (0x0100)
62#define DDR_PCTL_TWR_OFFSET (0x0104)
63#define DDR_PCTL_TWTR_OFFSET (0x0108)
64#define DDR_PCTL_TEXSR_OFFSET (0x010C)
65#define DDR_PCTL_TXP_OFFSET (0x0110)
66#define DDR_PCTL_TDQS_OFFSET (0x0120)
67#define DDR_PCTL_TXPDLL_OFFSET (0x0114)
68#define DDR_PCTL_TRTW_OFFSET (0x00E0)
69#define DDR_PCTL_TCKE_OFFSET (0x012C)
70#define DDR_PCTL_TMOD_OFFSET (0x0130)
71#define DDR_PCTL_TCKESR_OFFSET (0x0140)
72#define DDR_PCTL_SCFG_OFFSET (0x0000)
73#define DDR_PCTL_DFIWRLAT_OFFSET (0x0254)
74#define DDR_PCTL_DFITRDDATAEN_OFFSET (0x0260)
75#define DDR_PCTL_DFITPHYWRDATA_OFFSET (0x0250)
76#define DDR_PCTL_DFITPHYRDLAT_OFFSET (0x0264)
77#define DDR_PCTL_SCTL_OFFSET (0x0004)
78#define DDR_PCTL_STAT_OFFSET (0x0008)
79#define DDR_PCTL_DFISTCFG0_OFFSET (0x02C4)
80#define DDR_PCTL_DFISTCFG1_OFFSET (0x02C8)
81#define DDR_PCTL_DFISTCFG2_OFFSET (0x02D8)
82#define DDR_PCTL_DFILPCFG0_OFFSET (0x02F0)
83#define DDR_PCTL_DFIODTCFG_OFFSET (0x0244)
84#define DDR_PCTL_DFIODTCFG1_OFFSET (0x0248)
85#define DDR_PCTL_MCMD_OFFSET (0x0040)
86#define DDR_PCTL_DFIUPDCFG_OFFSET (0x0290)
87#define DDR_PCTL_CCFG_OFFSET (0x0480)
88#define DDR_PCTL_DCFG_OFFSET (0x0484)
89#define DDR_PCTL_PCFG0_OFFSET (0x0400)
90#define DDR_PCTL_DTUWACTL_OFFSET (0x0200)
91#define DDR_PCTL_DTURACTL_OFFSET (0x0204)
92#define DDR_PCTL_DTUCFG_OFFSET (0x0208)
93#define DDR_PCTL_DTUECTL_OFFSET (0x020C)
94#define DDR_PCTL_DTUWD0_OFFSET (0x0210)
95#define DDR_PCTL_DTUWD1_OFFSET (0x0214)
96#define DDR_PCTL_DTUWD2_OFFSET (0x0218)
97#define DDR_PCTL_DTUWD3_OFFSET (0x021C)
98#define DDR_PCTL_CCFG1_OFFSET (0x048C)
99
100#define DDR_PHY 0xB8180800
101#define DDRPHY_DCR_OFFSET (0x0030)
102#define DDRPHY_MR_OFFSET (0x0040)
103#define DDRPHY_EMR_OFFSET (0x0044)
104#define DDRPHY_EMR2_OFFSET (0x0048)
105#define DDRPHY_DSGCR_OFFSET (0x002C)
106#define DDRPHY_DTPR0_OFFSET (0x0034)
107#define DDRPHY_DTPR1_OFFSET (0x0038)
108#define DDRPHY_DTPR2_OFFSET (0x003C)
109#define DDRPHY_PTR0_OFFSET (0x0018)
110#define DDRPHY_PTR1_OFFSET (0x001C)
111#define DDRPHY_PGSR_OFFSET (0x000C)
112#define DDRPHY_PIR_OFFSET (0x0004)
113#define DDRPHY_BISTRR_OFFSET (0x0100)
114#define DDRPHY_BISTWCR_OFFSET (0x010C)
115#define DDRPHY_BISTAR0_OFFSET (0x0114)
116#define DDRPHY_BISTAR1_OFFSET (0x0118)
117#define DDRPHY_BISTAR2_OFFSET (0x011C)
118#define DDRPHY_BISTGSR_OFFSET (0x0124)
119#define DDRPHY_BISTUDPR_OFFSET (0x0120)
120#define DDRPHY_DLLGCR_OFFSET (0x0010)
121
122#define BL8 1
123#define UMCTL_INIT 0
124
125#define DDR_TIMEOUT_VALUE_US 100000
126
127static int wait_for_completion(u32 reg, u32 exp_val)
128{
129 struct stopwatch sw;
130
131 stopwatch_init_usecs_expire(&sw, DDR_TIMEOUT_VALUE_US);
132 while (read32(reg) != exp_val) {
133 if (stopwatch_expired(&sw))
134 return DDR_TIMEOUT;
135 }
136 return 0;
137}
138
139/*
140 * Configuration for the Winbond W972GG6JB-25 part using
141 * Synopsys DDR uMCTL and DDR Phy
142 */
143int init_ddr2(void)
144{
145
146 u32 exp_val;
147 u32 mr, md_dllrst, emr, emr2, emr3;
148
149 /*
150 * Reset the AXI bridge and DDR Controller in case any spurious
151 * writes have already happened to DDR - note must be done together,
152 * not sequentially
153 */
154 write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x00000000);
155 write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x0000000F);
156
157 /*
158 * Dummy read to fence the access between the reset above
159 * and thw DDR controller writes below
160 */
161 read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET);
162
163 /* Timings for 400MHz
164 * therefore 200MHz (5ns) uMCTL (Internal) Rate
165 */
166
167 /* TOGCNT1U: Toggle Counter 1U Register: 1us 200h C8h */
168 write32(DDR_PCTL + DDR_PCTL_TOGCNT1U_OFFSET, 0x000000C8);
169 /* TINIT: t_init Timing Register: at least 200us 200h C8h */
170 write32(DDR_PCTL + DDR_PCTL_TINIT_OFFSET, 0x000000C8);
171 /* TRSTH: Reset High Time Register DDR3 ONLY */
172 write32(DDR_PCTL + DDR_PCTL_TRSTH_OFFSET, 0x00000000);
173 /* TOGCNT100N: Toggle Counter 100N Register: 20d, 14h*/
174 write32(DDR_PCTL + DDR_PCTL_TOGG_CNTR_100NS_OFFSET, 0x00000014);
175 /* DTUAWDT DTU Address Width Register
176 * 1:0 column_addr_width Def 10 - 7 3 10 bits
177 * 4:3 bank_addr_width Def 3 - 2 1 3 bits (8 bank)
178 * 7:6 row_addr_width Def 14 - 13 1 3 bits
179 * 10:9 number_ranks Def 1 - 1 0 0 1 Rank
180 */
181 write32(DDR_PCTL + DDR_PCTL_DTUAWDT_OFFSET, 0x0000004B);
182 /* MCFG
183 * 0 BL 0 = 4 1 = 8
184 * 1 RDRIMM 0
185 * 2 BL8 Burst Terminate 0
186 * 3 2T = 0
187 * 4 Multi Rank 0
188 * 5 DDR3 En 0
189 * 6 LPDDR S4 En
190 * 7 BST En 0, 1 for LPDDR2/3
191 * 15:8 Power down Idle, passed by argument
192 * 16 Power Down Type, passed by argument
193 * 17 Power Down Exit 0 = slow, 1 = fast, pba
194 * 19:18 tFAW 45ns = 9 clk 5*2 -1 1h
195 * 21:20 mDDR/LPDDR2 BL 0
196 * 23:22 mDDR/LPDDR2 Enable 0
197 * 31:24 mDDR/LPDDR2/3 Dynamic Clock Stop 0
198 */
199 write32(DDR_PCTL + DDR_PCTL_MCFG_OFFSET,
200 0x00060000 | (BL8 ? 0x1 : 0x0));
201 /* MCFG1: Memory Configuration-1 Register
202 * c7:0 sr_idle Self Refresh Idle Entery 32 * nclks 14h, set 0 for BUB
203 * 10:8 Fine tune MCFG.19:18 -1
204 * 15:11 Reserved
205 * 23:16 Hardware Idle Period NA 0
206 * 30:24 Reserved
207 * 31 c_active_in_pin exit auto clk stop NA 0
208 */
209 write32(DDR_PCTL + DDR_PCTL_MCFG1_OFFSET, 0x00000100);
210 /* DCR DRAM Config
211 * 2:0 SDRAM => DDR2 2
212 * 3 DDR 8 Bank 1
213 * 6:4 Primary DQ DDR3 Only 0
214 * 7 Multi-Purpose Register DDR3 Only 0
215 * 9:8 DDRTYPE LPDDR2 00
216 * 26:10 Reserved
217 * 27 NOSRA No Simultaneous Rank Access 0
218 * 28 DDR 2T 0
219 * 29 UDIMM NA 0
220 * 30 RDIMM NA 0
221 * 31 TPD LPDDR2 0
222 */
223 write32(DDR_PHY + DDRPHY_DCR_OFFSET, 0x0000000A);
224 /* Generate to use with PHY and PCTL */
225 md_dllrst = 0x0B62 | (BL8 ? 0x1 : 0x0);
226 /* Generate to use with PHY and PCTL
227 * 2:0 BL 8 011
228 * 3 BT Sequential 0 Interleaved 1 = 0
229 * 6:4 CL 6
230 * 7 TM Normal 0
231 * 8 DLL Reset 1 (self Clearing)
232 * 11:9 WR 15 ns 6 (101)
233 * 12 PD Slow 1 Fast 0 0
234 */
235 mr = 0x0A62 | (BL8 ? 0x1 : 0x0);
236 /* MR0 : MR Register, bits 12:0 imported dfrom MR
237 * 12:0 md_dllrst
238 * c15:13 RSVD RSVD
239 * 31:16 Reserved
240 */
241 write32(DDR_PHY + DDRPHY_MR_OFFSET, 0x00000000 | mr);
242 /* Generate to use with PHY and PCTL
243 * 0 DE DLL Enable 0 Disable 1
244 * 1 DIC Output Driver Imp Ctl 0 Full, 1 Half
245 * 6,2 ODT 0 Disable, 1 75R, 2 150R, 3 50R = 1
246 * 5:3 AL = 0
247 * 9:7 OCD = 0
248 * 10 DQS 0 diff, 1 single = 0
249 * 11 RDQS NA 0
250 * 12 QOFF Normal mode 0
251 */
252 emr = 0x4;
253 /* MR1 : EMR Register
254 * 12:0 EMR1
255 * 15:13 RSVD
256 * 31:16 Reserved
257 */
258 write32(DDR_PHY + DDRPHY_EMR_OFFSET, 0x00000000 | emr);
259
260 /* Generate to use with PHY and PCTL
261 * 2:0 PASR, NA 000
262 * 3 DDC NA 0
263 * 6:4 RSVD
264 * 7 SFR 0
265 */
266 emr2 = 0x0;
267 /* MR2 : EMR2 Register
268 * 7:0 EMR2
269 * 15:8 RSVD
270 * 31:16 Reserved
271 */
272 write32(DDR_PHY + DDRPHY_EMR2_OFFSET, 0x00000000 | emr2);
273 emr3 = 0x0;
274 /* DSGCR
275 * 0 PUREN Def 1
276 * 1 BDISEN Def 1
277 * 2 ZUEN Def 1
278 * 3 LPIOPD DEf 1 0
279 * 4 LPDLLPD DEf 1 0
280 * 7:5 DQSGX DQS Extention 000
281 * 10:8 DQSGE DQS Early Gate
282 * 11 NOBUB No Bubbles, adds latency 0
283 * 12 FXDLAT Fixed Read Latency 0
284 * 15:13 Reserved
285 * 19:16 CKEPDD CKE Power Down 0000
286 * 23:20 ODTPDD ODT Power Down 0000
287 * 24 NL2PD Power Down Non LPDDR2 pins 0
288 * 25 NL2OE Output Enable Non LPDDR2 pins 1
289 * 26 TPDPD LPDDR Only 0
290 * 27 TPDOE LPDDR Only 0
291 * 28 CKOE Output Enable Clk's 1
292 * 29 ODTOE Output Enable ODT 1
293 * 30 RSTOE RST# Output Enable 1
294 * 31 CKEOE CKE Output Enable 1
295 */
296 write32(DDR_PHY + DDRPHY_DSGCR_OFFSET, 0xF2000007);
297 /* DTPR0 : DRAM Timing Params 0
298 * 1:0 tMRD 2
299 * 4:2 tRTP 3
300 * 7:5 tWTR 3
301 * 11:8 tRP 6
302 * 15:12 tRCD 6
303 * 20:16 tRAS 18
304 * 24:21 tRRD 4
305 * 30:25 tRC 24 (23)
306 * 31 tCCD 0 BL/2 Cas to Cas
307 */
308 write32(DDR_PHY + DDRPHY_DTPR0_OFFSET, 0x3092666E);
309 /* DTPR1 : DRAM Timing Params 1
310 * 1:0 ODT On/Off Del Std 0
311 * 2 tRTW Rd2Wr Del 0 std 1 +1 0
312 * 8:3 tFAW 4 Bank Act 45ns = 18 18
313 * 10:9 tMOD DDR3 Only 0
314 * 11 tRTODT DDR3 Only 0
315 * 15:12 Reserved
316 * 23:16 tRFC 195ns 78 def 131 78d
317 * 26:24 tDQSCK LPDDR2 only 1
318 * 29:27 tDQSCKmax 1
319 * 31:30 Reserved
320 */
321 write32(DDR_PHY + DDRPHY_DTPR1_OFFSET, 0x094E0092);
322 /* DTPR2 : DRAM Timing Params 2
323 * 9:0 tXS exit SR def 200, 200d
324 * 14:10 tXP PD Exit Del 8 3
325 * 18:15 tCKE CKE Min pulse 3
326 * 28:19 tDLLK DLL Lock time 200d
327 * 32:29 Reserved
328 */
329 write32(DDR_PHY + DDRPHY_DTPR2_OFFSET, 0x06418CC8);
330 /* PTR0 : PHY Timing Params 0
331 * 5:0 tDLLRST Def 27
332 * 17:6 tDLLLOCK Def 2750
333 * 21:18 tITMSRST Def 8
334 * 31:22 Reserved 0
335 */
336 write32(DDR_PHY + DDRPHY_PTR0_OFFSET, 0x0022AF9B);
337 /* PTR1 : PHY Timing Params 1
338 * 18:0 : tDINITO DRAM Init time 200us 80,000 Dec 0x13880
339 * 29:19 : tDINIT1 DRAM Init time 400ns 160 Dec 0xA0
340 */
341 write32(DDR_PHY + DDRPHY_PTR1_OFFSET, 0x05013880);
342
343 /* PGSR : Wait for INIT/DLL/Z Done from Power on Reset */
344 if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x00000007))
345 return DDR_TIMEOUT;
346
347 if (UMCTL_INIT == 1) {
348 /* PIR : Trigger INIT/DLL/Z following soft reset of DLL & ITM */
349 write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x0000001F);
350
351 /* PGSR : Wait for INIT?DLL?Z Done from SOFT Reset */
352 if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET,
353 0x00000007))
354 return DDR_TIMEOUT;
355
356 /* PIR : use uMCTL for DRAM Init */
357 write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x00040001);
358
359 /* PGSR : Wait for DRAM Init Done */
360 if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET,
361 0x0000000F))
362 return DDR_TIMEOUT;
363
364 } else {
365 /* PIR : use uMCTL for DRAM Init */
366 write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x000001DF);
367 /* PGSR : Wait for DRAM Init Done */
368
369 if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET,
370 0x0000001F))
371 return DDR_TIMEOUT;
372 }
373
374 /* DF1STAT0 : wait for DFI_INIT_COMPLETE */
375 if (wait_for_completion(DDR_PCTL + DDR_PCTL_DFISTAT0_OFFSET,
376 0x00000001))
377 return DDR_TIMEOUT;
378
379 /* POWCTL : Start the memory Power Up seq*/
380 write32(DDR_PCTL + DDR_PCTL_POWCTL_OFFSET, 0x00000001);
381
382 /* POWSTAT : wait for POWER_UP_DONE */
383 if (wait_for_completion(DDR_PCTL + DDR_PCTL_POWSTAT_OFFSET,
384 0x00000001))
385 return DDR_TIMEOUT;
386
387 /*
388 * TREFI : t_refi Timing Register 1X
389 * 12:0 t_refi 7.8us in 100ns 0x4E
390 * 15:13 Reserved 0
391 * 18:16 num_add_ref 0
392 * 30:19 Reserved 0
393 * 31 Update 1
394 */
395 write32(DDR_PCTL + DDR_PCTL_TREFI_OFFSET, 0x8000004E);
396 /* TMRD : t_mrd Timing Register -- Range 2 to 3 */
397 write32(DDR_PCTL + DDR_PCTL_TMRD_OFFSET, 0x00000002);
398 /*
399 * TRFC : t_rfc Timing Register -- Range 15 to 131
400 * 195ns / 2.5ns 78 x4E
401 */
402 write32(DDR_PCTL + DDR_PCTL_TRFC_OFFSET, 0x0000004E);
403 /* TRP : t_rp Timing Register -- Range 3 to 7
404 * 4:0 tRP 12.5 / 2.5 = 5 6 For Now 6-6-6
405 * 17:16 rpea_extra tRPall 8 bank 1
406 */
407 write32(DDR_PCTL + DDR_PCTL_TRP_OFFSET, 0x00010006);
408 /* TAL : Additive Latency Register -- AL in MR1 */
409 write32(DDR_PCTL + DDR_PCTL_TAL_OFFSET, 0x00000000);
410 /* DFITPHYWRLAT : Write cmd to dfi_wrdata_en */
411 write32(DDR_PCTL + DDR_PCTL_DFIWRLAT_OFFSET, 0x00000002);
412 /* DFITRDDATAEN : Read cmd to dfi_rddata_en */
413 write32(DDR_PCTL + DDR_PCTL_DFITRDDATAEN_OFFSET, 0x00000002);
414 /* TCL : CAS Latency Timing Register -- CASL in MR0 6-6-6 */
415 write32(DDR_PCTL + DDR_PCTL_TCL_OFFSET, 0x00000006);
416 /* TCWL : CAS Write Latency Register --CASL-1 */
417 write32(DDR_PCTL + DDR_PCTL_TCWL_OFFSET, 0x00000005);
418 /*
419 * TRAS : Activate to Precharge cmd time
420 * Range 8 to 24: 45ns / 2.5ns = 18d
421 */
422 write32(DDR_PCTL + DDR_PCTL_TRAS_OFFSET, 0x00000012);
423 /*
424 * TRC : Min. ROW cylce time
425 * Range 11 to 31: 57.5ns / 2.5ns = 23d Playing safe 24
426 */
427 write32(DDR_PCTL + DDR_PCTL_TRC_OFFSET, 0x00000018);
428 /*
429 * TRCD : Row to Column Delay
430 * Range 3 to 7 (TCL = TRCD): 2.5ns / 2.5ns = 5 but running 6-6-6 6
431 */
432 write32(DDR_PCTL + DDR_PCTL_TRCD_OFFSET, 0x00000006);
433 /* TRRD : Row to Row delay -- Range 2 to 6: 2K Page 10ns / 2.5ns = 4*/
434 write32(DDR_PCTL + DDR_PCTL_TRRD_OFFSET, 0x00000004);
435 /* TRTP : Read to Precharge time -- Range 2 to 4: 7.3ns / 2.5ns = 3 */
436 write32(DDR_PCTL + DDR_PCTL_TRTP_OFFSET, 0x00000003);
437 /* TWR : Write recovery time -- WR in MR0: 15ns / 2.5ns = 6
438 */
439 write32(DDR_PCTL + DDR_PCTL_TWR_OFFSET, 0x00000006);
440 /*
441 * TWTR : Write to read turn around time
442 * Range 2 to 4: 7.3ns / 2.5ns = 3
443 */
444 write32(DDR_PCTL + DDR_PCTL_TWTR_OFFSET, 0x00000003);
445 /* TEXSR : Exit Self Refresh to first valid cmd: tXS 200*/
446 write32(DDR_PCTL + DDR_PCTL_TEXSR_OFFSET, 0x000000C8);
447 /*
448 * TXP : Exit Power Down to first valid cmd
449 * tXP 2, Settingto 3 to match PHY
450 */
451 write32(DDR_PCTL + DDR_PCTL_TXP_OFFSET, 0x00000003);
452 /*
453 * TDQS : t_dqs Timing Register
454 * DQS additional turn around Rank 2 Rank (1 Rank) Def 1
455 */
456 write32(DDR_PCTL + DDR_PCTL_TDQS_OFFSET, 0x00000001);
457 /*TRTW : Read to Write turn around time Def 2
458 * Actual gap t_bl + t_rtw
459 */
460 write32(DDR_PCTL + DDR_PCTL_TRTW_OFFSET, 0x00000002);
461 /* TCKE : CKE min pulse width DEf 3 */
462 write32(DDR_PCTL + DDR_PCTL_TCKE_OFFSET, 0x00000003);
463 /*
464 * TXPDLL : Slow Exit Power Down to first valid cmd delay
465 * tXARDS 10+AL = 10
466 */
467 write32(DDR_PCTL + DDR_PCTL_TXPDLL_OFFSET, 0x0000000A);
468 /*
469 * TCKESR : Min CKE Low width for Self refresh entry to exit
470 * t_ckesr = 0 DDR2
471 */
472 write32(DDR_PCTL + DDR_PCTL_TCKESR_OFFSET, 0x00000000);
473 /* SCFG : State Configuration Register (Enabling Self Refresh)
474 * 0 LP_en Leave Off for Bring Up 0
475 * 5:1 Reserved
476 * 6 Synopsys Internal Only 0
477 * 7 Enale PHY indication of LP Opportunity 1
478 * 11:8 bbflags_timing max UPCTL_TCU_SED_P - tRP (16 - 6) Use 4
479 * 16:12 Additional delay on accertion of ac_pdd 4
480 * 31:17 Reserved
481 */
482 write32(DDR_PCTL + DDR_PCTL_SCFG_OFFSET, 0x00004480);
483 /*
484 * DFITPHYWRDATA : dfi_wrdata_en to drive wr data
485 * DFI Clks wrdata_en to wrdata Def 1
486 */
487 write32(DDR_PCTL + DDR_PCTL_DFITPHYWRDATA_OFFSET, 0x00000000);
488 /*
489 * DFITPHYRDLAT : dfi_rddata_en to dfi_rddata_valid
490 * DFI clks max rddata_en to rddata_valid Def 15
491 */
492 write32(DDR_PCTL + DDR_PCTL_DFITPHYRDLAT_OFFSET, 0x00000008);
493 /* MCMD : PREA, Addr 0 Bank 0 Rank 0 Del 0
494 * 3:0 cmd_opcode PREA 00001
495 * 16:4 cmd_addr 0
496 * 19:17 bank_addr 0
497 * 23:20 rank_sel 0 0001
498 * 27:24 cmddelay 0
499 * 30:24 Reserved
500 */
501 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
502
503 /* MRS cmd wait for completion */
504 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00100001))
505 return DDR_TIMEOUT;
506
507 /* SCTL : UPCTL switch INIT CONFIG State */
508 write32(DDR_PCTL + DDR_PCTL_SCTL_OFFSET, 0x00000001);
509
510 /* STAT : Wait for Switch INIT to Config State */
511 if (wait_for_completion(DDR_PCTL + DDR_PCTL_STAT_OFFSET, 0x00000001))
512 return DDR_TIMEOUT;
513
514 /* DFISTCFG0 : Drive various DFI signals appropriately
515 * 0 dfi_init_start 0
516 * 1 dfi_freq_ratio_en 1
517 * 2 dfi_data_byte_disable_en 1
518 */
519 write32(DDR_PCTL + DDR_PCTL_DFISTCFG0_OFFSET, 0x00000003);
520 /* DFISTCFG1 : Enable various DFI support
521 * 0 dfi_dram_clk_disable_en 1
522 * 1 dfi_dram_clk_disable_en_pdp only lPDDR 0
523 */
524 write32(DDR_PCTL + DDR_PCTL_DFISTCFG1_OFFSET, 0x00000001);
525 /* DFISTCFG2 : Enable Parity and asoc interrupt
526 * 0 dfi_parity_in Enable 1
527 * 1 Interrupt on dfi_parity_error 1
528 */
529 write32(DDR_PCTL + DDR_PCTL_DFISTCFG2_OFFSET, 0x00000003);
530 /* DFILPCFG0 : DFI Low Power Interface Configuration
531 * 0 Enable DFI LP IF during PD 1
532 * 3:1 Reserved
533 * 7:4 DFI tlp_wakeup time 0
534 * 8 Enable DFI LP IF during SR 1
535 * 11:9 Reserved
536 * 15:12 dfi_lp_wakeup in SR 0
537 * 19:16 tlp_resp DFI 2.1 recomend 7
538 * 23:20 Reserved
539 * 24 Enable DFI LP in Deep Power Down 0
540 * 27:25 Reserved
541 * 31:28 DFI LP Deep Power Down Value 0
542 */
543 write32(DDR_PCTL + DDR_PCTL_DFILPCFG0_OFFSET, 0x00070101);
544 /* DFIODTCFG : DFI ODT Configuration
545 * Only Enabled on Rank0 Writes
546 * 0 rank0_odt_read_nsel 0
547 * 1 rank0_odt_read_sel 0
548 * 2 rank0_odt_write_nsel 0
549 * 3 rank0_odt_write_sel 1
550 */
551 write32(DDR_PCTL + DDR_PCTL_DFIODTCFG_OFFSET, 0x00000008);
552
553 /* DFIODTCFG1 : DFI ODT Configuration
554 * 4:0 odt_lat_w 4
555 * 12:8 odt_lat_r 0 Def
556 * 4:0 odt_len_bl8_w 6 Def
557 * 12:8 odt_len_bl8_r 6 Def
558 */
559 write32(DDR_PCTL + DDR_PCTL_DFIODTCFG1_OFFSET, 0x06060004);
560
561 if (UMCTL_INIT == 1) {
562 /* MCMD : Deselect command */
563 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100000);
564 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
565 0x00100000))
566 return DDR_TIMEOUT;
567
568 /* MCMD : Precharge ALL Banks */
569 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
570 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
571 0x00100001))
572 return DDR_TIMEOUT;
573
574 /* MCMD : MRS Cmd, EMR2 -- High Temp Self refresh Disable */
575 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
576 0x80140003 | (emr2 << 4));
577 exp_val = (0x00140003 | (emr2 << 4));
578 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
579 exp_val))
580 return DDR_TIMEOUT;
581
582 /* MCMD : MRS cmd, EMR3 */
583 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
584 0x80160003 | (emr3 << 4));
585 exp_val = (0x00160003 | (emr3 << 4));
586 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
587 exp_val))
588 return DDR_TIMEOUT;
589
590 /* MCMD : MRS Cmd, EMR-- DLL Enable */
591 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
592 0x80120003 | (emr << 4));
593 exp_val = (0x00120003 | (emr << 4));
594 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
595 exp_val))
596 return DDR_TIMEOUT;
597
598 /* MCMD : MRS Cmd, MR--DLL Reset */
599 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
600 (0x80100003 | (md_dllrst << 4)));
601 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
602 0x80000000))
603 return DDR_TIMEOUT;
604
605 /* MCMD : Precharge ALL Banks */
606 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
607 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
608 0x00100001))
609 return DDR_TIMEOUT;
610
611 /* MCMD : Refresh Command */
612 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100002);
613 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
614 0x00100002))
615 return DDR_TIMEOUT;
616
617 /* MCMD : Refresh Command */
618 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100002);
619 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
620 0x00100002))
621 return DDR_TIMEOUT;
622
623 /* MCMD : MRS Cmd, MR0-- Initialize Device Operation */
624 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
625 0x80100003 | (mr << 4));
626 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x0))
627 return DDR_TIMEOUT;
628
629 /* MCMD : MRS Cmd, MR1-- Set OCD Calibration Default */
630 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
631 0x80123803 | (emr << 4));
632 exp_val = (0x00123803 | (emr << 4));
633 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
634 exp_val))
635 return DDR_TIMEOUT;
636
637 /* MCMD : MRS Cmd, MR1-- Exit OCD calibration Mode */
638 write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
639 0x80120003 | (emr << 4));
640 exp_val = (0x00120003 | (emr << 4));
641 if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
642 exp_val))
643 return DDR_TIMEOUT;
644 }
645
646 /* DCFG : DRAM Density 256 Mb 16 Bit IO Width
647 * 1:0 Devicw Width 1 x8, 2 x16, 3 x32 2
648 * 5:2 Density 2Gb = 5
649 * 6 Dram Type (MDDR/LPDDR2) Only 0
650 * 7 Reserved 0
651 * 10:8 Address Map R/B/C = 0
652 * 31:11 Reserved
653 */
654 write32(DDR_PCTL + DDR_PCTL_DCFG_OFFSET, 0x00000016);
655
656 /* PCFG_0 : Port 0 AXI config */
657 if (BL8 == 1)
658 write32(DDR_PCTL + DDR_PCTL_PCFG0_OFFSET, 0x000800A0);
659 else
660 write32(DDR_PCTL + DDR_PCTL_PCFG0_OFFSET, 0x000400A0);
661
662 /* SCTL : UPCTL switch Config to ACCESS State */
663 write32(DDR_PCTL + DDR_PCTL_SCTL_OFFSET, 0x00000002);
664 /* STAT : Wait for switch CFG -> GO State */
665 if (wait_for_completion(DDR_PCTL + DDR_PCTL_STAT_OFFSET, 0x3))
666 return DDR_TIMEOUT;
667
668 return 0;
669}