670 lines
21 KiB
C
670 lines
21 KiB
C
|
/*
|
||
|
* 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.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||
|
* MA 02110-1301 USA
|
||
|
*/
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <arch/cpu.h>
|
||
|
#include <delay.h>
|
||
|
#include <arch/io.h>
|
||
|
#include <soc/ddr_init.h>
|
||
|
#include <timer.h>
|
||
|
|
||
|
#define MAX_WAIT_MICROS 100000
|
||
|
|
||
|
#define TOPLEVEL_REGS 0xB8149000
|
||
|
|
||
|
#define DDR_CTRL_OFFSET (0x0020)
|
||
|
#define DDR_CLK_EN_MASK (0x00000002)
|
||
|
#define DDR_CLK_EN_SHIFT (1)
|
||
|
#define DDR_CLK_EN_LENGTH (1)
|
||
|
|
||
|
#define DDR_PCTL 0xB8180000
|
||
|
#define DDR_PCTL_TOGCNT1U_OFFSET (0x00C0)
|
||
|
#define DDR_PCTL_TINIT_OFFSET (0x00C4)
|
||
|
#define DDR_PCTL_TRSTH_OFFSET (0x00C8)
|
||
|
#define DDR_PCTL_TOGG_CNTR_100NS_OFFSET (0x00CC)
|
||
|
#define DDR_PCTL_MCFG_OFFSET (0x0080)
|
||
|
#define DDR_PCTL_MCFG1_OFFSET (0x007C)
|
||
|
#define DDR_PCTL_MSTAT_OFFSET (0x0088)
|
||
|
#define DDR_PCTL_DFISTAT0_OFFSET (0x02C0)
|
||
|
#define DDR_PCTL_POWCTL_OFFSET (0x0044)
|
||
|
#define DDR_PCTL_POWSTAT_OFFSET (0x0048)
|
||
|
#define DDR_PCTL_DTUAWDT_OFFSET (0x00B0)
|
||
|
#define DDR_PCTL_TREFI_OFFSET (0x00D0)
|
||
|
#define DDR_PCTL_TMRD_OFFSET (0x00D4)
|
||
|
#define DDR_PCTL_TRFC_OFFSET (0x00D8)
|
||
|
#define DDR_PCTL_TRP_OFFSET (0x00DC)
|
||
|
#define DDR_PCTL_TAL_OFFSET (0x00E4)
|
||
|
#define DDR_PCTL_TCL_OFFSET (0x00E8)
|
||
|
#define DDR_PCTL_TCWL_OFFSET (0x00EC)
|
||
|
#define DDR_PCTL_TRAS_OFFSET (0x00F0)
|
||
|
#define DDR_PCTL_TRC_OFFSET (0x00F4)
|
||
|
#define DDR_PCTL_TRCD_OFFSET (0x00F8)
|
||
|
#define DDR_PCTL_TRRD_OFFSET (0x00FC)
|
||
|
#define DDR_PCTL_TRTP_OFFSET (0x0100)
|
||
|
#define DDR_PCTL_TWR_OFFSET (0x0104)
|
||
|
#define DDR_PCTL_TWTR_OFFSET (0x0108)
|
||
|
#define DDR_PCTL_TEXSR_OFFSET (0x010C)
|
||
|
#define DDR_PCTL_TXP_OFFSET (0x0110)
|
||
|
#define DDR_PCTL_TDQS_OFFSET (0x0120)
|
||
|
#define DDR_PCTL_TXPDLL_OFFSET (0x0114)
|
||
|
#define DDR_PCTL_TRTW_OFFSET (0x00E0)
|
||
|
#define DDR_PCTL_TCKE_OFFSET (0x012C)
|
||
|
#define DDR_PCTL_TMOD_OFFSET (0x0130)
|
||
|
#define DDR_PCTL_TCKESR_OFFSET (0x0140)
|
||
|
#define DDR_PCTL_SCFG_OFFSET (0x0000)
|
||
|
#define DDR_PCTL_DFIWRLAT_OFFSET (0x0254)
|
||
|
#define DDR_PCTL_DFITRDDATAEN_OFFSET (0x0260)
|
||
|
#define DDR_PCTL_DFITPHYWRDATA_OFFSET (0x0250)
|
||
|
#define DDR_PCTL_DFITPHYRDLAT_OFFSET (0x0264)
|
||
|
#define DDR_PCTL_SCTL_OFFSET (0x0004)
|
||
|
#define DDR_PCTL_STAT_OFFSET (0x0008)
|
||
|
#define DDR_PCTL_DFISTCFG0_OFFSET (0x02C4)
|
||
|
#define DDR_PCTL_DFISTCFG1_OFFSET (0x02C8)
|
||
|
#define DDR_PCTL_DFISTCFG2_OFFSET (0x02D8)
|
||
|
#define DDR_PCTL_DFILPCFG0_OFFSET (0x02F0)
|
||
|
#define DDR_PCTL_DFIODTCFG_OFFSET (0x0244)
|
||
|
#define DDR_PCTL_DFIODTCFG1_OFFSET (0x0248)
|
||
|
#define DDR_PCTL_MCMD_OFFSET (0x0040)
|
||
|
#define DDR_PCTL_DFIUPDCFG_OFFSET (0x0290)
|
||
|
#define DDR_PCTL_CCFG_OFFSET (0x0480)
|
||
|
#define DDR_PCTL_DCFG_OFFSET (0x0484)
|
||
|
#define DDR_PCTL_PCFG0_OFFSET (0x0400)
|
||
|
#define DDR_PCTL_DTUWACTL_OFFSET (0x0200)
|
||
|
#define DDR_PCTL_DTURACTL_OFFSET (0x0204)
|
||
|
#define DDR_PCTL_DTUCFG_OFFSET (0x0208)
|
||
|
#define DDR_PCTL_DTUECTL_OFFSET (0x020C)
|
||
|
#define DDR_PCTL_DTUWD0_OFFSET (0x0210)
|
||
|
#define DDR_PCTL_DTUWD1_OFFSET (0x0214)
|
||
|
#define DDR_PCTL_DTUWD2_OFFSET (0x0218)
|
||
|
#define DDR_PCTL_DTUWD3_OFFSET (0x021C)
|
||
|
#define DDR_PCTL_CCFG1_OFFSET (0x048C)
|
||
|
|
||
|
#define DDR_PHY 0xB8180800
|
||
|
#define DDRPHY_DCR_OFFSET (0x0030)
|
||
|
#define DDRPHY_MR_OFFSET (0x0040)
|
||
|
#define DDRPHY_EMR_OFFSET (0x0044)
|
||
|
#define DDRPHY_EMR2_OFFSET (0x0048)
|
||
|
#define DDRPHY_DSGCR_OFFSET (0x002C)
|
||
|
#define DDRPHY_DTPR0_OFFSET (0x0034)
|
||
|
#define DDRPHY_DTPR1_OFFSET (0x0038)
|
||
|
#define DDRPHY_DTPR2_OFFSET (0x003C)
|
||
|
#define DDRPHY_PTR0_OFFSET (0x0018)
|
||
|
#define DDRPHY_PTR1_OFFSET (0x001C)
|
||
|
#define DDRPHY_PGSR_OFFSET (0x000C)
|
||
|
#define DDRPHY_PIR_OFFSET (0x0004)
|
||
|
#define DDRPHY_BISTRR_OFFSET (0x0100)
|
||
|
#define DDRPHY_BISTWCR_OFFSET (0x010C)
|
||
|
#define DDRPHY_BISTAR0_OFFSET (0x0114)
|
||
|
#define DDRPHY_BISTAR1_OFFSET (0x0118)
|
||
|
#define DDRPHY_BISTAR2_OFFSET (0x011C)
|
||
|
#define DDRPHY_BISTGSR_OFFSET (0x0124)
|
||
|
#define DDRPHY_BISTUDPR_OFFSET (0x0120)
|
||
|
#define DDRPHY_DLLGCR_OFFSET (0x0010)
|
||
|
|
||
|
#define BL8 1
|
||
|
#define UMCTL_INIT 0
|
||
|
|
||
|
#define DDR_TIMEOUT_VALUE_US 100000
|
||
|
|
||
|
static int wait_for_completion(u32 reg, u32 exp_val)
|
||
|
{
|
||
|
struct stopwatch sw;
|
||
|
|
||
|
stopwatch_init_usecs_expire(&sw, DDR_TIMEOUT_VALUE_US);
|
||
|
while (read32(reg) != exp_val) {
|
||
|
if (stopwatch_expired(&sw))
|
||
|
return DDR_TIMEOUT;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Configuration for the Winbond W972GG6JB-25 part using
|
||
|
* Synopsys DDR uMCTL and DDR Phy
|
||
|
*/
|
||
|
int init_ddr2(void)
|
||
|
{
|
||
|
|
||
|
u32 exp_val;
|
||
|
u32 mr, md_dllrst, emr, emr2, emr3;
|
||
|
|
||
|
/*
|
||
|
* Reset the AXI bridge and DDR Controller in case any spurious
|
||
|
* writes have already happened to DDR - note must be done together,
|
||
|
* not sequentially
|
||
|
*/
|
||
|
write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x00000000);
|
||
|
write32(TOPLEVEL_REGS + DDR_CTRL_OFFSET, 0x0000000F);
|
||
|
|
||
|
/*
|
||
|
* Dummy read to fence the access between the reset above
|
||
|
* and thw 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, 0x00000000);
|
||
|
/* 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 0 = 4 1 = 8
|
||
|
* 1 RDRIMM 0
|
||
|
* 2 BL8 Burst Terminate 0
|
||
|
* 3 2T = 0
|
||
|
* 4 Multi Rank 0
|
||
|
* 5 DDR3 En 0
|
||
|
* 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,
|
||
|
0x00060000 | (BL8 ? 0x1 : 0x0));
|
||
|
/* 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 => DDR2 2
|
||
|
* 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, 0x0000000A);
|
||
|
/* Generate to use with PHY and PCTL */
|
||
|
md_dllrst = 0x0B62 | (BL8 ? 0x1 : 0x0);
|
||
|
/* Generate to use with PHY and PCTL
|
||
|
* 2:0 BL 8 011
|
||
|
* 3 BT Sequential 0 Interleaved 1 = 0
|
||
|
* 6:4 CL 6
|
||
|
* 7 TM Normal 0
|
||
|
* 8 DLL Reset 1 (self Clearing)
|
||
|
* 11:9 WR 15 ns 6 (101)
|
||
|
* 12 PD Slow 1 Fast 0 0
|
||
|
*/
|
||
|
mr = 0x0A62 | (BL8 ? 0x1 : 0x0);
|
||
|
/* MR0 : MR Register, bits 12:0 imported dfrom MR
|
||
|
* 12:0 md_dllrst
|
||
|
* c15:13 RSVD RSVD
|
||
|
* 31:16 Reserved
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_MR_OFFSET, 0x00000000 | mr);
|
||
|
/* Generate to use with PHY and PCTL
|
||
|
* 0 DE DLL Enable 0 Disable 1
|
||
|
* 1 DIC Output Driver Imp Ctl 0 Full, 1 Half
|
||
|
* 6,2 ODT 0 Disable, 1 75R, 2 150R, 3 50R = 1
|
||
|
* 5:3 AL = 0
|
||
|
* 9:7 OCD = 0
|
||
|
* 10 DQS 0 diff, 1 single = 0
|
||
|
* 11 RDQS NA 0
|
||
|
* 12 QOFF Normal mode 0
|
||
|
*/
|
||
|
emr = 0x4;
|
||
|
/* MR1 : EMR Register
|
||
|
* 12:0 EMR1
|
||
|
* 15:13 RSVD
|
||
|
* 31:16 Reserved
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_EMR_OFFSET, 0x00000000 | emr);
|
||
|
|
||
|
/* Generate to use with PHY and PCTL
|
||
|
* 2:0 PASR, NA 000
|
||
|
* 3 DDC NA 0
|
||
|
* 6:4 RSVD
|
||
|
* 7 SFR 0
|
||
|
*/
|
||
|
emr2 = 0x0;
|
||
|
/* MR2 : EMR2 Register
|
||
|
* 7:0 EMR2
|
||
|
* 15:8 RSVD
|
||
|
* 31:16 Reserved
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_EMR2_OFFSET, 0x00000000 | emr2);
|
||
|
emr3 = 0x0;
|
||
|
/* 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 0
|
||
|
* 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 0
|
||
|
* 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, 0xF2000007);
|
||
|
/* DTPR0 : DRAM Timing Params 0
|
||
|
* 1:0 tMRD 2
|
||
|
* 4:2 tRTP 3
|
||
|
* 7:5 tWTR 3
|
||
|
* 11:8 tRP 6
|
||
|
* 15:12 tRCD 6
|
||
|
* 20:16 tRAS 18
|
||
|
* 24:21 tRRD 4
|
||
|
* 30:25 tRC 24 (23)
|
||
|
* 31 tCCD 0 BL/2 Cas to Cas
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_DTPR0_OFFSET, 0x3092666E);
|
||
|
/* 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 4 Bank Act 45ns = 18 18
|
||
|
* 10:9 tMOD DDR3 Only 0
|
||
|
* 11 tRTODT DDR3 Only 0
|
||
|
* 15:12 Reserved
|
||
|
* 23:16 tRFC 195ns 78 def 131 78d
|
||
|
* 26:24 tDQSCK LPDDR2 only 1
|
||
|
* 29:27 tDQSCKmax 1
|
||
|
* 31:30 Reserved
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_DTPR1_OFFSET, 0x094E0092);
|
||
|
/* DTPR2 : DRAM Timing Params 2
|
||
|
* 9:0 tXS exit SR def 200, 200d
|
||
|
* 14:10 tXP PD Exit Del 8 3
|
||
|
* 18:15 tCKE CKE Min pulse 3
|
||
|
* 28:19 tDLLK DLL Lock time 200d
|
||
|
* 32:29 Reserved
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_DTPR2_OFFSET, 0x06418CC8);
|
||
|
/* 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 200us 80,000 Dec 0x13880
|
||
|
* 29:19 : tDINIT1 DRAM Init time 400ns 160 Dec 0xA0
|
||
|
*/
|
||
|
write32(DDR_PHY + DDRPHY_PTR1_OFFSET, 0x05013880);
|
||
|
|
||
|
/* PGSR : Wait for INIT/DLL/Z Done from Power on Reset */
|
||
|
if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET, 0x00000007))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
if (UMCTL_INIT == 1) {
|
||
|
/* PIR : Trigger INIT/DLL/Z following soft reset of DLL & ITM */
|
||
|
write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x0000001F);
|
||
|
|
||
|
/* PGSR : Wait for INIT?DLL?Z Done from SOFT Reset */
|
||
|
if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET,
|
||
|
0x00000007))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* PIR : use uMCTL for DRAM Init */
|
||
|
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;
|
||
|
|
||
|
} else {
|
||
|
/* PIR : use uMCTL for DRAM Init */
|
||
|
write32(DDR_PHY + DDRPHY_PIR_OFFSET, 0x000001DF);
|
||
|
/* PGSR : Wait for DRAM Init Done */
|
||
|
|
||
|
if (wait_for_completion(DDR_PHY + DDRPHY_PGSR_OFFSET,
|
||
|
0x0000001F))
|
||
|
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, 0x00000001);
|
||
|
|
||
|
/* 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 3 */
|
||
|
write32(DDR_PCTL + DDR_PCTL_TMRD_OFFSET, 0x00000002);
|
||
|
/*
|
||
|
* 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 tRPall 8 bank 1
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_TRP_OFFSET, 0x00010006);
|
||
|
/* TAL : Additive Latency Register -- AL in MR1 */
|
||
|
write32(DDR_PCTL + DDR_PCTL_TAL_OFFSET, 0x00000000);
|
||
|
/* 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);
|
||
|
/* 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
|
||
|
* Range 8 to 24: 45ns / 2.5ns = 18d
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_TRAS_OFFSET, 0x00000012);
|
||
|
/*
|
||
|
* TRC : Min. ROW cylce time
|
||
|
* Range 11 to 31: 57.5ns / 2.5ns = 23d Playing safe 24
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_TRC_OFFSET, 0x00000018);
|
||
|
/*
|
||
|
* TRCD : Row to Column Delay
|
||
|
* Range 3 to 7 (TCL = TRCD): 2.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: 7.3ns / 2.5ns = 3 */
|
||
|
write32(DDR_PCTL + DDR_PCTL_TRTP_OFFSET, 0x00000003);
|
||
|
/* 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: 7.3ns / 2.5ns = 3
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_TWTR_OFFSET, 0x00000003);
|
||
|
/* TEXSR : Exit Self Refresh to first valid cmd: tXS 200*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_TEXSR_OFFSET, 0x000000C8);
|
||
|
/*
|
||
|
* 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, 0x00000000);
|
||
|
/* 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);
|
||
|
/*
|
||
|
* 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);
|
||
|
/* 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
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
|
||
|
|
||
|
/* MRS cmd wait for completion */
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x00100001))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* 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;
|
||
|
|
||
|
/* DFISTCFG0 : Drive various DFI signals appropriately
|
||
|
* 0 dfi_init_start 0
|
||
|
* 1 dfi_freq_ratio_en 1
|
||
|
* 2 dfi_data_byte_disable_en 1
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_DFISTCFG0_OFFSET, 0x00000003);
|
||
|
/* 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 4
|
||
|
* 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, 0x06060004);
|
||
|
|
||
|
if (UMCTL_INIT == 1) {
|
||
|
/* MCMD : Deselect command */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100000);
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x00100000))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : Precharge ALL Banks */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x00100001))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, EMR2 -- High Temp Self refresh Disable */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80140003 | (emr2 << 4));
|
||
|
exp_val = (0x00140003 | (emr2 << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
exp_val))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS cmd, EMR3 */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80160003 | (emr3 << 4));
|
||
|
exp_val = (0x00160003 | (emr3 << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
exp_val))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, EMR-- DLL Enable */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80120003 | (emr << 4));
|
||
|
exp_val = (0x00120003 | (emr << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
exp_val))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, MR--DLL Reset */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
(0x80100003 | (md_dllrst << 4)));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80000000))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : Precharge ALL Banks */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100001);
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x00100001))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : Refresh Command */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100002);
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x00100002))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : Refresh Command */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x80100002);
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x00100002))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, MR0-- Initialize Device Operation */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80100003 | (mr << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET, 0x0))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, MR1-- Set OCD Calibration Default */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80123803 | (emr << 4));
|
||
|
exp_val = (0x00123803 | (emr << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
exp_val))
|
||
|
return DDR_TIMEOUT;
|
||
|
|
||
|
/* MCMD : MRS Cmd, MR1-- Exit OCD calibration Mode */
|
||
|
write32(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
0x80120003 | (emr << 4));
|
||
|
exp_val = (0x00120003 | (emr << 4));
|
||
|
if (wait_for_completion(DDR_PCTL + DDR_PCTL_MCMD_OFFSET,
|
||
|
exp_val))
|
||
|
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 = 0
|
||
|
* 31:11 Reserved
|
||
|
*/
|
||
|
write32(DDR_PCTL + DDR_PCTL_DCFG_OFFSET, 0x00000016);
|
||
|
|
||
|
/* PCFG_0 : Port 0 AXI config */
|
||
|
if (BL8 == 1)
|
||
|
write32(DDR_PCTL + DDR_PCTL_PCFG0_OFFSET, 0x000800A0);
|
||
|
else
|
||
|
write32(DDR_PCTL + DDR_PCTL_PCFG0_OFFSET, 0x000400A0);
|
||
|
|
||
|
/* 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;
|
||
|
}
|