| /* |
| * This file is part of the coreboot project. |
| * |
| * Copyright (C) 2014 Imagination Technologies |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; version 2 of |
| * the License. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #include <stdint.h> |
| #include <arch/io.h> |
| #include <soc/ddr_init.h> |
| #include <soc/ddr_private_reg.h> |
| |
| /* |
| * Configuration for the Winbond W631GG6KB part using |
| * Synopsys DDR uMCTL and DDR Phy |
| */ |
| int init_ddr3(void) |
| { |
| uint32_t temp_rw_val; |
| |
| temp_rw_val = read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET); |
| /* Set CLK_EN = 1 */ |
| temp_rw_val |= 0x2; |
| write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, temp_rw_val); |
| read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET); |
| /* |
| * Reset the AXI bridge and DDR Controller in case any spurious |
| * writes have already happened to DDR |
| */ |
| /* Drive the 3 resets low */ |
| write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x00000002); |
| read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET); |
| read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET); |
| |
| /* And release */ |
| write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x0000000F); |
| /* Dummy read to fence the access between the reset above and |
| * the DDR controller writes below |
| */ |
| read32(TOPLEVEL_REGS + DDR_CTRL_OFFSET); |
| |
| /* Timings for 400MHz |
| * therefore 200MHz (5ns) uMCTL (Internal) Rate |
| */ |
| /* TOGCNT1U: Toggle Counter 1U Register: 1us 200h C8h */ |
| write32(DDR_PCTL + DDR_PCTL_TOGCNT1U_OFFSET, 0x000000C8); |
| /* TINIT: t_init Timing Register: at least 200us 200h C8h */ |
| write32(DDR_PCTL + DDR_PCTL_TINIT_OFFSET, 0x000000C8); |
| /* TRSTH: Reset High Time Register DDR3 ONLY */ |
| write32(DDR_PCTL + DDR_PCTL_TRSTH_OFFSET, 0x000001F4); |
| /* TOGCNT100N: Toggle Counter 100N Register: 20d, 14h*/ |
| write32(DDR_PCTL + DDR_PCTL_TOGG_CNTR_100NS_OFFSET, 0x00000014); |
| /* DTUAWDT DTU Address Width Register |
| * 1:0 column_addr_width Def 10 - 7 3 10 bits |
| * 4:3 bank_addr_width Def 3 - 2 1 3 bits (8 bank) |
| * 7:6 row_addr_width Def 14 - 13 1 3 bits |
| * 10:9 number_ranks Def 1 - 1 0 0 1 Rank |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DTUAWDT_OFFSET, 0x0000004B); |
| /* MCFG |
| * 0 BL 1 -> 8 fixed |
| * 1 RDRIMM 0 |
| * 2 BL8 Burst Terminate 0 |
| * 3 2T = 0 |
| * 4 Multi Rank 0 |
| * 5 DDR3 En 1 |
| * 6 LPDDR S4 En |
| * 7 BST En 0, 1 for LPDDR2/3 |
| * 15:8 Power down Idle, passed by argument |
| * 16 Power Down Type, passed by argument |
| * 17 Power Down Exit 0 = slow, 1 = fast, pba |
| * 19:18 tFAW 45ns = 9 clk 5*2 -1 1h |
| * 21:20 mDDR/LPDDR2 BL 0 |
| * 23:22 mDDR/LPDDR2 Enable 0 |
| * 31:24 mDDR/LPDDR2/3 Dynamic Clock Stop 0 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_MCFG_OFFSET, 0x00060021); |
| /* MCFG1: Memory Configuration-1 Register |
| * c7:0 sr_idle Self Refresh Idle Entery 32 * nclks 14h, set 0 for BUB |
| * 10:8 Fine tune MCFG.19:18 -1 |
| * 15:11 Reserved |
| * 23:16 Hardware Idle Period NA 0 |
| * 30:24 Reserved |
| * 31 c_active_in_pin exit auto clk stop NA 0 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_MCFG1_OFFSET, 0x00000100); |
| /* DCR DRAM Config |
| * 2:0 SDRAM => DDR3 3 |
| * 3 DDR 8 Bank 1 |
| * 6:4 Primary DQ DDR3 Only 0 |
| * 7 Multi-Purpose Register DDR3 Only 0 |
| * 9:8 DDRTYPE LPDDR2 00 |
| * 26:10 Reserved |
| * 27 NOSRA No Simultaneous Rank Access 0 |
| * 28 DDR 2T 0 |
| * 29 UDIMM NA 0 |
| * 30 RDIMM NA 0 |
| * 31 TPD LPDDR2 0 |
| */ |
| write32(DDR_PHY + DDRPHY_DCR_OFFSET, 0x0000000B); |
| /* Generate to use with PHY and PCTL |
| * MR0 : DDR3 mode register 0 |
| * 1:0 BL 8 fixed 00 |
| * 3 BT Sequential 0 Interleaved 1 = 0 |
| * 6:4,2 CL 6 |
| * 7 TM Normal 0 |
| * 8 DLL Reset 1 (self Clearing) |
| * 11:9 WR 15 ns 6 (010) |
| * 12 PD Slow 1 Fast 0 0 |
| * 15:13 RSVD RSVD |
| * 31:16 Reserved |
| */ |
| write32(DDR_PHY + DDRPHY_MR_OFFSET, 0x00001420); |
| /* MR1 : DDR3 mode register 1 |
| * Generate to use with PHY and PCTL |
| * 0 DE DLL Enable 0 Disable 1 |
| * 5,1 DIC Output Driver RZQ/6 |
| * 9,6,2 ODT RZQ/4 |
| * 4:3 AL = 0 |
| * 7 write leveling enabled 0 |
| * 10 DQS 0 diff, 1 single = 0 |
| * 11 TDQS NA 0 |
| * 12 QOFF Normal mode 0 |
| * 15:13 RSVD |
| * 31:16 Reserved |
| */ |
| write32(DDR_PHY + DDRPHY_EMR_OFFSET, 0x00000004); |
| /* MR2 : DDR3 mode register 2 |
| * Generate to use with PHY and PCTL |
| * 2:0 PASR, NA 000 |
| * 3 CWL 000 (5) tck = 22.5ns |
| * 6 auto self-refresh 1 |
| * 7 SRT normal 0 |
| * 8 RSVD |
| * 10:9 dynamic ODT 10 RZQ/2 |
| * 31:11 Reserved |
| */ |
| write32(DDR_PHY + DDRPHY_EMR2_OFFSET, 0x00000440); |
| /* MR3: DDR3 mode register 3 |
| * 1:0 MPRLOC 00 |
| * 2 MPR 0 |
| */ |
| write32(DDR_PHY + DDRPHY_EMR3_OFFSET, 0x00000000); |
| /* DTAR : Data Training Register |
| * 11:0 Data Training Column Address |
| * 27:12 Data Training Row Address |
| * 30:28 Data Training Bank Address |
| * 31 Data Training Use MPR (DDR3 Only) |
| */ |
| write32(DDR_PHY + DDRPHY_DTAR_OFFSET, 0x00000000); |
| /* DSGCR |
| * 0 PUREN Def 1 |
| * 1 BDISEN Def 1 |
| * 2 ZUEN Def 1 |
| * 3 LPIOPD DEf 1 0 |
| * 4 LPDLLPD DEf 1 0 |
| * 7:5 DQSGX DQS Extention 000 |
| * 10:8 DQSGE DQS Early Gate |
| * 11 NOBUB No Bubbles, adds latency 1 |
| * 12 FXDLAT Fixed Read Latency 0 |
| * 15:13 Reserved |
| * 19:16 CKEPDD CKE Power Down 0000 |
| * 23:20 ODTPDD ODT Power Down 0000 |
| * 24 NL2PD Power Down Non LPDDR2 pins 0 |
| * 25 NL2OE Output Enable Non LPDDR2 pins 1 |
| * 26 TPDPD LPDDR Only 0 |
| * 27 TPDOE LPDDR Only 1 |
| * 28 CKOE Output Enable Clk's 1 |
| * 29 ODTOE Output Enable ODT 1 |
| * 30 RSTOE RST# Output Enable 1 |
| * 31 CKEOE CKE Output Enable 1 |
| */ |
| write32(DDR_PHY + DDRPHY_DSGCR_OFFSET, 0xFA000807); |
| /* DTPR0 : DRAM Timing Params 0 |
| * 1:0 tMRD 0 |
| * 4:2 tRTP 2 |
| * 7:5 tWTR 4 |
| * 11:8 tRP 6 |
| * 15:12 tRCD 6 |
| * 20:16 tRAS 15 |
| * 24:21 tRRD 4 for x16 |
| * 30:25 tRC 21 |
| * 31 tCCD 0 BL/2 Cas to Cas |
| */ |
| write32(DDR_PHY + DDRPHY_DTPR0_OFFSET, 0x2A8F6688); |
| /* DTPR1 : DRAM Timing Params 1 |
| * 1:0 ODT On/Off Del Std 0 |
| * 2 tRTW Rd2Wr Del 0 std 1 +1 0 |
| * 8:3 tFAW 20 Clk |
| * 10:9 tMOD DDR3 Only 15 |
| * 11 tRTODT DDR3 Only 0 |
| * 15:12 Reserved |
| * 23:16 tRFC 160ns 64 ref 131 |
| * 26:24 tDQSCK LPDDR2 only 1 |
| * 29:27 tDQSCKmax 1 |
| * 31:30 Reserved |
| */ |
| write32(DDR_PHY + DDRPHY_DTPR1_OFFSET, 0x094006A0); |
| /* DTPR2 : DRAM Timing Params 2 |
| * 9:0 tXS exit SR def 512d |
| * 14:10 tXP PD Exit Del 8 5 |
| * 18:15 tCKE CKE Min pulse 5 |
| * 28:19 tDLLK DLL Lock time 512d |
| * 32:29 Reserved |
| */ |
| write32(DDR_PHY + DDRPHY_DTPR2_OFFSET, 0x10029600); |
| /* PTR0 : PHY Timing Params 0 |
| * 5:0 tDLLRST Def 27 |
| * 17:6 tDLLLOCK Def 2750 |
| * 21:18 tITMSRST Def 8 |
| * 31:22 Reserved 0 |
| */ |
| write32(DDR_PHY + DDRPHY_PTR0_OFFSET, 0x0022AF9B); |
| /* PTR1 : PHY Timing Params 1 |
| * 18:0 : tDINITO DRAM Init time 500us 200,000 Dec 0x30D40 |
| * 29:19 : tDINIT1 DRAM Init time tRFC + 10ns 68 |
| */ |
| write32(DDR_PHY + DDRPHY_PTR1_OFFSET, 0x02230D40); |
| /* DQS gating configuration: passive windowing mode */ |
| /* |
| * PGCR: PHY General cofiguration register |
| * 0 ITM DDR mode: 0 |
| * 1 DQS gading configuration: passive windowing 1 |
| * 2 DQS drift compensation: not supported in passive windowing 0 |
| * 4:3 DQS drift limit 0 |
| * 8:5 Digital test output select 0 |
| * 11:9 CK Enable: one bit for each 3 CK pair: 0x7 |
| * 13:12 CK Disable values: 0x2 |
| * 14 CK Invert 0 |
| * 15 IO loopback 0 |
| * 17:16 I/O DDR mode 0 |
| * 21:18 Ranks enable by training: 0xF |
| * 23:22 Impedance clock divider select 0x2 |
| * 24 Power down disable 1 |
| * 28:25 Refresh during training 0 |
| * 29 loopback DQS shift 0 |
| * 30 loopback DQS gating 0 |
| * 31 loopback mode 0 |
| */ |
| write32(DDR_PHY + DDRPHY_PGCR_OFFSET, 0x01BC2E02); |
| |
| /* PGSR : Wait for INIT/DLL/Z Done from Power on Reset */ |
| if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x00000007)) |
| return DDR_TIMEOUT; |
| /* PIR : PHY controlled init */ |
| write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x0000001F); |
| /* PGSR : Wait for DRAM Init Done */ |
| if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x00000007)) |
| return DDR_TIMEOUT; |
| /* PIR : controller DRAM initialization */ |
| write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x00040001); |
| /* PGSR : Wait for DRAM Init Done */ |
| if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x0000000F)) |
| return DDR_TIMEOUT; |
| /********************************************************************/ |
| /* DF1STAT0 : wait for DFI_INIT_COMPLETE */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_DFISTAT0_OFFSET, |
| 0x00000001)) |
| return DDR_TIMEOUT; |
| /* POWCTL : Start the memory Power Up seq*/ |
| write32(DDR_PCTL + DDR_PCTL_POWCTL_OFFSET, 0x80000001); |
| /* POWSTAT : wait for POWER_UP_DONE */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_POWSTAT_OFFSET, |
| 0x00000001)) |
| return DDR_TIMEOUT; |
| /* |
| * TREFI : t_refi Timing Register 1X |
| * 12:0 t_refi 7.8us in 100ns 0x4E |
| * 15:13 Reserved 0 |
| * 18:16 num_add_ref 0 |
| * 30:19 Reserved 0 |
| * 31 Update 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TREFI_OFFSET, 0x8000004E); |
| /* TMRD : t_mrd Timing Register -- Range 2 to 4*/ |
| write32(DDR_PCTL + DDR_PCTL_TMRD_OFFSET, 0x00000004); |
| /* |
| * TRFC : t_rfc Timing Register -- Range 15 to 131 |
| * 195ns / 2.5ns 78 x4E |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRFC_OFFSET, 0x0000004E); |
| /* TRP : t_rp Timing Register -- Range 3 to 7 |
| * 4:0 tRP 12.5 / 2.5 = 5 6 For Now 6-6-6 |
| * 17:16 rpea_extra DDR3 - value 0 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRP_OFFSET, 0x00000006); |
| /* TAL : Additive Latency Register -- AL in MR1 */ |
| write32(DDR_PCTL + DDR_PCTL_TAL_OFFSET, 0x00000000); |
| /* TCL : CAS Latency Timing Register -- CASL in MR0 6-6-6 */ |
| write32(DDR_PCTL + DDR_PCTL_TCL_OFFSET, 0x00000006); |
| /* TCWL : CAS Write Latency Register --CASL-1 */ |
| write32(DDR_PCTL + DDR_PCTL_TCWL_OFFSET, 0x00000005); |
| /* TRAS : Activate to Precharge cmd time 15 45ns / 2.5ns = 18d */ |
| write32(DDR_PCTL + DDR_PCTL_TRAS_OFFSET, 0x0000000F); |
| /* TRC : Min. ROW cylce time 21 |
| * 57.5ns / 2.5ns = 23d Playing safe 24 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRC_OFFSET, 0x00000015); |
| /* TRCD : Row to Column Delay # Range 3 to 7 (TCL = TRCD) |
| * 12.5ns / 2.5ns = 5 but running 6-6-6 6 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRCD_OFFSET, 0x00000006); |
| /* TRRD : Row to Row delay -- Range 2 to 6 |
| * 2K Page 10ns / 2.5ns = 4 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRRD_OFFSET, 0x00000004); |
| /* TRTP : Read to Precharge time -- Range 2 to 4 |
| * Largest 4 or 7.5ns / 2.5ns = 4 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRTP_OFFSET, 0x00000004); |
| /* TWR : Write recovery time -- WR in MR0: 15ns / 2.5ns = 6 */ |
| write32(DDR_PCTL + DDR_PCTL_TWR_OFFSET, 0x00000006); |
| /* TWTR : Write to read turn around time -- Range 2 to 4 |
| * Largest 4 or 7.5ns / 2.5ns = 4 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TWTR_OFFSET, 0x00000004); |
| /* TEXSR : Exit Self Refresh to first valid cmd: tXS 512 */ |
| write32(DDR_PCTL + DDR_PCTL_TEXSR_OFFSET, 0x00000200); |
| /* TXP : Exit Power Down to first valid cmd |
| * tXP 2, Settingto 3 to match PHY |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TXP_OFFSET, 0x00000003); |
| /* TDQS : t_dqs Timing Register |
| * DQS additional turn around Rank 2 Rank (1 Rank) Def 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TDQS_OFFSET, 0x00000001); |
| /* TRTW : Read to Write turn around time Def 2 |
| * Actual gap t_bl + t_rtw |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TRTW_OFFSET, 0x00000002); |
| /* TCKE : CKE min pulse width DEf 3 */ |
| write32(DDR_PCTL + DDR_PCTL_TCKE_OFFSET, 0x00000003); |
| /* TXPDLL : Slow Exit Power Down to first valid cmd delay |
| * tXARDS 10+AL = 10 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TXPDLL_OFFSET, 0x0000000A); |
| /* TCKESR : Min CKE Low width for Self refresh entry to exit |
| * t_ckesr = 0 DDR2 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_TCKESR_OFFSET, 0x00000004); |
| /* TMOD : MRS to any Non-MRS command -- Range 0 to 31 */ |
| write32(DDR_PCTL + DDR_PCTL_TMOD_OFFSET, 0x0000000F); |
| /* TZQCS : SDRAM ZQ Calibration Short Period */ |
| write32(DDR_PCTL + DDR_PCTL_TZQCS_OFFSET, 0x00000040); |
| /* TZQCL : SDRAM ZQ Calibration Long Period */ |
| write32(DDR_PCTL + DDR_PCTL_TZQCL_OFFSET, 0x00000200); |
| /* SCFG : State Configuration Register (Enabling Self Refresh) |
| * 0 LP_en Leave Off for Bring Up 0 |
| * 5:1 Reserved |
| * 6 Synopsys Internal Only 0 |
| * 7 Enale PHY indication of LP Opportunity 1 |
| * 11:8 bbflags_timing max UPCTL_TCU_SED_P - tRP (16 - 6) Use 4 |
| * 16:12 Additional delay on accertion of ac_pdd 4 |
| * 31:17 Reserved |
| */ |
| write32(DDR_PCTL + DDR_PCTL_SCFG_OFFSET, 0x00004480); |
| /* TREFI_MEM_DDR3 */ |
| write32(DDR_PCTL + DDR_PCTL_TREFI_MEM_DDR3_OFFSET, 0x00000C30); |
| |
| /* DFITPHYWRLAT : Write cmd to dfi_wrdata_en */ |
| write32(DDR_PCTL + DDR_PCTL_DFIWRLAT_OFFSET, 0x00000002); |
| /* DFITRDDATAEN : Read cmd to dfi_rddata_en */ |
| write32(DDR_PCTL + DDR_PCTL_DFITRDDATAEN_OFFSET, 0x00000002); |
| /* |
| * DFITPHYWRDATA : dfi_wrdata_en to drive wr data |
| * DFI Clks wrdata_en to wrdata Def 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFITPHYWRDATA_OFFSET, 0x00000000); |
| /* |
| * DFITPHYRDLAT : dfi_rddata_en to dfi_rddata_valid |
| * DFI clks max rddata_en to rddata_valid Def 15 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFITPHYRDLAT_OFFSET, 0x00000008); |
| /* DFISTCFG0 : Drive various DFI signals appropriately |
| * 0 dfi_init_start 1 |
| * 1 dfi_freq_ratio_en 1 |
| * 2 dfi_data_byte_disable_en 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFISTCFG0_OFFSET, 0x00000007); |
| /* DFISTCFG1 : Enable various DFI support |
| * 0 dfi_dram_clk_disable_en 1 |
| * 1 dfi_dram_clk_disable_en_pdp only lPDDR 0 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFISTCFG1_OFFSET, 0x00000001); |
| /* DFISTCFG2 : Enable Parity and asoc interrupt |
| * 0 dfi_parity_in Enable 1 |
| * 1 Interrupt on dfi_parity_error 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFISTCFG2_OFFSET, 0x00000003); |
| /* DFILPCFG0 : DFI Low Power Interface Configuration |
| * 0 Enable DFI LP IF during PD 1 |
| * 3:1 Reserved |
| * 7:4 DFI tlp_wakeup time 0 |
| * 8 Enable DFI LP IF during SR 1 |
| * 11:9 Reserved |
| * 15:12 dfi_lp_wakeup in SR 0 |
| * 19:16 tlp_resp DFI 2.1 recomend 7 |
| * 23:20 Reserved |
| * 24 Enable DFI LP in Deep Power Down 0 |
| * 27:25 Reserved |
| * 31:28 DFI LP Deep Power Down Value 0 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFILPCFG0_OFFSET, 0x00070101); |
| /* DFIODTCFG : DFI ODT Configuration |
| * Only Enabled on Rank0 Writes |
| * 0 rank0_odt_read_nsel 0 |
| * 1 rank0_odt_read_sel 0 |
| * 2 rank0_odt_write_nsel 0 |
| * 3 rank0_odt_write_sel 1 |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFIODTCFG_OFFSET, 0x00000008); |
| /* DFIODTCFG1 : DFI ODT Configuration |
| * 4:0 odt_lat_w 0 |
| * 12:8 odt_lat_r 0 Def |
| * 4:0 odt_len_bl8_w 6 Def |
| * 12:8 odt_len_bl8_r 6 Def |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DFIODTCFG1_OFFSET, 0x060600000); |
| |
| /* Memory initilization */ |
| /* MCMD : PREA, Addr 0 Bank 0 Rank 0 Del 0 |
| * 3:0 cmd_opcode PREA 00001 |
| * 16:4 cmd_addr 0 |
| * 19:17 bank_addr 0 |
| * 23:20 rank_sel 0 0001 |
| * 27:24 cmddelay 0 |
| * 30:24 Reserved |
| */ |
| /* MCMD: MR2 */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80004403); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00004403)) |
| return DDR_TIMEOUT; |
| /* MCMD: MR3 */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80000003); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00000003)) |
| return DDR_TIMEOUT; |
| /* MCMD: MR1 */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80000043); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00000043)) |
| return DDR_TIMEOUT; |
| /* MCMD: MR0 */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80015203); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00015203)) |
| return DDR_TIMEOUT; |
| /* MCMD: ZQS cmd, long 5 short 4 */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80104005); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00104005)) |
| return DDR_TIMEOUT; |
| /* MCMD: deselect command */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100000); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00100000)) |
| return DDR_TIMEOUT; |
| /* MCMD: deselect command */ |
| write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x8010000A); |
| /* MRS cmd wait for completion */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x0010000A)) |
| return DDR_TIMEOUT; |
| |
| /* DCFG : DRAM Density 256 Mb 16 Bit IO Width |
| * 1:0 Devicw Width 1 x8, 2 x16, 3 x32 2 |
| * 5:2 Density 2Gb = 5 |
| * 6 Dram Type (MDDR/LPDDR2) Only 0 |
| * 7 Reserved 0 |
| * 10:8 Address Map R/B/C = 1 |
| * 31:11 Reserved |
| */ |
| write32(DDR_PCTL + DDR_PCTL_DCFG_OFFSET, 0x00000116); |
| /* PCFG_0 : Port 0 AXI config */ |
| write32(DDR_PCTL + DDR_PCTL_PCFG0_OFFSET, 0x000800A0); |
| /* SCTL : UPCTL switch INIT CONFIG State */ |
| write32(DDR_PCTL + DDR_PCTL_SCTL_OFFSET, 0x00000001); |
| /* STAT : Wait for Switch INIT to Config State */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_STAT_OFFSET, 0x00000001)) |
| return DDR_TIMEOUT; |
| /* STAT : Wait for Switch INIT to Config State */ |
| write32(DDR_PCTL + DDR_PCTL_CMDTSTATEN_OFFSET, 0x00000001); |
| /* STAT : Wait for Switch INIT to Config State */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_CMDTSTAT_OFFSET, |
| 0x00000001)) |
| return DDR_TIMEOUT; |
| /* Use PHY for DRAM init */ |
| write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x00000181); |
| /* STAT : Wait for Switch INIT to Config State */ |
| if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x00000001F)) |
| return DDR_TIMEOUT; |
| /* SCTL : UPCTL switch Config to ACCESS State */ |
| write32(DDR_PCTL + DDR_PCTL_SCTL_OFFSET, 0x00000002); |
| /* STAT : Wait for switch CFG -> GO State */ |
| if (wait_for_completion(DDR_PCTL + DDR_PCTL_STAT_OFFSET, 0x3)) |
| return DDR_TIMEOUT; |
| |
| return 0; |
| } |