2 * This file is part of the coreboot project.
4 * Copyright (C) 2014 Imagination Technologies
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
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.
19 #include <soc/ddr_init.h>
20 #include <soc/ddr_private_reg.h>
23 * Configuration for the Winbond W631GG6KB part using
24 * Synopsys DDR uMCTL and DDR Phy
30 temp_rw_val
= read32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
);
33 write32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
, temp_rw_val
);
34 read32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
);
36 * Reset the AXI bridge and DDR Controller in case any spurious
37 * writes have already happened to DDR
39 /* Drive the 3 resets low */
40 write32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
, 0x00000002);
41 read32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
);
42 read32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
);
45 write32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
, 0x0000000F);
46 /* Dummy read to fence the access between the reset above and
47 * the DDR controller writes below
49 read32(TOPLEVEL_REGS
+ DDR_CTRL_OFFSET
);
52 * therefore 200MHz (5ns) uMCTL (Internal) Rate
54 /* TOGCNT1U: Toggle Counter 1U Register: 1us 200h C8h */
55 write32(DDR_PCTL
+ DDR_PCTL_TOGCNT1U_OFFSET
, 0x000000C8);
56 /* TINIT: t_init Timing Register: at least 200us 200h C8h */
57 write32(DDR_PCTL
+ DDR_PCTL_TINIT_OFFSET
, 0x000000C8);
58 /* TRSTH: Reset High Time Register DDR3 ONLY */
59 write32(DDR_PCTL
+ DDR_PCTL_TRSTH_OFFSET
, 0x000001F4);
60 /* TOGCNT100N: Toggle Counter 100N Register: 20d, 14h*/
61 write32(DDR_PCTL
+ DDR_PCTL_TOGG_CNTR_100NS_OFFSET
, 0x00000014);
62 /* DTUAWDT DTU Address Width Register
63 * 1:0 column_addr_width Def 10 - 7 3 10 bits
64 * 4:3 bank_addr_width Def 3 - 2 1 3 bits (8 bank)
65 * 7:6 row_addr_width Def 14 - 13 1 3 bits
66 * 10:9 number_ranks Def 1 - 1 0 0 1 Rank
68 write32(DDR_PCTL
+ DDR_PCTL_DTUAWDT_OFFSET
, 0x0000004B);
72 * 2 BL8 Burst Terminate 0
77 * 7 BST En 0, 1 for LPDDR2/3
78 * 15:8 Power down Idle, passed by argument
79 * 16 Power Down Type, passed by argument
80 * 17 Power Down Exit 0 = slow, 1 = fast, pba
81 * 19:18 tFAW 45ns = 9 clk 5*2 -1 1h
82 * 21:20 mDDR/LPDDR2 BL 0
83 * 23:22 mDDR/LPDDR2 Enable 0
84 * 31:24 mDDR/LPDDR2/3 Dynamic Clock Stop 0
86 write32(DDR_PCTL
+ DDR_PCTL_MCFG_OFFSET
, 0x00060021);
87 /* MCFG1: Memory Configuration-1 Register
88 * c7:0 sr_idle Self Refresh Idle Entery 32 * nclks 14h, set 0 for BUB
89 * 10:8 Fine tune MCFG.19:18 -1
91 * 23:16 Hardware Idle Period NA 0
93 * 31 c_active_in_pin exit auto clk stop NA 0
95 write32(DDR_PCTL
+ DDR_PCTL_MCFG1_OFFSET
, 0x00000100);
99 * 6:4 Primary DQ DDR3 Only 0
100 * 7 Multi-Purpose Register DDR3 Only 0
101 * 9:8 DDRTYPE LPDDR2 00
103 * 27 NOSRA No Simultaneous Rank Access 0
109 write32(DDR_PHY
+ DDRPHY_DCR_OFFSET
, 0x0000000B);
110 /* Generate to use with PHY and PCTL
111 * MR0 : DDR3 mode register 0
113 * 3 BT Sequential 0 Interleaved 1 = 0
116 * 8 DLL Reset 1 (self Clearing)
117 * 11:9 WR 15 ns 6 (010)
118 * 12 PD Slow 1 Fast 0 0
122 write32(DDR_PHY
+ DDRPHY_MR_OFFSET
, 0x00001420);
123 /* MR1 : DDR3 mode register 1
124 * Generate to use with PHY and PCTL
125 * 0 DE DLL Enable 0 Disable 1
126 * 5,1 DIC Output Driver RZQ/6
129 * 7 write leveling enabled 0
130 * 10 DQS 0 diff, 1 single = 0
132 * 12 QOFF Normal mode 0
136 write32(DDR_PHY
+ DDRPHY_EMR_OFFSET
, 0x00000004);
137 /* MR2 : DDR3 mode register 2
138 * Generate to use with PHY and PCTL
140 * 3 CWL 000 (5) tck = 22.5ns
141 * 6 auto self-refresh 1
144 * 10:9 dynamic ODT 10 RZQ/2
147 write32(DDR_PHY
+ DDRPHY_EMR2_OFFSET
, 0x00000440);
148 /* MR3: DDR3 mode register 3
152 write32(DDR_PHY
+ DDRPHY_EMR3_OFFSET
, 0x00000000);
153 /* DTAR : Data Training Register
154 * 11:0 Data Training Column Address
155 * 27:12 Data Training Row Address
156 * 30:28 Data Training Bank Address
157 * 31 Data Training Use MPR (DDR3 Only)
159 write32(DDR_PHY
+ DDRPHY_DTAR_OFFSET
, 0x00000000);
166 * 7:5 DQSGX DQS Extention 000
167 * 10:8 DQSGE DQS Early Gate
168 * 11 NOBUB No Bubbles, adds latency 1
169 * 12 FXDLAT Fixed Read Latency 0
171 * 19:16 CKEPDD CKE Power Down 0000
172 * 23:20 ODTPDD ODT Power Down 0000
173 * 24 NL2PD Power Down Non LPDDR2 pins 0
174 * 25 NL2OE Output Enable Non LPDDR2 pins 1
175 * 26 TPDPD LPDDR Only 0
176 * 27 TPDOE LPDDR Only 1
177 * 28 CKOE Output Enable Clk's 1
178 * 29 ODTOE Output Enable ODT 1
179 * 30 RSTOE RST# Output Enable 1
180 * 31 CKEOE CKE Output Enable 1
182 write32(DDR_PHY
+ DDRPHY_DSGCR_OFFSET
, 0xFA000807);
183 /* DTPR0 : DRAM Timing Params 0
190 * 24:21 tRRD 4 for x16
192 * 31 tCCD 0 BL/2 Cas to Cas
194 write32(DDR_PHY
+ DDRPHY_DTPR0_OFFSET
, 0x2A8F6688);
195 /* DTPR1 : DRAM Timing Params 1
196 * 1:0 ODT On/Off Del Std 0
197 * 2 tRTW Rd2Wr Del 0 std 1 +1 0
199 * 10:9 tMOD DDR3 Only 15
200 * 11 tRTODT DDR3 Only 0
202 * 23:16 tRFC 160ns 64 ref 131
203 * 26:24 tDQSCK LPDDR2 only 1
207 write32(DDR_PHY
+ DDRPHY_DTPR1_OFFSET
, 0x094006A0);
208 /* DTPR2 : DRAM Timing Params 2
209 * 9:0 tXS exit SR def 512d
210 * 14:10 tXP PD Exit Del 8 5
211 * 18:15 tCKE CKE Min pulse 5
212 * 28:19 tDLLK DLL Lock time 512d
215 write32(DDR_PHY
+ DDRPHY_DTPR2_OFFSET
, 0x10029600);
216 /* PTR0 : PHY Timing Params 0
218 * 17:6 tDLLLOCK Def 2750
219 * 21:18 tITMSRST Def 8
222 write32(DDR_PHY
+ DDRPHY_PTR0_OFFSET
, 0x0022AF9B);
223 /* PTR1 : PHY Timing Params 1
224 * 18:0 : tDINITO DRAM Init time 500us 200,000 Dec 0x30D40
225 * 29:19 : tDINIT1 DRAM Init time tRFC + 10ns 68
227 write32(DDR_PHY
+ DDRPHY_PTR1_OFFSET
, 0x02230D40);
228 /* DQS gating configuration: passive windowing mode */
230 * PGCR: PHY General cofiguration register
232 * 1 DQS gading configuration: passive windowing 1
233 * 2 DQS drift compensation: not supported in passive windowing 0
234 * 4:3 DQS drift limit 0
235 * 8:5 Digital test output select 0
236 * 11:9 CK Enable: one bit for each 3 CK pair: 0x7
237 * 13:12 CK Disable values: 0x2
240 * 17:16 I/O DDR mode 0
241 * 21:18 Ranks enable by training: 0xF
242 * 23:22 Impedance clock divider select 0x2
243 * 24 Power down disable 1
244 * 28:25 Refresh during training 0
245 * 29 loopback DQS shift 0
246 * 30 loopback DQS gating 0
249 write32(DDR_PHY
+ DDRPHY_PGCR_OFFSET
, 0x01BC2E02);
251 /* PGSR : Wait for INIT/DLL/Z Done from Power on Reset */
252 if (wait_for_completion(DDR_PHY
+ DDRPHY_PGSR_OFFSET
, 0x00000007))
254 /* PIR : PHY controlled init */
255 write32(DDR_PHY
+ DDRPHY_PIR_OFFSET
, 0x0000001F);
256 /* PGSR : Wait for DRAM Init Done */
257 if (wait_for_completion(DDR_PHY
+ DDRPHY_PGSR_OFFSET
, 0x00000007))
259 /* PIR : controller DRAM initialization */
260 write32(DDR_PHY
+ DDRPHY_PIR_OFFSET
, 0x00040001);
261 /* PGSR : Wait for DRAM Init Done */
262 if (wait_for_completion(DDR_PHY
+ DDRPHY_PGSR_OFFSET
, 0x0000000F))
264 /********************************************************************/
265 /* DF1STAT0 : wait for DFI_INIT_COMPLETE */
266 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_DFISTAT0_OFFSET
,
269 /* POWCTL : Start the memory Power Up seq*/
270 write32(DDR_PCTL
+ DDR_PCTL_POWCTL_OFFSET
, 0x80000001);
271 /* POWSTAT : wait for POWER_UP_DONE */
272 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_POWSTAT_OFFSET
,
276 * TREFI : t_refi Timing Register 1X
277 * 12:0 t_refi 7.8us in 100ns 0x4E
279 * 18:16 num_add_ref 0
283 write32(DDR_PCTL
+ DDR_PCTL_TREFI_OFFSET
, 0x8000004E);
284 /* TMRD : t_mrd Timing Register -- Range 2 to 4*/
285 write32(DDR_PCTL
+ DDR_PCTL_TMRD_OFFSET
, 0x00000004);
287 * TRFC : t_rfc Timing Register -- Range 15 to 131
288 * 195ns / 2.5ns 78 x4E
290 write32(DDR_PCTL
+ DDR_PCTL_TRFC_OFFSET
, 0x0000004E);
291 /* TRP : t_rp Timing Register -- Range 3 to 7
292 * 4:0 tRP 12.5 / 2.5 = 5 6 For Now 6-6-6
293 * 17:16 rpea_extra DDR3 - value 0
295 write32(DDR_PCTL
+ DDR_PCTL_TRP_OFFSET
, 0x00000006);
296 /* TAL : Additive Latency Register -- AL in MR1 */
297 write32(DDR_PCTL
+ DDR_PCTL_TAL_OFFSET
, 0x00000000);
298 /* TCL : CAS Latency Timing Register -- CASL in MR0 6-6-6 */
299 write32(DDR_PCTL
+ DDR_PCTL_TCL_OFFSET
, 0x00000006);
300 /* TCWL : CAS Write Latency Register --CASL-1 */
301 write32(DDR_PCTL
+ DDR_PCTL_TCWL_OFFSET
, 0x00000005);
302 /* TRAS : Activate to Precharge cmd time 15 45ns / 2.5ns = 18d */
303 write32(DDR_PCTL
+ DDR_PCTL_TRAS_OFFSET
, 0x0000000F);
304 /* TRC : Min. ROW cylce time 21
305 * 57.5ns / 2.5ns = 23d Playing safe 24
307 write32(DDR_PCTL
+ DDR_PCTL_TRC_OFFSET
, 0x00000015);
308 /* TRCD : Row to Column Delay # Range 3 to 7 (TCL = TRCD)
309 * 12.5ns / 2.5ns = 5 but running 6-6-6 6
311 write32(DDR_PCTL
+ DDR_PCTL_TRCD_OFFSET
, 0x00000006);
312 /* TRRD : Row to Row delay -- Range 2 to 6
313 * 2K Page 10ns / 2.5ns = 4
315 write32(DDR_PCTL
+ DDR_PCTL_TRRD_OFFSET
, 0x00000004);
316 /* TRTP : Read to Precharge time -- Range 2 to 4
317 * Largest 4 or 7.5ns / 2.5ns = 4
319 write32(DDR_PCTL
+ DDR_PCTL_TRTP_OFFSET
, 0x00000004);
320 /* TWR : Write recovery time -- WR in MR0: 15ns / 2.5ns = 6 */
321 write32(DDR_PCTL
+ DDR_PCTL_TWR_OFFSET
, 0x00000006);
322 /* TWTR : Write to read turn around time -- Range 2 to 4
323 * Largest 4 or 7.5ns / 2.5ns = 4
325 write32(DDR_PCTL
+ DDR_PCTL_TWTR_OFFSET
, 0x00000004);
326 /* TEXSR : Exit Self Refresh to first valid cmd: tXS 512 */
327 write32(DDR_PCTL
+ DDR_PCTL_TEXSR_OFFSET
, 0x00000200);
328 /* TXP : Exit Power Down to first valid cmd
329 * tXP 2, Settingto 3 to match PHY
331 write32(DDR_PCTL
+ DDR_PCTL_TXP_OFFSET
, 0x00000003);
332 /* TDQS : t_dqs Timing Register
333 * DQS additional turn around Rank 2 Rank (1 Rank) Def 1
335 write32(DDR_PCTL
+ DDR_PCTL_TDQS_OFFSET
, 0x00000001);
336 /* TRTW : Read to Write turn around time Def 2
337 * Actual gap t_bl + t_rtw
339 write32(DDR_PCTL
+ DDR_PCTL_TRTW_OFFSET
, 0x00000002);
340 /* TCKE : CKE min pulse width DEf 3 */
341 write32(DDR_PCTL
+ DDR_PCTL_TCKE_OFFSET
, 0x00000003);
342 /* TXPDLL : Slow Exit Power Down to first valid cmd delay
345 write32(DDR_PCTL
+ DDR_PCTL_TXPDLL_OFFSET
, 0x0000000A);
346 /* TCKESR : Min CKE Low width for Self refresh entry to exit
349 write32(DDR_PCTL
+ DDR_PCTL_TCKESR_OFFSET
, 0x00000004);
350 /* TMOD : MRS to any Non-MRS command -- Range 0 to 31 */
351 write32(DDR_PCTL
+ DDR_PCTL_TMOD_OFFSET
, 0x0000000F);
352 /* TZQCS : SDRAM ZQ Calibration Short Period */
353 write32(DDR_PCTL
+ DDR_PCTL_TZQCS_OFFSET
, 0x00000040);
354 /* TZQCL : SDRAM ZQ Calibration Long Period */
355 write32(DDR_PCTL
+ DDR_PCTL_TZQCL_OFFSET
, 0x00000200);
356 /* SCFG : State Configuration Register (Enabling Self Refresh)
357 * 0 LP_en Leave Off for Bring Up 0
359 * 6 Synopsys Internal Only 0
360 * 7 Enale PHY indication of LP Opportunity 1
361 * 11:8 bbflags_timing max UPCTL_TCU_SED_P - tRP (16 - 6) Use 4
362 * 16:12 Additional delay on accertion of ac_pdd 4
365 write32(DDR_PCTL
+ DDR_PCTL_SCFG_OFFSET
, 0x00004480);
367 write32(DDR_PCTL
+ DDR_PCTL_TREFI_MEM_DDR3_OFFSET
, 0x00000C30);
369 /* DFITPHYWRLAT : Write cmd to dfi_wrdata_en */
370 write32(DDR_PCTL
+ DDR_PCTL_DFIWRLAT_OFFSET
, 0x00000002);
371 /* DFITRDDATAEN : Read cmd to dfi_rddata_en */
372 write32(DDR_PCTL
+ DDR_PCTL_DFITRDDATAEN_OFFSET
, 0x00000002);
374 * DFITPHYWRDATA : dfi_wrdata_en to drive wr data
375 * DFI Clks wrdata_en to wrdata Def 1
377 write32(DDR_PCTL
+ DDR_PCTL_DFITPHYWRDATA_OFFSET
, 0x00000000);
379 * DFITPHYRDLAT : dfi_rddata_en to dfi_rddata_valid
380 * DFI clks max rddata_en to rddata_valid Def 15
382 write32(DDR_PCTL
+ DDR_PCTL_DFITPHYRDLAT_OFFSET
, 0x00000008);
383 /* DFISTCFG0 : Drive various DFI signals appropriately
385 * 1 dfi_freq_ratio_en 1
386 * 2 dfi_data_byte_disable_en 1
388 write32(DDR_PCTL
+ DDR_PCTL_DFISTCFG0_OFFSET
, 0x00000007);
389 /* DFISTCFG1 : Enable various DFI support
390 * 0 dfi_dram_clk_disable_en 1
391 * 1 dfi_dram_clk_disable_en_pdp only lPDDR 0
393 write32(DDR_PCTL
+ DDR_PCTL_DFISTCFG1_OFFSET
, 0x00000001);
394 /* DFISTCFG2 : Enable Parity and asoc interrupt
395 * 0 dfi_parity_in Enable 1
396 * 1 Interrupt on dfi_parity_error 1
398 write32(DDR_PCTL
+ DDR_PCTL_DFISTCFG2_OFFSET
, 0x00000003);
399 /* DFILPCFG0 : DFI Low Power Interface Configuration
400 * 0 Enable DFI LP IF during PD 1
402 * 7:4 DFI tlp_wakeup time 0
403 * 8 Enable DFI LP IF during SR 1
405 * 15:12 dfi_lp_wakeup in SR 0
406 * 19:16 tlp_resp DFI 2.1 recomend 7
408 * 24 Enable DFI LP in Deep Power Down 0
410 * 31:28 DFI LP Deep Power Down Value 0
412 write32(DDR_PCTL
+ DDR_PCTL_DFILPCFG0_OFFSET
, 0x00070101);
413 /* DFIODTCFG : DFI ODT Configuration
414 * Only Enabled on Rank0 Writes
415 * 0 rank0_odt_read_nsel 0
416 * 1 rank0_odt_read_sel 0
417 * 2 rank0_odt_write_nsel 0
418 * 3 rank0_odt_write_sel 1
420 write32(DDR_PCTL
+ DDR_PCTL_DFIODTCFG_OFFSET
, 0x00000008);
421 /* DFIODTCFG1 : DFI ODT Configuration
423 * 12:8 odt_lat_r 0 Def
424 * 4:0 odt_len_bl8_w 6 Def
425 * 12:8 odt_len_bl8_r 6 Def
427 write32(DDR_PCTL
+ DDR_PCTL_DFIODTCFG1_OFFSET
, 0x060600000);
429 /* Memory initilization */
430 /* MCMD : PREA, Addr 0 Bank 0 Rank 0 Del 0
431 * 3:0 cmd_opcode PREA 00001
434 * 23:20 rank_sel 0 0001
439 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80004403);
440 /* MRS cmd wait for completion */
441 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00004403))
444 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80000003);
445 /* MRS cmd wait for completion */
446 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00000003))
449 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80000043);
450 /* MRS cmd wait for completion */
451 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00000043))
454 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80015203);
455 /* MRS cmd wait for completion */
456 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00015203))
458 /* MCMD: ZQS cmd, long 5 short 4 */
459 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80104005);
460 /* MRS cmd wait for completion */
461 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00104005))
463 /* MCMD: deselect command */
464 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x80100000);
465 /* MRS cmd wait for completion */
466 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x00100000))
468 /* MCMD: deselect command */
469 write32(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x8010000A);
470 /* MRS cmd wait for completion */
471 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_MCMD_OFFSET
, 0x0010000A))
474 /* DCFG : DRAM Density 256 Mb 16 Bit IO Width
475 * 1:0 Devicw Width 1 x8, 2 x16, 3 x32 2
476 * 5:2 Density 2Gb = 5
477 * 6 Dram Type (MDDR/LPDDR2) Only 0
479 * 10:8 Address Map R/B/C = 1
482 write32(DDR_PCTL
+ DDR_PCTL_DCFG_OFFSET
, 0x00000116);
483 /* PCFG_0 : Port 0 AXI config */
484 write32(DDR_PCTL
+ DDR_PCTL_PCFG0_OFFSET
, 0x000800A0);
485 /* SCTL : UPCTL switch INIT CONFIG State */
486 write32(DDR_PCTL
+ DDR_PCTL_SCTL_OFFSET
, 0x00000001);
487 /* STAT : Wait for Switch INIT to Config State */
488 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_STAT_OFFSET
, 0x00000001))
490 /* STAT : Wait for Switch INIT to Config State */
491 write32(DDR_PCTL
+ DDR_PCTL_CMDTSTATEN_OFFSET
, 0x00000001);
492 /* STAT : Wait for Switch INIT to Config State */
493 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_CMDTSTAT_OFFSET
,
496 /* Use PHY for DRAM init */
497 write32(DDR_PHY
+ DDRPHY_PIR_OFFSET
, 0x00000181);
498 /* STAT : Wait for Switch INIT to Config State */
499 if (wait_for_completion(DDR_PHY
+ DDRPHY_PGSR_OFFSET
, 0x00000001F))
501 /* SCTL : UPCTL switch Config to ACCESS State */
502 write32(DDR_PCTL
+ DDR_PCTL_SCTL_OFFSET
, 0x00000002);
503 /* STAT : Wait for switch CFG -> GO State */
504 if (wait_for_completion(DDR_PCTL
+ DDR_PCTL_STAT_OFFSET
, 0x3))